From 079a1e704fcaa9fddc9bb3de0a205969cba058bc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 18 Nov 2012 18:17:30 -0800 Subject: BulletSim: remove the obsolete interface to the Bullet code. Update BulletSim libraries with code stripped of the obsolete code. --- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 134 --------------------- bin/lib32/BulletSim.dll | Bin 599040 -> 551424 bytes bin/lib32/libBulletSim.so | Bin 2778687 -> 1707213 bytes bin/lib64/BulletSim.dll | Bin 765440 -> 699904 bytes bin/lib64/libBulletSim.so | Bin 3034072 -> 1844124 bytes 5 files changed, 134 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 07149d8..28fae13 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -429,140 +429,6 @@ static class BulletSimAPI { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -[return: MarshalAs(UnmanagedType.LPStr)] -public static extern string GetVersion(); - -/* Remove the linkage to the old api methods -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray, - DebugLogCallback logRoutine); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void CreateInitialGroundPlaneAndTerrain(uint worldID); - -[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 bool UpdateParameter(uint worldID, uint localID, - [MarshalAs(UnmanagedType.LPStr)]string paramCode, float value); - -// =============================================================================== -[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 CreateMesh(uint worldID, System.UInt64 meshKey, - int indexCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, - int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices - ); - -[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 DestroyMesh(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 Vector3 GetObjectPosition(uint WorldID, uint id); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Quaternion GetObjectOrientation(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 SetObjectAngularVelocity(uint worldID, uint id, Vector3 angularVelocity); - -// Set the current force acting on the object -[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 SetObjectGhost(uint worldID, uint id, bool ghostly); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetObjectProperties(uint worldID, uint id, bool isStatic, bool isSolid, bool genCollisions, float mass); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetObjectBuoyancy(uint worldID, uint id, float buoyancy); - -[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); - -// =============================================================================== -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpBulletStatistics(); -*/ -// Log a debug message -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetDebugLogCallback(DebugLogCallback callback); - -// =============================================================================== -// =============================================================================== -// =============================================================================== -// A new version of the API that enables moving all the logic out of the C++ code and into -// the C# code. This will make modifications easier for the next person. -// This interface passes the actual pointers to the objects in the unmanaged -// address space. All the management (calls for creation/destruction/lookup) -// is done in the C# code. -// The names have a "2" tacked on. This will be removed as the C# code gets rebuilt -// and the old code is removed. - -// Functions use while converting from API1 to API2. Can be removed when totally converted. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetSimHandle2(uint worldID); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetBodyHandle2(IntPtr world, uint id); - // =============================================================================== // Initialization and simulation [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 51526a7..9c8cf00 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index 8bb9d10..0277cf1 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 1a07d6a..5675ff3 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index bbdd380..49396a8 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From 22be36be69bbf571b26753307b9c2c5456a34d73 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 18 Nov 2012 22:57:26 -0800 Subject: BulletSim: fix the problem with flying being disabled when crossing region boundries. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index f33c124..3c48dcc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -78,8 +78,8 @@ public sealed class BSCharacter : BSPhysObject private float _PIDHoverTao; public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) + : base(parent_scene, localID, avName, "BSCharacter") { - base.BaseInitialize(parent_scene, localID, avName, "BSCharacter"); _physicsActorType = (int)ActorTypes.Agent; _position = pos; _size = size; @@ -131,6 +131,10 @@ public sealed class BSCharacter : BSPhysObject // Set the velocity and compute the proper friction ForceVelocity = _velocity; + // This will enable or disable the flying buoyancy of the avatar. + // Needs to be reset especially when an avatar is recreated after crossing a region boundry. + Flying = _flying; + BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.avatarRestitution); BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); @@ -615,7 +619,7 @@ public sealed class BSCharacter : BSPhysObject newScale.Y = PhysicsScene.Params.avatarCapsuleRadius; // From the total height, remove the capsule half spheres that are at each end - newScale.Z = size.Z- (newScale.X + newScale.Y); + newScale.Z = size.Z - (newScale.X + newScale.Y); Scale = newScale; } -- cgit v1.1 From 6c961d8addf5c6aad81165042e684e45429b3b21 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 18 Nov 2012 22:58:36 -0800 Subject: BulletSim: Use base class constructors for initialization of BSShape and other classes. --- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 5 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 421 ++++++++++----------- 4 files changed, 214 insertions(+), 216 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index e803072..991e5b1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -47,7 +47,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin */ public abstract class BSPhysObject : PhysicsActor { - protected void BaseInitialize(BSScene parentScene, uint localID, string name, string typeName) + protected BSPhysObject() + { + } + protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 14eb505..500c84a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -88,9 +88,9 @@ public sealed class BSPrim : BSPhysObject public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) + : base(parent_scene, localID, primName, "BSPrim") { // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); - base.BaseInitialize(parent_scene, localID, primName, "BSPrim"); _physicsActorType = (int)ActorTypes.Prim; _position = pos; _size = size; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 1cc607a..2fee95e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -683,7 +683,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters #region Taints // Calls to the PhysicsActors can't directly call into the physics engine - // because it might be busy. We delay changes to a known time. + // because it might be busy. 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(String ident, TaintCallback callback) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 5e2c4a8..d59a486 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -1,213 +1,208 @@ -/* - * 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 abstract class BSShape -{ - public IntPtr ptr { get; set; } - public ShapeData.PhysicsShapeType type { get; set; } - public System.UInt64 key { get; set; } - public int referenceCount { get; set; } - public DateTime lastReferenced { get; set; } - - protected void Initialize() - { - ptr = IntPtr.Zero; - type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; - key = 0; - referenceCount = 0; - lastReferenced = DateTime.Now; - } - - // Get a reference to a physical shape. Create if it doesn't exist - public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) - { - BSShape ret = null; - - if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR) - { - // an avatar capsule is close to a native shape (it is not shared) - ret = BSShapeNative.GetReference(physicsScene, prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR, - ShapeData.FixedShapeKey.KEY_CAPSULE); - physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret); - } - - // Compound shapes are handled special as they are rebuilt from scratch. - // This isn't too great a hardship since most of the child shapes will already been created. - if (ret == null && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_COMPOUND) - { - // Getting a reference to a compound shape gets you the compound shape with the root prim shape added - ret = BSShapeCompound.GetReference(prim); - physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); - } - - if (ret == null) - ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); - - return ret; - } - public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) - { - return null; - } - public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) - { - return null; - } - - // Release the use of a physical shape. - public abstract void Dereference(BSScene physicsScene); - - // All shapes have a static call to get a reference to the physical shape - // protected abstract static BSShape GetReference(); - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - -public class BSShapeNull : BSShape -{ - public BSShapeNull() - { - base.Initialize(); - } - public static BSShape GetReference() { return new BSShapeNull(); } - public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ } -} - -public class BSShapeNative : BSShape -{ - private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; - public BSShapeNative() - { - base.Initialize(); - } - public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, - ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) - { - // Native shapes are not shared and are always built anew. - return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); - } - - private BSShapeNative(BSScene physicsScene, BSPhysObject prim, - ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) - { - ShapeData nativeShapeData = new ShapeData(); - nativeShapeData.Type = shapeType; - nativeShapeData.ID = prim.LocalID; - nativeShapeData.Scale = prim.Scale; - nativeShapeData.Size = prim.Scale; - nativeShapeData.MeshKey = (ulong)shapeKey; - nativeShapeData.HullKey = (ulong)shapeKey; - - - if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) - { - ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); - physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); - } - else - { - ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData); - } - if (ptr == IntPtr.Zero) - { - physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", - LogHeader, prim.LocalID, shapeType); - } - type = shapeType; - key = (UInt64)shapeKey; - } - // Make this reference to the physical shape go away since native shapes are not shared. - public override void Dereference(BSScene physicsScene) - { - // Native shapes are not tracked and are released immediately - physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); - BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr); - ptr = IntPtr.Zero; - // Garbage collection will free up this instance. - } -} - -public class BSShapeMesh : BSShape -{ - private static string LogHeader = "[BULLETSIM SHAPE MESH]"; - private static Dictionary Meshes = new Dictionary(); - - public BSShapeMesh() - { - base.Initialize(); - } - public static BSShape GetReference() { return new BSShapeNull(); } - public override void Dereference(BSScene physicsScene) { } -} - -public class BSShapeHull : BSShape -{ - private static string LogHeader = "[BULLETSIM SHAPE HULL]"; - private static Dictionary Hulls = new Dictionary(); - - public BSShapeHull() - { - base.Initialize(); - } - public static BSShape GetReference() { return new BSShapeNull(); } - public override void Dereference(BSScene physicsScene) { } -} - -public class BSShapeCompound : BSShape -{ - private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; - public BSShapeCompound() - { - base.Initialize(); - } - public static BSShape GetReference(BSPhysObject prim) - { - return new BSShapeNull(); - } - public override void Dereference(BSScene physicsScene) { } -} -} +/* + * 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 abstract class BSShape +{ + public IntPtr ptr { get; set; } + public ShapeData.PhysicsShapeType type { get; set; } + public System.UInt64 key { get; set; } + public int referenceCount { get; set; } + public DateTime lastReferenced { get; set; } + + public BSShape() + { + ptr = IntPtr.Zero; + type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; + key = 0; + referenceCount = 0; + lastReferenced = DateTime.Now; + } + + // Get a reference to a physical shape. Create if it doesn't exist + public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) + { + BSShape ret = null; + + if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR) + { + // an avatar capsule is close to a native shape (it is not shared) + ret = BSShapeNative.GetReference(physicsScene, prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR, + ShapeData.FixedShapeKey.KEY_CAPSULE); + physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret); + } + + // Compound shapes are handled special as they are rebuilt from scratch. + // This isn't too great a hardship since most of the child shapes will already been created. + if (ret == null && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_COMPOUND) + { + // Getting a reference to a compound shape gets you the compound shape with the root prim shape added + ret = BSShapeCompound.GetReference(prim); + physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); + } + + if (ret == null) + ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); + + return ret; + } + public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) + { + return null; + } + public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) + { + return null; + } + + // Release the use of a physical shape. + public abstract void Dereference(BSScene physicsScene); + + // All shapes have a static call to get a reference to the physical shape + // protected abstract static BSShape GetReference(); + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +public class BSShapeNull : BSShape +{ + public BSShapeNull() : base() + { + } + public static BSShape GetReference() { return new BSShapeNull(); } + public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ } +} + +public class BSShapeNative : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; + public BSShapeNative() : base() + { + } + public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, + ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) + { + // Native shapes are not shared and are always built anew. + return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); + } + + private BSShapeNative(BSScene physicsScene, BSPhysObject prim, + ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) + { + ShapeData nativeShapeData = new ShapeData(); + nativeShapeData.Type = shapeType; + nativeShapeData.ID = prim.LocalID; + nativeShapeData.Scale = prim.Scale; + nativeShapeData.Size = prim.Scale; + nativeShapeData.MeshKey = (ulong)shapeKey; + nativeShapeData.HullKey = (ulong)shapeKey; + + + if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) + { + ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); + physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); + } + else + { + ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData); + } + if (ptr == IntPtr.Zero) + { + physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", + LogHeader, prim.LocalID, shapeType); + } + type = shapeType; + key = (UInt64)shapeKey; + } + // Make this reference to the physical shape go away since native shapes are not shared. + public override void Dereference(BSScene physicsScene) + { + // Native shapes are not tracked and are released immediately + physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); + BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr); + ptr = IntPtr.Zero; + // Garbage collection will free up this instance. + } +} + +public class BSShapeMesh : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE MESH]"; + private static Dictionary Meshes = new Dictionary(); + + public BSShapeMesh() : base() + { + } + public static BSShape GetReference() { return new BSShapeNull(); } + public override void Dereference(BSScene physicsScene) { } +} + +public class BSShapeHull : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE HULL]"; + private static Dictionary Hulls = new Dictionary(); + + public BSShapeHull() : base() + { + } + public static BSShape GetReference() { return new BSShapeNull(); } + public override void Dereference(BSScene physicsScene) { } +} + +public class BSShapeCompound : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; + public BSShapeCompound() : base() + { + } + public static BSShape GetReference(BSPhysObject prim) + { + return new BSShapeNull(); + } + public override void Dereference(BSScene physicsScene) { } +} +} -- cgit v1.1 From 665f79e15c1de3a98f777004cba278625b8b3181 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 19 Nov 2012 21:47:49 -0500 Subject: Expose configuration options for the XmlRpcGridRouter Expose configuration options for the XmlRpcGridRouter to allow simulators to register llRemoteData channels with an external routing service --- bin/OpenSim.ini.example | 23 ++++++++++++++++++++++- bin/OpenSimDefaults.ini | 14 -------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index c7df7bb..e591a69 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -443,9 +443,30 @@ ;; What is reported as the "User-Agent" when using llHTTPRequest ;; Defaults to not sent if not set here. See the notes section in the wiki ;; at http://wiki.secondlife.com/wiki/LlHTTPRequest for comments on adding - ;; " (Mozilla Compatible)" to the text where there are problems with a web server + ;; " (Mozilla Compatible)" to the text where there are problems with a + ;; web server ; user_agent = "OpenSim LSL (Mozilla Compatible)" +[XMLRPC] + ;# {XmlRpcRouterModule} {} {Module used to route incoming llRemoteData calls} {XmlRpcRouterModule XmlRpcGridRouterModule} XmlRpcRouterModule + ;; If enabled and set to XmlRpcRouterModule, this will post an event, + ;; "xmlrpc_uri(string)" to the script concurrently with the first + ;; remote_data event. This will contain the fully qualified URI an + ;; external site needs to use to send XMLRPC requests to that script + ;; + ;; If enabled and set to XmlRpcGridRouterModule, newly created channels + ;; will be registered with an external service via a configured uri + ;XmlRpcRouterModule = "XmlRpcRouterModule" + + ;# {XmlRpcPort} {} {Port for incoming llRemoteData xmlrpc calls} {} 20800 + ;XmlRpcPort = 20800 + + ;# {XmlRpcHubURI} {XmlRpcRouterModule} {URI for external service used to register xmlrpc channels created in the simulator. This depends on XmlRpcRouterModule being set to XmlRpcGridRouterModule} http://example.com + ;; If XmlRpcRouterModule is set to XmlRpcGridRouterModule, the simulator + ;; will use this address to register xmlrpc channels on the external + ;; service + ; XmlRpcHubURI = http://example.com + [ClientStack.LindenUDP] ;; See OpensSimDefaults.ini for the throttle options. You can copy the diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index ed1b969..c81c658 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -429,20 +429,6 @@ ; many simultaneous requests, default is 30 and is currently applied only to assets ;MaxRequestConcurrency = 30 -[XMLRPC] - ; ## - ; ## Scripting XMLRPC mapper - ; ## - - ; If enabled, this will post an event, "xmlrpc_uri(string)" to the - ; script concurrently with the first remote_data event. - ; This will contain the fully qualified URI an external site needs - ; to use to send XMLRPC requests to that script - - ;XmlRpcRouterModule = "XmlRpcRouterModule" - ;XmlRpcPort = 20800 - - [ClientStack.LindenUDP] ; Set this to true to process incoming packets asynchronously. Networking is ; already separated from packet handling with a queue, so this will only -- cgit v1.1 From dc5711ad6221f087b6250179ac9a6a389581058c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 20 Nov 2012 04:10:03 +0000 Subject: minor: If logging full incoming HTTP data, don't deceptively print ... at the end of the body. --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 410a76a..66d80cf 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -719,8 +719,11 @@ namespace OpenSim.Framework.Servers.HttpServer if (DebugLevel == 5) { const int sampleLength = 80; - char[] sampleChars = new char[sampleLength]; + char[] sampleChars = new char[sampleLength + 3]; reader.Read(sampleChars, 0, sampleLength); + sampleChars[80] = '.'; + sampleChars[81] = '.'; + sampleChars[82] = '.'; output = new string(sampleChars); } else @@ -728,7 +731,7 @@ namespace OpenSim.Framework.Servers.HttpServer output = reader.ReadToEnd(); } - m_log.DebugFormat("[BASE HTTP SERVER]: {0}...", output.Replace("\n", @"\n")); + m_log.DebugFormat("[BASE HTTP SERVER]: {0}", output.Replace("\n", @"\n")); } } -- cgit v1.1 From 0962a35d2ff8e2d0a8cf87bfce542276dfb2c0f5 Mon Sep 17 00:00:00 2001 From: Iain Oliver Date: Wed, 14 Nov 2012 15:02:35 +0000 Subject: Fix movetotarget on mega regions. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 96bca3e..342de78 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1698,8 +1698,18 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", // Name, pos, m_scene.RegionInfo.RegionName); - if (pos.X < 0 || pos.X >= Constants.RegionSize - || pos.Y < 0 || pos.Y >= Constants.RegionSize + Vector2 regionSize; + IRegionCombinerModule regionCombinerModule = m_scene.RequestModuleInterface(); + if(regionCombinerModule != null) + { + regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); + } + else + { + regionSize = new Vector2(Constants.RegionSize); + } + if (pos.X < 0 || pos.X >= regionSize.X + || pos.Y < 0 || pos.Y >= regionSize.Y || pos.Z < 0) return; @@ -1713,7 +1723,15 @@ namespace OpenSim.Region.Framework.Scenes // pos.Z = AbsolutePosition.Z; // } - float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; + int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X); + int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y); + UUID target_regionID = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y).RegionID; + Scene targetScene = m_scene; + if(!SceneManager.Instance.TryGetScene(target_regionID, out targetScene)) + { + targetScene = m_scene; + } + float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)]; pos.Z = Math.Max(terrainHeight, pos.Z); // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is -- cgit v1.1 From 597a101b9f65e2f0b67f9f2de99654f2e5979855 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 20 Nov 2012 05:09:44 +0000 Subject: Minor formatting for 0962a35d and a few one-line comments as to why that code is there --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 342de78..6f36c0b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1698,16 +1698,14 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", // Name, pos, m_scene.RegionInfo.RegionName); + // Allow move to another sub-region within a megaregion Vector2 regionSize; IRegionCombinerModule regionCombinerModule = m_scene.RequestModuleInterface(); - if(regionCombinerModule != null) - { + if (regionCombinerModule != null) regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); - } else - { regionSize = new Vector2(Constants.RegionSize); - } + if (pos.X < 0 || pos.X >= regionSize.X || pos.Y < 0 || pos.Y >= regionSize.Y || pos.Z < 0) @@ -1723,14 +1721,15 @@ namespace OpenSim.Region.Framework.Scenes // pos.Z = AbsolutePosition.Z; // } + // Get terrain height for sub-region in a megaregion if necessary int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X); int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y); UUID target_regionID = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y).RegionID; Scene targetScene = m_scene; - if(!SceneManager.Instance.TryGetScene(target_regionID, out targetScene)) - { + + if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene)) targetScene = m_scene; - } + float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)]; pos.Z = Math.Max(terrainHeight, pos.Z); -- cgit v1.1 From 5aec4f6dd015185a64de34bc7bdc2ac364f53481 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 20 Nov 2012 05:15:04 +0000 Subject: Add Iain Oliver to CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index e5a6d49..43dea0b 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -93,6 +93,7 @@ what it is today. * Garmin Kawaguichi * Gryc Ueusp * Hiro Lecker +* Iain Oliver * Imaze Rhiano * Intimidated * Jeremy Bongio (IBM) -- cgit v1.1 From ea65a64f7b1867780261c2a01a6323e057ddc097 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 20 Nov 2012 10:11:57 +0000 Subject: refactor: Move common presence connector code into BasePresenceServiceConnector --- .../Presence/BasePresenceServiceConnector.cs | 133 +++++++++++++++++++++ .../Presence/LocalPresenceServiceConnector.cs | 113 ++--------------- .../Presence/RemotePresenceServiceConnector.cs | 89 +------------- .../Presence/Tests/PresenceConnectorsTests.cs | 3 +- 4 files changed, 145 insertions(+), 193 deletions(-) create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs new file mode 100644 index 0000000..c84518d --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs @@ -0,0 +1,133 @@ +/* + * 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 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 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.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence +{ + public class BasePresenceServiceConnector : IPresenceService + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected bool m_Enabled; + + protected PresenceDetector m_PresenceDetector; + + /// + /// Underlying presence service. Do not use directly. + /// + public IPresenceService m_PresenceService; + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + // m_log.DebugFormat( + // "[LOCAL PRESENCE CONNECTOR]: Registering IPresenceService to scene {0}", scene.RegionInfo.RegionName); + + scene.RegisterModuleInterface(this); + m_PresenceDetector.AddRegion(scene); + + m_log.InfoFormat("[BASE PRESENCE SERVICE CONNECTOR]: Enabled for region {0}", scene.Name); + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + m_PresenceDetector.RemoveRegion(scene); + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + #region IPresenceService + + public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) + { + m_log.Warn("[BASE PRESENCE SERVICE CONNECTOR]: LoginAgent connector not implemented at the simulators"); + return false; + } + + public bool LogoutAgent(UUID sessionID) + { + return m_PresenceService.LogoutAgent(sessionID); + } + + public bool LogoutRegionAgents(UUID regionID) + { + return m_PresenceService.LogoutRegionAgents(regionID); + } + + public bool ReportAgent(UUID sessionID, UUID regionID) + { + return m_PresenceService.ReportAgent(sessionID, regionID); + } + + public PresenceInfo GetAgent(UUID sessionID) + { + return m_PresenceService.GetAgent(sessionID); + } + + public PresenceInfo[] GetAgents(string[] userIDs) + { + return m_PresenceService.GetAgents(userIDs); + } + + #endregion + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs index d8bed1b..db5c520 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs @@ -24,53 +24,29 @@ * (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 Mono.Addins; +using Nini.Config; +using OpenMetaverse; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; -using OpenMetaverse; -using log4net; -using Mono.Addins; -using Nini.Config; - namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalPresenceServicesConnector")] - public class LocalPresenceServicesConnector : ISharedRegionModule, IPresenceService + public class LocalPresenceServicesConnector : BasePresenceServiceConnector, ISharedRegionModule, IPresenceService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool m_Enabled = false; - - private PresenceDetector m_PresenceDetector; - - /// - /// Underlying presence service. Do not use directly. - /// - public IPresenceService m_PresenceService; - - public LocalPresenceServicesConnector() - { - } - - public LocalPresenceServicesConnector(IConfigSource source) - { - Initialise(source); - } - #region ISharedRegionModule - public Type ReplaceableInterface - { - get { return null; } - } - public string Name { get { return "LocalPresenceServicesConnector"; } @@ -121,81 +97,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence } } - public void PostInitialise() - { - } - - public void Close() - { - } - - public void AddRegion(Scene scene) - { - if (!m_Enabled) - return; - - // m_log.DebugFormat( - // "[LOCAL PRESENCE CONNECTOR]: Registering IPresenceService to scene {0}", scene.RegionInfo.RegionName); - - scene.RegisterModuleInterface(this); - m_PresenceDetector.AddRegion(scene); - - m_log.InfoFormat("[LOCAL PRESENCE CONNECTOR]: Enabled local presence for region {0}", scene.RegionInfo.RegionName); - - } - - public void RemoveRegion(Scene scene) - { - if (!m_Enabled) - return; - - m_PresenceDetector.RemoveRegion(scene); - } - - public void RegionLoaded(Scene scene) - { - if (!m_Enabled) - return; - - } - #endregion - - #region IPresenceService - - public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) - { - m_log.Warn("[LOCAL PRESENCE CONNECTOR]: LoginAgent connector not implemented at the simulators"); - return false; - } - - public bool LogoutAgent(UUID sessionID) - { - return m_PresenceService.LogoutAgent(sessionID); - } - - - public bool LogoutRegionAgents(UUID regionID) - { - return m_PresenceService.LogoutRegionAgents(regionID); - } - - public bool ReportAgent(UUID sessionID, UUID regionID) - { - return m_PresenceService.ReportAgent(sessionID, regionID); - } - - public PresenceInfo GetAgent(UUID sessionID) - { - return m_PresenceService.GetAgent(sessionID); - } - - public PresenceInfo[] GetAgents(string[] userIDs) - { - return m_PresenceService.GetAgents(userIDs); - } - - #endregion - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs index be73932..6ca5c28 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs @@ -43,22 +43,12 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemotePresenceServicesConnector")] - public class RemotePresenceServicesConnector : ISharedRegionModule, IPresenceService + public class RemotePresenceServicesConnector : BasePresenceServiceConnector, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); #region ISharedRegionModule - private bool m_Enabled = false; - - private PresenceDetector m_PresenceDetector; - private IPresenceService m_RemoteConnector; - - public Type ReplaceableInterface - { - get { return null; } - } - public string Name { get { return "RemotePresenceServicesConnector"; } @@ -72,7 +62,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence string name = moduleConfig.GetString("PresenceServices", ""); if (name == Name) { - m_RemoteConnector = new PresenceServicesConnector(source); + m_PresenceService = new PresenceServicesConnector(source); m_Enabled = true; @@ -81,81 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence m_log.Info("[REMOTE PRESENCE CONNECTOR]: Remote presence enabled"); } } - - } - - public void PostInitialise() - { - } - - public void Close() - { - } - - public void AddRegion(Scene scene) - { - if (!m_Enabled) - return; - - scene.RegisterModuleInterface(this); - m_PresenceDetector.AddRegion(scene); - - m_log.InfoFormat("[REMOTE PRESENCE CONNECTOR]: Enabled remote presence for region {0}", scene.RegionInfo.RegionName); - - } - - public void RemoveRegion(Scene scene) - { - if (!m_Enabled) - return; - - m_PresenceDetector.RemoveRegion(scene); - } - - public void RegionLoaded(Scene scene) - { - if (!m_Enabled) - return; - - } - - #endregion - - #region IPresenceService - - public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) - { - m_log.Warn("[REMOTE PRESENCE CONNECTOR]: LoginAgent connector not implemented at the simulators"); - return false; - } - - public bool LogoutAgent(UUID sessionID) - { - return m_RemoteConnector.LogoutAgent(sessionID); - } - - - public bool LogoutRegionAgents(UUID regionID) - { - return m_RemoteConnector.LogoutRegionAgents(regionID); - } - - public bool ReportAgent(UUID sessionID, UUID regionID) - { - return m_RemoteConnector.ReportAgent(sessionID, regionID); - } - - public PresenceInfo GetAgent(UUID sessionID) - { - return m_RemoteConnector.GetAgent(sessionID); - } - - public PresenceInfo[] GetAgents(string[] userIDs) - { - return m_RemoteConnector.GetAgents(userIDs); } #endregion - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs index 4556df3..32e47f9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs @@ -56,7 +56,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests config.Configs["PresenceService"].Set("LocalServiceModule", "OpenSim.Services.PresenceService.dll:PresenceService"); config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); - m_LocalConnector = new LocalPresenceServicesConnector(config); + m_LocalConnector = new LocalPresenceServicesConnector(); + m_LocalConnector.Initialise(config); // Let's stick in a test presence m_LocalConnector.m_PresenceService.LoginAgent(UUID.Zero.ToString(), UUID.Zero, UUID.Zero); -- cgit v1.1 From f656adee31f5210acb4d1c8c89fe0d1e9362feee Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 20 Nov 2012 10:22:49 +0000 Subject: If GetAgents() is called with an empty userIDs array then don't bother with a useless potentially network call on the scene presence service connector. This also eliminates the "[PRESENCE HANDLER]: GetAgents called without required uuids argument" which has started to pop up in the logs when a call is made with an empty uuid array as occasionally happens. --- .../ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs index c84518d..fdbe10a 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs @@ -125,6 +125,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence public PresenceInfo[] GetAgents(string[] userIDs) { + // Don't bother potentially making a useless network call if we not going to ask for any users anyway. + if (userIDs.Length == 0) + return new PresenceInfo[0]; + return m_PresenceService.GetAgents(userIDs); } -- cgit v1.1 From bac8ac32dae4049e84f74d276bb5ce83a2a512ac Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 21 Nov 2012 23:42:34 +0000 Subject: Add regression test for a good request made to the asset service post handler. Adds new OpenSim.Server.Handlers.Tests.dll to test suite --- .nant/local.include | 10 +++ .../Asset/Tests/AssetServerPostHandlerTests.cs | 84 ++++++++++++++++++++++ prebuild.xml | 46 ++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs diff --git a/.nant/local.include b/.nant/local.include index 9c9aa28..5185717 100644 --- a/.nant/local.include +++ b/.nant/local.include @@ -132,6 +132,11 @@ + + + + + @@ -240,6 +245,11 @@ + + + + + diff --git a/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs b/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs new file mode 100644 index 0000000..9e82576 --- /dev/null +++ b/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs @@ -0,0 +1,84 @@ +/* + * 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 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 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.IO; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Server.Handlers.Asset; +using OpenSim.Services.AssetService; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; + +namespace OpenSim.Server.Handlers.Asset.Test +{ + [TestFixture] + public class AssetServerPostHandlerTests : OpenSimTestCase + { + [Test] + public void TestGoodAssetStoreRequest() + { + TestHelpers.InMethod(); + + UUID assetId = TestHelpers.ParseTail(0x1); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("AssetService"); + config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); + + AssetService assetService = new AssetService(config); + + AssetServerPostHandler asph = new AssetServerPostHandler(assetService); + + AssetBase asset = AssetHelpers.CreateNotecardAsset(assetId, "Hello World"); + + MemoryStream buffer = new MemoryStream(); + + XmlWriterSettings settings = new XmlWriterSettings(); + settings.Encoding = Encoding.UTF8; + + using (XmlWriter writer = XmlWriter.Create(buffer, settings)) + { + XmlSerializer serializer = new XmlSerializer(typeof(AssetBase)); + serializer.Serialize(writer, asset); + writer.Flush(); + } + + buffer.Position = 0; + asph.Handle(null, buffer, null, null); + + AssetBase retrievedAsset = assetService.Get(assetId.ToString()); + + Assert.That(retrievedAsset, Is.Not.Null); + } + } +} \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index 7694861..bb9d80c 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3297,6 +3297,52 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.1 From 2f5fe4b88e8eb0388cc2138c48a941b1317ed560 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 20 Nov 2012 08:34:18 -0800 Subject: BulletSim: tweek avatar capsule parameters so avatar feet don't go below ground. This solves the bouncing, short avatar problem (Mantis 6403). --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 7 ++++--- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 11 ++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 3c48dcc..fa1a23f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -184,8 +184,8 @@ public sealed class BSCharacter : BSPhysObject _size = value; ComputeAvatarScale(_size); ComputeAvatarVolumeAndMass(); - DetailLog("{0},BSCharacter.setSize,call,scale={1},density={2},volume={3},mass={4}", - LocalID, Scale, _avatarDensity, _avatarVolume, RawMass); + DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", + LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { @@ -619,7 +619,8 @@ public sealed class BSCharacter : BSPhysObject newScale.Y = PhysicsScene.Params.avatarCapsuleRadius; // From the total height, remove the capsule half spheres that are at each end - newScale.Z = size.Z - (newScale.X + newScale.Y); + // The 1.15f came from ODE. Not sure what this factors in. + newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y); Scale = newScale; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 2fee95e..58dccea 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -712,7 +712,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // here just before the physics engine is called to step the simulation. public void ProcessTaints() { - InTaintTime = true; + InTaintTime = true; // Only used for debugging so locking is not necessary. ProcessRegularTaints(); ProcessPostTaintTaints(); InTaintTime = false; @@ -758,6 +758,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters DetailLog("{0},BSScene.ProcessTaints,leftTaintsOnList,numNotProcessed={1}", DetailLogZero, _taintOperations.Count); } */ + // swizzle a new list into the list location so we can process what's there List oldList; lock (_taintLock) @@ -787,8 +788,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // will replace any previous operation by the same object. public void PostTaintObject(String ident, uint ID, TaintCallback callback) { - if (!m_initialized) return; - string uniqueIdent = ident + "-" + ID.ToString(); lock (_taintLock) { @@ -864,13 +863,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } + // Only used for debugging. Does not change state of anything so locking is not necessary. public bool AssertInTaintTime(string whereFrom) { if (!InTaintTime) { DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); - Util.PrintCallStack(); + Util.PrintCallStack(); // Prints the stack into the DEBUG log file. } return InTaintTime; } @@ -1186,7 +1186,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].avatarCapsuleRadius; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", - 1.5f, + // 1.5f, + 2.140599f, (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarCapsuleHeight; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), -- cgit v1.1 From 4d29488216f3619455cda72aaf2d6ccf8f3e2402 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 20 Nov 2012 08:43:43 -0800 Subject: BulletSim: change PositionSanityCheck to apply a force to correct position corrections (below ground and floating). --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 61 ++++++++++------------ .../Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 500c84a..b1b5846 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -47,7 +47,6 @@ public sealed class BSPrim : BSPhysObject // _size is what the user passed. Scale is what we pass to the physics engine with the mesh. // Often Scale is unity because the meshmerizer will apply _size when creating the mesh. private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user - // private OMV.Vector3 _scale; // the multiplier for each mesh dimension for the mesh as created by the meshmerizer private bool _grabbed; private bool _isSelected; @@ -274,19 +273,19 @@ public sealed class BSPrim : BSPhysObject if (!Linkset.IsRoot(this)) _position = Linkset.Position(this); - // 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); return _position; } set { - // If you must push the position into the physics engine, use ForcePosition. + // If the position must be forced into the physics engine, use ForcePosition. if (_position == value) { return; } _position = value; // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? - PositionSanityCheck(); + PositionSanityCheck(false); PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); @@ -302,7 +301,7 @@ public sealed class BSPrim : BSPhysObject } set { _position = value; - PositionSanityCheck(); + // PositionSanityCheck(); // Don't do this! Causes a loop and caller should know better. BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); ActivateIfPhysical(false); } @@ -311,52 +310,43 @@ public sealed class BSPrim : BSPhysObject // Check that the current position is sane and, if not, modify the position to make it so. // Check for being below terrain and being out of bounds. // Returns 'true' of the position was made sane by some action. - private bool PositionSanityCheck() + private bool PositionSanityCheck(bool inTaintTime) { bool ret = false; - // If totally below the ground, move the prim up - // TODO: figure out the right solution for this... only for dynamic objects? - /* float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); + OMV.Vector3 upForce = OMV.Vector3.Zero; if (Position.Z < terrainHeight) { DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); - _position.Z = terrainHeight + 2.0f; + float targetHeight = terrainHeight + (Size.Z / 2f); + // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. + upForce.Z = (terrainHeight - Position.Z) * 1f; ret = true; } - */ + if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) { float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); // TODO: a floating motor so object will bob in the water - if (Position.Z < waterHeight) + if (Math.Abs(Position.Z - waterHeight) > 0.1f) { - _position.Z = waterHeight; + // Upforce proportional to the distance away from the water. Correct the error in 1 sec. + upForce.Z = (waterHeight - Position.Z) * 1f; ret = true; } } // TODO: check for out of bounds - return ret; - } - // A version of the sanity check that also makes sure a new position value is - // pushed to the physics engine. This routine would be used by anyone - // who is not already pushing the value. - private bool PositionSanityCheck(bool inTaintTime) - { - bool ret = false; - if (PositionSanityCheck()) + // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. + if (ret) { - // The new position value must be pushed into the physics engine but we can't - // just assign to "Position" because of potential call loops. - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck", delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck:belowTerrain", delegate() { - DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); - ForcePosition = _position; + // Apply upforce and overcome gravity. + ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity; }); - ret = true; } return ret; } @@ -940,6 +930,7 @@ public sealed class BSPrim : BSPhysObject public override void AddForce(OMV.Vector3 force, bool pushforce) { AddForce(force, pushforce, false); } + // Applying a force just adds this to the total force on the object. public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { // for an object, doesn't matter if force is a pushforce or not if (force.IsFinite()) @@ -971,6 +962,7 @@ public sealed class BSPrim : BSPhysObject }); } + // An impulse force is scaled by the mass of the object. public void ApplyForceImpulse(OMV.Vector3 impulse, bool inTaintTime) { OMV.Vector3 applyImpulse = impulse; @@ -1423,7 +1415,7 @@ public sealed class BSPrim : BSPhysObject if (changed != 0) { // Only update the position of single objects and linkset roots - if (this._parentPrim == null) + if (Linkset.IsRoot(this)) { base.RequestPhysicsterseUpdate(); } @@ -1435,19 +1427,24 @@ public sealed class BSPrim : BSPhysObject // Updates only for individual prims and for the root object of a linkset. if (Linkset.IsRoot(this)) { - // Assign to the local variables so the normal set action does not happen + // Assign directly to the local variables so the normal set action does not happen _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; + // The sanity check can change the velocity and/or position. + if (PositionSanityCheck(true)) + { + entprop.Position = _position; + entprop.Velocity = _velocity; + } + // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; - PositionSanityCheck(true); - OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 29a23c0..7ef6429 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -940,7 +940,7 @@ public sealed class BSShapeCollection : IDisposable else { bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, - prim.LocalID, prim.ForcePosition, prim.ForceOrientation); + prim.LocalID, prim.RawPosition, prim.RawOrientation); DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); } aBody = new BulletBody(prim.LocalID, bodyPtr); -- cgit v1.1 From d6db0d5740dae03174f65846556f2f06d573b5c4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 20 Nov 2012 11:24:25 -0800 Subject: BulletSim: uplevel PhysicsShapeType out of ShapeData structure (since it is getting simplified out of existance someday) and update all the references to that enum. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 4 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 6 +-- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 56 +++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 16 +++---- .../Physics/BulletSPlugin/BSTerrainManager.cs | 4 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 37 +++++++------- 9 files changed, 67 insertions(+), 66 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index fa1a23f..92ff804 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -203,9 +203,9 @@ public sealed class BSCharacter : BSPhysObject set { BaseShape = value; } } // I want the physics engine to make an avatar capsule - public override ShapeData.PhysicsShapeType PreferredPhysicalShape + public override PhysicsShapeType PreferredPhysicalShape { - get {return ShapeData.PhysicsShapeType.SHAPE_AVATAR; } + get {return PhysicsShapeType.SHAPE_AVATAR; } } public override bool Grabbed { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 436e043..4ee047b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -82,9 +82,9 @@ public abstract class BSLinkset // Some linksets have a preferred physical shape. // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. - public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) + public virtual PhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) { - return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; + return PhysicsShapeType.SHAPE_UNKNOWN; } // Linksets move around the children so the linkset might need to compute the child position diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 3238c85..cb37840 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -42,12 +42,12 @@ public sealed class BSLinksetCompound : BSLinkset } // For compound implimented linksets, if there are children, use compound shape for the root. - public override ShapeData.PhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) + public override PhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) { - ShapeData.PhysicsShapeType ret = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; + PhysicsShapeType ret = PhysicsShapeType.SHAPE_UNKNOWN; if (IsRoot(requestor) && HasAnyChildren) { - ret = ShapeData.PhysicsShapeType.SHAPE_COMPOUND; + ret = PhysicsShapeType.SHAPE_COMPOUND; } // DetailLog("{0},BSLinksetCompound.PreferredPhysicalShape,call,shape={1}", LinksetRoot.LocalID, ret); return ret; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 991e5b1..e68b167 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -94,9 +94,9 @@ public abstract class BSPhysObject : PhysicsActor public PrimitiveBaseShape BaseShape { get; protected set; } // Some types of objects have preferred physical representations. // Returns SHAPE_UNKNOWN if there is no preference. - public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape + public virtual PhysicsShapeType PreferredPhysicalShape { - get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } + get { return PhysicsShapeType.SHAPE_UNKNOWN; } } // When the physical properties are updated, an EntityProperty holds the update values. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index b1b5846..2657e4b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -169,7 +169,7 @@ public sealed class BSPrim : BSPhysObject } } // Whatever the linkset wants is what I want. - public override ShapeData.PhysicsShapeType PreferredPhysicalShape + public override PhysicsShapeType PreferredPhysicalShape { get { return Linkset.PreferredPhysicalShape(this); } } public override bool ForceBodyShapeRebuild(bool inTaintTime) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 7ef6429..746a52e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -178,7 +178,7 @@ public sealed class BSShapeCollection : IDisposable bool ret = false; switch (shape.type) { - case ShapeData.PhysicsShapeType.SHAPE_MESH: + case PhysicsShapeType.SHAPE_MESH: MeshDesc meshDesc; if (Meshes.TryGetValue(shape.shapeKey, out meshDesc)) { @@ -201,7 +201,7 @@ public sealed class BSShapeCollection : IDisposable meshDesc.lastReferenced = System.DateTime.Now; Meshes[shape.shapeKey] = meshDesc; break; - case ShapeData.PhysicsShapeType.SHAPE_HULL: + case PhysicsShapeType.SHAPE_HULL: HullDesc hullDesc; if (Hulls.TryGetValue(shape.shapeKey, out hullDesc)) { @@ -224,7 +224,7 @@ public sealed class BSShapeCollection : IDisposable hullDesc.lastReferenced = System.DateTime.Now; Hulls[shape.shapeKey] = hullDesc; break; - case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: + case PhysicsShapeType.SHAPE_UNKNOWN: break; default: // Native shapes are not tracked and they don't go into any list @@ -255,16 +255,16 @@ public sealed class BSShapeCollection : IDisposable { switch (shape.type) { - case ShapeData.PhysicsShapeType.SHAPE_HULL: + case PhysicsShapeType.SHAPE_HULL: DereferenceHull(shape, shapeCallback); break; - case ShapeData.PhysicsShapeType.SHAPE_MESH: + case PhysicsShapeType.SHAPE_MESH: DereferenceMesh(shape, shapeCallback); break; - case ShapeData.PhysicsShapeType.SHAPE_COMPOUND: + case PhysicsShapeType.SHAPE_COMPOUND: DereferenceCompound(shape, shapeCallback); break; - case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: + case PhysicsShapeType.SHAPE_UNKNOWN: break; default: break; @@ -352,28 +352,28 @@ public sealed class BSShapeCollection : IDisposable BulletShape shapeInfo = new BulletShape(cShape); if (TryGetMeshByPtr(cShape, out meshDesc)) { - shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_MESH; + shapeInfo.type = PhysicsShapeType.SHAPE_MESH; shapeInfo.shapeKey = meshDesc.shapeKey; } else { if (TryGetHullByPtr(cShape, out hullDesc)) { - shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_HULL; + shapeInfo.type = PhysicsShapeType.SHAPE_HULL; shapeInfo.shapeKey = hullDesc.shapeKey; } else { if (BulletSimAPI.IsCompound2(cShape)) { - shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_COMPOUND; + shapeInfo.type = PhysicsShapeType.SHAPE_COMPOUND; } else { if (BulletSimAPI.IsNativeShape2(cShape)) { shapeInfo.isNativeShape = true; - shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) + shapeInfo.type = PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) } } } @@ -381,7 +381,7 @@ public sealed class BSShapeCollection : IDisposable DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); - if (shapeInfo.type != ShapeData.PhysicsShapeType.SHAPE_UNKNOWN) + if (shapeInfo.type != PhysicsShapeType.SHAPE_UNKNOWN) { DereferenceShape(shapeInfo, true, null); } @@ -405,10 +405,10 @@ public sealed class BSShapeCollection : IDisposable bool ret = false; bool haveShape = false; - if (!haveShape && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR) + if (!haveShape && prim.PreferredPhysicalShape == PhysicsShapeType.SHAPE_AVATAR) { // an avatar capsule is close to a native shape (it is not shared) - ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR, + ret = GetReferenceToNativeShape(prim, PhysicsShapeType.SHAPE_AVATAR, ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; @@ -417,7 +417,7 @@ public sealed class BSShapeCollection : IDisposable // Compound shapes are handled special as they are rebuilt from scratch. // This isn't too great a hardship since most of the child shapes will already been created. - if (!haveShape && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_COMPOUND) + if (!haveShape && prim.PreferredPhysicalShape == PhysicsShapeType.SHAPE_COMPOUND) { ret = GetReferenceToCompoundShape(prim, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); @@ -460,10 +460,10 @@ public sealed class BSShapeCollection : IDisposable haveShape = true; if (forceRebuild || prim.Scale != prim.Size - || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE + || prim.PhysShape.type != PhysicsShapeType.SHAPE_SPHERE ) { - ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_SPHERE, + ret = GetReferenceToNativeShape(prim, PhysicsShapeType.SHAPE_SPHERE, ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); @@ -474,10 +474,10 @@ public sealed class BSShapeCollection : IDisposable haveShape = true; if (forceRebuild || prim.Scale != prim.Size - || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX + || prim.PhysShape.type != PhysicsShapeType.SHAPE_BOX ) { - ret = GetReferenceToNativeShape( prim, ShapeData.PhysicsShapeType.SHAPE_BOX, + ret = GetReferenceToNativeShape( prim, PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); @@ -519,7 +519,7 @@ public sealed class BSShapeCollection : IDisposable // Creates a native shape and assignes it to prim.BSShape. // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape(). private bool GetReferenceToNativeShape(BSPhysObject prim, - ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey, + PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey, ShapeDestructionCallback shapeCallback) { // release any previous shape @@ -538,7 +538,7 @@ public sealed class BSShapeCollection : IDisposable return true; } - private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, ShapeData.PhysicsShapeType shapeType, + private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) { BulletShape newShape; @@ -551,7 +551,7 @@ public sealed class BSShapeCollection : IDisposable nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey; - if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) + if (shapeType == PhysicsShapeType.SHAPE_AVATAR) { newShape = new BulletShape( BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) @@ -585,7 +585,7 @@ public sealed class BSShapeCollection : IDisposable System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); // if this new shape is the same as last time, don't recreate the mesh - if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) + if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == PhysicsShapeType.SHAPE_MESH) return false; DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", @@ -643,7 +643,7 @@ public sealed class BSShapeCollection : IDisposable indices.GetLength(0), indices, vertices.Count, verticesAsFloats); } } - BulletShape newShape = new BulletShape(meshPtr, ShapeData.PhysicsShapeType.SHAPE_MESH); + BulletShape newShape = new BulletShape(meshPtr, PhysicsShapeType.SHAPE_MESH); newShape.shapeKey = newMeshKey; return newShape; @@ -659,7 +659,7 @@ public sealed class BSShapeCollection : IDisposable System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); // if the hull hasn't changed, don't rebuild it - if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) + if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == PhysicsShapeType.SHAPE_HULL) return false; DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", @@ -780,7 +780,7 @@ public sealed class BSShapeCollection : IDisposable } } - BulletShape newShape = new BulletShape(hullPtr, ShapeData.PhysicsShapeType.SHAPE_HULL); + BulletShape newShape = new BulletShape(hullPtr, PhysicsShapeType.SHAPE_HULL); newShape.shapeKey = newHullKey; return newShape; // 'true' means a new shape has been added to this prim @@ -803,7 +803,7 @@ public sealed class BSShapeCollection : IDisposable // DereferenceShape(prim.PhysShape, true, shapeCallback); BulletShape cShape = new BulletShape( - BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), ShapeData.PhysicsShapeType.SHAPE_COMPOUND); + BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), PhysicsShapeType.SHAPE_COMPOUND); // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. CreateGeomMeshOrHull(prim, shapeCallback); @@ -894,7 +894,7 @@ public sealed class BSShapeCollection : IDisposable // While we figure out the real problem, stick a simple native shape on the object. BulletShape fillinShape = - BuildPhysicalNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); + BuildPhysicalNativeShape(prim, PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); return fillinShape; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index d59a486..2896805 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -35,7 +35,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin public abstract class BSShape { public IntPtr ptr { get; set; } - public ShapeData.PhysicsShapeType type { get; set; } + public PhysicsShapeType type { get; set; } public System.UInt64 key { get; set; } public int referenceCount { get; set; } public DateTime lastReferenced { get; set; } @@ -43,7 +43,7 @@ public abstract class BSShape public BSShape() { ptr = IntPtr.Zero; - type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; + type = PhysicsShapeType.SHAPE_UNKNOWN; key = 0; referenceCount = 0; lastReferenced = DateTime.Now; @@ -54,17 +54,17 @@ public abstract class BSShape { BSShape ret = null; - if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR) + if (prim.PreferredPhysicalShape == PhysicsShapeType.SHAPE_AVATAR) { // an avatar capsule is close to a native shape (it is not shared) - ret = BSShapeNative.GetReference(physicsScene, prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR, + ret = BSShapeNative.GetReference(physicsScene, prim, PhysicsShapeType.SHAPE_AVATAR, ShapeData.FixedShapeKey.KEY_CAPSULE); physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret); } // Compound shapes are handled special as they are rebuilt from scratch. // This isn't too great a hardship since most of the child shapes will already been created. - if (ret == null && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_COMPOUND) + if (ret == null && prim.PreferredPhysicalShape == PhysicsShapeType.SHAPE_COMPOUND) { // Getting a reference to a compound shape gets you the compound shape with the root prim shape added ret = BSShapeCompound.GetReference(prim); @@ -123,14 +123,14 @@ public class BSShapeNative : BSShape { } public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, - ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) + PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) { // Native shapes are not shared and are always built anew. return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); } private BSShapeNative(BSScene physicsScene, BSPhysObject prim, - ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) + PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) { ShapeData nativeShapeData = new ShapeData(); nativeShapeData.Type = shapeType; @@ -141,7 +141,7 @@ public class BSShapeNative : BSShape nativeShapeData.HullKey = (ulong)shapeKey; - if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) + if (shapeType == PhysicsShapeType.SHAPE_AVATAR) { ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 7c34af2..cc28e4d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -109,7 +109,7 @@ public sealed class BSTerrainManager // The ground plane is here to catch things that are trying to drop to negative infinity BulletShape groundPlaneShape = new BulletShape( BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN), - ShapeData.PhysicsShapeType.SHAPE_GROUNDPLANE); + PhysicsShapeType.SHAPE_GROUNDPLANE); m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity)); @@ -299,7 +299,7 @@ public sealed class BSTerrainManager // Create the terrain shape from the mapInfo mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr), - ShapeData.PhysicsShapeType.SHAPE_TERRAIN); + PhysicsShapeType.SHAPE_TERRAIN); // The terrain object initial position is at the center of the object Vector3 centerPos; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 28fae13..bb63b0a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -88,11 +88,11 @@ public struct BulletShape public BulletShape(IntPtr xx) { ptr = xx; - type=ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; + type=PhysicsShapeType.SHAPE_UNKNOWN; shapeKey = 0; isNativeShape = false; } - public BulletShape(IntPtr xx, ShapeData.PhysicsShapeType typ) + public BulletShape(IntPtr xx, PhysicsShapeType typ) { ptr = xx; type = typ; @@ -100,7 +100,7 @@ public struct BulletShape isNativeShape = false; } public IntPtr ptr; - public ShapeData.PhysicsShapeType type; + public PhysicsShapeType type; public System.UInt64 shapeKey; public bool isNativeShape; public override string ToString() @@ -178,24 +178,25 @@ public struct ConvexHull int VertexCount; Vector3[] Vertices; } +public enum PhysicsShapeType +{ + SHAPE_UNKNOWN = 0, + SHAPE_AVATAR = 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, +}; [StructLayout(LayoutKind.Sequential)] public struct ShapeData { - public enum PhysicsShapeType - { - SHAPE_UNKNOWN = 0, - SHAPE_AVATAR = 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, - }; public uint ID; public PhysicsShapeType Type; public Vector3 Position; -- cgit v1.1 From 65e55ada87e110b65f3d69eb0a4f2402fb1f3ece Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 20 Nov 2012 11:30:22 -0800 Subject: BulletSim: uplevel FixedShapeKey out of ShapeData structure (since it is getting simplified out of existance someday) and update all the references to same. --- .../Physics/BulletSPlugin/BSShapeCollection.cs | 12 +++++------ OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 6 +++--- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 24 ++++++++++++---------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 746a52e..0232618 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -409,7 +409,7 @@ public sealed class BSShapeCollection : IDisposable { // an avatar capsule is close to a native shape (it is not shared) ret = GetReferenceToNativeShape(prim, PhysicsShapeType.SHAPE_AVATAR, - ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback); + FixedShapeKey.KEY_CAPSULE, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; haveShape = true; @@ -464,7 +464,7 @@ public sealed class BSShapeCollection : IDisposable ) { ret = GetReferenceToNativeShape(prim, PhysicsShapeType.SHAPE_SPHERE, - ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); + FixedShapeKey.KEY_SPHERE, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); } @@ -478,7 +478,7 @@ public sealed class BSShapeCollection : IDisposable ) { ret = GetReferenceToNativeShape( prim, PhysicsShapeType.SHAPE_BOX, - ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); + FixedShapeKey.KEY_BOX, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); } @@ -519,7 +519,7 @@ public sealed class BSShapeCollection : IDisposable // Creates a native shape and assignes it to prim.BSShape. // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape(). private bool GetReferenceToNativeShape(BSPhysObject prim, - PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey, + PhysicsShapeType shapeType, FixedShapeKey shapeKey, ShapeDestructionCallback shapeCallback) { // release any previous shape @@ -539,7 +539,7 @@ public sealed class BSShapeCollection : IDisposable } private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, PhysicsShapeType shapeType, - ShapeData.FixedShapeKey shapeKey) + FixedShapeKey shapeKey) { BulletShape newShape; // Need to make sure the passed shape information is for the native type. @@ -894,7 +894,7 @@ public sealed class BSShapeCollection : IDisposable // While we figure out the real problem, stick a simple native shape on the object. BulletShape fillinShape = - BuildPhysicalNativeShape(prim, PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); + BuildPhysicalNativeShape(prim, PhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); return fillinShape; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 2896805..71b5074 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -58,7 +58,7 @@ public abstract class BSShape { // an avatar capsule is close to a native shape (it is not shared) ret = BSShapeNative.GetReference(physicsScene, prim, PhysicsShapeType.SHAPE_AVATAR, - ShapeData.FixedShapeKey.KEY_CAPSULE); + FixedShapeKey.KEY_CAPSULE); physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret); } @@ -123,14 +123,14 @@ public class BSShapeNative : BSShape { } public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, - PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) + PhysicsShapeType shapeType, FixedShapeKey shapeKey) { // Native shapes are not shared and are always built anew. return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); } private BSShapeNative(BSScene physicsScene, BSPhysObject prim, - PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) + PhysicsShapeType shapeType, FixedShapeKey shapeKey) { ShapeData nativeShapeData = new ShapeData(); nativeShapeData.Type = shapeType; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index bb63b0a..75e7f99 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -89,7 +89,7 @@ public struct BulletShape { ptr = xx; type=PhysicsShapeType.SHAPE_UNKNOWN; - shapeKey = 0; + shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; isNativeShape = false; } public BulletShape(IntPtr xx, PhysicsShapeType typ) @@ -194,6 +194,18 @@ public enum PhysicsShapeType SHAPE_COMPOUND = 22, SHAPE_HEIGHTMAP = 23, }; + +// 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, +} + [StructLayout(LayoutKind.Sequential)] public struct ShapeData { @@ -217,16 +229,6 @@ public struct ShapeData // 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; - - // The native shapes have predefined shape hash keys - public enum FixedShapeKey : ulong - { - KEY_BOX = 1, - KEY_SPHERE = 2, - KEY_CONE = 3, - KEY_CYLINDER = 4, - KEY_CAPSULE = 5, - } } [StructLayout(LayoutKind.Sequential)] public struct SweepHit -- cgit v1.1 From 8dd5813889b17cc213d20491b41dbf8142b3ccb9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 20 Nov 2012 11:33:42 -0800 Subject: BulletSim: rename SHAPE_AVATAR to SHAPE_CAPSULE with the eye to eventually having mesh avatars. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 6 +++--- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 6 +++--- OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 92ff804..799211e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -205,7 +205,7 @@ public sealed class BSCharacter : BSPhysObject // I want the physics engine to make an avatar capsule public override PhysicsShapeType PreferredPhysicalShape { - get {return PhysicsShapeType.SHAPE_AVATAR; } + get {return PhysicsShapeType.SHAPE_CAPSULE; } } public override bool Grabbed { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 0232618..a53ad6e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -405,10 +405,10 @@ public sealed class BSShapeCollection : IDisposable bool ret = false; bool haveShape = false; - if (!haveShape && prim.PreferredPhysicalShape == PhysicsShapeType.SHAPE_AVATAR) + if (!haveShape && prim.PreferredPhysicalShape == PhysicsShapeType.SHAPE_CAPSULE) { // an avatar capsule is close to a native shape (it is not shared) - ret = GetReferenceToNativeShape(prim, PhysicsShapeType.SHAPE_AVATAR, + ret = GetReferenceToNativeShape(prim, PhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; @@ -551,7 +551,7 @@ public sealed class BSShapeCollection : IDisposable nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey; - if (shapeType == PhysicsShapeType.SHAPE_AVATAR) + if (shapeType == PhysicsShapeType.SHAPE_CAPSULE) { newShape = new BulletShape( BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 71b5074..f2e62d9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -54,10 +54,10 @@ public abstract class BSShape { BSShape ret = null; - if (prim.PreferredPhysicalShape == PhysicsShapeType.SHAPE_AVATAR) + if (prim.PreferredPhysicalShape == PhysicsShapeType.SHAPE_CAPSULE) { // an avatar capsule is close to a native shape (it is not shared) - ret = BSShapeNative.GetReference(physicsScene, prim, PhysicsShapeType.SHAPE_AVATAR, + ret = BSShapeNative.GetReference(physicsScene, prim, PhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE); physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret); } @@ -141,7 +141,7 @@ public class BSShapeNative : BSShape nativeShapeData.HullKey = (ulong)shapeKey; - if (shapeType == PhysicsShapeType.SHAPE_AVATAR) + if (shapeType == PhysicsShapeType.SHAPE_CAPSULE) { ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 75e7f99..407d6d7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -181,7 +181,7 @@ public struct ConvexHull public enum PhysicsShapeType { SHAPE_UNKNOWN = 0, - SHAPE_AVATAR = 1, + SHAPE_CAPSULE = 1, SHAPE_BOX = 2, SHAPE_CONE = 3, SHAPE_CYLINDER = 4, -- cgit v1.1 From 71b9640dfa67e830769aad64ef208d767e102c92 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 20 Nov 2012 14:51:50 -0800 Subject: BulletSim: pull heightmap implementation out of the terrain manager so a mesh terrain can be implemented. --- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 174 ++++++++++++++ .../Physics/BulletSPlugin/BSTerrainManager.cs | 257 +++++++-------------- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 73 ++++++ .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 4 +- 4 files changed, 327 insertions(+), 181 deletions(-) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs new file mode 100755 index 0000000..3bb63cd --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -0,0 +1,174 @@ +/* + * 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.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules; +using OpenSim.Region.Physics.Manager; + +using Nini.Config; +using log4net; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public sealed class BSTerrainHeightmap : BSTerrainPhys +{ + static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; + + BulletHeightMapInfo m_mapInfo; + + public BSTerrainHeightmap(BSScene physicsScene, uint id, Vector3 regionSize) + : base(physicsScene) + { + Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); + Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); + int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; + float[] initialMap = new float[totalHeights]; + for (int ii = 0; ii < totalHeights; ii++) + { + initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; + } + m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo.minCoords = minTerrainCoords; + m_mapInfo.maxCoords = maxTerrainCoords; + // Don't have to free any previous since we just got here. + BuildHeightmapTerrain(); + } + + // This minCoords and maxCoords passed in give the size of the terrain (min and max Z + // are the high and low points of the heightmap). + public BSTerrainHeightmap(BSScene physicsScene, uint id, float[] initialMap, + Vector3 minCoords, Vector3 maxCoords) + : base(physicsScene) + { + m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo.minCoords = minCoords; + m_mapInfo.maxCoords = maxCoords; + m_mapInfo.minZ = minCoords.Z; + m_mapInfo.maxZ = maxCoords.Z; + + // Don't have to free any previous since we just got here. + BuildHeightmapTerrain(); + } + + public override void Dispose() + { + ReleaseHeightMapTerrain(); + } + + // Using the information in m_mapInfo, create the physical representation of the heightmap. + private void BuildHeightmapTerrain() + { + m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, + m_mapInfo.minCoords, m_mapInfo.maxCoords, + m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN); + + // Create the terrain shape from the mapInfo + m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), + PhysicsShapeType.SHAPE_TERRAIN); + + // The terrain object initial position is at the center of the object + Vector3 centerPos; + centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); + centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); + centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f); + + m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, + BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, + m_mapInfo.ID, centerPos, Quaternion.Identity)); + + // Set current terrain attributes + BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); + BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); + BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); + BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + + // Return the new terrain to the world of physical objects + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + + // redo its bounding box now that it is in the world + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + + BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr, + (uint)CollisionFilterGroups.TerrainFilter, + (uint)CollisionFilterGroups.TerrainMask); + + // Make it so the terrain will not move or be considered for movement. + BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + + return; + } + + // If there is information in m_mapInfo pointing to physical structures, release same. + private void ReleaseHeightMapTerrain() + { + if (m_mapInfo != null) + { + if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) + { + if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr)) + { + // Frees both the body and the shape. + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); + } + } + } + m_mapInfo = null; + } + + // The passed position is relative to the base of the region. + public override float GetHeightAtXYZ(Vector3 pos) + { + float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + + int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; + try + { + ret = m_mapInfo.heightMap[mapIndex]; + } + catch + { + // Sometimes they give us wonky values of X and Y. Give a warning and return something. + PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", + LogHeader, m_mapInfo.terrainRegionBase, pos); + ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + } + return ret; + } + + public override Vector3 TerrainBase + { + get { return m_mapInfo.terrainRegionBase; } + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index cc28e4d..db04299 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -40,6 +40,22 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { + +// The physical implementation of the terrain is wrapped in this class. +public abstract class BSTerrainPhys : IDisposable +{ + public BSScene PhysicsScene { get; private set; } + + public BSTerrainPhys(BSScene physicsScene) + { + PhysicsScene = physicsScene; + } + public abstract void Dispose(); + public abstract float GetHeightAtXYZ(Vector3 pos); + public abstract Vector3 TerrainBase { get; } +} + +// ========================================================================================== public sealed class BSTerrainManager { static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; @@ -67,11 +83,10 @@ public sealed class BSTerrainManager // If doing mega-regions, if we're region zero we will be managing multiple // region terrains since region zero does the physics for the whole mega-region. - private Dictionary m_heightMaps; + private Dictionary m_terrains; - // True of the terrain has been modified. - // Used to force recalculation of terrain height after terrain has been modified - private bool m_terrainModified; + // Flags used to know when to recalculate the height. + private bool m_terrainModified = false; // If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount. // This is incremented before assigning to new region so it is the last ID allocated. @@ -89,8 +104,7 @@ public sealed class BSTerrainManager public BSTerrainManager(BSScene physicsScene) { PhysicsScene = physicsScene; - m_heightMaps = new Dictionary(); - m_terrainModified = false; + m_terrains = new Dictionary(); // Assume one region of default size m_worldOffset = Vector3.Zero; @@ -99,9 +113,6 @@ public sealed class BSTerrainManager } // Create the initial instance of terrain and the underlying ground plane. - // The objects are allocated in the unmanaged space and the pointers are tracked - // by the managed code. - // The terrains and the groundPlane are not added to the list of PhysObjects. // This is called from the initialization routine so we presume it is // safe to call Bullet in real time. We hope no one is moving prims around yet. public void CreateInitialGroundPlaneAndTerrain() @@ -121,15 +132,9 @@ public sealed class BSTerrainManager BulletSimAPI.SetCollisionFilterMask2(m_groundPlane.ptr, (uint)CollisionFilterGroups.GroundPlaneFilter, (uint)CollisionFilterGroups.GroundPlaneMask); - Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE); - Vector3 maxTerrainCoords = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, HEIGHT_INITIALIZATION); - int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; - float[] initialMap = new float[totalHeights]; - for (int ii = 0; ii < totalHeights; ii++) - { - initialMap[ii] = HEIGHT_INITIALIZATION; - } - UpdateOrCreateTerrain(BSScene.TERRAIN_ID, initialMap, minTerrainCoords, maxTerrainCoords, true); + // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. + BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, BSScene.TERRAIN_ID, DefaultRegionSize); + m_terrains.Add(Vector3.Zero, initialTerrain); } // Release all the terrain structures we might have allocated @@ -150,15 +155,11 @@ public sealed class BSTerrainManager // Release all the terrain we have allocated public void ReleaseTerrain() { - foreach (KeyValuePair kvp in m_heightMaps) + foreach (KeyValuePair kvp in m_terrains) { - if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, kvp.Value.terrainBody.ptr)) - { - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, kvp.Value.terrainBody.ptr); - BulletSimAPI.ReleaseHeightMapInfo2(kvp.Value.Ptr); - } + kvp.Value.Dispose(); } - m_heightMaps.Clear(); + m_terrains.Clear(); } // The simulator wants to set a new heightmap for the terrain. @@ -176,8 +177,9 @@ public sealed class BSTerrainManager { DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", BSScene.DetailLogZero, m_worldOffset, m_worldMax); - ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateOrCreateTerrain(BSScene.CHILDTERRAIN_ID, - localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true); + ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( + BSScene.CHILDTERRAIN_ID, localHeightMap, + m_worldOffset, m_worldOffset + DefaultRegionSize, true); } } else @@ -185,7 +187,7 @@ public sealed class BSTerrainManager // If not doing the mega-prim thing, just change the terrain DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); - UpdateOrCreateTerrain(BSScene.TERRAIN_ID, localHeightMap, + UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true); } }); @@ -195,56 +197,60 @@ public sealed class BSTerrainManager // based on the passed information. The 'id' should be either the terrain id or // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used. // The latter feature is for creating child terrains for mega-regions. - // If called with a mapInfo in m_heightMaps but the terrain has no body yet (mapInfo.terrainBody.Ptr == 0) - // then a new body and shape is created and the mapInfo is filled. - // This call is used for doing the initial terrain creation. // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new // terrain shape is created and added to the body. // This call is most often used to update the heightMap and parameters of the terrain. // (The above does suggest that some simplification/refactoring is in order.) - private void UpdateOrCreateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) + private void UpdateTerrain(uint id, float[] heightMap, + Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) { - DetailLog("{0},BSTerrainManager.UpdateOrCreateTerrain,call,minC={1},maxC={2},inTaintTime={3}", + DetailLog("{0},BSTerrainManager.UpdateTerrain,call,minC={1},maxC={2},inTaintTime={3}", BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime); + // Find high and low points of passed heightmap. + // The min and max passed in are usually the region objects can exist in (maximum + // object height, for instance). The terrain wants the bounding box for the + // terrain so we replace passed min and max Z with the actual terrain min/max Z. + // limit, for float minZ = float.MaxValue; float maxZ = float.MinValue; - Vector2 terrainRegionBase = new Vector2(minCoords.X, minCoords.Y); - - int heightMapSize = heightMap.Length; - for (int ii = 0; ii < heightMapSize; ii++) + foreach (float height in heightMap) { - float height = heightMap[ii]; if (height < minZ) minZ = height; if (height > maxZ) maxZ = height; } - - // The shape of the terrain is from its base to its extents. minCoords.Z = minZ; maxCoords.Z = maxZ; - BulletHeightMapInfo mapInfo; - if (m_heightMaps.TryGetValue(terrainRegionBase, out mapInfo)) + Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); + + BSTerrainPhys terrainPhys; + if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) { // If this is terrain we know about, it's easy to update - mapInfo.heightMap = heightMap; - mapInfo.minCoords = minCoords; - mapInfo.maxCoords = maxCoords; - mapInfo.minZ = minZ; - mapInfo.maxZ = maxZ; - mapInfo.sizeX = maxCoords.X - minCoords.X; - mapInfo.sizeY = maxCoords.Y - minCoords.Y; - DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,call,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}", - BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY); - - PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateOrCreateTerrain:UpdateExisting", delegate() + DetailLog("{0},UpdateTerrain:UpdateExisting,call,terrainBase={1}", BSScene.DetailLogZero, terrainRegionBase); + + PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate() { - if (MegaRegionParentPhysicsScene != null) + // Remove old terrain from the collection + m_terrains.Remove(terrainPhys.TerrainBase); + // Release any physical memory it may be using. + terrainPhys.Dispose(); + + if (MegaRegionParentPhysicsScene == null) + { + BSTerrainPhys newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, id, + heightMap, minCoords, maxCoords); + m_terrains.Add(terrainRegionBase, newTerrainPhys); + + m_terrainModified = true; + } + else { // It's possible that Combine() was called after this code was queued. // If we are a child of combined regions, we don't create any terrain for us. - DetailLog("{0},UpdateOrCreateTerrain:AmACombineChild,taint", BSScene.DetailLogZero); + DetailLog("{0},BSTerrainManager.UpdateTerrain:AmACombineChild,taint", BSScene.DetailLogZero); // Get rid of any terrain that may have been allocated for us. ReleaseGroundPlaneAndTerrain(); @@ -252,91 +258,6 @@ public sealed class BSTerrainManager // I hate doing this, but just bail return; } - - if (mapInfo.terrainBody.ptr != IntPtr.Zero) - { - // Updating an existing terrain. - DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,taint,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}", - BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY); - - // Remove from the dynamics world because we're going to mangle this object - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); - - // Get rid of the old terrain - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); - BulletSimAPI.ReleaseHeightMapInfo2(mapInfo.Ptr); - mapInfo.Ptr = IntPtr.Zero; - - /* - // NOTE: This routine is half here because I can't get the terrain shape replacement - // to work. In the short term, the above three lines completely delete the old - // terrain and the code below recreates one from scratch. - // Hopefully the Bullet community will help me out on this one. - - // First, release the old collision shape (there is only one terrain) - BulletSimAPI.DeleteCollisionShape2(m_physicsScene.World.Ptr, mapInfo.terrainShape.Ptr); - - // Fill the existing height map info with the new location and size information - BulletSimAPI.FillHeightMapInfo2(m_physicsScene.World.Ptr, mapInfo.Ptr, mapInfo.ID, - mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN); - - // Create a terrain shape based on the new info - mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr)); - - // Stuff the shape into the existing terrain body - BulletSimAPI.SetBodyShape2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr, mapInfo.terrainShape.Ptr); - */ - } - // else - { - // Creating a new terrain. - DetailLog("{0},UpdateOrCreateTerrain:CreateNewTerrain,taint,baseX={1},baseY={2},minZ={3},maxZ={4}", - BSScene.DetailLogZero, mapInfo.minCoords.X, mapInfo.minCoords.Y, minZ, maxZ); - - mapInfo.ID = id; - mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, mapInfo.ID, - mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN); - - // Create the terrain shape from the mapInfo - mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr), - PhysicsShapeType.SHAPE_TERRAIN); - - // The terrain object initial position is at the center of the object - Vector3 centerPos; - centerPos.X = minCoords.X + (mapInfo.sizeX / 2f); - centerPos.Y = minCoords.Y + (mapInfo.sizeY / 2f); - centerPos.Z = minZ + ((maxZ - minZ) / 2f); - - mapInfo.terrainBody = new BulletBody(mapInfo.ID, - BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.ptr, - id, centerPos, Quaternion.Identity)); - } - - // Make sure the entry is in the heightmap table - m_heightMaps[terrainRegionBase] = mapInfo; - - // Set current terrain attributes - BulletSimAPI.SetFriction2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); - BulletSimAPI.SetHitFraction2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); - BulletSimAPI.SetRestitution2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); - BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - - // Return the new terrain to the world of physical objects - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); - - // redo its bounding box now that it is in the world - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); - - BulletSimAPI.SetCollisionFilterMask2(mapInfo.terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainFilter, - (uint)CollisionFilterGroups.TerrainMask); - - // Make sure the new shape is processed. - // BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true); - // BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.ISLAND_SLEEPING); - BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); - - m_terrainModified = true; }); } else @@ -353,34 +274,23 @@ public sealed class BSTerrainManager Vector3 minCoordsX = minCoords; Vector3 maxCoordsX = maxCoords; - DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}", + DetailLog("{0},UpdateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}", BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); // Code that must happen at taint-time - PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateOrCreateTerrain:NewTerrain", delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:NewTerrain", delegate() { - DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y); - // Create a new mapInfo that will be filled with the new info - mapInfo = new BulletHeightMapInfo(id, heightMapX, - BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, newTerrainID, - minCoordsX, maxCoordsX, heightMapX, TERRAIN_COLLISION_MARGIN)); - // Put the unfilled heightmap info into the collection of same - m_heightMaps.Add(terrainRegionBase, mapInfo); - // Build the terrain - UpdateOrCreateTerrain(newTerrainID, heightMap, minCoords, maxCoords, true); + DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}", + BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y); + BSTerrainPhys newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, newTerrainID, + heightMapX, minCoordsX, maxCoordsX); + m_terrains.Add(terrainRegionBase, newTerrainPhys); m_terrainModified = true; }); } } - // Someday we will have complex terrain with caves and tunnels - public float GetTerrainHeightAtXYZ(Vector3 loc) - { - // For the moment, it's flat and convex - return GetTerrainHeightAtXY(loc.X, loc.Y); - } - // Given an X and Y, find the height of the terrain. // Since we could be handling multiple terrains for a mega-region, // the base of the region is calcuated assuming all regions are @@ -390,8 +300,10 @@ public sealed class BSTerrainManager private float lastHeightTX = 999999f; private float lastHeightTY = 999999f; private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT; - private float GetTerrainHeightAtXY(float tX, float tY) + public float GetTerrainHeightAtXYZ(Vector3 loc) { + float tX = loc.X; + float tY = loc.Y; // You'd be surprized at the number of times this routine is called // with the same parameters as last time. if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) @@ -403,27 +315,14 @@ public sealed class BSTerrainManager int offsetX = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; - Vector2 terrainBaseXY = new Vector2(offsetX, offsetY); + Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); - BulletHeightMapInfo mapInfo; - if (m_heightMaps.TryGetValue(terrainBaseXY, out mapInfo)) + BSTerrainPhys physTerrain; + if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) { - float regionX = tX - offsetX; - float regionY = tY - offsetY; - int mapIndex = (int)regionY * (int)mapInfo.sizeY + (int)regionX; - try - { - ret = mapInfo.heightMap[mapIndex]; - } - catch - { - // Sometimes they give us wonky values of X and Y. Give a warning and return something. - PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, x={2}, y={3}", - LogHeader, terrainBaseXY, regionX, regionY); - ret = HEIGHT_GETHEIGHT_RET; - } - // DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXY,bX={1},baseY={2},szX={3},szY={4},regX={5},regY={6},index={7},ht={8}", - // BSScene.DetailLogZero, offsetX, offsetY, mapInfo.sizeX, mapInfo.sizeY, regionX, regionY, mapIndex, ret); + ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); + DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,loc={1},base={2},height={3}", + BSScene.DetailLogZero, loc, terrainBaseXYZ, ret); } else { @@ -466,7 +365,7 @@ public sealed class BSTerrainManager // Unhook all the combining that I know about. public void UnCombine(PhysicsScene pScene) { - // Just like ODE, for the moment a NOP + // Just like ODE, we don't do anything yet. DetailLog("{0},BSTerrainManager.UnCombine", BSScene.DetailLogZero); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs new file mode 100755 index 0000000..387c78b --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -0,0 +1,73 @@ +/* + * 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.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules; +using OpenSim.Region.Physics.Manager; + +using Nini.Config; +using log4net; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public sealed class BSTerrainMesh : BSTerrainPhys +{ + static string LogHeader = "[BULLETSIM TERRAIN MESH]"; + + public BSTerrainMesh(BSScene physicsScene, uint id, Vector3 regionSize) + : base(physicsScene) + { + } + + public BSTerrainMesh(BSScene physicsScene /* parameters for making mesh */) + : base(physicsScene) + { + } + + public override void Dispose() + { + return; + } + + public override float GetHeightAtXYZ(Vector3 pos) + { + return 12345f; + } + + public override Vector3 TerrainBase + { + get { return Vector3.Zero; } + } + +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 407d6d7..bab3b3d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -152,7 +152,7 @@ public class BulletHeightMapInfo ID = id; Ptr = xx; heightMap = hm; - terrainRegionBase = new Vector2(0f, 0f); + terrainRegionBase = Vector3.Zero; minCoords = new Vector3(100f, 100f, 25f); maxCoords = new Vector3(101f, 101f, 26f); minZ = maxZ = 0f; @@ -161,7 +161,7 @@ public class BulletHeightMapInfo public uint ID; public IntPtr Ptr; public float[] heightMap; - public Vector2 terrainRegionBase; + public Vector3 terrainRegionBase; public Vector3 minCoords; public Vector3 maxCoords; public float sizeX, sizeY; -- cgit v1.1 From 34cbc738a84b7946a87e8bfd3bb04869519b3dee Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 20 Nov 2012 20:36:49 -0800 Subject: BulletSim: enablement and debugging of mesh terrain. --- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 28 ++- .../Physics/BulletSPlugin/BSTerrainManager.cs | 26 ++- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 229 ++++++++++++++++++++- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 6 +- 4 files changed, 253 insertions(+), 36 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 3bb63cd..e9fd0cb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -44,10 +44,11 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; - BulletHeightMapInfo m_mapInfo; + BulletHeightMapInfo m_mapInfo = null; - public BSTerrainHeightmap(BSScene physicsScene, uint id, Vector3 regionSize) - : base(physicsScene) + // Constructor to build a default, flat heightmap terrain. + public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) + : base(physicsScene, regionBase, id) { Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); @@ -60,21 +61,23 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo.minCoords = minTerrainCoords; m_mapInfo.maxCoords = maxTerrainCoords; + m_mapInfo.terrainRegionBase = TerrainBase; // Don't have to free any previous since we just got here. BuildHeightmapTerrain(); } // This minCoords and maxCoords passed in give the size of the terrain (min and max Z // are the high and low points of the heightmap). - public BSTerrainHeightmap(BSScene physicsScene, uint id, float[] initialMap, + public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, Vector3 minCoords, Vector3 maxCoords) - : base(physicsScene) + : base(physicsScene, regionBase, id) { m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo.minCoords = minCoords; m_mapInfo.maxCoords = maxCoords; m_mapInfo.minZ = minCoords.Z; m_mapInfo.maxZ = maxCoords.Z; + m_mapInfo.terrainRegionBase = TerrainBase; // Don't have to free any previous since we just got here. BuildHeightmapTerrain(); @@ -135,12 +138,10 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) { - if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr)) - { - // Frees both the body and the shape. - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); - } + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + // Frees both the body and the shape. + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); } } m_mapInfo = null; @@ -165,10 +166,5 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys } return ret; } - - public override Vector3 TerrainBase - { - get { return m_mapInfo.terrainRegionBase; } - } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index db04299..ed0dfa8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -45,14 +45,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin public abstract class BSTerrainPhys : IDisposable { public BSScene PhysicsScene { get; private set; } + // Base of the region in world coordinates. Coordinates inside the region are relative to this. + public Vector3 TerrainBase { get; private set; } + public uint ID { get; private set; } - public BSTerrainPhys(BSScene physicsScene) + public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id) { PhysicsScene = physicsScene; + TerrainBase = regionBase; + ID = id; } public abstract void Dispose(); public abstract float GetHeightAtXYZ(Vector3 pos); - public abstract Vector3 TerrainBase { get; } } // ========================================================================================== @@ -133,7 +137,7 @@ public sealed class BSTerrainManager (uint)CollisionFilterGroups.GroundPlaneFilter, (uint)CollisionFilterGroups.GroundPlaneMask); // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. - BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, BSScene.TERRAIN_ID, DefaultRegionSize); + BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); m_terrains.Add(Vector3.Zero, initialTerrain); } @@ -208,10 +212,9 @@ public sealed class BSTerrainManager BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime); // Find high and low points of passed heightmap. - // The min and max passed in are usually the region objects can exist in (maximum + // The min and max passed in is usually the area objects can be in (maximum // object height, for instance). The terrain wants the bounding box for the // terrain so we replace passed min and max Z with the actual terrain min/max Z. - // limit, for float minZ = float.MaxValue; float maxZ = float.MinValue; foreach (float height in heightMap) @@ -219,6 +222,11 @@ public sealed class BSTerrainManager if (height < minZ) minZ = height; if (height > maxZ) maxZ = height; } + if (minZ == maxZ) + { + // If min and max are the same, reduce min a little bit so a good bounding box is created. + minZ -= BSTerrainManager.HEIGHT_EQUAL_FUDGE; + } minCoords.Z = minZ; maxCoords.Z = maxZ; @@ -240,7 +248,9 @@ public sealed class BSTerrainManager if (MegaRegionParentPhysicsScene == null) { - BSTerrainPhys newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, id, + // BSTerrainPhys newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, + // heightMap, minCoords, maxCoords); + BSTerrainPhys newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, heightMap, minCoords, maxCoords); m_terrains.Add(terrainRegionBase, newTerrainPhys); @@ -282,8 +292,8 @@ public sealed class BSTerrainManager { DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y); - BSTerrainPhys newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, newTerrainID, - heightMapX, minCoordsX, maxCoordsX); + BSTerrainPhys newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, + newTerrainID, heightMapX, minCoordsX, maxCoordsX); m_terrains.Add(terrainRegionBase, newTerrainPhys); m_terrainModified = true; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 387c78b..bbb014a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -44,30 +44,241 @@ public sealed class BSTerrainMesh : BSTerrainPhys { static string LogHeader = "[BULLETSIM TERRAIN MESH]"; - public BSTerrainMesh(BSScene physicsScene, uint id, Vector3 regionSize) - : base(physicsScene) + private float[] m_savedHeightMap; + int m_sizeX; + int m_sizeY; + + BulletShape m_terrainShape; + BulletBody m_terrainBody; + + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) + : base(physicsScene, regionBase, id) { } - public BSTerrainMesh(BSScene physicsScene /* parameters for making mesh */) - : base(physicsScene) + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) + : base(physicsScene, regionBase, id) { } + // Create terrain mesh from a heightmap. + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, + Vector3 minCoords, Vector3 maxCoords) + : base(physicsScene, regionBase, id) + { + int indicesCount; + int[] indices; + int verticesCount; + float[] vertices; + + m_savedHeightMap = initialMap; + + m_sizeX = (int)(maxCoords.X - minCoords.X); + m_sizeY = (int)(maxCoords.Y - minCoords.Y); + + if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY, + (float)m_sizeX, (float)m_sizeY, + Vector3.Zero, 1.0f, + out indicesCount, out indices, out verticesCount, out vertices)) + { + // DISASTER!! + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); + PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}", + ID, verticesCount, indicesCount); + + m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, + indicesCount, indices, verticesCount, vertices), + PhysicsShapeType.SHAPE_MESH); + if (m_terrainShape.ptr == IntPtr.Zero) + { + // DISASTER!! + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); + physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape); + + // The terrain object initial position is at the center of the object + Vector3 centerPos; + centerPos.X = minCoords.X + (m_sizeX / 2f); + centerPos.Y = minCoords.Y + (m_sizeY / 2f); + centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f); + Quaternion rot = Quaternion.Identity; + + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot); + m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( + m_terrainShape.ptr, ID, centerPos, rot)); + if (m_terrainBody.ptr == IntPtr.Zero) + { + // DISASTER!! + physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody); + + // Set current terrain attributes + BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction); + BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); + BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution); + BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + + // Static objects are not very massive. + BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); + + // Return the new terrain to the world of physical objects + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); + + // redo its bounding box now that it is in the world + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); + + BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, + (uint)CollisionFilterGroups.TerrainFilter, + (uint)CollisionFilterGroups.TerrainMask); + + // Make it so the terrain will not move or be considered for movement. + BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + } + public override void Dispose() { - return; + if (m_terrainBody.ptr != IntPtr.Zero) + { + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); + // Frees both the body and the shape. + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr); + } } public override float GetHeightAtXYZ(Vector3 pos) { - return 12345f; + // For the moment use the saved heightmap to get the terrain height. + // TODO: raycast downward to find the true terrain below the position. + float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + + int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X; + try + { + ret = m_savedHeightMap[mapIndex]; + } + catch + { + // Sometimes they give us wonky values of X and Y. Give a warning and return something. + PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", + LogHeader, TerrainBase, pos); + ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + } + return ret; } - public override Vector3 TerrainBase + // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). + // Return 'true' if successfully created. + public static bool ConvertHeightmapToMesh( + BSScene physicsScene, + float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap + float extentX, float extentY, // zero based range for output vertices + Vector3 extentBase, // base to be added to all vertices + float magnification, // number of vertices to create between heightMap coords + out int indicesCountO, out int[] indicesO, + out int verticesCountO, out float[] verticesO) { - get { return Vector3.Zero; } - } + bool ret = false; + + int indicesCount = 0; + int verticesCount = 0; + int[] indices = new int[0]; + float[] vertices = new float[0]; + // Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY. + // TODO: do a more general solution that scales, adds new vertices and smoothes the result. + + try + { + // One vertice per heightmap value plus the vertices off the top and bottom edge. + int totalVertices = (sizeX + 1) * (sizeY + 1); + vertices = new float[totalVertices * 3]; + int totalIndices = sizeX * sizeY * 6; + indices = new int[totalIndices]; + + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}", + BSScene.DetailLogZero, totalVertices, totalIndices); + float magX = (float)sizeX / extentX; + float magY = (float)sizeY / extentY; + // Note that sizeX+1 vertices are created since there is land between this and the next region. + for (int yy = 0; yy <= sizeY; yy++) + { + for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times + { + int offset = yy * sizeX + xx; + // Extend the height from the height from the last row or column + if (yy == sizeY) offset -= sizeX; + if (xx == sizeX) offset -= 1; + float height = heightMap[offset]; + vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; + vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; + vertices[verticesCount + 2] = height + extentBase.Z; + if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG + { + Vector3 genVertex = new Vector3( + vertices[verticesCount + 0], + vertices[verticesCount + 1], + vertices[verticesCount + 2]); + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}", + BSScene.DetailLogZero, verticesCount/3, genVertex); + } + verticesCount += 3; + } + } + verticesCount = verticesCount / 3; + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}", + BSScene.DetailLogZero, verticesCount); + + for (int yy = 0; yy < sizeY; yy++) + { + for (int xx = 0; xx < sizeX; xx++) + { + int offset = yy * sizeX + xx; + // Each vertices is presumed to be the upper left corner of a box of two triangles + indices[indicesCount + 0] = offset; + indices[indicesCount + 1] = offset + 1; + indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column + indices[indicesCount + 3] = offset + 1; + indices[indicesCount + 4] = offset + sizeX + 2; + indices[indicesCount + 5] = offset + sizeX + 1; + if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG + BSScene.DetailLogZero, + indices[indicesCount + 0], + indices[indicesCount + 1], + indices[indicesCount + 2], + indices[indicesCount + 3], + indices[indicesCount + 4], + indices[indicesCount + 5] + ); + indicesCount += 6; + } + } + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG + LogHeader, indicesCount); // DEBUG + ret = true; + } + catch (Exception e) + { + physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}", + LogHeader, extentBase, e); + } + + indicesCountO = indicesCount; + indicesO = indices; + verticesCountO = verticesCount; + verticesO = vertices; + + return ret; + } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index bab3b3d..a2271a9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -391,13 +391,13 @@ public enum CollisionFilterGroups : uint ObjectFilter = BSolidFilter, ObjectMask = BAllFilter, StaticObjectFilter = BStaticFilter, - StaticObjectMask = BAllFilter, + StaticObjectMask = BAllFilter & ~BStaticFilter, // static objects don't collide with each other LinksetFilter = BLinksetFilter, - LinksetMask = BAllFilter & ~BLinksetFilter, + LinksetMask = BAllFilter & ~BLinksetFilter, // linkset objects don't collide with each other VolumeDetectFilter = BSensorTrigger, VolumeDetectMask = ~BSensorTrigger, TerrainFilter = BTerrainFilter, - TerrainMask = BAllFilter & ~BStaticFilter, + TerrainMask = BAllFilter & ~BStaticFilter, // static objects on the ground don't collide GroundPlaneFilter = BGroundPlaneFilter, GroundPlaneMask = BAllFilter -- cgit v1.1 From 2dc7e9d3fa091418814af90565244a8c1972feec Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 20 Nov 2012 20:38:51 -0800 Subject: BulletSim: fix line endings to be all Linux style (windows style keeps creeping in) --- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 340 ++++++------ .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 568 ++++++++++----------- 2 files changed, 454 insertions(+), 454 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index e9fd0cb..8fc36d1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -1,170 +1,170 @@ -/* - * 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.Text; - -using OpenSim.Framework; -using OpenSim.Region.Framework; -using OpenSim.Region.CoreModules; -using OpenSim.Region.Physics.Manager; - -using Nini.Config; -using log4net; - -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ -public sealed class BSTerrainHeightmap : BSTerrainPhys -{ - static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; - - BulletHeightMapInfo m_mapInfo = null; - - // Constructor to build a default, flat heightmap terrain. - public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) - : base(physicsScene, regionBase, id) - { - Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); - Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); - int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; - float[] initialMap = new float[totalHeights]; - for (int ii = 0; ii < totalHeights; ii++) - { - initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; - } - m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); - m_mapInfo.minCoords = minTerrainCoords; - m_mapInfo.maxCoords = maxTerrainCoords; - m_mapInfo.terrainRegionBase = TerrainBase; - // Don't have to free any previous since we just got here. - BuildHeightmapTerrain(); - } - - // This minCoords and maxCoords passed in give the size of the terrain (min and max Z - // are the high and low points of the heightmap). - public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, - Vector3 minCoords, Vector3 maxCoords) - : base(physicsScene, regionBase, id) - { - m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); - m_mapInfo.minCoords = minCoords; - m_mapInfo.maxCoords = maxCoords; - m_mapInfo.minZ = minCoords.Z; - m_mapInfo.maxZ = maxCoords.Z; - m_mapInfo.terrainRegionBase = TerrainBase; - - // Don't have to free any previous since we just got here. - BuildHeightmapTerrain(); - } - - public override void Dispose() - { - ReleaseHeightMapTerrain(); - } - - // Using the information in m_mapInfo, create the physical representation of the heightmap. - private void BuildHeightmapTerrain() - { - m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, - m_mapInfo.minCoords, m_mapInfo.maxCoords, - m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN); - - // Create the terrain shape from the mapInfo - m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), - PhysicsShapeType.SHAPE_TERRAIN); - - // The terrain object initial position is at the center of the object - Vector3 centerPos; - centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); - centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); - centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f); - - m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, - BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, - m_mapInfo.ID, centerPos, Quaternion.Identity)); - - // Set current terrain attributes - BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); - BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); - BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); - BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - - // Return the new terrain to the world of physical objects - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - - // redo its bounding box now that it is in the world - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - - BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainFilter, - (uint)CollisionFilterGroups.TerrainMask); - - // Make it so the terrain will not move or be considered for movement. - BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); - - return; - } - - // If there is information in m_mapInfo pointing to physical structures, release same. - private void ReleaseHeightMapTerrain() - { - if (m_mapInfo != null) - { - if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) - { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - // Frees both the body and the shape. - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); - } - } - m_mapInfo = null; - } - - // The passed position is relative to the base of the region. - public override float GetHeightAtXYZ(Vector3 pos) - { - float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - - int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; - try - { - ret = m_mapInfo.heightMap[mapIndex]; - } - catch - { - // Sometimes they give us wonky values of X and Y. Give a warning and return something. - PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", - LogHeader, m_mapInfo.terrainRegionBase, pos); - ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - } - return ret; - } -} -} +/* + * 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.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules; +using OpenSim.Region.Physics.Manager; + +using Nini.Config; +using log4net; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public sealed class BSTerrainHeightmap : BSTerrainPhys +{ + static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; + + BulletHeightMapInfo m_mapInfo = null; + + // Constructor to build a default, flat heightmap terrain. + public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) + : base(physicsScene, regionBase, id) + { + Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); + Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); + int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; + float[] initialMap = new float[totalHeights]; + for (int ii = 0; ii < totalHeights; ii++) + { + initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; + } + m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo.minCoords = minTerrainCoords; + m_mapInfo.maxCoords = maxTerrainCoords; + m_mapInfo.terrainRegionBase = TerrainBase; + // Don't have to free any previous since we just got here. + BuildHeightmapTerrain(); + } + + // This minCoords and maxCoords passed in give the size of the terrain (min and max Z + // are the high and low points of the heightmap). + public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, + Vector3 minCoords, Vector3 maxCoords) + : base(physicsScene, regionBase, id) + { + m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo.minCoords = minCoords; + m_mapInfo.maxCoords = maxCoords; + m_mapInfo.minZ = minCoords.Z; + m_mapInfo.maxZ = maxCoords.Z; + m_mapInfo.terrainRegionBase = TerrainBase; + + // Don't have to free any previous since we just got here. + BuildHeightmapTerrain(); + } + + public override void Dispose() + { + ReleaseHeightMapTerrain(); + } + + // Using the information in m_mapInfo, create the physical representation of the heightmap. + private void BuildHeightmapTerrain() + { + m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, + m_mapInfo.minCoords, m_mapInfo.maxCoords, + m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN); + + // Create the terrain shape from the mapInfo + m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), + PhysicsShapeType.SHAPE_TERRAIN); + + // The terrain object initial position is at the center of the object + Vector3 centerPos; + centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); + centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); + centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f); + + m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, + BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, + m_mapInfo.ID, centerPos, Quaternion.Identity)); + + // Set current terrain attributes + BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); + BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); + BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); + BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + + // Return the new terrain to the world of physical objects + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + + // redo its bounding box now that it is in the world + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + + BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr, + (uint)CollisionFilterGroups.TerrainFilter, + (uint)CollisionFilterGroups.TerrainMask); + + // Make it so the terrain will not move or be considered for movement. + BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + + return; + } + + // If there is information in m_mapInfo pointing to physical structures, release same. + private void ReleaseHeightMapTerrain() + { + if (m_mapInfo != null) + { + if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) + { + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + // Frees both the body and the shape. + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); + } + } + m_mapInfo = null; + } + + // The passed position is relative to the base of the region. + public override float GetHeightAtXYZ(Vector3 pos) + { + float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + + int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; + try + { + ret = m_mapInfo.heightMap[mapIndex]; + } + catch + { + // Sometimes they give us wonky values of X and Y. Give a warning and return something. + PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", + LogHeader, m_mapInfo.terrainRegionBase, pos); + ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + } + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index bbb014a..a199078 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -1,284 +1,284 @@ -/* - * 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.Text; - -using OpenSim.Framework; -using OpenSim.Region.Framework; -using OpenSim.Region.CoreModules; -using OpenSim.Region.Physics.Manager; - -using Nini.Config; -using log4net; - -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ -public sealed class BSTerrainMesh : BSTerrainPhys -{ - static string LogHeader = "[BULLETSIM TERRAIN MESH]"; - - private float[] m_savedHeightMap; - int m_sizeX; - int m_sizeY; - - BulletShape m_terrainShape; - BulletBody m_terrainBody; - - public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) - : base(physicsScene, regionBase, id) - { - } - - public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) - : base(physicsScene, regionBase, id) - { - } - - // Create terrain mesh from a heightmap. - public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, - Vector3 minCoords, Vector3 maxCoords) - : base(physicsScene, regionBase, id) - { - int indicesCount; - int[] indices; - int verticesCount; - float[] vertices; - - m_savedHeightMap = initialMap; - - m_sizeX = (int)(maxCoords.X - minCoords.X); - m_sizeY = (int)(maxCoords.Y - minCoords.Y); - - if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY, - (float)m_sizeX, (float)m_sizeY, - Vector3.Zero, 1.0f, - out indicesCount, out indices, out verticesCount, out vertices)) - { - // DISASTER!! - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); - PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); - // Something is very messed up and a crash is in our future. - return; - } - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}", - ID, verticesCount, indicesCount); - - m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, - indicesCount, indices, verticesCount, vertices), - PhysicsShapeType.SHAPE_MESH); - if (m_terrainShape.ptr == IntPtr.Zero) - { - // DISASTER!! - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); - physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); - // Something is very messed up and a crash is in our future. - return; - } - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape); - - // The terrain object initial position is at the center of the object - Vector3 centerPos; - centerPos.X = minCoords.X + (m_sizeX / 2f); - centerPos.Y = minCoords.Y + (m_sizeY / 2f); - centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f); - Quaternion rot = Quaternion.Identity; - - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot); - m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( - m_terrainShape.ptr, ID, centerPos, rot)); - if (m_terrainBody.ptr == IntPtr.Zero) - { - // DISASTER!! - physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); - // Something is very messed up and a crash is in our future. - return; - } - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody); - - // Set current terrain attributes - BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction); - BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); - BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution); - BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - - // Static objects are not very massive. - BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); - - // Return the new terrain to the world of physical objects - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); - - // redo its bounding box now that it is in the world - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); - - BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainFilter, - (uint)CollisionFilterGroups.TerrainMask); - - // Make it so the terrain will not move or be considered for movement. - BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); - } - - public override void Dispose() - { - if (m_terrainBody.ptr != IntPtr.Zero) - { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); - // Frees both the body and the shape. - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr); - } - } - - public override float GetHeightAtXYZ(Vector3 pos) - { - // For the moment use the saved heightmap to get the terrain height. - // TODO: raycast downward to find the true terrain below the position. - float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - - int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X; - try - { - ret = m_savedHeightMap[mapIndex]; - } - catch - { - // Sometimes they give us wonky values of X and Y. Give a warning and return something. - PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", - LogHeader, TerrainBase, pos); - ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - } - return ret; - } - - // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). - // Return 'true' if successfully created. - public static bool ConvertHeightmapToMesh( - BSScene physicsScene, - float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap - float extentX, float extentY, // zero based range for output vertices - Vector3 extentBase, // base to be added to all vertices - float magnification, // number of vertices to create between heightMap coords - out int indicesCountO, out int[] indicesO, - out int verticesCountO, out float[] verticesO) - { - bool ret = false; - - int indicesCount = 0; - int verticesCount = 0; - int[] indices = new int[0]; - float[] vertices = new float[0]; - - // Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY. - // TODO: do a more general solution that scales, adds new vertices and smoothes the result. - - try - { - // One vertice per heightmap value plus the vertices off the top and bottom edge. - int totalVertices = (sizeX + 1) * (sizeY + 1); - vertices = new float[totalVertices * 3]; - int totalIndices = sizeX * sizeY * 6; - indices = new int[totalIndices]; - - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}", - BSScene.DetailLogZero, totalVertices, totalIndices); - float magX = (float)sizeX / extentX; - float magY = (float)sizeY / extentY; - // Note that sizeX+1 vertices are created since there is land between this and the next region. - for (int yy = 0; yy <= sizeY; yy++) - { - for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times - { - int offset = yy * sizeX + xx; - // Extend the height from the height from the last row or column - if (yy == sizeY) offset -= sizeX; - if (xx == sizeX) offset -= 1; - float height = heightMap[offset]; - vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; - vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; - vertices[verticesCount + 2] = height + extentBase.Z; - if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG - { - Vector3 genVertex = new Vector3( - vertices[verticesCount + 0], - vertices[verticesCount + 1], - vertices[verticesCount + 2]); - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}", - BSScene.DetailLogZero, verticesCount/3, genVertex); - } - verticesCount += 3; - } - } - verticesCount = verticesCount / 3; - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}", - BSScene.DetailLogZero, verticesCount); - - for (int yy = 0; yy < sizeY; yy++) - { - for (int xx = 0; xx < sizeX; xx++) - { - int offset = yy * sizeX + xx; - // Each vertices is presumed to be the upper left corner of a box of two triangles - indices[indicesCount + 0] = offset; - indices[indicesCount + 1] = offset + 1; - indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column - indices[indicesCount + 3] = offset + 1; - indices[indicesCount + 4] = offset + sizeX + 2; - indices[indicesCount + 5] = offset + sizeX + 1; - if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG - BSScene.DetailLogZero, - indices[indicesCount + 0], - indices[indicesCount + 1], - indices[indicesCount + 2], - indices[indicesCount + 3], - indices[indicesCount + 4], - indices[indicesCount + 5] - ); - indicesCount += 6; - } - } - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG - LogHeader, indicesCount); // DEBUG - ret = true; - } - catch (Exception e) - { - physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}", - LogHeader, extentBase, e); - } - - indicesCountO = indicesCount; - indicesO = indices; - verticesCountO = verticesCount; - verticesO = vertices; - - return ret; - } -} -} +/* + * 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.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules; +using OpenSim.Region.Physics.Manager; + +using Nini.Config; +using log4net; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public sealed class BSTerrainMesh : BSTerrainPhys +{ + static string LogHeader = "[BULLETSIM TERRAIN MESH]"; + + private float[] m_savedHeightMap; + int m_sizeX; + int m_sizeY; + + BulletShape m_terrainShape; + BulletBody m_terrainBody; + + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) + : base(physicsScene, regionBase, id) + { + } + + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) + : base(physicsScene, regionBase, id) + { + } + + // Create terrain mesh from a heightmap. + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, + Vector3 minCoords, Vector3 maxCoords) + : base(physicsScene, regionBase, id) + { + int indicesCount; + int[] indices; + int verticesCount; + float[] vertices; + + m_savedHeightMap = initialMap; + + m_sizeX = (int)(maxCoords.X - minCoords.X); + m_sizeY = (int)(maxCoords.Y - minCoords.Y); + + if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY, + (float)m_sizeX, (float)m_sizeY, + Vector3.Zero, 1.0f, + out indicesCount, out indices, out verticesCount, out vertices)) + { + // DISASTER!! + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); + PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}", + ID, verticesCount, indicesCount); + + m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, + indicesCount, indices, verticesCount, vertices), + PhysicsShapeType.SHAPE_MESH); + if (m_terrainShape.ptr == IntPtr.Zero) + { + // DISASTER!! + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); + physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape); + + // The terrain object initial position is at the center of the object + Vector3 centerPos; + centerPos.X = minCoords.X + (m_sizeX / 2f); + centerPos.Y = minCoords.Y + (m_sizeY / 2f); + centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f); + Quaternion rot = Quaternion.Identity; + + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot); + m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( + m_terrainShape.ptr, ID, centerPos, rot)); + if (m_terrainBody.ptr == IntPtr.Zero) + { + // DISASTER!! + physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody); + + // Set current terrain attributes + BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction); + BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); + BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution); + BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + + // Static objects are not very massive. + BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); + + // Return the new terrain to the world of physical objects + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); + + // redo its bounding box now that it is in the world + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); + + BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, + (uint)CollisionFilterGroups.TerrainFilter, + (uint)CollisionFilterGroups.TerrainMask); + + // Make it so the terrain will not move or be considered for movement. + BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + } + + public override void Dispose() + { + if (m_terrainBody.ptr != IntPtr.Zero) + { + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); + // Frees both the body and the shape. + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr); + } + } + + public override float GetHeightAtXYZ(Vector3 pos) + { + // For the moment use the saved heightmap to get the terrain height. + // TODO: raycast downward to find the true terrain below the position. + float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + + int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X; + try + { + ret = m_savedHeightMap[mapIndex]; + } + catch + { + // Sometimes they give us wonky values of X and Y. Give a warning and return something. + PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", + LogHeader, TerrainBase, pos); + ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + } + return ret; + } + + // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). + // Return 'true' if successfully created. + public static bool ConvertHeightmapToMesh( + BSScene physicsScene, + float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap + float extentX, float extentY, // zero based range for output vertices + Vector3 extentBase, // base to be added to all vertices + float magnification, // number of vertices to create between heightMap coords + out int indicesCountO, out int[] indicesO, + out int verticesCountO, out float[] verticesO) + { + bool ret = false; + + int indicesCount = 0; + int verticesCount = 0; + int[] indices = new int[0]; + float[] vertices = new float[0]; + + // Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY. + // TODO: do a more general solution that scales, adds new vertices and smoothes the result. + + try + { + // One vertice per heightmap value plus the vertices off the top and bottom edge. + int totalVertices = (sizeX + 1) * (sizeY + 1); + vertices = new float[totalVertices * 3]; + int totalIndices = sizeX * sizeY * 6; + indices = new int[totalIndices]; + + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}", + BSScene.DetailLogZero, totalVertices, totalIndices); + float magX = (float)sizeX / extentX; + float magY = (float)sizeY / extentY; + // Note that sizeX+1 vertices are created since there is land between this and the next region. + for (int yy = 0; yy <= sizeY; yy++) + { + for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times + { + int offset = yy * sizeX + xx; + // Extend the height from the height from the last row or column + if (yy == sizeY) offset -= sizeX; + if (xx == sizeX) offset -= 1; + float height = heightMap[offset]; + vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; + vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; + vertices[verticesCount + 2] = height + extentBase.Z; + if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG + { + Vector3 genVertex = new Vector3( + vertices[verticesCount + 0], + vertices[verticesCount + 1], + vertices[verticesCount + 2]); + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}", + BSScene.DetailLogZero, verticesCount/3, genVertex); + } + verticesCount += 3; + } + } + verticesCount = verticesCount / 3; + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}", + BSScene.DetailLogZero, verticesCount); + + for (int yy = 0; yy < sizeY; yy++) + { + for (int xx = 0; xx < sizeX; xx++) + { + int offset = yy * sizeX + xx; + // Each vertices is presumed to be the upper left corner of a box of two triangles + indices[indicesCount + 0] = offset; + indices[indicesCount + 1] = offset + 1; + indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column + indices[indicesCount + 3] = offset + 1; + indices[indicesCount + 4] = offset + sizeX + 2; + indices[indicesCount + 5] = offset + sizeX + 1; + if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG + BSScene.DetailLogZero, + indices[indicesCount + 0], + indices[indicesCount + 1], + indices[indicesCount + 2], + indices[indicesCount + 3], + indices[indicesCount + 4], + indices[indicesCount + 5] + ); + indicesCount += 6; + } + } + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG + LogHeader, indicesCount); // DEBUG + ret = true; + } + catch (Exception e) + { + physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}", + LogHeader, extentBase, e); + } + + indicesCountO = indicesCount; + indicesO = indices; + verticesCountO = verticesCount; + verticesO = vertices; + + return ret; + } +} +} -- cgit v1.1 From a59368c4a1889ccd79da9e564ee84b213a7f6fbd Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 21 Nov 2012 10:37:40 -0800 Subject: BulletSim: add terrainImplementation parameter with default to Mesh. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 5 +++ .../Physics/BulletSPlugin/BSTerrainManager.cs | 45 +++++++++++++++++++--- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 1 + 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 58dccea..0e73d04 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1145,6 +1145,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); }, (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), + new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", + (float)BSTerrainPhys.TerrainImplementation.Mesh, + (s,cf,p,v) => { s.m_params[0].terrainImplementation = cf.GetFloat(p,v); }, + (s) => { return s.m_params[0].terrainImplementation; }, + (s,p,l,v) => { s.m_params[0].terrainImplementation = v; } ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 0.5f, (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index ed0dfa8..b88f561 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -44,6 +44,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The physical implementation of the terrain is wrapped in this class. public abstract class BSTerrainPhys : IDisposable { + public enum TerrainImplementation + { + Heightmap = 0, + Mesh = 1 + } + public BSScene PhysicsScene { get; private set; } // Base of the region in world coordinates. Coordinates inside the region are relative to this. public Vector3 TerrainBase { get; private set; } @@ -246,12 +252,27 @@ public sealed class BSTerrainManager // Release any physical memory it may be using. terrainPhys.Dispose(); + BSTerrainPhys newTerrainPhys = null; ; if (MegaRegionParentPhysicsScene == null) { - // BSTerrainPhys newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, - // heightMap, minCoords, maxCoords); - BSTerrainPhys newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, + // TODO: redo terrain implementation selection to be centralized (there is another + // use below) and to accept an asset specification (for a mesh). + switch ((int)PhysicsScene.Params.terrainImplementation) + { + case (int)BSTerrainPhys.TerrainImplementation.Heightmap: + newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, + heightMap, minCoords, maxCoords); + break; + case (int)BSTerrainPhys.TerrainImplementation.Mesh: + newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, heightMap, minCoords, maxCoords); + break; + default: + PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. type={1}/{2}", + LogHeader, (int)PhysicsScene.Params.terrainImplementation, PhysicsScene.Params.terrainImplementation); + break; + } + m_terrains.Add(terrainRegionBase, newTerrainPhys); m_terrainModified = true; @@ -292,8 +313,22 @@ public sealed class BSTerrainManager { DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y); - BSTerrainPhys newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, - newTerrainID, heightMapX, minCoordsX, maxCoordsX); + BSTerrainPhys newTerrainPhys = null; + switch ((int)PhysicsScene.Params.terrainImplementation) + { + case (int)BSTerrainPhys.TerrainImplementation.Heightmap: + newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, + heightMap, minCoords, maxCoords); + break; + case (int)BSTerrainPhys.TerrainImplementation.Mesh: + newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, + heightMap, minCoords, maxCoords); + break; + default: + PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. type={1}/{2}", + LogHeader, (int)PhysicsScene.Params.terrainImplementation, PhysicsScene.Params.terrainImplementation); + break; + } m_terrains.Add(terrainRegionBase, newTerrainPhys); m_terrainModified = true; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index a2271a9..e218053 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -283,6 +283,7 @@ public struct ConfigurationParameters public float ccdSweptSphereRadius; public float contactProcessingThreshold; + public float terrainImplementation; public float terrainFriction; public float terrainHitFraction; public float terrainRestitution; -- cgit v1.1 From 4a0de0170412a939bade6cd149c94c7fd3ef020e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 21 Nov 2012 13:44:02 -0800 Subject: BulletSim: Properly position mesh terrain on creation (fixes terrain not appearing to be working). Centralize terrain shape creation logic. Remove very chatty detail log messages. --- .../Physics/BulletSPlugin/BSTerrainManager.cs | 74 ++++++++++------------ .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 46 +++----------- 2 files changed, 44 insertions(+), 76 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index b88f561..097cd3e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -241,38 +241,20 @@ public sealed class BSTerrainManager BSTerrainPhys terrainPhys; if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) { - // If this is terrain we know about, it's easy to update - - DetailLog("{0},UpdateTerrain:UpdateExisting,call,terrainBase={1}", BSScene.DetailLogZero, terrainRegionBase); + // There is already a terrain in this spot. Free the old and build the new. + DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", + BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate() { // Remove old terrain from the collection - m_terrains.Remove(terrainPhys.TerrainBase); + m_terrains.Remove(terrainRegionBase); // Release any physical memory it may be using. terrainPhys.Dispose(); - BSTerrainPhys newTerrainPhys = null; ; if (MegaRegionParentPhysicsScene == null) { - // TODO: redo terrain implementation selection to be centralized (there is another - // use below) and to accept an asset specification (for a mesh). - switch ((int)PhysicsScene.Params.terrainImplementation) - { - case (int)BSTerrainPhys.TerrainImplementation.Heightmap: - newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, - heightMap, minCoords, maxCoords); - break; - case (int)BSTerrainPhys.TerrainImplementation.Mesh: - newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, - heightMap, minCoords, maxCoords); - break; - default: - PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. type={1}/{2}", - LogHeader, (int)PhysicsScene.Params.terrainImplementation, PhysicsScene.Params.terrainImplementation); - break; - } - + BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); m_terrains.Add(terrainRegionBase, newTerrainPhys); m_terrainModified = true; @@ -313,22 +295,7 @@ public sealed class BSTerrainManager { DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y); - BSTerrainPhys newTerrainPhys = null; - switch ((int)PhysicsScene.Params.terrainImplementation) - { - case (int)BSTerrainPhys.TerrainImplementation.Heightmap: - newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, - heightMap, minCoords, maxCoords); - break; - case (int)BSTerrainPhys.TerrainImplementation.Mesh: - newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, - heightMap, minCoords, maxCoords); - break; - default: - PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. type={1}/{2}", - LogHeader, (int)PhysicsScene.Params.terrainImplementation, PhysicsScene.Params.terrainImplementation); - break; - } + BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); m_terrains.Add(terrainRegionBase, newTerrainPhys); m_terrainModified = true; @@ -336,6 +303,35 @@ public sealed class BSTerrainManager } } + // TODO: redo terrain implementation selection to allow other base types than heightMap. + private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords) + { + PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}", + LogHeader, PhysicsScene.RegionName, terrainRegionBase, + PhysicsScene.Params.terrainImplementation); + BSTerrainPhys newTerrainPhys = null; + switch ((int)PhysicsScene.Params.terrainImplementation) + { + case (int)BSTerrainPhys.TerrainImplementation.Heightmap: + newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, + heightMap, minCoords, maxCoords); + break; + case (int)BSTerrainPhys.TerrainImplementation.Mesh: + newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, + heightMap, minCoords, maxCoords); + break; + default: + PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}", + LogHeader, + (int)PhysicsScene.Params.terrainImplementation, + PhysicsScene.Params.terrainImplementation, + PhysicsScene.RegionName, terrainRegionBase); + break; + } + return newTerrainPhys; + } + + // Given an X and Y, find the height of the terrain. // Since we could be handling multiple terrains for a mega-region, // the base of the region is calcuated assuming all regions are diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index a199078..3279b6f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -76,7 +76,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys m_sizeX = (int)(maxCoords.X - minCoords.X); m_sizeY = (int)(maxCoords.Y - minCoords.Y); - if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY, + if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, + m_sizeX, m_sizeY, (float)m_sizeX, (float)m_sizeY, Vector3.Zero, 1.0f, out indicesCount, out indices, out verticesCount, out vertices)) @@ -87,8 +88,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Something is very messed up and a crash is in our future. return; } - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}", - ID, verticesCount, indicesCount); m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, indicesCount, indices, verticesCount, vertices), @@ -101,18 +100,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Something is very messed up and a crash is in our future. return; } - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape); - // The terrain object initial position is at the center of the object - Vector3 centerPos; - centerPos.X = minCoords.X + (m_sizeX / 2f); - centerPos.Y = minCoords.Y + (m_sizeY / 2f); - centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f); + Vector3 pos = regionBase; Quaternion rot = Quaternion.Identity; - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot); - m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( - m_terrainShape.ptr, ID, centerPos, rot)); + m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot)); if (m_terrainBody.ptr == IntPtr.Zero) { // DISASTER!! @@ -120,7 +112,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Something is very messed up and a crash is in our future. return; } - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody); // Set current terrain attributes BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction); @@ -194,7 +185,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys int[] indices = new int[0]; float[] vertices = new float[0]; - // Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY. + // Simple mesh creation which assumes magnification == 1. // TODO: do a more general solution that scales, adds new vertices and smoothes the result. try @@ -205,10 +196,10 @@ public sealed class BSTerrainMesh : BSTerrainPhys int totalIndices = sizeX * sizeY * 6; indices = new int[totalIndices]; - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}", - BSScene.DetailLogZero, totalVertices, totalIndices); float magX = (float)sizeX / extentX; float magY = (float)sizeY / extentY; + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", + BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); // Note that sizeX+1 vertices are created since there is land between this and the next region. for (int yy = 0; yy <= sizeY; yy++) { @@ -222,15 +213,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; vertices[verticesCount + 2] = height + extentBase.Z; - if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG - { - Vector3 genVertex = new Vector3( - vertices[verticesCount + 0], - vertices[verticesCount + 1], - vertices[verticesCount + 2]); - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}", - BSScene.DetailLogZero, verticesCount/3, genVertex); - } verticesCount += 3; } } @@ -250,16 +232,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys indices[indicesCount + 3] = offset + 1; indices[indicesCount + 4] = offset + sizeX + 2; indices[indicesCount + 5] = offset + sizeX + 1; - if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG - BSScene.DetailLogZero, - indices[indicesCount + 0], - indices[indicesCount + 1], - indices[indicesCount + 2], - indices[indicesCount + 3], - indices[indicesCount + 4], - indices[indicesCount + 5] - ); indicesCount += 6; } } @@ -269,8 +241,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys } catch (Exception e) { - physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}", - LogHeader, extentBase, e); + physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", + LogHeader, physicsScene.RegionName, extentBase, e); } indicesCountO = indicesCount; -- cgit v1.1 From cbc7e7bf85bfd9e916146b0ae4a605996c24720b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 21 Nov 2012 16:31:23 -0800 Subject: BulletSim: Make avatar capsule so it is not circular. Simple attempt to make avatars better shaped. Replace parameter 'avatarCapsuleRadius' with 'avatarCapsuleWidth' and 'avatarCapsuleDepth'. More tweeking to avatar height calculation. A little better but short avatar's feet are above the terrain and tall avatar's feet are a little below the ground. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 24 +++++++++++++++------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 +++- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 18 +++++++++------- .../Physics/BulletSPlugin/BSShapeCollection.cs | 9 ++++---- .../Physics/BulletSPlugin/BSTerrainManager.cs | 2 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 3 ++- bin/OpenSimDefaults.ini | 3 ++- 7 files changed, 41 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 799211e..e2aa41e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -82,7 +82,13 @@ public sealed class BSCharacter : BSPhysObject { _physicsActorType = (int)ActorTypes.Agent; _position = pos; + + // Old versions of ScenePresence passed only the height. If width and/or depth are zero, + // replace with the default values. _size = size; + if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; + if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; + _flying = isFlying; _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; @@ -175,8 +181,7 @@ public sealed class BSCharacter : BSPhysObject get { // Avatar capsule size is kept in the scale parameter. - // return _size; - return new OMV.Vector3(Scale.X * 2f, Scale.Y * 2f, Scale.Z); + return _size; } set { @@ -614,14 +619,19 @@ public sealed class BSCharacter : BSPhysObject // The 'size' given by the simulator is the mid-point of the avatar // and X and Y are unspecified. - OMV.Vector3 newScale = OMV.Vector3.Zero; - newScale.X = PhysicsScene.Params.avatarCapsuleRadius; - newScale.Y = PhysicsScene.Params.avatarCapsuleRadius; + OMV.Vector3 newScale = size; + // newScale.X = PhysicsScene.Params.avatarCapsuleWidth; + // newScale.Y = PhysicsScene.Params.avatarCapsuleDepth; // From the total height, remove the capsule half spheres that are at each end // The 1.15f came from ODE. Not sure what this factors in. - newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y); - Scale = newScale; + // newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y); + + // The total scale height is the central cylindar plus the caps on the two ends. + newScale.Z = size.Z + (Math.Min(size.X, size.Y) * 2f); + + // Convert diameters to radii and height to half height -- the way Bullet expects it. + Scale = newScale / 2f; } // set _avatarVolume and _mass based on capsule size, _density and Scale diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 2657e4b..5d16bbf 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -93,7 +93,7 @@ public sealed class BSPrim : BSPhysObject _physicsActorType = (int)ActorTypes.Prim; _position = pos; _size = size; - Scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type + Scale = size; // the scale will be set by CreateGeom depending on object type _orientation = rotation; _buoyancy = 1f; _velocity = OMV.Vector3.Zero; @@ -154,6 +154,8 @@ public sealed class BSPrim : BSPhysObject public override OMV.Vector3 Size { get { return _size; } set { + // We presume the scale and size are the same. If scale must be changed for + // the physical shape, that is done when the geometry is built. _size = value; ForceBodyShapeRebuild(false); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 0e73d04..27a78d1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1185,14 +1185,18 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarRestitution; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ), - new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar", - 0.37f, - (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarCapsuleRadius; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), + new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", + 0.6f, + (s,cf,p,v) => { s.m_params[0].avatarCapsuleWidth = cf.GetFloat(p, v); }, + (s) => { return s.m_params[0].avatarCapsuleWidth; }, + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleWidth, p, l, v); } ), + new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", + 0.45f, + (s,cf,p,v) => { s.m_params[0].avatarCapsuleDepth = cf.GetFloat(p, v); }, + (s) => { return s.m_params[0].avatarCapsuleDepth; }, + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleDepth, p, l, v); } ), new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", - // 1.5f, - 2.140599f, + 1.5f, (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarCapsuleHeight; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index a53ad6e..869735c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -525,9 +525,6 @@ public sealed class BSShapeCollection : IDisposable // release any previous shape DereferenceShape(prim.PhysShape, true, shapeCallback); - // Bullet native objects are scaled by the Bullet engine so pass the size in - prim.Scale = prim.Size; - BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. @@ -547,12 +544,13 @@ public sealed class BSShapeCollection : IDisposable nativeShapeData.Type = shapeType; nativeShapeData.ID = prim.LocalID; nativeShapeData.Scale = prim.Scale; - nativeShapeData.Size = prim.Scale; + nativeShapeData.Size = prim.Scale; // unneeded, I think. nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey; if (shapeType == PhysicsShapeType.SHAPE_CAPSULE) { + // The proper scale has been calculated in the prim. newShape = new BulletShape( BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) , shapeType); @@ -560,6 +558,9 @@ public sealed class BSShapeCollection : IDisposable } else { + // Native shapes are scaled in Bullet so set the scaling to the size + prim.Scale = prim.Size; + nativeShapeData.Scale = prim.Scale; newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); } if (newShape.ptr == IntPtr.Zero) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 097cd3e..71fca33 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -308,7 +308,7 @@ public sealed class BSTerrainManager { PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}", LogHeader, PhysicsScene.RegionName, terrainRegionBase, - PhysicsScene.Params.terrainImplementation); + (BSTerrainPhys.TerrainImplementation)PhysicsScene.Params.terrainImplementation); BSTerrainPhys newTerrainPhys = null; switch ((int)PhysicsScene.Params.terrainImplementation) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index e218053..4647c2d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -291,7 +291,8 @@ public struct ConfigurationParameters public float avatarStandingFriction; public float avatarDensity; public float avatarRestitution; - public float avatarCapsuleRadius; + public float avatarCapsuleWidth; + public float avatarCapsuleDepth; public float avatarCapsuleHeight; public float avatarContactProcessingThreshold; diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index c81c658..818321e 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -913,7 +913,8 @@ AvatarFriction = 0.2 AvatarRestitution = 0.0 AvatarDensity = 60.0 - AvatarCapsuleRadius = 0.37 + AvatarCapsuleWidth = 0.6 + AvatarCapsuleDepth = 0.45 AvatarCapsuleHeight = 1.5 AvatarContactProcessingThreshold = 0.1 -- cgit v1.1 From 56ef180c92b33d1a0ce24990868253c96fd9fd84 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 21 Nov 2012 16:36:50 -0800 Subject: BulletSim: update DLLs and SOs. No functional changes. Only the parameter block format changed. --- bin/lib32/BulletSim.dll | Bin 551424 -> 551424 bytes bin/lib32/libBulletSim.so | Bin 1707213 -> 1707321 bytes bin/lib64/BulletSim.dll | Bin 699904 -> 699904 bytes bin/lib64/libBulletSim.so | Bin 1844124 -> 1844228 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 9c8cf00..2ae1c75 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index 0277cf1..d4852a5 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 5675ff3..77cf7e3 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 49396a8..4ec62b2 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From 448811ccddfa6fb3dbbd7279e240ff9ef805d218 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 Nov 2012 03:01:57 +0000 Subject: If an asset POST does not contain well-formed XML, return a 400 (Bad Request) HTTP status rather than simply dropping the request. --- .../Handlers/Asset/AssetServerPostHandler.cs | 15 ++++++++++--- .../Asset/Tests/AssetServerPostHandlerTests.cs | 26 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/OpenSim/Server/Handlers/Asset/AssetServerPostHandler.cs b/OpenSim/Server/Handlers/Asset/AssetServerPostHandler.cs index 87b3d2d..a006fa8 100644 --- a/OpenSim/Server/Handlers/Asset/AssetServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Asset/AssetServerPostHandler.cs @@ -57,14 +57,23 @@ namespace OpenSim.Server.Handlers.Asset public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { + AssetBase asset; XmlSerializer xs = new XmlSerializer(typeof (AssetBase)); - AssetBase asset = (AssetBase) xs.Deserialize(request); + + try + { + asset = (AssetBase)xs.Deserialize(request); + } + catch (XmlException) + { + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + return null; + } string[] p = SplitParams(path); if (p.Length > 1) { - bool result = - m_AssetService.UpdateContent(p[1], asset.Data); + bool result = m_AssetService.UpdateContent(p[1], asset.Data); xs = new XmlSerializer(typeof(bool)); return ServerUtils.SerializeResult(xs, result); diff --git a/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs b/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs index 9e82576..427fa16 100644 --- a/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs +++ b/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs @@ -27,6 +27,7 @@ using System; using System.IO; +using System.Net; using System.Text; using System.Xml; using System.Xml.Serialization; @@ -38,6 +39,7 @@ using OpenSim.Server.Handlers.Asset; using OpenSim.Services.AssetService; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; namespace OpenSim.Server.Handlers.Asset.Test { @@ -80,5 +82,29 @@ namespace OpenSim.Server.Handlers.Asset.Test Assert.That(retrievedAsset, Is.Not.Null); } + + [Test] + public void TestBadXmlAssetStoreRequest() + { + TestHelpers.InMethod(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("AssetService"); + config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); + + AssetService assetService = new AssetService(config); + + AssetServerPostHandler asph = new AssetServerPostHandler(assetService); + + MemoryStream buffer = new MemoryStream(); + byte[] badData = new byte[] { 0x48, 0x65, 0x6c, 0x6c, 0x6f }; + buffer.Write(badData, 0, badData.Length); + buffer.Position = 0; + + TestOSHttpResponse response = new TestOSHttpResponse(); + asph.Handle(null, buffer, null, response); + + Assert.That(response.StatusCode, Is.EqualTo((int)HttpStatusCode.BadRequest)); + } } } \ No newline at end of file -- cgit v1.1 From 74a20a62eee8c565a9410d6896754242eb602abc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 Nov 2012 03:43:21 +0000 Subject: refactor: Factor out copy/pasted server uptime report code --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 29 ++----------- OpenSim/Framework/Servers/ServerBase.cs | 58 ++++++++++++++++++++++++++ OpenSim/Server/Base/ServicesServerBase.cs | 27 ++---------- 3 files changed, 66 insertions(+), 48 deletions(-) create mode 100644 OpenSim/Framework/Servers/ServerBase.cs diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 5b2d7dc..6346279 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -38,6 +38,8 @@ using log4net; using log4net.Appender; using log4net.Core; using log4net.Repository; +using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Framework.Monitoring; @@ -45,16 +47,12 @@ using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using Timer=System.Timers.Timer; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - - namespace OpenSim.Framework.Servers { /// /// Common base for the main OpenSimServers (user, grid, inventory, region, etc) /// - public abstract class BaseOpenSimServer + public abstract class BaseOpenSimServer : ServerBase { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -69,11 +67,6 @@ namespace OpenSim.Framework.Servers protected IAppender m_logFileAppender = null; /// - /// Time at which this server was started - /// - protected DateTime m_startuptime; - - /// /// Record the initial startup directory for info purposes /// protected string m_startupDirectory = Environment.CurrentDirectory; @@ -96,9 +89,8 @@ namespace OpenSim.Framework.Servers get { return m_httpServer; } } - public BaseOpenSimServer() + public BaseOpenSimServer() : base() { - m_startuptime = DateTime.Now; m_version = VersionInfo.Version; // Random uuid for private data @@ -284,19 +276,6 @@ namespace OpenSim.Framework.Servers } /// - /// Return a report about the uptime of this server - /// - /// - protected string GetUptimeReport() - { - StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now)); - sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime)); - sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime)); - - return sb.ToString(); - } - - /// /// Performs initialisation of the scene, such as loading configuration from disk. /// public virtual void Startup() diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs new file mode 100644 index 0000000..d19234b --- /dev/null +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -0,0 +1,58 @@ +/* + * 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 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 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.Text; + +namespace OpenSim.Framework.Servers +{ + public class ServerBase + { + /// + /// Time at which this server was started + /// + protected DateTime m_startuptime; + + public ServerBase() + { + m_startuptime = DateTime.Now; + } + + /// + /// Return a report about the uptime of this server + /// + /// + protected string GetUptimeReport() + { + StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now)); + sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime)); + sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime)); + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index 0cff6ed..56bb7ae 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -34,6 +34,7 @@ using System.Text; using System.Xml; using OpenSim.Framework; using OpenSim.Framework.Console; +using OpenSim.Framework.Servers; using log4net; using log4net.Config; using log4net.Appender; @@ -43,7 +44,7 @@ using Nini.Config; namespace OpenSim.Server.Base { - public class ServicesServerBase + public class ServicesServerBase : ServerBase { // Logger // @@ -72,17 +73,10 @@ namespace OpenSim.Server.Base // private string m_pidFile = String.Empty; - /// - /// Time at which this server was started - /// - protected DateTime m_startuptime; - // Handle all the automagical stuff // - public ServicesServerBase(string prompt, string[] args) + public ServicesServerBase(string prompt, string[] args) : base() { - m_startuptime = DateTime.Now; - // Save raw arguments // m_Arguments = args; @@ -373,18 +367,5 @@ namespace OpenSim.Server.Base break; } } - - /// - /// Return a report about the uptime of this server - /// - /// - protected string GetUptimeReport() - { - StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now)); - sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime)); - sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime)); - - return sb.ToString(); - } } -} +} \ No newline at end of file -- cgit v1.1 From 5c48d7a378ff066f59b9cee02f2803ebe1616481 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 Nov 2012 04:05:09 +0000 Subject: factor out common HandleShow code for "show uptime" --- OpenSim/Framework/Console/CommandConsole.cs | 2 +- OpenSim/Framework/Console/ConsoleBase.cs | 10 +----- OpenSim/Framework/Console/MockConsole.cs | 7 +++- OpenSim/Framework/ICommandConsole.cs | 5 +++ OpenSim/Framework/IConsole.cs | 2 +- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 39 +++----------------- OpenSim/Framework/Servers/ServerBase.cs | 50 ++++++++++++++++++++++++++ OpenSim/Region/Application/OpenSimBase.cs | 2 +- OpenSim/Server/Base/ServicesServerBase.cs | 18 ++-------- 9 files changed, 72 insertions(+), 63 deletions(-) diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index bd23d1c..d1e29b4 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs @@ -711,7 +711,7 @@ namespace OpenSim.Framework.Console /// public void Prompt() { - string line = ReadLine(m_defaultPrompt + "# ", true, true); + string line = ReadLine(DefaultPrompt + "# ", true, true); if (line != String.Empty) Output("Invalid command"); diff --git a/OpenSim/Framework/Console/ConsoleBase.cs b/OpenSim/Framework/Console/ConsoleBase.cs index 4b375d9..2d8e723 100755 --- a/OpenSim/Framework/Console/ConsoleBase.cs +++ b/OpenSim/Framework/Console/ConsoleBase.cs @@ -43,15 +43,7 @@ namespace OpenSim.Framework.Console public object ConsoleScene { get; set; } - /// - /// The default prompt text. - /// - public string DefaultPrompt - { - set { m_defaultPrompt = value; } - get { return m_defaultPrompt; } - } - protected string m_defaultPrompt; + public string DefaultPrompt { get; set; } public ConsoleBase(string defaultPrompt) { diff --git a/OpenSim/Framework/Console/MockConsole.cs b/OpenSim/Framework/Console/MockConsole.cs index b489f93..8ba58e4 100644 --- a/OpenSim/Framework/Console/MockConsole.cs +++ b/OpenSim/Framework/Console/MockConsole.cs @@ -46,13 +46,18 @@ namespace OpenSim.Framework.Console public ICommands Commands { get { return m_commands; } } + public string DefaultPrompt { get; set; } + public void Prompt() {} public void RunCommand(string cmd) {} public string ReadLine(string p, bool isCommand, bool e) { return ""; } - public object ConsoleScene { get { return null; } } + public object ConsoleScene { + get { return null; } + set {} + } public void Output(string text, string level) {} public void Output(string text) {} diff --git a/OpenSim/Framework/ICommandConsole.cs b/OpenSim/Framework/ICommandConsole.cs index 8cd20da..a6573f8 100644 --- a/OpenSim/Framework/ICommandConsole.cs +++ b/OpenSim/Framework/ICommandConsole.cs @@ -83,6 +83,11 @@ namespace OpenSim.Framework ICommands Commands { get; } /// + /// The default prompt text. + /// + string DefaultPrompt { get; set; } + + /// /// Display a command prompt on the console and wait for user input /// void Prompt(); diff --git a/OpenSim/Framework/IConsole.cs b/OpenSim/Framework/IConsole.cs index 33024b2..79560d8 100644 --- a/OpenSim/Framework/IConsole.cs +++ b/OpenSim/Framework/IConsole.cs @@ -32,7 +32,7 @@ namespace OpenSim.Framework { public interface IConsole { - object ConsoleScene { get; } + object ConsoleScene { get; set; } void Output(string text, string level); void Output(string text); diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 6346279..4f9ac08 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -62,7 +62,6 @@ namespace OpenSim.Framework.Servers /// private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); - protected CommandConsole m_console; protected OpenSimAppender m_consoleAppender; protected IAppender m_logFileAppender = null; @@ -139,7 +138,8 @@ namespace OpenSim.Framework.Servers } else { - m_consoleAppender.Console = m_console; + // FIXME: This should be done through an interface rather than casting. + m_consoleAppender.Console = (ConsoleBase)m_console; // If there is no threshold set then the threshold is effectively everything. if (null == m_consoleAppender.Threshold) @@ -367,8 +367,10 @@ namespace OpenSim.Framework.Servers } } - public virtual void HandleShow(string module, string[] cmd) + public override void HandleShow(string module, string[] cmd) { + base.HandleShow(module, cmd); + List args = new List(cmd); args.RemoveAt(0); @@ -385,10 +387,6 @@ namespace OpenSim.Framework.Servers Notice(GetThreadsReport()); break; - case "uptime": - Notice(GetUptimeReport()); - break; - case "version": Notice(GetVersionText()); break; @@ -430,33 +428,6 @@ namespace OpenSim.Framework.Servers } /// - /// Console output is only possible if a console has been established. - /// That is something that cannot be determined within this class. So - /// all attempts to use the console MUST be verified. - /// - /// - protected void Notice(string msg) - { - if (m_console != null) - { - m_console.Output(msg); - } - } - - /// - /// Console output is only possible if a console has been established. - /// That is something that cannot be determined within this class. So - /// all attempts to use the console MUST be verified. - /// - /// - /// - protected void Notice(string format, params string[] components) - { - if (m_console != null) - m_console.OutputFormat(format, components); - } - - /// /// Enhance the version string with extra information if it's available. /// protected void EnhanceVersionInformation() diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index d19234b..afe1f73 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -26,13 +26,20 @@ */ using System; +using System.Collections.Generic; using System.Text; +using OpenSim.Framework.Console; namespace OpenSim.Framework.Servers { public class ServerBase { /// + /// Console to be used for any command line output. Can be null, in which case there should be no output. + /// + protected ICommandConsole m_console; + + /// /// Time at which this server was started /// protected DateTime m_startuptime; @@ -42,6 +49,22 @@ namespace OpenSim.Framework.Servers m_startuptime = DateTime.Now; } + public virtual void HandleShow(string module, string[] cmd) + { + List args = new List(cmd); + + args.RemoveAt(0); + + string[] showParams = args.ToArray(); + + switch (showParams[0]) + { + case "uptime": + Notice(GetUptimeReport()); + break; + } + } + /// /// Return a report about the uptime of this server /// @@ -54,5 +77,32 @@ namespace OpenSim.Framework.Servers return sb.ToString(); } + + /// + /// Console output is only possible if a console has been established. + /// That is something that cannot be determined within this class. So + /// all attempts to use the console MUST be verified. + /// + /// + protected void Notice(string msg) + { + if (m_console != null) + { + m_console.Output(msg); + } + } + + /// + /// Console output is only possible if a console has been established. + /// That is something that cannot be determined within this class. So + /// all attempts to use the console MUST be verified. + /// + /// + /// + protected void Notice(string format, params string[] components) + { + if (m_console != null) + m_console.OutputFormat(format, components); + } } } \ No newline at end of file diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 808c760..618ce0a 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -242,7 +242,7 @@ namespace OpenSim } } - protected virtual void AddPluginCommands(CommandConsole console) + protected virtual void AddPluginCommands(ICommandConsole console) { List topics = GetHelpTopics(); diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index 56bb7ae..7b49ac9 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -174,6 +174,8 @@ namespace OpenSim.Server.Base MainConsole.Instance = new LocalConsole(prompt); } + m_console = MainConsole.Instance; + // Configure the appenders for log4net // OpenSimAppender consoleAppender = null; @@ -351,21 +353,5 @@ namespace OpenSim.Server.Base { } } - - public virtual void HandleShow(string module, string[] cmd) - { - List args = new List(cmd); - - args.RemoveAt(0); - - string[] showParams = args.ToArray(); - - switch (showParams[0]) - { - case "uptime": - MainConsole.Instance.Output(GetUptimeReport()); - break; - } - } } } \ No newline at end of file -- cgit v1.1 From cf03d6ea9223e71c27ca91633a30abcf1368ec58 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 Nov 2012 04:11:03 +0000 Subject: Factor out common registration of "show uptime" command --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 130 ++++++++++++------------- OpenSim/Framework/Servers/ServerBase.cs | 12 +++ OpenSim/Server/Base/ServicesServerBase.cs | 7 +- 3 files changed, 78 insertions(+), 71 deletions(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 4f9ac08..019b68b 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -118,78 +118,76 @@ namespace OpenSim.Framework.Servers /// protected virtual void StartupSpecific() { - if (m_console != null) - { - ILoggerRepository repository = LogManager.GetRepository(); - IAppender[] appenders = repository.GetAppenders(); + if (m_console == null) + return; - foreach (IAppender appender in appenders) - { - if (appender.Name == "Console") - { - m_consoleAppender = (OpenSimAppender)appender; - break; - } - } + ILoggerRepository repository = LogManager.GetRepository(); + IAppender[] appenders = repository.GetAppenders(); - if (null == m_consoleAppender) - { - Notice("No appender named Console found (see the log4net config file for this executable)!"); - } - else + foreach (IAppender appender in appenders) + { + if (appender.Name == "Console") { - // FIXME: This should be done through an interface rather than casting. - m_consoleAppender.Console = (ConsoleBase)m_console; - - // If there is no threshold set then the threshold is effectively everything. - if (null == m_consoleAppender.Threshold) - m_consoleAppender.Threshold = Level.All; - - Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); + m_consoleAppender = (OpenSimAppender)appender; + break; } + } + + if (null == m_consoleAppender) + { + Notice("No appender named Console found (see the log4net config file for this executable)!"); + } + else + { + // FIXME: This should be done through an interface rather than casting. + m_consoleAppender.Console = (ConsoleBase)m_console; - m_console.Commands.AddCommand("General", false, "quit", - "quit", - "Quit the application", HandleQuit); - - m_console.Commands.AddCommand("General", false, "shutdown", - "shutdown", - "Quit the application", HandleQuit); - - m_console.Commands.AddCommand("General", false, "set log level", - "set log level ", - "Set the console logging level", HandleLogLevel); - - m_console.Commands.AddCommand("General", false, "show info", - "show info", - "Show general information about the server", HandleShow); - - m_console.Commands.AddCommand("General", false, "show threads", - "show threads", - "Show thread status", HandleShow); - - m_console.Commands.AddCommand("General", false, "show uptime", - "show uptime", - "Show server uptime", HandleShow); - - m_console.Commands.AddCommand("General", false, "show version", - "show version", - "Show server version", HandleShow); - - m_console.Commands.AddCommand("General", false, "threads abort", - "threads abort ", - "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); - - m_console.Commands.AddCommand("General", false, "threads show", - "threads show", - "Show thread status. Synonym for \"show threads\"", - (string module, string[] args) => Notice(GetThreadsReport())); - - m_console.Commands.AddCommand("General", false, "force gc", - "force gc", - "Manually invoke runtime garbage collection. For debugging purposes", - HandleForceGc); + // If there is no threshold set then the threshold is effectively everything. + if (null == m_consoleAppender.Threshold) + m_consoleAppender.Threshold = Level.All; + + Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); } + + RegisterCommonCommands(); + + m_console.Commands.AddCommand("General", false, "quit", + "quit", + "Quit the application", HandleQuit); + + m_console.Commands.AddCommand("General", false, "shutdown", + "shutdown", + "Quit the application", HandleQuit); + + m_console.Commands.AddCommand("General", false, "set log level", + "set log level ", + "Set the console logging level", HandleLogLevel); + + m_console.Commands.AddCommand("General", false, "show info", + "show info", + "Show general information about the server", HandleShow); + + m_console.Commands.AddCommand("General", false, "show threads", + "show threads", + "Show thread status", HandleShow); + + m_console.Commands.AddCommand("General", false, "show version", + "show version", + "Show server version", HandleShow); + + m_console.Commands.AddCommand("General", false, "threads abort", + "threads abort ", + "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); + + m_console.Commands.AddCommand("General", false, "threads show", + "threads show", + "Show thread status. Synonym for \"show threads\"", + (string module, string[] args) => Notice(GetThreadsReport())); + + m_console.Commands.AddCommand("General", false, "force gc", + "force gc", + "Manually invoke runtime garbage collection. For debugging purposes", + HandleForceGc); } private void HandleForceGc(string module, string[] args) diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index afe1f73..0835aad 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -49,6 +49,18 @@ namespace OpenSim.Framework.Servers m_startuptime = DateTime.Now; } + /// + /// Register common commands once m_console has been set if it is going to be set + /// + public void RegisterCommonCommands() + { + if (m_console == null) + return; + + m_console.Commands.AddCommand( + "General", false, "show uptime", "show uptime", "Show server uptime", HandleShow); + } + public virtual void HandleShow(string module, string[] cmd) { List args = new List(cmd); diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index 7b49ac9..285168c 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -239,6 +239,8 @@ namespace OpenSim.Server.Base CreatePIDFile(startupConfig.GetString("PIDFile")); } + RegisterCommonCommands(); + // Register the quit command // MainConsole.Instance.Commands.AddCommand("General", false, "quit", @@ -254,11 +256,6 @@ namespace OpenSim.Server.Base "command-script