Adding BulletSim module
parent
b0173de7ec
commit
05dbf31567
|
@ -0,0 +1,413 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Intel Corporation
|
||||
*
|
||||
* 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 copyright
|
||||
* 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 Intel Corporation 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.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSCharacter : PhysicsActor
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly string LogHeader = "[BULLETS CHAR]";
|
||||
|
||||
private BSScene _scene;
|
||||
private String _avName;
|
||||
private bool _stopped;
|
||||
private Vector3 _size;
|
||||
private Vector3 _scale;
|
||||
private PrimitiveBaseShape _pbs;
|
||||
private uint _localID = 0;
|
||||
private bool _grabbed;
|
||||
private bool _selected;
|
||||
private Vector3 _position;
|
||||
private float _mass = 80f;
|
||||
public float _density = 60f;
|
||||
public float CAPSULE_RADIUS = 0.37f;
|
||||
public float CAPSULE_LENGTH = 2.140599f;
|
||||
private Vector3 _force;
|
||||
private Vector3 _velocity;
|
||||
private Vector3 _torque;
|
||||
private float _collisionScore;
|
||||
private Vector3 _acceleration;
|
||||
private Quaternion _orientation;
|
||||
private int _physicsActorType;
|
||||
private bool _isPhysical;
|
||||
private bool _flying;
|
||||
private bool _setAlwaysRun;
|
||||
private bool _throttleUpdates;
|
||||
private bool _isColliding;
|
||||
private long _collidingStep;
|
||||
private bool _collidingGround;
|
||||
private long _collidingGroundStep;
|
||||
private bool _collidingObj;
|
||||
private bool _floatOnWater;
|
||||
private Vector3 _rotationalVelocity;
|
||||
private bool _kinematic;
|
||||
private float _buoyancy;
|
||||
|
||||
private int _subscribedEventsMs = 0;
|
||||
|
||||
private Vector3 _PIDTarget;
|
||||
private bool _usePID;
|
||||
private float _PIDTau;
|
||||
private bool _useHoverPID;
|
||||
private float _PIDHoverHeight;
|
||||
private PIDHoverType _PIDHoverType;
|
||||
private float _PIDHoverTao;
|
||||
|
||||
public BSCharacter(uint localID, String avName, BSScene parent_scene, Vector3 pos, Vector3 size, bool isFlying)
|
||||
{
|
||||
_localID = localID;
|
||||
_avName = avName;
|
||||
_scene = parent_scene;
|
||||
_position = pos;
|
||||
_size = size;
|
||||
_orientation = Quaternion.Identity;
|
||||
_velocity = Vector3.Zero;
|
||||
_scale = new Vector3(1f, 1f, 1f);
|
||||
float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH);
|
||||
_mass = _density*AVvolume;
|
||||
|
||||
ShapeData shapeData = new ShapeData();
|
||||
shapeData.ID = _localID;
|
||||
shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
|
||||
shapeData.Position = _position;
|
||||
shapeData.Rotation = _orientation;
|
||||
shapeData.Velocity = _velocity;
|
||||
shapeData.Scale = _scale;
|
||||
shapeData.Mass = _mass;
|
||||
shapeData.Flying = isFlying ? ShapeData.numericTrue : ShapeData.numericFalse;
|
||||
shapeData.Dynamic = ShapeData.numericFalse;
|
||||
|
||||
BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// called when this character is being destroyed and the resources should be released
|
||||
public void Destroy()
|
||||
{
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
|
||||
});
|
||||
}
|
||||
|
||||
public override void RequestPhysicsterseUpdate()
|
||||
{
|
||||
base.RequestPhysicsterseUpdate();
|
||||
}
|
||||
|
||||
public override bool Stopped {
|
||||
get { return _stopped; }
|
||||
}
|
||||
public override Vector3 Size {
|
||||
get { return _size; }
|
||||
set { _size = value;
|
||||
}
|
||||
}
|
||||
public override PrimitiveBaseShape Shape {
|
||||
set { _pbs = value;
|
||||
}
|
||||
}
|
||||
public override uint LocalID {
|
||||
set { _localID = value;
|
||||
}
|
||||
get { return _localID; }
|
||||
}
|
||||
public override bool Grabbed {
|
||||
set { _grabbed = value;
|
||||
}
|
||||
}
|
||||
public override bool Selected {
|
||||
set { _selected = value;
|
||||
}
|
||||
}
|
||||
public override void CrossingFailure() { return; }
|
||||
public override void link(PhysicsActor obj) { return; }
|
||||
public override void delink() { return; }
|
||||
public override void LockAngularMotion(Vector3 axis) { return; }
|
||||
|
||||
public override Vector3 Position {
|
||||
get {
|
||||
_position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
return _position;
|
||||
}
|
||||
set {
|
||||
_position = value;
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
});
|
||||
}
|
||||
}
|
||||
public override float Mass {
|
||||
get {
|
||||
return _mass;
|
||||
}
|
||||
}
|
||||
public override Vector3 Force {
|
||||
get { return _force; }
|
||||
set {
|
||||
_force = value;
|
||||
m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override int VehicleType {
|
||||
get { return 0; }
|
||||
set { return; }
|
||||
}
|
||||
public override void VehicleFloatParam(int param, float value) { }
|
||||
public override void VehicleVectorParam(int param, Vector3 value) {}
|
||||
public override void VehicleRotationParam(int param, Quaternion rotation) { }
|
||||
public override void VehicleFlags(int param, bool remove) { }
|
||||
|
||||
// Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
|
||||
public override void SetVolumeDetect(int param) { return; }
|
||||
|
||||
public override Vector3 GeometricCenter { get { return Vector3.Zero; } }
|
||||
public override Vector3 CenterOfMass { get { return Vector3.Zero; } }
|
||||
public override Vector3 Velocity {
|
||||
get { return _velocity; }
|
||||
set {
|
||||
_velocity = value;
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity);
|
||||
});
|
||||
}
|
||||
}
|
||||
public override Vector3 Torque {
|
||||
get { return _torque; }
|
||||
set { _torque = value;
|
||||
}
|
||||
}
|
||||
public override float CollisionScore {
|
||||
get { return _collisionScore; }
|
||||
set { _collisionScore = value;
|
||||
}
|
||||
}
|
||||
public override Vector3 Acceleration {
|
||||
get { return _acceleration; }
|
||||
}
|
||||
public override Quaternion Orientation {
|
||||
get { return _orientation; }
|
||||
set {
|
||||
_orientation = value;
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
_position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
});
|
||||
}
|
||||
}
|
||||
public override int PhysicsActorType {
|
||||
get { return _physicsActorType; }
|
||||
set { _physicsActorType = value;
|
||||
}
|
||||
}
|
||||
public override bool IsPhysical {
|
||||
get { return _isPhysical; }
|
||||
set { _isPhysical = value;
|
||||
}
|
||||
}
|
||||
public override bool Flying {
|
||||
get { return _flying; }
|
||||
set {
|
||||
_flying = value;
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.SetObjectFlying(_scene.WorldID, LocalID, _flying);
|
||||
});
|
||||
}
|
||||
}
|
||||
public override bool
|
||||
SetAlwaysRun {
|
||||
get { return _setAlwaysRun; }
|
||||
set { _setAlwaysRun = value; }
|
||||
}
|
||||
public override bool ThrottleUpdates {
|
||||
get { return _throttleUpdates; }
|
||||
set { _throttleUpdates = value; }
|
||||
}
|
||||
public override bool IsColliding {
|
||||
get { return (_collidingStep == _scene.SimulationStep); }
|
||||
set { _isColliding = value; }
|
||||
}
|
||||
public override bool CollidingGround {
|
||||
get { return (_collidingGroundStep == _scene.SimulationStep); }
|
||||
set { _collidingGround = value; }
|
||||
}
|
||||
public override bool CollidingObj {
|
||||
get { return _collidingObj; }
|
||||
set { _collidingObj = value; }
|
||||
}
|
||||
public override bool FloatOnWater {
|
||||
set { _floatOnWater = value; }
|
||||
}
|
||||
public override Vector3 RotationalVelocity {
|
||||
get { return _rotationalVelocity; }
|
||||
set { _rotationalVelocity = value; }
|
||||
}
|
||||
public override bool Kinematic {
|
||||
get { return _kinematic; }
|
||||
set { _kinematic = value; }
|
||||
}
|
||||
public override float Buoyancy {
|
||||
get { return _buoyancy; }
|
||||
set { _buoyancy = value; }
|
||||
}
|
||||
|
||||
// Used for MoveTo
|
||||
public override Vector3 PIDTarget {
|
||||
set { _PIDTarget = value; }
|
||||
}
|
||||
public override bool PIDActive {
|
||||
set { _usePID = value; }
|
||||
}
|
||||
public override float PIDTau {
|
||||
set { _PIDTau = value; }
|
||||
}
|
||||
|
||||
// Used for llSetHoverHeight and maybe vehicle height
|
||||
// Hover Height will override MoveTo target's Z
|
||||
public override bool PIDHoverActive {
|
||||
set { _useHoverPID = value; }
|
||||
}
|
||||
public override float PIDHoverHeight {
|
||||
set { _PIDHoverHeight = value; }
|
||||
}
|
||||
public override PIDHoverType PIDHoverType {
|
||||
set { _PIDHoverType = value; }
|
||||
}
|
||||
public override float PIDHoverTau {
|
||||
set { _PIDHoverTao = value; }
|
||||
}
|
||||
|
||||
// For RotLookAt
|
||||
public override Quaternion APIDTarget { set { return; } }
|
||||
public override bool APIDActive { set { return; } }
|
||||
public override float APIDStrength { set { return; } }
|
||||
public override float APIDDamping { set { return; } }
|
||||
|
||||
public override void AddForce(Vector3 force, bool pushforce) {
|
||||
if (force.IsFinite())
|
||||
{
|
||||
_force.X += force.X;
|
||||
_force.Y += force.Y;
|
||||
_force.Z += force.Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
|
||||
}
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
||||
});
|
||||
//m_lastUpdateSent = false;
|
||||
}
|
||||
public override void AddAngularForce(Vector3 force, bool pushforce) {
|
||||
}
|
||||
public override void SetMomentum(Vector3 momentum) {
|
||||
}
|
||||
public override void SubscribeEvents(int ms) {
|
||||
_subscribedEventsMs = ms;
|
||||
}
|
||||
public override void UnSubscribeEvents() {
|
||||
_subscribedEventsMs = 0;
|
||||
}
|
||||
public override bool SubscribedEvents() {
|
||||
return (_subscribedEventsMs > 0);
|
||||
}
|
||||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
// the world that things have changed.
|
||||
public void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
bool changed = false;
|
||||
// we assign to the local variables so the normal set action does not happen
|
||||
if (_position != entprop.Position)
|
||||
{
|
||||
_position = entprop.Position;
|
||||
changed = true;
|
||||
}
|
||||
if (_orientation != entprop.Rotation)
|
||||
{
|
||||
_orientation = entprop.Rotation;
|
||||
changed = true;
|
||||
}
|
||||
if (_velocity != entprop.Velocity)
|
||||
{
|
||||
_velocity = entprop.Velocity;
|
||||
changed = true;
|
||||
}
|
||||
if (_acceleration != entprop.Acceleration)
|
||||
{
|
||||
_acceleration = entprop.Acceleration;
|
||||
changed = true;
|
||||
}
|
||||
if (_rotationalVelocity != entprop.AngularVelocity)
|
||||
{
|
||||
_rotationalVelocity = entprop.AngularVelocity;
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
base.RequestPhysicsterseUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
||||
if (_subscribedEventsMs == 0) return; // don't want collisions
|
||||
|
||||
// The following says we're colliding this simulation step
|
||||
_collidingStep = _scene.SimulationStep;
|
||||
if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
|
||||
{
|
||||
_collidingGroundStep = _scene.SimulationStep;
|
||||
}
|
||||
|
||||
Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>();
|
||||
contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
CollisionEventUpdate args = new CollisionEventUpdate(LocalID, (int)type, 1, contactPoints);
|
||||
base.SendCollisionUpdate(args);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) Intel Corporation
|
||||
*
|
||||
* 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 copyright
|
||||
* 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 Intel Corporation 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 OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSPlugin : IPhysicsPlugin
|
||||
{
|
||||
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private BSScene _mScene;
|
||||
|
||||
public BSPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public PhysicsScene GetScene(String sceneIdentifier)
|
||||
{
|
||||
if (_mScene == null)
|
||||
{
|
||||
_mScene = new BSScene(sceneIdentifier);
|
||||
}
|
||||
return (_mScene);
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return ("BulletSim");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,471 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Intel Corporation
|
||||
*
|
||||
* 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 copyright
|
||||
* 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 Intel Corporation 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.Text;
|
||||
using System.Threading;
|
||||
using Nini.Config;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Region.Framework;
|
||||
|
||||
// TODOs for BulletSim (both BSScene and BSPrim)
|
||||
// Does NeedsMeshing() really need to exclude all the different shapes?
|
||||
// Based on material, set density and friction
|
||||
// More efficient memory usage in passing hull information from BSPrim to BulletSim
|
||||
// Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly?
|
||||
// In SL one can set both physical and phantom (gravity, does not effect others, makes collisions)
|
||||
// Need three states for objects: sense and report collisions, have physical effects, affects other objects
|
||||
// LinkSets
|
||||
// Freeing of memory of linksets in BulletSim::DestroyObject
|
||||
// Should prim.link() and prim.delink() be done at taint time?
|
||||
// Pass collision enable flags to BulletSim code so collisions are not reported up unless they are really needed
|
||||
// Set child prims phantom since the physicality is handled by the parent prim
|
||||
// Linked children need rotation relative to parent (passed as world rotation)
|
||||
//
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSScene : PhysicsScene
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly string LogHeader = "[BULLETS SCENE]";
|
||||
|
||||
private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
|
||||
private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
|
||||
private float[] m_heightMap;
|
||||
private uint m_worldID;
|
||||
public uint WorldID { get { return m_worldID; } }
|
||||
|
||||
public IMesher mesher;
|
||||
public int meshLOD = 32;
|
||||
|
||||
private int m_maxSubSteps = 10;
|
||||
private float m_fixedTimeStep = 1f / 60f;
|
||||
private long m_simulationStep = 0;
|
||||
public long SimulationStep { get { return m_simulationStep; } }
|
||||
|
||||
private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed
|
||||
private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes
|
||||
public float maximumMassObject = 10000.01f;
|
||||
|
||||
public const uint TERRAIN_ID = 0;
|
||||
public const uint GROUNDPLANE_ID = 1;
|
||||
|
||||
public float DefaultFriction = 0.70f;
|
||||
public float DefaultDensity = 10.000006836f; // Aluminum g/cm3; TODO: compute based on object material
|
||||
|
||||
public delegate void TaintCallback();
|
||||
private List<TaintCallback> _taintedObjects;
|
||||
|
||||
private BulletSimAPI.DebugLogCallback debugLogCallbackHandle;
|
||||
|
||||
public BSScene(string identifier)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
||||
{
|
||||
if (config != null)
|
||||
{
|
||||
IConfig pConfig = config.Configs["BulletSim"];
|
||||
if (pConfig != null)
|
||||
{
|
||||
DefaultFriction = pConfig.GetFloat("Friction", DefaultFriction);
|
||||
DefaultDensity = pConfig.GetFloat("Density", DefaultDensity);
|
||||
}
|
||||
}
|
||||
// if Debug, enable logging from the unmanaged code
|
||||
if (m_log.IsDebugEnabled)
|
||||
{
|
||||
m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
|
||||
debugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
|
||||
BulletSimAPI.SetDebugLogCallback(debugLogCallbackHandle);
|
||||
}
|
||||
|
||||
_meshSculptedPrim = true; // mesh sculpted prims
|
||||
_forceSimplePrimMeshing = false; // use complex meshing if called for
|
||||
|
||||
_taintedObjects = new List<TaintCallback>();
|
||||
|
||||
mesher = meshmerizer;
|
||||
// m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
|
||||
m_worldID = BulletSimAPI.Initialize(new Vector3(Constants.RegionSize, Constants.RegionSize, 1000f));
|
||||
}
|
||||
|
||||
private void BulletLogger(string msg)
|
||||
{
|
||||
m_log.Debug("[BULLETS UNMANAGED]:" + msg);
|
||||
}
|
||||
|
||||
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
|
||||
{
|
||||
m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
|
||||
return null;
|
||||
}
|
||||
|
||||
public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
|
||||
BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
|
||||
lock (m_avatars) m_avatars.Add(localID, actor);
|
||||
return actor;
|
||||
}
|
||||
|
||||
public override void RemoveAvatar(PhysicsActor actor)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: RemoveAvatar", LogHeader);
|
||||
if (actor is BSCharacter)
|
||||
{
|
||||
((BSCharacter)actor).Destroy();
|
||||
}
|
||||
try
|
||||
{
|
||||
lock (m_avatars) m_avatars.Remove(actor.LocalID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e);
|
||||
}
|
||||
}
|
||||
|
||||
public override void RemovePrim(PhysicsActor prim)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: RemovePrim", LogHeader);
|
||||
if (prim is BSPrim)
|
||||
{
|
||||
((BSPrim)prim).Destroy();
|
||||
}
|
||||
try
|
||||
{
|
||||
lock (m_prims) m_prims.Remove(prim.LocalID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e);
|
||||
}
|
||||
}
|
||||
|
||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||
Vector3 size, Quaternion rotation) // deprecated
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||
Vector3 size, Quaternion rotation, bool isPhysical)
|
||||
{
|
||||
m_log.ErrorFormat("{0}: CALL TO AddPrimShape in BSScene. NOT IMPLEMENTED", LogHeader);
|
||||
return null;
|
||||
}
|
||||
|
||||
public override PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||
Vector3 size, Quaternion rotation, bool isPhysical)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName);
|
||||
IMesh mesh = null;
|
||||
if (NeedsMeshing(pbs))
|
||||
{
|
||||
// if the prim is complex, create the mesh for it.
|
||||
// If simple (box or sphere) leave 'mesh' null and physics will do a native shape.
|
||||
// m_log.DebugFormat("{0}: AddPrimShape2: creating mesh", LogHeader);
|
||||
mesh = mesher.CreateMesh(primName, pbs, size, this.meshLOD, isPhysical);
|
||||
}
|
||||
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, mesh, pbs, isPhysical);
|
||||
lock (m_prims) m_prims.Add(localID, prim);
|
||||
return prim;
|
||||
}
|
||||
|
||||
public override void AddPhysicsActorTaint(PhysicsActor prim) { }
|
||||
|
||||
public override float Simulate(float timeStep)
|
||||
{
|
||||
int updatedEntityCount;
|
||||
IntPtr updatedEntitiesPtr;
|
||||
IntPtr[] updatedEntities;
|
||||
int collidersCount;
|
||||
IntPtr collidersPtr;
|
||||
int[] colliders; // should be uint but Marshal.Copy does not have that overload
|
||||
|
||||
// update the prim states while we know the physics engine is not busy
|
||||
ProcessTaints();
|
||||
|
||||
// step the physical world one interval
|
||||
m_simulationStep++;
|
||||
int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
||||
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
|
||||
|
||||
// if there were collisions, they show up here
|
||||
if (collidersCount > 0)
|
||||
{
|
||||
colliders = new int[collidersCount];
|
||||
Marshal.Copy(collidersPtr, colliders, 0, collidersCount);
|
||||
for (int ii = 0; ii < collidersCount; ii+=2)
|
||||
{
|
||||
uint cA = (uint)colliders[ii];
|
||||
uint cB = (uint)colliders[ii+1];
|
||||
SendCollision(cA, cB);
|
||||
SendCollision(cB, cA);
|
||||
}
|
||||
}
|
||||
|
||||
// if any of the objects had updated properties, they are returned in the updatedEntity structure
|
||||
if (updatedEntityCount > 0)
|
||||
{
|
||||
updatedEntities = new IntPtr[updatedEntityCount];
|
||||
Marshal.Copy(updatedEntitiesPtr, updatedEntities, 0, updatedEntityCount);
|
||||
for (int ii = 0; ii < updatedEntityCount; ii++)
|
||||
{
|
||||
IntPtr updatePointer = updatedEntities[ii];
|
||||
EntityProperties entprop = (EntityProperties)Marshal.PtrToStructure(updatePointer, typeof(EntityProperties));
|
||||
// m_log.DebugFormat("{0}: entprop: id={1}, pos={2}", LogHeader, entprop.ID, entprop.Position);
|
||||
if (m_avatars.ContainsKey(entprop.ID))
|
||||
{
|
||||
BSCharacter actor = m_avatars[entprop.ID];
|
||||
actor.UpdateProperties(entprop);
|
||||
}
|
||||
if (m_prims.ContainsKey(entprop.ID))
|
||||
{
|
||||
BSPrim prim = m_prims[entprop.ID];
|
||||
prim.UpdateProperties(entprop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 11f; // returns frames per second
|
||||
}
|
||||
|
||||
// Something has collided
|
||||
private void SendCollision(uint localID, uint collidingWith)
|
||||
{
|
||||
if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID)
|
||||
{
|
||||
// we never send collisions to the terrain
|
||||
return;
|
||||
}
|
||||
|
||||
ActorTypes type = ActorTypes.Prim;
|
||||
if (m_avatars.ContainsKey(collidingWith))
|
||||
type = ActorTypes.Agent;
|
||||
else if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID)
|
||||
type = ActorTypes.Ground;
|
||||
|
||||
if (m_prims.ContainsKey(localID))
|
||||
{
|
||||
BSPrim prim = m_prims[localID];
|
||||
prim.Collide(collidingWith, type, Vector3.Zero, Vector3.UnitZ, 0.01f);
|
||||
return;
|
||||
}
|
||||
if (m_avatars.ContainsKey(localID))
|
||||
{
|
||||
BSCharacter actor = m_avatars[localID];
|
||||
actor.Collide(collidingWith, type, Vector3.Zero, Vector3.UnitZ, 0.01f);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public override void GetResults() { }
|
||||
|
||||
public override void SetTerrain(float[] heightMap) {
|
||||
m_log.DebugFormat("{0}: SetTerrain", LogHeader);
|
||||
m_heightMap = heightMap;
|
||||
this.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
|
||||
});
|
||||
}
|
||||
|
||||
public override void SetWaterLevel(float baseheight) { }
|
||||
|
||||
public override void DeleteTerrain()
|
||||
{
|
||||
m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
m_log.DebugFormat("{0}: Dispose()", LogHeader);
|
||||
}
|
||||
|
||||
public override Dictionary<uint, float> GetTopColliders()
|
||||
{
|
||||
return new Dictionary<uint, float>();
|
||||
}
|
||||
|
||||
public override bool IsThreaded { get { return false; } }
|
||||
|
||||
/// <summary>
|
||||
/// Routine to figure out if we need to mesh this prim with our mesher
|
||||
/// </summary>
|
||||
/// <param name="pbs"></param>
|
||||
/// <returns>true if the prim needs meshing</returns>
|
||||
public bool NeedsMeshing(PrimitiveBaseShape pbs)
|
||||
{
|
||||
// most of this is redundant now as the mesher will return null if it cant mesh a prim
|
||||
// but we still need to check for sculptie meshing being enabled so this is the most
|
||||
// convenient place to do it for now...
|
||||
|
||||
// int iPropertiesNotSupportedDefault = 0;
|
||||
|
||||
if (pbs.SculptEntry && !_meshSculptedPrim)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: NeedsMeshing: scultpy mesh", LogHeader);
|
||||
return false;
|
||||
}
|
||||
|
||||
// if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since Bullet
|
||||
// can use an internal representation for the prim
|
||||
if (!_forceSimplePrimMeshing)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: NeedsMeshing: simple mesh: profshape={1}, curve={2}", LogHeader, pbs.ProfileShape, pbs.PathCurve);
|
||||
if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
|| (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
|
||||
&& pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
|
||||
{
|
||||
|
||||
if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
|
||||
&& pbs.ProfileHollow == 0
|
||||
&& pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
|
||||
&& pbs.PathBegin == 0 && pbs.PathEnd == 0
|
||||
&& pbs.PathTaperX == 0 && pbs.PathTaperY == 0
|
||||
&& pbs.PathScaleX == 100 && pbs.PathScaleY == 100
|
||||
&& pbs.PathShearX == 0 && pbs.PathShearY == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: verify that the mesher will now do all these shapes
|
||||
if (pbs.ProfileHollow != 0)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
// test for torus
|
||||
if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
|
||||
{
|
||||
if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
}
|
||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
|
||||
{
|
||||
if (pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
|
||||
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
}
|
||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
|
||||
{
|
||||
if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
}
|
||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
|
||||
{
|
||||
if (pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
}
|
||||
if (iPropertiesNotSupportedDefault == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
// The calls to the PhysicsActors can't directly call into the physics engine
|
||||
// because it might be busy. We we delay changes to a known time.
|
||||
// We rely on C#'s closure to save and restore the context for the delegate.
|
||||
public void TaintedObject(TaintCallback callback)
|
||||
{
|
||||
// do we need to lock?
|
||||
_taintedObjects.Add(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
// When someone tries to change a property on a BSPrim or BSCharacter, the object queues
|
||||
// a callback into itself to do the actual property change. That callback is called
|
||||
// here just before the physics engine is called to step the simulation.
|
||||
public void ProcessTaints()
|
||||
{
|
||||
// swizzle a new list into the list location so we can process what's there
|
||||
List<TaintCallback> newList = new List<TaintCallback>();
|
||||
List<TaintCallback> oldList = (List<TaintCallback>)Interlocked.Exchange(ref _taintedObjects, newList);
|
||||
|
||||
foreach (TaintCallback callback in oldList)
|
||||
{
|
||||
try
|
||||
{
|
||||
callback();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("{0}: ProcessTaints: Exception: {1}", LogHeader, e);
|
||||
}
|
||||
}
|
||||
oldList.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
Copyright (c) 2011, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
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 copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
* Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin {
|
||||
|
||||
public struct ConvexHull
|
||||
{
|
||||
Vector3 Offset;
|
||||
int VertexCount;
|
||||
Vector3[] Vertices;
|
||||
}
|
||||
public struct ShapeData
|
||||
{
|
||||
public enum PhysicsShapeType
|
||||
{
|
||||
SHAPE_AVATAR = 0,
|
||||
SHAPE_BOX = 1,
|
||||
SHAPE_CONE = 2,
|
||||
SHAPE_CYLINDER = 3,
|
||||
SHAPE_SPHERE = 4,
|
||||
SHAPE_HULL = 5
|
||||
};
|
||||
public const int numericTrue = 1;
|
||||
public const int numericFalse = 0;
|
||||
public uint ID;
|
||||
public PhysicsShapeType Type;
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
public Vector3 Velocity;
|
||||
public Vector3 Scale;
|
||||
public float Mass;
|
||||
public System.UInt64 MeshKey;
|
||||
public int Collidable;
|
||||
public int Flying;
|
||||
public float Friction;
|
||||
public int Dynamic;
|
||||
// note that bools are passed as ints since bool size changes by language
|
||||
}
|
||||
public struct SweepHit
|
||||
{
|
||||
public uint ID;
|
||||
public float Fraction;
|
||||
public Vector3 Normal;
|
||||
public Vector3 Point;
|
||||
}
|
||||
public struct RaycastHit
|
||||
{
|
||||
public uint ID;
|
||||
public float Fraction;
|
||||
public Vector3 Normal;
|
||||
}
|
||||
|
||||
public struct EntityProperties
|
||||
{
|
||||
public uint ID;
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
public Vector3 Velocity;
|
||||
public Vector3 Acceleration;
|
||||
public Vector3 AngularVelocity;
|
||||
}
|
||||
|
||||
static class BulletSimAPI {
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern uint Initialize(Vector3 maxPosition);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void Shutdown(uint worldID);
|
||||
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep,
|
||||
out int updatedEntityCount,
|
||||
out IntPtr updatedEntitiesPtr,
|
||||
out int collidersCount,
|
||||
out IntPtr collidersPtr);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool CreateHull(uint worldID, System.UInt64 meshKey, int hullCount,
|
||||
[MarshalAs(UnmanagedType.LPArray)] float[] hulls
|
||||
);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool DestroyHull(uint worldID, System.UInt64 meshKey);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool CreateObject(uint worldID, ShapeData shapeData);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern Vector3 GetObjectPosition(uint WorldID, uint id);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetObjectTranslation(uint worldID, uint id, Vector3 position, Quaternion rotation);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetObjectVelocity(uint worldID, uint id, Vector3 velocity);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetObjectForce(uint worldID, uint id, Vector3 force);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetObjectScaleMass(uint worldID, uint id, Vector3 scale, float mass, bool isDynamic);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetObjectCollidable(uint worldID, uint id, bool phantom);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetObjectDynamic(uint worldID, uint id, bool isDynamic, float mass);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetObjectFlying(uint worldID, uint id, bool flying);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool HasObject(uint worldID, uint id);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool DestroyObject(uint worldID, uint id);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern RaycastHit RayTest(uint worldID, uint id, Vector3 from, Vector3 to);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
|
||||
|
||||
// Log a debug message
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void SetDebugLogCallback(DebugLogCallback callback);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletSPlugin" path="addon-modules/BulletSPlugin" type="Library">
|
||||
<Configuration name="Debug">
|
||||
<Options>
|
||||
<OutputPath>../../bin/Physics/</OutputPath>
|
||||
</Options>
|
||||
</Configuration>
|
||||
<Configuration name="Release">
|
||||
<Options>
|
||||
<OutputPath>../../bin/Physics/</OutputPath>
|
||||
</Options>
|
||||
</Configuration>
|
||||
|
||||
<ReferencePath>../../bin/</ReferencePath>
|
||||
<Reference name="System"/>
|
||||
<Reference name="System.Core"/>
|
||||
<Reference name="System.Xml"/>
|
||||
<Reference name="OpenMetaverseTypes" path="../../bin/"/>
|
||||
<Reference name="Nini.dll" path="../../bin/"/>
|
||||
<Reference name="OpenSim.Framework"/>
|
||||
<Reference name="OpenSim.Region.Framework"/>
|
||||
<Reference name="OpenSim.Region.CoreModules"/>
|
||||
<Reference name="OpenSim.Framework.Console"/>
|
||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
|
||||
<Reference name="log4net.dll" path="../../bin/"/>
|
||||
|
||||
<Files>
|
||||
<Match pattern="*.cs" recurse="true">
|
||||
<Exclude name="Tests" pattern="Tests"/>
|
||||
</Match>
|
||||
</Files>
|
||||
</Project>
|
Loading…
Reference in New Issue