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) public void ScriptRemoved(UUID itemID)
{ {
System.Console.WriteLine("TEST Script Removed!"); // System.Console.WriteLine("TEST Script Removed!");
} }
public void ObjectRemoved(UUID objectID) 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(); _mass = CalculateMass();
// No body or shape yet
PhysBody = new BulletBody(LocalID);
PhysShape = new BulletShape();
Linkset.Refresh(this); Linkset.Refresh(this);
DetailLog("{0},BSPrim.constructor,call", LocalID); 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() private void SetPhysicalProperties()
{ {
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody);
ZeroMotion(true); ZeroMotion(true);
ForcePosition = _position; 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. // Needs to be reset especially when an avatar is recreated after crossing a region boundry.
Flying = _flying; Flying = _flying;
BulletSimAPI.SetRestitution2(PhysBody.ptr, BSParam.AvatarRestitution); PhysicsScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution);
BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); PhysicsScene.PE.SetMargin(PhysShape, PhysicsScene.Params.collisionMargin);
BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); PhysicsScene.PE.SetLocalScaling(PhysShape, Scale);
BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
if (BSParam.CcdMotionThreshold > 0f) if (BSParam.CcdMotionThreshold > 0f)
{ {
BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
} }
UpdatePhysicalMassProperties(RawMass, false); UpdatePhysicalMassProperties(RawMass, false);
// Make so capsule does not fall over // 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); // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_DEACTIVATION); PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION);
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
// Do this after the object has been added to the world // Do this after the object has been added to the world
PhysBody.collisionType = CollisionType.Avatar; PhysBody.collisionType = CollisionType.Avatar;
PhysBody.ApplyCollisionMask(); PhysBody.ApplyCollisionMask(PhysicsScene);
} }
// The avatar's movement is controlled by this motor that speeds up and slows down // 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) if (!Flying && !IsColliding)
{ {
stepVelocity.Z = _velocity.Z; stepVelocity.Z = _velocity.Z;
DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
LocalID, stepVelocity);
} }
// 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. // '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); AddForce(moveForce, false, true);
} }
*/ */
DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
LocalID, stepVelocity, _velocity, Mass, moveForce);
AddForce(moveForce, false, true); AddForce(moveForce, false, true);
}); });
} }
@ -267,10 +265,10 @@ public sealed class BSCharacter : BSPhysObject
{ {
if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape)
{ {
BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); PhysicsScene.PE.SetLocalScaling(PhysShape, Scale);
UpdatePhysicalMassProperties(RawMass, true); UpdatePhysicalMassProperties(RawMass, true);
// Make sure this change appears as a property update event // 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() PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
{ {
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
BulletSimAPI.ClearAllForces2(PhysBody.ptr); PhysicsScene.PE.ClearAllForces(PhysBody);
}); });
} }
public override void ZeroAngularMotion(bool inTaintTime) public override void ZeroAngularMotion(bool inTaintTime)
@ -322,10 +320,10 @@ public sealed class BSCharacter : BSPhysObject
{ {
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero);
BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, 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. // 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 { public override OMV.Vector3 Position {
get { get {
// Don't refetch the position because this function is called a zillion times // 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; return _position;
} }
set { set {
@ -352,19 +350,19 @@ public sealed class BSCharacter : BSPhysObject
{ {
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
}); });
} }
} }
public override OMV.Vector3 ForcePosition { public override OMV.Vector3 ForcePosition {
get { get {
_position = BulletSimAPI.GetPosition2(PhysBody.ptr); _position = PhysicsScene.PE.GetPosition(PhysBody);
return _position; return _position;
} }
set { set {
_position = value; _position = value;
PositionSanityCheck(); 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); DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
}); });
ret = true; ret = true;
} }
@ -435,8 +433,8 @@ public sealed class BSCharacter : BSPhysObject
} }
public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) public override void UpdatePhysicalMassProperties(float physMass, bool inWorld)
{ {
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); OMV.Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); PhysicsScene.PE.SetMassProps(PhysBody, physMass, localInertia);
} }
public override OMV.Vector3 Force { public override OMV.Vector3 Force {
@ -448,7 +446,7 @@ public sealed class BSCharacter : BSPhysObject
{ {
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
if (PhysBody.HasPhysicalBody) 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; _currentFriction = BSParam.AvatarStandingFriction;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
} }
} }
else else
@ -531,12 +529,12 @@ public sealed class BSCharacter : BSPhysObject
{ {
_currentFriction = BSParam.AvatarFriction; _currentFriction = BSParam.AvatarFriction;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
} }
} }
BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
BulletSimAPI.Activate2(PhysBody.ptr, true); PhysicsScene.PE.Activate(PhysBody, true);
} }
} }
public override OMV.Vector3 Torque { public override OMV.Vector3 Torque {
@ -578,7 +576,7 @@ public sealed class BSCharacter : BSPhysObject
{ {
get get
{ {
_orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); _orientation = PhysicsScene.PE.GetOrientation(PhysBody);
return _orientation; return _orientation;
} }
set set
@ -586,8 +584,8 @@ public sealed class BSCharacter : BSPhysObject
_orientation = value; _orientation = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
// _position = BulletSimAPI.GetPosition2(BSBody.ptr); // _position = PhysicsScene.PE.GetPosition(BSBody);
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
} }
} }
} }
@ -638,9 +636,9 @@ public sealed class BSCharacter : BSPhysObject
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
if (_floatOnWater) if (_floatOnWater)
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
else 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 // Buoyancy is faked by changing the gravity applied to the object
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
if (PhysBody.HasPhysicalBody) 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() PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
{ {
// Bullet adds this central force to the total force for this tick // 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) 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]"; private static string LogHeader = "[BULLETSIM CONSTRAINT]";
protected BulletWorld m_world; protected BulletWorld m_world;
protected BSScene PhysicsScene;
protected BulletBody m_body1; protected BulletBody m_body1;
protected BulletBody m_body2; protected BulletBody m_body2;
protected BulletConstraint m_constraint; protected BulletConstraint m_constraint;
@ -48,8 +49,10 @@ public abstract class BSConstraint : IDisposable
public abstract ConstraintType Type { get; } public abstract ConstraintType Type { get; }
public bool IsEnabled { get { return m_enabled; } } public bool IsEnabled { get { return m_enabled; } }
public BSConstraint() public BSConstraint(BulletWorld world)
{ {
m_world = world;
PhysicsScene = m_world.physicsScene;
} }
public virtual void Dispose() public virtual void Dispose()
@ -59,11 +62,11 @@ public abstract class BSConstraint : IDisposable
m_enabled = false; m_enabled = false;
if (m_constraint.HasPhysicalConstraint) 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}", m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}",
BSScene.DetailLogZero, BSScene.DetailLogZero,
m_body1.ID, m_body1.ptr.ToString("X"), m_body1.ID, m_body1.AddrString,
m_body2.ID, m_body2.ptr.ToString("X"), m_body2.ID, m_body2.AddrString,
success); success);
m_constraint.Clear(); m_constraint.Clear();
} }
@ -74,7 +77,7 @@ public abstract class BSConstraint : IDisposable
{ {
bool ret = false; bool ret = false;
if (m_enabled) if (m_enabled)
ret = BulletSimAPI.SetLinearLimits2(m_constraint.ptr, low, high); ret = PhysicsScene.PE.SetLinearLimits(m_constraint, low, high);
return ret; return ret;
} }
@ -82,7 +85,7 @@ public abstract class BSConstraint : IDisposable
{ {
bool ret = false; bool ret = false;
if (m_enabled) if (m_enabled)
ret = BulletSimAPI.SetAngularLimits2(m_constraint.ptr, low, high); ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high);
return ret; return ret;
} }
@ -91,7 +94,7 @@ public abstract class BSConstraint : IDisposable
bool ret = false; bool ret = false;
if (m_enabled) if (m_enabled)
{ {
BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.ptr, cnt); PhysicsScene.PE.SetConstraintNumSolverIterations(m_constraint, cnt);
ret = true; ret = true;
} }
return ret; return ret;
@ -103,7 +106,7 @@ public abstract class BSConstraint : IDisposable
if (m_enabled) if (m_enabled)
{ {
// Recompute the internal transforms // Recompute the internal transforms
BulletSimAPI.CalculateTransforms2(m_constraint.ptr); PhysicsScene.PE.CalculateTransforms(m_constraint);
ret = true; ret = true;
} }
return ret; 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) // Setting an object's mass to zero (making it static like when it's selected)
// automatically disables the constraints. // automatically disables the constraints.
// If the link is enabled, be sure to set the constraint itself to enabled. // 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 else
{ {

View File

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

View File

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

View File

@ -558,30 +558,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Friction affects are handled by this vehicle code // Friction affects are handled by this vehicle code
float friction = 0f; float friction = 0f;
BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); PhysicsScene.PE.SetFriction(Prim.PhysBody, friction);
// Moderate angular movement introduced by Bullet. // Moderate angular movement introduced by Bullet.
// TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
// Maybe compute linear and angular factor and damping from params. // Maybe compute linear and angular factor and damping from params.
float angularDamping = BSParam.VehicleAngularDamping; 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 // 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); Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia);
BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody);
Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); 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}", VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}",
Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping);
} }
else 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) if ((m_knownChanged & m_knownChangedVelocity) != 0)
{ {
Prim.ForceVelocity = m_knownVelocity; Prim.ForceVelocity = m_knownVelocity;
BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity);
} }
if ((m_knownChanged & m_knownChangedForce) != 0) if ((m_knownChanged & m_knownChangedForce) != 0)
@ -661,7 +661,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
Prim.ForceRotationalVelocity = m_knownRotationalVelocity; Prim.ForceRotationalVelocity = m_knownRotationalVelocity;
// Fake out Bullet by making it think the velocity is the same as last time. // 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) 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 // 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. // an UpdateProperties event to send the changes up to the simulator.
BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); PhysicsScene.PE.PushUpdate(Prim.PhysBody);
} }
m_knownChanged = 0; m_knownChanged = 0;
} }
@ -823,7 +823,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (!IsActive) return; if (!IsActive) return;
if (PhysicsScene.VehiclePhysicalLoggingEnabled) if (PhysicsScene.VehiclePhysicalLoggingEnabled)
BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr); PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
ForgetKnownVehicleProperties(); ForgetKnownVehicleProperties();
@ -840,7 +840,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
PushKnownChanged(); PushKnownChanged();
if (PhysicsScene.VehiclePhysicalLoggingEnabled) 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}", VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); 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 // The origional prims are removed from the world as the shape of the root compound
// shape takes over. // shape takes over.
BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); PhysicsScene.PE.AddToCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); PhysicsScene.PE.ForceActivationState(child.PhysBody, ActivationState.DISABLE_SIMULATION);
// We don't want collisions from the old linkset children. // 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; child.PhysBody.collisionType = CollisionType.LinksetChild;
@ -159,12 +159,12 @@ public sealed class BSLinksetCompound : BSLinkset
else else
{ {
// The non-physical children can come back to life. // 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; child.PhysBody.collisionType = CollisionType.LinksetChild;
// Don't force activation so setting of DISABLE_SIMULATION can stay if used. // 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; ret = true;
} }
return ret; return ret;
@ -196,7 +196,7 @@ public sealed class BSLinksetCompound : BSLinkset
bool ret = false; bool ret = false;
DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", 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)) 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}", DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
child.LocalID, child.LocalID,
LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString,
child.LocalID, child.PhysBody.ptr.ToString("X")); child.LocalID, child.PhysBody.AddrString);
// Cause the child's body to be rebuilt and thus restored to normal operation // Cause the child's body to be rebuilt and thus restored to normal operation
RecomputeChildWorldPosition(child, false); RecomputeChildWorldPosition(child, false);
@ -359,7 +359,7 @@ public sealed class BSLinksetCompound : BSLinkset
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
BulletShape newShape = cPrim.PhysShape; BulletShape newShape = cPrim.PhysShape;
cPrim.PhysShape = saveShape; 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 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}", PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); 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 return false; // 'false' says to move onto the next child in the list
@ -386,12 +386,7 @@ public sealed class BSLinksetCompound : BSLinkset
Rebuilding = false; Rebuilding = false;
} }
BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr); PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
// DEBUG: see of inter-linkset collisions are causing problems for constraint linksets.
// BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
} }
} }
} }

View File

@ -48,12 +48,15 @@ public sealed class BSLinksetConstraints : BSLinkset
{ {
base.Refresh(requestor); base.Refresh(requestor);
// Queue to happen after all the other taint processing if (HasAnyChildren && IsRoot(requestor))
PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() {
{ // Queue to happen after all the other taint processing
if (HasAnyChildren && IsRoot(requestor)) PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
RecomputeLinksetConstraints(); {
}); if (HasAnyChildren && IsRoot(requestor))
RecomputeLinksetConstraints();
});
}
} }
// The object is going dynamic (physical). Do any setup necessary // The object is going dynamic (physical). Do any setup necessary
@ -95,7 +98,7 @@ public sealed class BSLinksetConstraints : BSLinkset
bool ret = false; bool ret = false;
DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", 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) 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}", DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
childx.LocalID, childx.LocalID,
rootx.LocalID, rootx.PhysBody.ptr.ToString("X"), rootx.LocalID, rootx.PhysBody.AddrString,
childx.LocalID, childx.PhysBody.ptr.ToString("X")); childx.LocalID, childx.PhysBody.AddrString);
PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() 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}", DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
rootPrim.LocalID, rootPrim.LocalID,
rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"), rootPrim.LocalID, rootPrim.PhysBody.AddrString,
childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X"), childPrim.LocalID, childPrim.PhysBody.AddrString,
rootPrim.Position, childPrim.Position, midPoint); rootPrim.Position, childPrim.Position, midPoint);
// create a constraint that allows no freedom of movement between the two objects // 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; bool ret = false;
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
rootPrim.LocalID, rootPrim.LocalID,
rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"), rootPrim.LocalID, rootPrim.PhysBody.AddrString,
childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X")); childPrim.LocalID, childPrim.PhysBody.AddrString);
// Find the constraint for this link and get rid of it from the overall collection and from my list // 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)) if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
{ {
// Make the child refresh its location // Make the child refresh its location
BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr); PhysicsScene.PE.PushUpdate(childPrim.PhysBody);
ret = true; ret = true;
} }
@ -283,11 +286,8 @@ public sealed class BSLinksetConstraints : BSLinkset
float linksetMass = LinksetMass; float linksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true); 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}", 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) foreach (BSPhysObject child in m_children)
{ {
@ -304,11 +304,7 @@ public sealed class BSLinksetConstraints : BSLinkset
} }
constrain.RecomputeConstraintVariables(linksetMass); constrain.RecomputeConstraintVariables(linksetMass);
// DEBUG: see of inter-linkset collisions are causing problems // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
// BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
// BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // 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,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); },
(s) => { return s.UnmanagedParams[0].gravity; }, (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,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)", 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,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); },
(s) => { return LinearDamping; }, (s) => { return LinearDamping; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); }, (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)", new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
0f, 0f,
(s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); },
(s) => { return AngularDamping; }, (s) => { return AngularDamping; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); }, (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", new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
0.2f, 0.2f,
(s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); },
(s) => { return DeactivationTime; }, (s) => { return DeactivationTime; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); }, (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", new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
0.8f, 0.8f,
(s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); },
(s) => { return LinearSleepingThreshold; }, (s) => { return LinearSleepingThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); }, (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", new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
1.0f, 1.0f,
(s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); },
(s) => { return AngularSleepingThreshold; }, (s) => { return AngularSleepingThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, (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)" , new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
0f, // set to zero to disable 0f, // set to zero to disable
(s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); },
(s) => { return CcdMotionThreshold; }, (s) => { return CcdMotionThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, (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" , new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
0f, 0f,
(s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); },
(s) => { return CcdSweptSphereRadius; }, (s) => { return CcdSweptSphereRadius; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, (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" , new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
0.1f, 0.1f,
(s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); },
(s) => { return ContactProcessingThreshold; }, (s) => { return ContactProcessingThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, (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)", new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
(float)BSTerrainPhys.TerrainImplementation.Mesh, (float)BSTerrainPhys.TerrainImplementation.Mesh,

View File

@ -67,6 +67,11 @@ public abstract class BSPhysObject : PhysicsActor
PhysObjectName = name; PhysObjectName = name;
TypeName = typeName; 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); Linkset = BSLinkset.Factory(PhysicsScene, this);
LastAssetBuildFailed = false; LastAssetBuildFailed = false;
@ -303,7 +308,7 @@ public abstract class BSPhysObject : PhysicsActor
PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
{ {
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
}); });
} }
else 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. // Make sure there is a body there because sometimes destruction happens in an un-ideal order.
if (PhysBody.HasPhysicalBody) 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 // Return 'true' if the simulator wants collision events

View File

@ -111,10 +111,7 @@ public sealed class BSPrim : BSPhysObject
_mass = CalculateMass(); _mass = CalculateMass();
// No body or shape yet // Cause linkset variables to be initialized (like mass)
PhysBody = new BulletBody(LocalID);
PhysShape = new BulletShape();
Linkset.Refresh(this); Linkset.Refresh(this);
DetailLog("{0},BSPrim.constructor,call", LocalID); DetailLog("{0},BSPrim.constructor,call", LocalID);
@ -123,7 +120,7 @@ public sealed class BSPrim : BSPhysObject
{ {
CreateGeomAndObject(true); 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() PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
{ {
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
BulletSimAPI.ClearAllForces2(PhysBody.ptr); PhysicsScene.PE.ClearAllForces(PhysBody);
}); });
} }
public override void ZeroAngularMotion(bool inTaintTime) public override void ZeroAngularMotion(bool inTaintTime)
@ -268,8 +265,8 @@ public sealed class BSPrim : BSPhysObject
// DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _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. // 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; return _position;
} }
set { set {
@ -321,14 +318,14 @@ public sealed class BSPrim : BSPhysObject
} }
public override OMV.Vector3 ForcePosition { public override OMV.Vector3 ForcePosition {
get { get {
_position = BulletSimAPI.GetPosition2(PhysBody.ptr); _position = PhysicsScene.PE.GetPosition(PhysBody);
return _position; return _position;
} }
set { set {
_position = value; _position = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
} }
@ -408,10 +405,10 @@ public sealed class BSPrim : BSPhysObject
{ {
if (IsStatic) if (IsStatic)
{ {
BulletSimAPI.SetGravity2(PhysBody.ptr, PhysicsScene.DefaultGravity); PhysicsScene.PE.SetGravity(PhysBody, PhysicsScene.DefaultGravity);
Inertia = OMV.Vector3.Zero; Inertia = OMV.Vector3.Zero;
BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); PhysicsScene.PE.SetMassProps(PhysBody, 0f, Inertia);
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
} }
else else
{ {
@ -422,18 +419,18 @@ public sealed class BSPrim : BSPhysObject
// Changing interesting properties doesn't change proxy and collision cache // Changing interesting properties doesn't change proxy and collision cache
// information. The Bullet solution is to re-add the object to the world // information. The Bullet solution is to re-add the object to the world
// after parameters are changed. // 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. // 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); Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia);
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
// center of mass is at the zero of the object // 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); DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld);
if (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, // 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 // 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); DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force);
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, _force); PhysicsScene.PE.ApplyCentralForce(PhysBody, _force);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
} }
@ -586,7 +583,7 @@ public sealed class BSPrim : BSPhysObject
_velocity = value; _velocity = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
} }
@ -652,9 +649,9 @@ public sealed class BSPrim : BSPhysObject
{ {
if (PhysBody.HasPhysicalBody) 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); // 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 get
{ {
_orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); _orientation = PhysicsScene.PE.GetOrientation(PhysBody);
return _orientation; return _orientation;
} }
set set
{ {
_orientation = value; _orientation = value;
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
} }
} }
public override int PhysicsActorType { 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. // 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). // 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) // Set up the object physicalness (does gravity and collisions move this object)
MakeDynamic(IsStatic); MakeDynamic(IsStatic);
@ -743,7 +740,7 @@ public sealed class BSPrim : BSPhysObject
AddObjectToPhysicalWorld(); AddObjectToPhysicalWorld();
// Rebuild its shape // Rebuild its shape
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
// Recompute any linkset parameters. // Recompute any linkset parameters.
// When going from non-physical to physical, this re-enables the constraints that // When going from non-physical to physical, this re-enables the constraints that
@ -765,28 +762,28 @@ public sealed class BSPrim : BSPhysObject
if (makeStatic) if (makeStatic)
{ {
// Become a Bullet 'static' object type // 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 // Stop all movement
ZeroMotion(true); ZeroMotion(true);
// Set various physical properties so other object interact properly // Set various physical properties so other object interact properly
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction);
BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution);
// Mass is zero which disables a bunch of physics stuff in Bullet // Mass is zero which disables a bunch of physics stuff in Bullet
UpdatePhysicalMassProperties(0f, false); UpdatePhysicalMassProperties(0f, false);
// Set collision detection parameters // Set collision detection parameters
if (BSParam.CcdMotionThreshold > 0f) if (BSParam.CcdMotionThreshold > 0f)
{ {
BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
} }
// The activation state is 'disabled' so Bullet will not try to act on it. // 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. // 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 // This collides like a static object
PhysBody.collisionType = CollisionType.Static; PhysBody.collisionType = CollisionType.Static;
@ -797,22 +794,22 @@ public sealed class BSPrim : BSPhysObject
else else
{ {
// Not a Bullet static object // 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 // Set various physical properties so other object interact properly
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true); MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true);
BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction);
BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution);
// per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
// Since this can be called multiple times, only zero forces when becoming physical // 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 // 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 // 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 // A dynamic object has mass
UpdatePhysicalMassProperties(RawMass, false); UpdatePhysicalMassProperties(RawMass, false);
@ -820,22 +817,22 @@ public sealed class BSPrim : BSPhysObject
// Set collision detection parameters // Set collision detection parameters
if (BSParam.CcdMotionThreshold > 0f) if (BSParam.CcdMotionThreshold > 0f)
{ {
BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
} }
// Various values for simulation limits // Various values for simulation limits
BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping); PhysicsScene.PE.SetDamping(PhysBody, BSParam.LinearDamping, BSParam.AngularDamping);
BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, BSParam.DeactivationTime); PhysicsScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime);
BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); PhysicsScene.PE.SetSleepingThresholds(PhysBody, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold);
BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
// This collides like an object. // This collides like an object.
PhysBody.collisionType = CollisionType.Dynamic; PhysBody.collisionType = CollisionType.Dynamic;
// Force activation of the object so Bullet will act on it. // Force activation of the object so Bullet will act on it.
// Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. // 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. // There might be special things needed for implementing linksets.
Linkset.MakeDynamic(this); 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. // the functions after this one set up the state of a possibly newly created collision body.
private void MakeSolid(bool makeSolid) private void MakeSolid(bool makeSolid)
{ {
CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(PhysBody.ptr); CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(PhysBody);
if (makeSolid) if (makeSolid)
{ {
// Verify the previous code created the correct shape for this type of thing. // 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); 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 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); 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 // Change collision info from a static object to a ghosty collision object
PhysBody.collisionType = CollisionType.VolumeDetect; PhysBody.collisionType = CollisionType.VolumeDetect;
@ -877,7 +874,7 @@ public sealed class BSPrim : BSPhysObject
private void ActivateIfPhysical(bool forceIt) private void ActivateIfPhysical(bool forceIt)
{ {
if (IsPhysical && PhysBody.HasPhysicalBody) 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. // 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) if (wantsCollisionEvents)
{ {
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
} }
else 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) 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. // TODO: Fix this. Total kludge because adding object to world resets its gravity to default.
// Replace this when the new AddObjectToWorld function is complete. // 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 // 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); m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID);
DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType);
@ -944,9 +941,9 @@ public sealed class BSPrim : BSPhysObject
PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate() PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate()
{ {
if (_floatOnWater) if (_floatOnWater)
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
else 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; _rotationalVelocity = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
} }
@ -1064,7 +1061,7 @@ public sealed class BSPrim : BSPhysObject
DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
}); });
@ -1088,7 +1085,7 @@ public sealed class BSPrim : BSPhysObject
{ {
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.ApplyTorque2(PhysBody.ptr, angForce); PhysicsScene.PE.ApplyTorque(PhysBody, angForce);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
}); });
@ -1111,7 +1108,7 @@ public sealed class BSPrim : BSPhysObject
{ {
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); PhysicsScene.PE.ApplyTorqueImpulse(PhysBody, applyImpulse);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
}); });

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -42,14 +43,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
public sealed class BSScene : PhysicsScene, IPhysicsParameters public sealed class BSScene : PhysicsScene, IPhysicsParameters
{ {
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); internal static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS SCENE]"; internal static readonly string LogHeader = "[BULLETS SCENE]";
// The name of the region we're working for. // The name of the region we're working for.
public string RegionName { get; private set; } public string RegionName { get; private set; }
public string BulletSimVersion = "?"; 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 Dictionary<uint, BSPhysObject> PhysObjects;
public BSShapeCollection Shapes; public BSShapeCollection Shapes;
@ -99,11 +104,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Pinned memory used to pass step information between managed and unmanaged // Pinned memory used to pass step information between managed and unmanaged
internal int m_maxCollisionsPerFrame; internal int m_maxCollisionsPerFrame;
internal CollisionDesc[] m_collisionArray; internal CollisionDesc[] m_collisionArray;
internal GCHandle m_collisionArrayPinnedHandle;
internal int m_maxUpdatesPerFrame; internal int m_maxUpdatesPerFrame;
internal EntityProperties[] m_updateArray; 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 TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
public const uint GROUNDPLANE_ID = 1; 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 // A pointer to an instance if this structure is passed to the C++ code
// Used to pass basic configuration values to the unmanaged code. // Used to pass basic configuration values to the unmanaged code.
internal ConfigurationParameters[] UnmanagedParams; 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. // Sometimes you just have to log everything.
public Logging.LogWriter PhysicsLogging; public Logging.LogWriter PhysicsLogging;
@ -187,16 +184,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Allocate pinned memory to pass parameters. // Allocate pinned memory to pass parameters.
UnmanagedParams = new ConfigurationParameters[1]; UnmanagedParams = new ConfigurationParameters[1];
m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned);
// Set default values for physics parameters plus any overrides from the ini file // Set default values for physics parameters plus any overrides from the ini file
GetInitialParameterValues(config); GetInitialParameterValues(config);
// allocate more pinned memory close to the above in an attempt to get the memory all together // Get the connection to the physics engine (could be native or one of many DLLs)
m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; PE = SelectUnderlyingBulletEngine(BulletEngineName);
m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned);
m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
// Enable very detailed logging. // Enable very detailed logging.
// By creating an empty logger when not logging, the log message invocation code // 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(); PhysicsLogging = new Logging.LogWriter();
} }
// If Debug logging level, enable logging from the unmanaged code // Allocate memory for returning of the updates and collisions from the physics engine
m_DebugLogCallbackHandle = null; m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame];
if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
{
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);
// The bounding box for the simulated world. The origin is 0,0,0 unless we're // The bounding box for the simulated world. The origin is 0,0,0 unless we're
// a child in a mega-region. // 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. // area. It tracks active objects no matter where they are.
Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
// m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray);
World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(),
m_DebugLogCallbackHandle));
Constraints = new BSConstraintCollection(World); Constraints = new BSConstraintCollection(World);
@ -268,6 +244,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
{ {
BSParam.SetParameterConfigurationValues(this, pConfig); BSParam.SetParameterConfigurationValues(this, pConfig);
// There are two Bullet implementations to choose from
BulletEngineName = pConfig.GetString("BulletEngine", "BulletUnmanaged");
// Very detailed logging for physics debugging // Very detailed logging for physics debugging
// TODO: the boolean values can be moved to the normal parameter processing. // TODO: the boolean values can be moved to the normal parameter processing.
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
@ -309,16 +288,41 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
return ret; return ret;
} }
// Called directly from unmanaged code so don't do much // Select the connection to the actual Bullet implementation.
private void BulletLogger(string msg) // 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 string selectionName = engineName.ToLower();
private void BulletLoggerPhysLog(string msg) int hyphenIndex = engineName.IndexOf("-");
{ if (hyphenIndex > 0)
DetailLog("[BULLETS UNMANAGED]:" + msg); 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() public override void Dispose()
@ -355,7 +359,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
} }
// Anything left in the unmanaged code should be cleaned out // Anything left in the unmanaged code should be cleaned out
BulletSimAPI.Shutdown2(World.ptr); PE.Shutdown(World);
// Not logging any more // Not logging any more
PhysicsLogging.Close(); PhysicsLogging.Close();
@ -468,9 +472,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
LastTimeStep = timeStep; LastTimeStep = timeStep;
int updatedEntityCount = 0; int updatedEntityCount = 0;
IntPtr updatedEntitiesPtr;
int collidersCount = 0; int collidersCount = 0;
IntPtr collidersPtr;
int beforeTime = 0; int beforeTime = 0;
int simTime = 0; int simTime = 0;
@ -486,6 +488,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
TriggerPreStepEvent(timeStep); TriggerPreStepEvent(timeStep);
// the prestep actions might have added taints // the prestep actions might have added taints
numTaints += _taintOperations.Count;
ProcessTaints(); ProcessTaints();
InTaintTime = false; // Only used for debugging so locking is not necessary. 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. // 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. // Only enable this in a limited test world with few objects.
if (m_physicsPhysicalDumpEnabled) if (m_physicsPhysicalDumpEnabled)
BulletSimAPI.DumpAllInfo2(World.ptr); PE.DumpAllInfo(World);
// step the physical world one interval // step the physical world one interval
m_simulationStep++; m_simulationStep++;
int numSubSteps = 0; int numSubSteps = 0;
try try
{ {
if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); if (PhysicsLogging.Enabled)
beforeTime = Util.EnvironmentTickCount();
numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); if (PhysicsLogging.Enabled)
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", {
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, simTime = Util.EnvironmentTickCountSubtract(beforeTime);
updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); 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) catch (Exception e)
{ {
@ -521,8 +526,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
collidersCount = 0; 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. // Get a value for 'now' so all the collision and update routines don't have to get their own.
SimulationNowTime = Util.EnvironmentTickCount(); SimulationNowTime = Util.EnvironmentTickCount();
@ -564,7 +567,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Objects that are done colliding are removed from the ObjectsWithCollisions list. // Objects that are done colliding are removed from the ObjectsWithCollisions list.
// Not done above because it is inside an iteration of ObjectWithCollisions. // Not done above because it is inside an iteration of ObjectWithCollisions.
// This complex collision processing is required to create an empty collision // 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. // the simulator to generate the 'collision end' event.
if (ObjectsWithNoMoreCollisions.Count > 0) 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. // 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. // Only enable this in a limited test world with few objects.
if (m_physicsPhysicalDumpEnabled) if (m_physicsPhysicalDumpEnabled)
BulletSimAPI.DumpAllInfo2(World.ptr); PE.DumpAllInfo(World);
// The physics engine returns the number of milliseconds it simulated this call. // 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. // 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; 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); if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body);
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() 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); 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 the caller needs to know the old body is going away, pass the event up.
if (bodyCallback != null) bodyCallback(body); 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); 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. // 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); PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, new BulletShape());
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); PhysicsScene.PE.DestroyObject(PhysicsScene.World, body);
}); });
} }
} }
@ -259,9 +259,9 @@ public sealed class BSShapeCollection : IDisposable
{ {
// Native shapes are not tracked and are released immediately // Native shapes are not tracked and are released immediately
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", 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); if (shapeCallback != null) shapeCallback(shape);
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape);
} }
else else
{ {
@ -332,36 +332,36 @@ public sealed class BSShapeCollection : IDisposable
// Called at taint-time. // Called at taint-time.
private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback)
{ {
if (!BulletSimAPI.IsCompound2(shape.ptr)) if (!PhysicsScene.PE.IsCompound(shape))
{ {
// Failed the sanity check!! // Failed the sanity check!!
PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", 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}", 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; 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); if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren);
for (int ii = numChildren - 1; ii >= 0; ii--) for (int ii = numChildren - 1; ii >= 0; ii--)
{ {
IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); BulletShape childShape = PhysicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(shape, ii);
DereferenceAnonCollisionShape(childShape); 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. // 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. // Figure out type and call the correct dereference routine.
// Called at taint-time. // Called at taint-time.
private void DereferenceAnonCollisionShape(IntPtr cShape) private void DereferenceAnonCollisionShape(BulletShape shapeInfo)
{ {
MeshDesc meshDesc; MeshDesc meshDesc;
HullDesc hullDesc; HullDesc hullDesc;
BulletShape shapeInfo = new BulletShape(cShape); IntPtr cShape = shapeInfo.ptr;
if (TryGetMeshByPtr(cShape, out meshDesc)) if (TryGetMeshByPtr(cShape, out meshDesc))
{ {
shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH; shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH;
@ -376,13 +376,13 @@ public sealed class BSShapeCollection : IDisposable
} }
else else
{ {
if (BulletSimAPI.IsCompound2(cShape)) if (PhysicsScene.PE.IsCompound(shapeInfo))
{ {
shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND; shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND;
} }
else else
{ {
if (BulletSimAPI.IsNativeShape2(cShape)) if (PhysicsScene.PE.IsNativeShape(shapeInfo))
{ {
shapeInfo.isNativeShape = true; shapeInfo.isNativeShape = true;
shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter)
@ -400,7 +400,7 @@ public sealed class BSShapeCollection : IDisposable
else else
{ {
PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}", 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. // 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; OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero;
if (prim.PhysShape.HasPhysicalShape) 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}", 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); prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type);
@ -570,19 +570,15 @@ public sealed class BSShapeCollection : IDisposable
if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
{ {
// The proper scale has been calculated in the prim.
newShape = new BulletShape( newShape = PhysicsScene.PE.BuildCapsuleShape(PhysicsScene.World, 1f, 1f, prim.Scale);
// 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);
if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
} }
else else
{ {
// Native shapes are scaled in Bullet so set the scaling to the size // 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) 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) private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{ {
BulletShape newShape = new BulletShape();
IMesh meshData = null; IMesh meshData = null;
IntPtr meshPtr = IntPtr.Zero;
MeshDesc meshDesc; MeshDesc meshDesc;
if (Meshes.TryGetValue(newMeshKey, out meshDesc)) if (Meshes.TryGetValue(newMeshKey, out meshDesc))
{ {
// If the mesh has already been built just use it. // If the mesh has already been built just use it.
meshPtr = meshDesc.ptr; newShape = new BulletShape(meshDesc.ptr, BSPhysicsShapeType.SHAPE_MESH);
} }
else 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}", // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
// LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); // 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); indices.GetLength(0), indices, vertices.Count, verticesAsFloats);
} }
} }
BulletShape newShape = new BulletShape(meshPtr, BSPhysicsShapeType.SHAPE_MESH);
newShape.shapeKey = newMeshKey; newShape.shapeKey = newMeshKey;
return newShape; 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) private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{ {
BulletShape newShape = new BulletShape();
IntPtr hullPtr = IntPtr.Zero; IntPtr hullPtr = IntPtr.Zero;
HullDesc hullDesc; HullDesc hullDesc;
if (Hulls.TryGetValue(newHullKey, out hullDesc)) if (Hulls.TryGetValue(newHullKey, out hullDesc))
{ {
// If the hull shape already is created, just use it. // If the hull shape already is created, just use it.
hullPtr = hullDesc.ptr; newShape = new BulletShape(hullDesc.ptr, BSPhysicsShapeType.SHAPE_HULL);
} }
else else
{ {
@ -793,11 +791,10 @@ public sealed class BSShapeCollection : IDisposable
} }
} }
// create the hull data structure in Bullet // 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; newShape.shapeKey = newHullKey;
return newShape; 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. // Don't need to do this as the shape is freed when the new root shape is created below.
// DereferenceShape(prim.PhysShape, true, shapeCallback); // 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. // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
CreateGeomMeshOrHull(prim, shapeCallback); 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}", if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
prim.LocalID, cShape, prim.PhysShape); 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 not a solid object, body is a GhostObject. Otherwise a RigidBody.
if (!mustRebuild) 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 if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY
|| !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT)
{ {
@ -947,20 +944,16 @@ public sealed class BSShapeCollection : IDisposable
DereferenceBody(prim.PhysBody, true, bodyCallback); DereferenceBody(prim.PhysBody, true, bodyCallback);
BulletBody aBody; BulletBody aBody;
IntPtr bodyPtr = IntPtr.Zero;
if (prim.IsSolid) if (prim.IsSolid)
{ {
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, aBody = PhysicsScene.PE.CreateBodyFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation);
prim.LocalID, prim.RawPosition, prim.RawOrientation); if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
} }
else else
{ {
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, aBody = PhysicsScene.PE.CreateGhostFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation);
prim.LocalID, prim.RawPosition, prim.RawOrientation); if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
} }
aBody = new BulletBody(prim.LocalID, bodyPtr);
ReferenceBody(aBody, true); 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 // All shapes have a static call to get a reference to the physical shape
// protected abstract static BSShape GetReference(); // 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() public override string ToString()
{ {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.Append("<p="); buff.Append("<p=");
buff.Append(ptr.ToString("X")); buff.Append(AddrString);
buff.Append(",s="); buff.Append(",s=");
buff.Append(type.ToString()); buff.Append(type.ToString());
buff.Append(",k="); buff.Append(",k=");
@ -126,7 +132,8 @@ public class BSShapeNative : BSShape
BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
{ {
// Native shapes are not shared and are always built anew. // 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, private BSShapeNative(BSScene physicsScene, BSPhysObject prim,
@ -141,14 +148,15 @@ public class BSShapeNative : BSShape
nativeShapeData.HullKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey;
/*
if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) 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); physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
} }
else else
{ {
ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData); ptr = PhysicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData);
} }
if (ptr == IntPtr.Zero) if (ptr == IntPtr.Zero)
{ {
@ -157,15 +165,18 @@ public class BSShapeNative : BSShape
} }
type = shapeType; type = shapeType;
key = (UInt64)shapeKey; key = (UInt64)shapeKey;
*/
} }
// Make this reference to the physical shape go away since native shapes are not shared. // Make this reference to the physical shape go away since native shapes are not shared.
public override void Dereference(BSScene physicsScene) public override void Dereference(BSScene physicsScene)
{ {
/*
// Native shapes are not tracked and are released immediately // Native shapes are not tracked and are released immediately
physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); 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; ptr = IntPtr.Zero;
// Garbage collection will free up this instance. // Garbage collection will free up this instance.
*/
} }
} }

View File

@ -44,7 +44,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
{ {
static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]";
BulletHeightMapInfo m_mapInfo = null; BulletHMapInfo m_mapInfo = null;
// Constructor to build a default, flat heightmap terrain. // Constructor to build a default, flat heightmap terrain.
public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
@ -58,7 +58,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
{ {
initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; 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.minCoords = minTerrainCoords;
m_mapInfo.maxCoords = maxTerrainCoords; m_mapInfo.maxCoords = maxTerrainCoords;
m_mapInfo.terrainRegionBase = TerrainBase; m_mapInfo.terrainRegionBase = TerrainBase;
@ -72,7 +72,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
Vector3 minCoords, Vector3 maxCoords) Vector3 minCoords, Vector3 maxCoords)
: base(physicsScene, regionBase, id) : base(physicsScene, regionBase, id)
{ {
m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo = new BulletHMapInfo(id, initialMap);
m_mapInfo.minCoords = minCoords; m_mapInfo.minCoords = minCoords;
m_mapInfo.maxCoords = maxCoords; m_mapInfo.maxCoords = maxCoords;
m_mapInfo.minZ = minCoords.Z; 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. // Using the information in m_mapInfo, create the physical representation of the heightmap.
private void BuildHeightmapTerrain() 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 // Create the terrain shape from the mapInfo
m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape( m_mapInfo.ID,
BSPhysicsShapeType.SHAPE_TERRAIN); 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 // The terrain object initial position is at the center of the object
Vector3 centerPos; Vector3 centerPos;
@ -105,27 +103,26 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f);
centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f); centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f);
m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, m_mapInfo.terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_mapInfo.terrainShape,
BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, m_mapInfo.ID, centerPos, Quaternion.Identity);
m_mapInfo.ID, centerPos, Quaternion.Identity));
// Set current terrain attributes // Set current terrain attributes
BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction); PhysicsScene.PE.SetFriction(m_mapInfo.terrainBody, BSParam.TerrainFriction);
BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainHitFraction); PhysicsScene.PE.SetHitFraction(m_mapInfo.terrainBody, BSParam.TerrainHitFraction);
BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, BSParam.TerrainRestitution); PhysicsScene.PE.SetRestitution(m_mapInfo.terrainBody, BSParam.TerrainRestitution);
BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); PhysicsScene.PE.SetCollisionFlags(m_mapInfo.terrainBody, CollisionFlags.CF_STATIC_OBJECT);
// Return the new terrain to the world of physical objects // 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 // 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.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. // 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; return;
} }
@ -137,10 +134,9 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
{ {
if (m_mapInfo.terrainBody.HasPhysicalBody) 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. // Frees both the body and the shape.
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody);
BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr);
} }
} }
m_mapInfo = null; m_mapInfo = null;

View File

@ -133,20 +133,17 @@ public sealed class BSTerrainManager : IDisposable
public void CreateInitialGroundPlaneAndTerrain() public void CreateInitialGroundPlaneAndTerrain()
{ {
// The ground plane is here to catch things that are trying to drop to negative infinity // The ground plane is here to catch things that are trying to drop to negative infinity
BulletShape groundPlaneShape = new BulletShape( BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin);
BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape,
BSParam.TerrainCollisionMargin), BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity);
BSPhysicsShapeType.SHAPE_GROUNDPLANE);
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_groundPlane);
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_groundPlane);
Vector3.Zero, Quaternion.Identity));
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr);
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr);
// Ground plane does not move // 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. // Everything collides with the ground plane.
m_groundPlane.collisionType = CollisionType.Groundplane; 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. // 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); 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 (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(); 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}", PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}",
ID, indicesCount, indices.Length, verticesCount, vertices.Length); ID, indicesCount, indices.Length, verticesCount, vertices.Length);
m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices);
indicesCount, indices, verticesCount, vertices),
BSPhysicsShapeType.SHAPE_MESH);
if (!m_terrainShape.HasPhysicalShape) if (!m_terrainShape.HasPhysicalShape)
{ {
// DISASTER!! // DISASTER!!
@ -106,7 +104,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
Vector3 pos = regionBase; Vector3 pos = regionBase;
Quaternion rot = Quaternion.Identity; 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) if (!m_terrainBody.HasPhysicalBody)
{ {
// DISASTER!! // DISASTER!!
@ -116,34 +114,34 @@ public sealed class BSTerrainMesh : BSTerrainPhys
} }
// Set current terrain attributes // Set current terrain attributes
BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction); PhysicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction);
BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction); PhysicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction);
BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution); PhysicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution);
BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT);
// Static objects are not very massive. // 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 // 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 // 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.collisionType = CollisionType.Terrain;
m_terrainBody.ApplyCollisionMask(); m_terrainBody.ApplyCollisionMask(PhysicsScene);
// Make it so the terrain will not move or be considered for movement. // 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() public override void Dispose()
{ {
if (m_terrainBody.HasPhysicalBody) 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. // 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. // These hold pointers to allocated objects in the unmanaged space.
// The physics engine controller class created at initialization // The physics engine controller class created at initialization
public struct BulletWorld public class BulletWorld
{ {
public BulletWorld(uint worldId, BSScene bss, IntPtr xx) public BulletWorld(uint worldId, BSScene bss, IntPtr xx)
{ {
@ -50,7 +50,7 @@ public struct BulletWorld
} }
// An allocated Bullet btRigidBody // An allocated Bullet btRigidBody
public struct BulletBody public class BulletBody
{ {
public BulletBody(uint id) : this(id, IntPtr.Zero) public BulletBody(uint id) : this(id, IntPtr.Zero)
{ {
@ -72,23 +72,32 @@ public struct BulletBody
public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
// Apply the specificed collision mask into the physical world // 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. // 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 // (The collision masks are stored in the collision proxy cache which only exists for
// a collision body that is in the world.) // a collision body that is in the world.)
return BulletSimAPI.SetCollisionGroupMask2(ptr, return physicsScene.PE.SetCollisionGroupMask(this,
BulletSimData.CollisionTypeMasks[collisionType].group, BulletSimData.CollisionTypeMasks[collisionType].group,
BulletSimData.CollisionTypeMasks[collisionType].mask); 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() public override string ToString()
{ {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.Append("<id="); buff.Append("<id=");
buff.Append(ID.ToString()); buff.Append(ID.ToString());
buff.Append(",p="); buff.Append(",p=");
buff.Append(ptr.ToString("X")); buff.Append(AddrString);
buff.Append(",c="); buff.Append(",c=");
buff.Append(collisionType); buff.Append(collisionType);
buff.Append(">"); 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) public BulletShape(IntPtr xx, BSPhysicsShapeType typ)
@ -119,11 +133,20 @@ public struct BulletShape
} }
public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } 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() public override string ToString()
{ {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.Append("<p="); buff.Append("<p=");
buff.Append(ptr.ToString("X")); buff.Append(AddrString);
buff.Append(",s="); buff.Append(",s=");
buff.Append(type.ToString()); buff.Append(type.ToString());
buff.Append(",k="); buff.Append(",k=");
@ -136,7 +159,7 @@ public struct BulletShape
} }
// An allocated Bullet btConstraint // An allocated Bullet btConstraint
public struct BulletConstraint public class BulletConstraint
{ {
public BulletConstraint(IntPtr xx) public BulletConstraint(IntPtr xx)
{ {
@ -149,17 +172,25 @@ public struct BulletConstraint
ptr = IntPtr.Zero; ptr = IntPtr.Zero;
} }
public bool HasPhysicalConstraint { get { return 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. // An allocated HeightMapThing which holds various heightmap info.
// Made a class rather than a struct so there would be only one // Made a class rather than a struct so there would be only one
// instance of this and C# will pass around pointers rather // instance of this and C# will pass around pointers rather
// than making copies. // 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; ID = id;
Ptr = xx;
heightMap = hm; heightMap = hm;
terrainRegionBase = OMV.Vector3.Zero; terrainRegionBase = OMV.Vector3.Zero;
minCoords = new OMV.Vector3(100f, 100f, 25f); minCoords = new OMV.Vector3(100f, 100f, 25f);
@ -168,7 +199,6 @@ public class BulletHeightMapInfo
sizeX = sizeY = 256f; sizeX = sizeY = 256f;
} }
public uint ID; public uint ID;
public IntPtr Ptr;
public float[] heightMap; public float[] heightMap;
public OMV.Vector3 terrainRegionBase; public OMV.Vector3 terrainRegionBase;
public OMV.Vector3 minCoords; public OMV.Vector3 minCoords;

View File

@ -31,6 +31,7 @@ CRASHES
VEHICLES TODO LIST: VEHICLES TODO LIST:
================================================= =================================================
Angular motor direction is global coordinates rather than local coordinates
Border crossing with linked vehicle causes crash Border crossing with linked vehicle causes crash
Vehicles (Move smoothly) Vehicles (Move smoothly)
Add vehicle collisions so IsColliding is properly reported. Add vehicle collisions so IsColliding is properly reported.
@ -60,7 +61,8 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
BULLETSIM TODO LIST: 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. Revisit CollisionMargin. Builders notice the 0.04 spacing between prims.
Duplicating a physical prim causes old prim to jump away 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. 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. 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 The chain will fall apart and pairs will dance around on ground
Chains of 1x1x.2 will stay connected but will dance. 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, ...) Add PID motor for avatar movement (slow to stop, ...)
setForce should set a constant force. Different than AddImpulse. setForce should set a constant force. Different than AddImpulse.
Implement raycast. 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. Re-implement buoyancy as a separate force on the object rather than diddling gravity.
Register a pre-step event to add the force. Register a pre-step event to add the force.
More efficient memory usage when passing hull information from BSPrim to BulletSim 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 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 Linksets should allow collisions to individual children
Add LocalID to children shapes in LinksetCompound and create events for individuals Add LocalID to children shapes in LinksetCompound and create events for individuals
LinksetCompound: when one of the children changes orientation (like tires 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 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() Consider moving prim/character body and shape destruction in destroy()
to postTimeTime rather than protecting all the potential sets that to postTimeTime rather than protecting all the potential sets that
might have been queued up. 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. keeps the object from being freed, but that is just an accident.
Possibly have and 'active' flag that is checked by the taint processor? 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) 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 THREADING
================================================= =================================================
@ -253,3 +268,5 @@ llApplyImpulse()
(Resolution: tested on SL and OS. AddForce scales the force for timestep) (Resolution: tested on SL and OS. AddForce scales the force for timestep)
llSetBuoyancy() (DONE) llSetBuoyancy() (DONE)
(Resolution: Bullet resets object gravity when added to world. Moved set gravity) (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_ScriptDelayFactor = 1.0f;
protected float m_ScriptDistanceFactor = 1.0f; protected float m_ScriptDistanceFactor = 1.0f;
protected float m_MinTimerInterval = 0.5f; protected float m_MinTimerInterval = 0.5f;
protected float m_recoilScaleFactor = 0.0f;
protected DateTime m_timer = DateTime.Now; protected DateTime m_timer = DateTime.Now;
protected bool m_waitingForScriptAnswer = false; 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. // there's an smtp config, so load in the snooze time.
EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_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() public override Object InitializeLifetimeService()
@ -2829,10 +2834,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
PhysicsActor pa = new_group.RootPart.PhysActor; PhysicsActor pa = new_group.RootPart.PhysActor;
//Recoil.
if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
{ {
//Recoil. Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
llApplyImpulse(vel * groupmass, 0); if (recoil != Vector3.Zero)
{
llApplyImpulse(recoil, 0);
}
} }
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) // 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.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/> <Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
<Reference name="BulletXNA.dll" path="../../../../bin/"/>
<Reference name="log4net.dll" path="../../../../bin/"/> <Reference name="log4net.dll" path="../../../../bin/"/>
<Files> <Files>