diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 0428f5a41c..10beaff218 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -71,6 +71,11 @@ namespace OpenSim physicsEngine = "RealPhysX"; allowFlying = true; } + if (args[i] == "-bulletX") + { + physicsEngine = "BulletXEngine"; + allowFlying = true; + } if (args[i] == "-ode") { physicsEngine = "OpenDynamicsEngine"; diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs index bc9537be7a..48997e2320 100644 --- a/OpenSim/Region/Application/OpenSimMain.cs +++ b/OpenSim/Region/Application/OpenSimMain.cs @@ -373,6 +373,11 @@ namespace OpenSim this.m_physicsEngine = "OpenDynamicsEngine"; ScenePresence.PhysicsEngineFlying = true; break; + + case "BulletXEngine": + this.m_physicsEngine = "BulletXEngine"; + ScenePresence.PhysicsEngineFlying = true; + break; } configData.Commit(); diff --git a/OpenSim/Region/Environment/Scenes/Primitive.cs b/OpenSim/Region/Environment/Scenes/Primitive.cs index 53314e3bf4..ab5037393f 100644 --- a/OpenSim/Region/Environment/Scenes/Primitive.cs +++ b/OpenSim/Region/Environment/Scenes/Primitive.cs @@ -174,7 +174,7 @@ namespace OpenSim.Region.Environment.Scenes dupe.Rotation = new Quaternion(this.Rotation.w, this.Rotation.x, this.Rotation.y, this.Rotation.z); dupe.Pos = new LLVector3(this.Pos.X, this.Pos.Y, this.Pos.Z); rootParent.AddChildToList(dupe); - + foreach (Primitive prim in this.children) { Primitive primClone = prim.Copy(this, rootParent); diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index c8714aea6e..0305b50a6d 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -453,7 +453,7 @@ namespace OpenSim.Region.Environment.Scenes } - protected override void SubscribeToClientEvents(IClientAPI client) + protected virtual void SubscribeToClientEvents(IClientAPI client) { client.OnRegionHandShakeReply += this.SendLayerData; //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims); diff --git a/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs new file mode 100644 index 0000000000..bda35f7aa5 --- /dev/null +++ b/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("BulletXPlugin")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BulletXPlugin")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs new file mode 100644 index 0000000000..1ca5efebec --- /dev/null +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -0,0 +1,534 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 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 OpenSim 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. +* +*/ +#region References +using System; +using System.Collections.Generic; +using OpenSim.Physics.Manager; +using Axiom.Math; +//Specific References for BulletXPlugin +using MonoXnaCompactMaths; +using XnaDevRu.BulletX; +using XnaDevRu.BulletX.Dynamics; +#endregion + +namespace OpenSim.Region.Physics.BulletXPlugin +{ + /// + /// This Class converts objects and types for BulletX + /// + public class BulletXConversions + { + public static MonoXnaCompactMaths.Vector3 PhysicsVectorToXnaVector3(PhysicsVector physicsVector) + { + return new MonoXnaCompactMaths.Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z); + } + public static void PhysicsVectorToXnaVector3(PhysicsVector physicsVector, out MonoXnaCompactMaths.Vector3 XnaVector3) + { + XnaVector3.X = physicsVector.X; + XnaVector3.Y = physicsVector.Y; + XnaVector3.Z = physicsVector.Z; + } + public static PhysicsVector XnaVector3ToPhysicsVector(MonoXnaCompactMaths.Vector3 xnaVector3) + { + return new PhysicsVector(xnaVector3.X, xnaVector3.Y, xnaVector3.Z); + } + /*public static void XnaVector3ToPhysicsVector(MonoXnaCompactMaths.Vector3 xnaVector3, out PhysicsVector physicsVector) + { + xnaVector3.X = physicsVector.X; + xnaVector3.Y = physicsVector.Y; + xnaVector3.Z = physicsVector.Z; + }*/ + #region Axiom and Xna + ///// + ///// BTW maybe some conversions will be a simply converion that it doesn't require this class, but i don't know + ///// + ///// + ///// + //public static MonoXnaCompactMaths.Vector3 Vector3AxiomToXna(Axiom.Math.Vector3 AxiomVector3) + //{ + // return new MonoXnaCompactMaths.Vector3(AxiomVector3.x, AxiomVector3.y, AxiomVector3.z); + //} + #endregion + } + /// + /// PhysicsPlugin Class for BulletX + /// + public class BulletXPlugin : IPhysicsPlugin + { + private BulletXScene _mScene; + + public BulletXPlugin() + { + } + public bool Init() + { + return true; + } + public PhysicsScene GetScene() + { + if (_mScene == null) + { + _mScene = new BulletXScene(); + } + return (_mScene); + } + public string GetName() + { + return ("BulletXEngine"); + } + public void Dispose() + { + } + } + /// + /// PhysicsScene Class for BulletX + /// + public class BulletXScene : PhysicsScene + { + public DiscreteDynamicsWorld ddWorld; + private CollisionDispatcher cDispatcher; + private OverlappingPairCache opCache; + private SequentialImpulseConstraintSolver sicSolver; + + private const int minXY = 0; + private const int minZ = 0; + private const int maxXY = 256; + private const int maxZ = 4096; + private const int maxHandles = 32766; //Why? I don't know + private static float gravity = 9.8f; + private static float heightLevel0 = 77.0f; + private static float heightLevel1 = 200.0f; + private static float lowGravityFactor = 0.2f; + + private float[] _heightmap; + private List _characters = new List(); + + public static float Gravity { get { return gravity; } } + public static float HeightLevel0 { get { return heightLevel0; } } + public static float HeightLevel1 { get { return heightLevel1; } } + public static float LowGravityFactor { get { return lowGravityFactor; } } + + public BulletXScene() + { + cDispatcher = new CollisionDispatcher(); + MonoXnaCompactMaths.Vector3 worldMinDim = new MonoXnaCompactMaths.Vector3((float)minXY, (float)minXY, (float)minZ); + MonoXnaCompactMaths.Vector3 worldMaxDim = new MonoXnaCompactMaths.Vector3((float)maxXY, (float)maxXY, (float)maxZ); + opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles); + sicSolver = new SequentialImpulseConstraintSolver(); + + ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver); + ddWorld.Gravity = new MonoXnaCompactMaths.Vector3(0, 0, -gravity); + + this._heightmap = new float[65536]; + } + + public override PhysicsActor AddAvatar(PhysicsVector position) + { + PhysicsVector pos = new PhysicsVector(); + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z + 20; + BulletXCharacter newAv = new BulletXCharacter(this, pos); + this._characters.Add(newAv); + return newAv; + } + + public override void RemoveAvatar(PhysicsActor actor) + { + + } + + public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size) + { + PhysicsVector pos = new PhysicsVector(); + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z; + PhysicsVector siz = new PhysicsVector(); + siz.X = size.X; + siz.Y = size.Y; + siz.Z = size.Z; + return new BulletXPrim(); + } + + public override void Simulate(float timeStep) + { + foreach (BulletXCharacter actor in _characters) + { + actor.Move(timeStep); + + } + ddWorld.StepSimulation(timeStep, 0, timeStep); + foreach (BulletXCharacter actor in _characters) + { + actor.ValidateHeight(this._heightmap[ + (int)Math.Round(actor.RigidBodyHorizontalPosition.x) * 256 + + (int)Math.Round(actor.RigidBodyHorizontalPosition.y)]); + } + foreach (BulletXCharacter actor in _characters) + { + actor.UpdatePosition(); + } + + } + + public override void GetResults() + { + + } + + public override bool IsThreaded + { + get + { + return (false); // for now we won't be multithreaded + } + } + + public override void SetTerrain(float[] heightMap) + { + //As the same as ODE, heightmap (x,y) must be swapped for BulletX + for (int i = 0; i < 65536; i++) + { + // this._heightmap[i] = (double)heightMap[i]; + // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) + int x = i & 0xff; + int y = i >> 8; + this._heightmap[i] = heightMap[x * 256 + y]; + } + } + + public override void DeleteTerrain() + { + + } + } + /// + /// PhysicsActor Character Class for BulletX + /// + public class BulletXCharacter : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _acceleration; + private bool flying; + private RigidBody rigidBody; + public Axiom.Math.Vector2 RigidBodyHorizontalPosition + { + get + { + return new Axiom.Math.Vector2(this.rigidBody.CenterOfMassPosition.X, this.rigidBody.CenterOfMassPosition.Y); + } + } + public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos) + { + _velocity = new PhysicsVector(); + _position = pos; + _acceleration = new PhysicsVector(); + float _mass = 50.0f; //This depends of avatar's dimensions + Matrix _startTransform = Matrix.Identity; + _startTransform.Translation = BulletXConversions.PhysicsVectorToXnaVector3(pos); + Matrix _centerOfMassOffset = Matrix.Identity; + CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(0.5f, 0.5f, 1.60f)); + DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); + MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3(); + _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0 + + //The next values might change + float _linearDamping = 0.0f; + float _angularDamping = 0.0f; + float _friction = 0.5f; + float _restitution = 0.0f; + + rigidBody = new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution); + rigidBody.ActivationState = ActivationState.DisableDeactivation; + + parent_scene.ddWorld.AddRigidBody(rigidBody); + } + + public override bool Flying + { + get + { + return flying; + } + set + { + flying = value; + } + } + + public override PhysicsVector Position + { + get + { + return _position; + } + set + { + _position = value; + } + } + + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override bool Kinematic + { + get + { + return false; + } + set + { + + } + } + + public override Axiom.Math.Quaternion Orientation + { + get + { + return Axiom.Math.Quaternion.Identity; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + + } + public void SetAcceleration(PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + + } + + public override void SetMomentum(PhysicsVector momentum) + { + + } + + public void Move(float timeStep) + { + MonoXnaCompactMaths.Vector3 vec = new MonoXnaCompactMaths.Vector3(); + //if (this._velocity.X == 0.0f) + // vec.X = this.rigidBody.LinearVelocity.X; //current velocity + //else + vec.X = this._velocity.X; //overrides current velocity + + //if (this._velocity.Y == 0.0f) + // vec.Y = this.rigidBody.LinearVelocity.Y; //current velocity + //else + vec.Y = this._velocity.Y; //overrides current velocity + + float nextZVelocity; + //if (this._velocity.Z == 0.0f) + // nextZVelocity = this.rigidBody.LinearVelocity.Z; //current velocity + //else + nextZVelocity = this._velocity.Z; //overrides current velocity + + if (flying) + { + //Antigravity with movement + if (this._position.Z <= BulletXScene.HeightLevel0) + { + vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep; + } + //Lowgravity with movement + else if((this._position.Z > BulletXScene.HeightLevel0) + && (this._position.Z <= BulletXScene.HeightLevel1)) + { + vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); + } + //Lowgravity with... + else if (this._position.Z > BulletXScene.HeightLevel1) + { + if(nextZVelocity > 0) //no movement + vec.Z = BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); + else + vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); + + } + } + else + { + vec.Z = nextZVelocity; + } + rigidBody.LinearVelocity = vec; + } + + public void UpdatePosition() + { + this._position = BulletXConversions.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition); + } + + //This validation is very basic + internal void ValidateHeight(float heighmapPositionValue) + { + if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue) + { + Matrix m = rigidBody.WorldTransform; + MonoXnaCompactMaths.Vector3 v3 = m.Translation; + v3.Z = heighmapPositionValue; + m.Translation = v3; + rigidBody.WorldTransform = m; + } + } + } + /// + /// PhysicsActor Prim Class for BulletX + /// + public class BulletXPrim : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _acceleration; + + public BulletXPrim() + { + _velocity = new PhysicsVector(); + _position = new PhysicsVector(); + _acceleration = new PhysicsVector(); + } + public override bool Flying + { + get + { + return false; //no flying prims for you + } + set + { + + } + } + public override PhysicsVector Position + { + get + { + PhysicsVector pos = new PhysicsVector(); + // PhysicsVector vec = this._prim.Position; + //pos.X = vec.X; + //pos.Y = vec.Y; + //pos.Z = vec.Z; + return pos; + + } + set + { + /*PhysicsVector vec = value; + PhysicsVector pos = new PhysicsVector(); + pos.X = vec.X; + pos.Y = vec.Y; + pos.Z = vec.Z; + this._prim.Position = pos;*/ + } + } + + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override bool Kinematic + { + get + { + return false; + //return this._prim.Kinematic; + } + set + { + //this._prim.Kinematic = value; + } + } + + public override Axiom.Math.Quaternion Orientation + { + get + { + Axiom.Math.Quaternion res = new Axiom.Math.Quaternion(); + return res; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + + } + public void SetAcceleration(PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + + } + + public override void SetMomentum(PhysicsVector momentum) + { + + } + } +} diff --git a/bin/Modified.XnaDevRu.BulletX.dll b/bin/Modified.XnaDevRu.BulletX.dll new file mode 100644 index 0000000000..8de2a5f71a Binary files /dev/null and b/bin/Modified.XnaDevRu.BulletX.dll differ diff --git a/bin/MonoXnaCompactMaths.dll b/bin/MonoXnaCompactMaths.dll new file mode 100644 index 0000000000..a4e345abd8 Binary files /dev/null and b/bin/MonoXnaCompactMaths.dll differ