public KinematicCharacterController(PairCachingGhostObject ghostObject, ConvexShape convexShape, float stepHeight, int upAxis = 1)
 {
     m_upAxis                  = upAxis;
     m_addedMargin             = 0.02f;
     m_walkDirection           = Vector3.Zero;
     m_useGhostObjectSweepTest = true;
     m_ghostObject             = ghostObject;
     m_stepHeight              = stepHeight;
     m_turnAngle               = 0f;
     m_convexShape             = convexShape;
     m_useWalkDirection        = true; // use walk direction by default, legacy behavior
     m_velocityTimeInterval    = 0.0f;
     m_verticalVelocity        = 0.0f;
     m_verticalOffset          = 0.0f;
     Gravity             = 9.8f * 3; // 3G acceleration.
     m_fallSpeed         = 55.0f;    // Terminal velocity of a sky diver in m/s.
     m_jumpSpeed         = 10.0f;    // ?
     m_wasOnGround       = false;
     m_wasJumping        = false;
     m_interpolateUp     = true;
     MaxSlope            = MathUtil.DegToRadians(45.0f);
     m_currentStepOffset = 0;
     full_drop           = false;
     bounce_fix          = false;
 }
 public KinematicCharacterController(PairCachingGhostObject ghostObject, ConvexShape convexShape, float stepHeight, int upAxis = 1)
 {
     m_upAxis = upAxis;
     m_addedMargin = 0.02f;
     m_walkDirection = Vector3.Zero;
     m_useGhostObjectSweepTest = true;
     m_ghostObject = ghostObject;
     m_stepHeight = stepHeight;
     m_turnAngle = 0f;
     m_convexShape = convexShape;
     m_useWalkDirection = true;	// use walk direction by default, legacy behavior
     m_velocityTimeInterval = 0.0f;
     m_verticalVelocity = 0.0f;
     m_verticalOffset = 0.0f;
     Gravity = 9.8f * 3; // 3G acceleration.
     m_fallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s.
     m_jumpSpeed = 10.0f; // ?
     m_wasOnGround = false;
     m_wasJumping = false;
     m_interpolateUp = true;
     MaxSlope = MathUtil.DegToRadians(45.0f);
     m_currentStepOffset = 0;
     full_drop = false;
     bounce_fix = false;
 }
Example #3
0
 /// <summary>
 /// コンストラクター
 /// </summary>
 public CollisionObject()
 {
     this.shape = null;
     this.ghostObject = null;
     this.offset = new Vector3 (0, 0, 0);
     this.collideWith = -1;
     this.ignoreWith = 0;
 }
Example #4
0
        /// <inheritdoc/>
        public override BulletSharp.PairCachingGhostObject CreateGhostObject()
        {
            var col = new PairCachingGhostObject ();
               col.CollisionShape = new BulletSharp.SphereShape(radius);
               col.CollisionFlags |= CollisionFlags.NoContactResponse;

               return col;
        }
        internal override bool _BuildCollisionObject()
        {
            BPhysicsWorld world = BPhysicsWorld.Get();

            if (m_collisionObject != null)
            {
                if (isInWorld && world != null)
                {
                    world.RemoveCollisionObject(this);
                }
            }

            if (transform.localScale != UnityEngine.Vector3.one)
            {
                Debug.LogError("The local scale on this collision shape is not one. Bullet physics does not support scaling on a rigid body world transform. Instead alter the dimensions of the CollisionShape.");
            }

            m_collisionShape = GetComponent <BCollisionShape>();
            if (m_collisionShape == null)
            {
                Debug.LogError("There was no collision shape component attached to this BRigidBody. " + name);
                return(false);
            }

            CollisionShape cs = m_collisionShape.GetCollisionShape();

            //rigidbody is dynamic if and only if mass is non zero, otherwise static


            if (m_collisionObject == null)
            {
                m_collisionObject = new BulletSharp.PairCachingGhostObject();
                m_collisionObject.CollisionShape = cs;
                BulletSharp.Math.Matrix     worldTrans;
                BulletSharp.Math.Quaternion q = transform.rotation.ToBullet();
                BulletSharp.Math.Matrix.RotationQuaternion(ref q, out worldTrans);
                worldTrans.Origin = transform.position.ToBullet();
                m_collisionObject.WorldTransform  = worldTrans;
                m_collisionObject.UserObject      = this;
                m_collisionObject.CollisionFlags  = m_collisionObject.CollisionFlags | BulletSharp.CollisionFlags.KinematicObject;
                m_collisionObject.CollisionFlags &= ~BulletSharp.CollisionFlags.StaticObject;
            }
            else
            {
                BulletSharp.Math.Matrix     worldTrans;
                BulletSharp.Math.Quaternion q = transform.rotation.ToBullet();
                BulletSharp.Math.Matrix.RotationQuaternion(ref q, out worldTrans);
                worldTrans.Origin = transform.position.ToBullet();
                m_collisionObject.WorldTransform  = worldTrans;
                m_collisionObject.CollisionShape  = cs;
                m_collisionObject.CollisionFlags  = m_collisionObject.CollisionFlags | BulletSharp.CollisionFlags.KinematicObject;
                m_collisionObject.CollisionFlags &= ~BulletSharp.CollisionFlags.StaticObject;
            }
            return(true);
        }
        internal override bool _BuildCollisionObject()
        {
            BPhysicsWorld world = BPhysicsWorld.Get();
            if (m_collisionObject != null)
            {
                if (isInWorld && world != null)
                {
                    world.RemoveCollisionObject(m_collisionObject);
                }
            }

            if (transform.localScale != UnityEngine.Vector3.one)
            {
                Debug.LogError("The local scale on this collision shape is not one. Bullet physics does not support scaling on a rigid body world transform. Instead alter the dimensions of the CollisionShape.");
            }

            m_collisionShape = GetComponent<BCollisionShape>();
            if (m_collisionShape == null)
            {
                Debug.LogError("There was no collision shape component attached to this BRigidBody. " + name);
                return false;
            }

            CollisionShape cs = m_collisionShape.GetCollisionShape();
            //rigidbody is dynamic if and only if mass is non zero, otherwise static

            if (m_collisionObject == null)
            {
                m_collisionObject = new BulletSharp.PairCachingGhostObject();
                m_collisionObject.CollisionShape = cs;
                BulletSharp.Math.Matrix worldTrans;
                BulletSharp.Math.Quaternion q = transform.rotation.ToBullet();
                BulletSharp.Math.Matrix.RotationQuaternion(ref q, out worldTrans);
                worldTrans.Origin = transform.position.ToBullet();
                m_collisionObject.WorldTransform = worldTrans;
                m_collisionObject.UserObject = this;
                m_collisionObject.CollisionFlags = m_collisionObject.CollisionFlags | BulletSharp.CollisionFlags.KinematicObject;
                m_collisionObject.CollisionFlags &= ~BulletSharp.CollisionFlags.StaticObject;
            }
            else {
                BulletSharp.Math.Matrix worldTrans;
                BulletSharp.Math.Quaternion q = transform.rotation.ToBullet();
                BulletSharp.Math.Matrix.RotationQuaternion(ref q, out worldTrans);
                worldTrans.Origin = transform.position.ToBullet();
                m_collisionObject.WorldTransform = worldTrans;
                m_collisionObject.CollisionShape = cs;
                m_collisionObject.CollisionFlags = m_collisionObject.CollisionFlags | BulletSharp.CollisionFlags.KinematicObject;
                m_collisionObject.CollisionFlags &= ~BulletSharp.CollisionFlags.StaticObject;
            }
            return true;
        }
        public KinematicCharacterController(PairCachingGhostObject ghostObject, ConvexShape convexShape, float stepHeight, ref Vector3 up)
        {
            m_ghostObject             = ghostObject;
            m_jumpAxis                = new Vector3(0.0f, 0.0f, 1.0f);
            m_addedMargin             = 0.02f;
            m_useGhostObjectSweepTest = true;
            m_convexShape             = convexShape;
            m_useWalkDirection        = true;    // use walk direction by default, legacy behavior
            m_gravity             = 9.8f * 3.0f; // 3G acceleration.
            m_fallSpeed           = 55.0f;       // Terminal velocity of a sky diver in m/s.
            m_jumpSpeed           = 10.0f;       // ?
            m_SetjumpSpeed        = m_jumpSpeed;
            m_interpolateUp       = true;
            m_maxPenetrationDepth = 0.2f;

            Up         = up;
            StepHeight = stepHeight;
            MaxSlope   = MathUtil.DegToRadians(45.0f);
        }
        protected override void OnInitializePhysics()
        {
            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new DefaultCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(CollisionConf);

            Broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000));
            Solver = new SequentialImpulseConstraintSolver();

            World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf);
            World.DispatchInfo.AllowedCcdPenetration = 0.0001f;
            //World.Gravity = Freelook.Up * -10.0f;

            Matrix startTransform = Matrix.Translation(10.210098f, -1.6433364f, 16.453260f);
            ghostObject = new PairCachingGhostObject();
            ghostObject.WorldTransform = startTransform;
            Broadphase.OverlappingPairCache.SetInternalGhostPairCallback(new GhostPairCallback());

            const float characterHeight = 1.75f;
            const float characterWidth = 1.75f;
            ConvexShape capsule = new CapsuleShape(characterWidth, characterHeight);
            ghostObject.CollisionShape = capsule;
            ghostObject.CollisionFlags = CollisionFlags.CharacterObject;

            const float stepHeight = 0.35f;
            character = new KinematicCharacterController(ghostObject, capsule, stepHeight);

            BspLoader bspLoader = new BspLoader();
            bspLoader.LoadBspFile("data/BspDemo.bsp");
            BspConverter bsp2Bullet = new BspToBulletConverter(this);
            bsp2Bullet.ConvertBsp(bspLoader, 0.1f);

            World.AddCollisionObject(ghostObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter);

            World.AddAction(character);

            convexResultCallback = new ClosestConvexResultCallback();
            convexResultCallback.CollisionFilterMask = (short)CollisionFilterGroups.StaticFilter;
            cameraSphere = new SphereShape(0.2f);
        }
        static void TestGhostObjectPairs(PairCachingGhostObject ghostObject)
        {
            AlignedManifoldArray manifoldArray = new AlignedManifoldArray();
            AlignedBroadphasePairArray pairArray = ghostObject.OverlappingPairCache.OverlappingPairArray;
            int numPairs = pairArray.Count;

            for (int i = 0; i < numPairs; i++)
            {
                manifoldArray.Clear();

                BroadphasePair pair = pairArray[i];

                //unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache:
                BroadphasePair collisionPair = world.PairCache.FindPair(pair.Proxy0, pair.Proxy1);
                if (collisionPair == null)
                    continue;

                if (collisionPair.Algorithm != null)
                    collisionPair.Algorithm.GetAllContactManifolds(manifoldArray);

                for (int j = 0; j < manifoldArray.Count; j++)
                {
                    PersistentManifold manifold = manifoldArray[j];
                    float directionSign = manifold.Body0 == ghostObject ? -1.0f : 1.0f;
                    for (int p = 0; p < manifold.NumContacts; p++)
                    {
                        ManifoldPoint pt = manifold.GetContactPoint(p);
                        if (pt.Distance < 0.0f)
                        {
                            Vector3 ptA = pt.PositionWorldOnA;
                            Vector3 ptB = pt.PositionWorldOnB;
                            Vector3 normalOnB = pt.NormalWorldOnB;
                            /// work here
                        }
                    }
                }
            }
        }
        static void TestGCCollection()
        {
            var conf = new DefaultCollisionConfiguration();
            var dispatcher = new CollisionDispatcher(conf);
            var broadphase = new DbvtBroadphase();
            //var broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000));
            world = new DiscreteDynamicsWorld(dispatcher, broadphase, null, conf);
            world.Gravity = new Vector3(0, -10, 0);
            dispatcher.NearCallback = DispatcherNearCallback;

            CreateBody(0.0f, new BoxShape(50, 1, 50), Vector3.Zero);
            var dynamicObject = CreateBody(10.0f, new SphereShape(1.0f), new Vector3(2, 2, 0));
            var dynamicObject2 = CreateBody(1.0f, new SphereShape(1.0f), new Vector3(0, 2, 0));

            var ghostPairCallback = new GhostPairCallback();
            broadphase.OverlappingPairCache.SetInternalGhostPairCallback(ghostPairCallback);
            AddToDisposeQueue(ghostPairCallback);
            ghostPairCallback = null;
            var ghostObject = new PairCachingGhostObject();
            ghostObject.CollisionShape = new BoxShape(2);
            ghostObject.WorldTransform = Matrix.Translation(2,2,0);
            world.AddCollisionObject(ghostObject);

            var trimesh = new TriangleMesh();
            Vector3 v0 = new Vector3(0, 0, 0);
            Vector3 v1 = new Vector3(1, 0, 0);
            Vector3 v2 = new Vector3(0, 1, 0);
            Vector3 v3 = new Vector3(1, 1, 0);
            trimesh.AddTriangle(v0, v1, v2);
            trimesh.AddTriangle(v1, v3, v2);
            var triangleMeshShape = new BvhTriangleMeshShape(trimesh, false);
            var triMeshObject = CreateBody(0, triangleMeshShape, new Vector3(20,0,20));
            AddToDisposeQueue(triangleMeshShape);
            AddToDisposeQueue(trimesh);
            AddToDisposeQueue(triMeshObject);
            triangleMeshShape = null;
            trimesh = null;

            AddToDisposeQueue(conf);
            AddToDisposeQueue(dispatcher);
            AddToDisposeQueue(broadphase);
            AddToDisposeQueue(world);

            //conf.Dispose();
            conf = null;
            //dispatcher.Dispose();
            dispatcher = null;
            //broadphase.Dispose();
            broadphase = null;
            world.DebugDrawer = new DebugDrawTest();
            AddToDisposeQueue(world.DebugDrawer);
            world.SetInternalTickCallback(WorldPreTickCallback);
            for (int i = 0; i < 600; i++)
            {
                world.StepSimulation(1.0f / 60.0f);
            }

            world.DispatchInfo.DebugDraw = new DebugDrawTest2();
            AddToDisposeQueue(world.DispatchInfo.DebugDraw);
            world.DispatchInfo.DebugDraw = world.DispatchInfo.DebugDraw;
            AddToDisposeQueue(world.DispatchInfo.DebugDraw);
            world.DispatchInfo.DebugDraw = null;
            world.DebugDrawer = null;
            world.DebugDrawer = new DebugDrawTest2();
            world.StepSimulation(1.0f / 60.0f);
            world.DebugDrawWorld();
            AddToDisposeQueue(world.DispatchInfo.DebugDraw);

            world.DebugDrawer = new DebugDrawTest();
            world.DebugDrawWorld();
            AddToDisposeQueue(world.DebugDrawer);
            world.DebugDrawer = null;

            TestContactTest(dynamicObject, dynamicObject2);
            TestGhostObjectPairs(ghostObject);
            TestRayCast(dynamicObject);
            TestTriangleMeshRayCast(triMeshObject);
            dynamicObject = null;
            dynamicObject2 = null;
            triMeshObject = null;

            //world.SetInternalTickCallback(null);
            world.Dispose();
            world = null;

            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            GC.WaitForPendingFinalizers();

            TestWeakRefs();
            disposeQueue.Clear();
        }
Example #11
0
 /// <inheritdoc/>
 void System.IDisposable.Dispose()
 {
     if (ghostObject != null) {
         // (注意)
         // このメソッドが呼ばれる時にはすでにデタッチされているので
         // ここでコリジョン ワールドから削除する事ができない
         // 削除せずに Dispose() を呼ぶとワールドのDispose()を呼んだタイミングで
         // BulletSharp が不正なメモリアクセスで落ちる。
         // 従って忘れずに OnDestroyed() でワールドから取り除いておくこと。
         ghostObject.Dispose ();
         this.ghostObject = null;
     }
 }
Example #12
0
 ///<inheritdoc/>
 public override BulletSharp.PairCachingGhostObject CreateGhostObject()
 {
     var col = new PairCachingGhostObject ();
     col.CollisionShape = new BulletSharp.BoxShape (halfWidth, halfHeight, halfDepth);
     col.CollisionFlags |= CollisionFlags.NoContactResponse;
     return col;
 }
        internal override bool _BuildCollisionObject()
        {
            BPhysicsWorld world = BPhysicsWorld.Get();
            if (m_collisionObject != null)
            {
                if (isInWorld && world != null)
                {
                    isInWorld = false;
                    world.RemoveCollisionObject(m_collisionObject);
                }
            }

            if (transform.localScale != UnityEngine.Vector3.one)
            {
                Debug.LogError("The local scale on this collision shape is not one. Bullet physics does not support scaling on a rigid body world transform. Instead alter the dimensions of the CollisionShape.");
            }

            m_collisionShape = GetComponent<BCollisionShape>();
            if (m_collisionShape == null)
            {
                Debug.LogError("There was no collision shape component attached to this BRigidBody. " + name);
                return false;
            }
            if (!(m_collisionShape.GetCollisionShape() is ConvexShape))
            {
                Debug.LogError("The CollisionShape on this BCharacterController was not a convex shape. " + name);
                return false;
            }

            m_collisionShape.GetCollisionShape();
            if (m_collisionObject == null)
            {
                m_collisionObject = new PairCachingGhostObject();
                m_collisionObject.CollisionShape = m_collisionShape.GetCollisionShape();
                m_collisionObject.CollisionFlags = m_collisionFlags;
                m_characterController = new KinematicCharacterController((PairCachingGhostObject)m_collisionObject, (ConvexShape)m_collisionShape.GetCollisionShape(), stepHeight, upAxis);
                BulletSharp.Math.Matrix worldTrans;
                BulletSharp.Math.Quaternion q = transform.rotation.ToBullet();
                BulletSharp.Math.Matrix.RotationQuaternion(ref q, out worldTrans);
                worldTrans.Origin = transform.position.ToBullet();
                m_collisionObject.WorldTransform = worldTrans;
                m_collisionObject.UserObject = this;
                //world.world.AddCollisionObject(m_collisionObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter);
                //((DynamicsWorld)world.world).AddAction(m_characterController);
            }
            else {
                m_collisionObject.CollisionShape = m_collisionShape.GetCollisionShape();
                m_collisionObject.CollisionFlags = m_collisionFlags;
                if (m_characterController != null)
                {
                    world.RemoveAction(m_characterController);
                }
                m_characterController = new KinematicCharacterController((PairCachingGhostObject)m_collisionObject, (ConvexShape)m_collisionShape.GetCollisionShape(), stepHeight, upAxis);
                BulletSharp.Math.Matrix worldTrans;
                BulletSharp.Math.Quaternion q = transform.rotation.ToBullet();
                BulletSharp.Math.Matrix.RotationQuaternion(ref q, out worldTrans);
                worldTrans.Origin = transform.position.ToBullet();
                m_collisionObject.WorldTransform = worldTrans;
                m_collisionObject.UserObject = this;
            }
            return true;
        }
Example #14
0
        public void CreateGhosts()
        {
            if (Bf.Animations.Model == null || Bf.Animations.Model.MeshCount <= 0)
                return;

            Bt.ManifoldArray = new AlignedManifoldArray();
            Bt.Shapes.Clear();
            Bt.GhostObjects.Clear();
            Bt.LastCollisions.Clear();
            for(var i = 0; i < Bf.BoneTags.Count; i++)
            {
                var box = COLLISION_GHOST_VOLUME_COEFFICIENT *
                          (Bf.BoneTags[i].MeshBase.BBMax - Bf.BoneTags[i].MeshBase.BBMin);
                Bt.Shapes.Add(new BoxShape(box.ToBullet()));
                Bt.Shapes.Last().Margin = COLLISION_MARGIN_DEFAULT;
                Bf.BoneTags[i].MeshBase.Radius = Math.Min(Math.Min(box.X, box.Y), box.Z);

                var pcg = new PairCachingGhostObject();

                pcg.SetIgnoreCollisionCheck(Bt.BtBody[i], true);

                var gltr = Transform * Bf.BoneTags[i].FullTransform;
                gltr.Origin = gltr * Bf.BoneTags[i].MeshBase.Center;

                pcg.WorldTransform = ((Matrix4)gltr).ToBullet();
                pcg.CollisionFlags |= CollisionFlags.NoContactResponse | CollisionFlags.CharacterObject;
                pcg.UserObject = Self;
                pcg.CollisionShape = Bt.Shapes.Last();
                BtEngineDynamicsWorld.AddCollisionObject(pcg, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.AllFilter);
                Bt.GhostObjects.Add(pcg);

                Bt.LastCollisions.Add(new EntityCollisionNode());
            }
        }
Example #15
0
        /// <summary>
        /// It is from bullet_character_controller
        /// </summary>
        public static int GhostGetPenetrationFixVector(PairCachingGhostObject ghost, AlignedManifoldArray manifoldArray,
            out Vector3 correction)
        {
            // Here we must refresh the overlapping paircache as the penetrating movement itself or the
            // previous recovery iteration might have used setWorldTransform and pushed us into an object
            // that is not in the previous cache contents from the last timestep, as will happen if we
            // are pushed into a new AABB overlap. Unhandled this means the next convex sweep gets stuck.
            //
            // Do this by calling the broadphase's setAabb with the moved AABB, this will update the broadphase
            // paircache and the ghostobject's internal paircache at the same time.    /BW

            var ret = 0;
            var pairArray = ghost.OverlappingPairCache.OverlappingPairArray;
            BulletSharp.Math.Vector3 aabb_min, aabb_max, t;

            ghost.CollisionShape.GetAabb(ghost.WorldTransform, out aabb_min, out aabb_max);
            BtEngineDynamicsWorld.Broadphase.SetAabb(ghost.BroadphaseHandle, aabb_min, aabb_max,
                BtEngineDynamicsWorld.Dispatcher);
            BtEngineDynamicsWorld.Dispatcher.DispatchAllCollisionPairs(ghost.OverlappingPairCache,
                BtEngineDynamicsWorld.DispatchInfo, BtEngineDynamicsWorld.Dispatcher);

            correction = Vector3.Zero;
            var numPairs = ghost.OverlappingPairCache.NumOverlappingPairs;
            for (var i = 0; i < numPairs; i++)
            {
                manifoldArray.Clear();
                // do not use commented code: it prevents to collision skips.
                //var pair = pairArray[i];
                //var collisionPair = Global.BtEngineDynamicsWorld.PairCache.FindPair(pair.Proxy0, pair.Proxy1);
                var collisionPair = pairArray[i];

                if(collisionPair == null)
                {
                    continue;
                }

                collisionPair.Algorithm?.GetAllContactManifolds(manifoldArray);

                foreach (var manifold in manifoldArray)
                {
                    var directionSign = manifold.Body0 == ghost ? -1.0f : 1.0f;
                    var cont0 = (EngineContainer) manifold.Body0.UserObject;
                    var cont1 = (EngineContainer) manifold.Body1.UserObject;
                    if(cont0.CollisionType == COLLISION_TYPE.Ghost && cont1.CollisionType == COLLISION_TYPE.Ghost)
                    {
                        continue;
                    }
                    for(var k = 0; k < manifold.NumContacts; k++)
                    {
                        var pt = manifold.GetContactPoint(k);
                        var dist = pt.Distance;

                        if(dist < 0.0f)
                        {
                            t = pt.NormalWorldOnB * dist * directionSign;
                            correction += t.ToOpenTK();
                            ret++;
                        }
                    }
                }
            }

            return ret;
        }