public void Cast(CollisionWorld cw, float frameDelta)
        {
#if BATCH_RAYCASTER
		    if (!gBatchRaycaster)
			    return;

		    gBatchRaycaster->clearRays ();
		    for (int i = 0; i < NumRays; i++)
		    {
			    gBatchRaycaster->addRay (source[i], dest[i]);
		    }
		    gBatchRaycaster->performBatchRaycast ();
		    for (int i = 0; i < gBatchRaycaster->getNumRays(); i++)
		    {
				    const SpuRaycastTaskWorkUnitOut& out = (*gBatchRaycaster)[i];
				    _hitPoint[i].setInterpolate3(_source[i], _destination[i], out.HitFraction);
				    _normal[i] = out.hitNormal;
				    _normal[i].Normalize();
		    }
#else
            for (int i = 0; i < NumRays; i++)
            {
                using (var cb = new ClosestRayResultCallback(ref _source[i], ref _destination[i]))
                {
                    cw.RayTestRef(ref _source[i], ref _destination[i], cb);
                    if (cb.HasHit)
                    {
                        _hitPoint[i] = cb.HitPointWorld;
                        _normal[i] = cb.HitNormalWorld;
                        _normal[i].Normalize();
                    }
                    else
                    {
                        _hitPoint[i] = _destination[i];
                        _normal[i] = new Vector3(1.0f, 0.0f, 0.0f);
                    }
                }
            }

            _time += frameDelta;
            _frameCount++;
            if (_frameCount > 50)
            {
                if (_time < _timeMin) _timeMin = _time;
                if (_time > _timeMax) _timeMax = _time;
                _timeTotal += _time;
                _sampleCount++;
                float timeMean = _timeTotal / _sampleCount;
                Console.WriteLine("{0} rays in {1} s, min {2}, max {3}, mean {4}",
                    NumRays * _frameCount,
                    _time.ToString("0.000", CultureInfo.InvariantCulture),
                    _timeMin.ToString("0.000", CultureInfo.InvariantCulture),
                    _timeMax.ToString("0.000", CultureInfo.InvariantCulture),
                    timeMean.ToString("0.000", CultureInfo.InvariantCulture));
                _time = 0;
                _frameCount = 0;
            }
#endif
        }
Esempio n. 2
0
        /// <summary>
        /// コンストラクター
        /// </summary>
        public CollisionAnalyzer()
        {
            var cc = new DefaultCollisionConfiguration ();
            dispatcher = new CollisionDispatcher (cc);
            broadphase = new DbvtBroadphase ();
            broadphase.OverlappingPairCache.SetInternalGhostPairCallback (new GhostPairCallback ());
            // solver = new SequentialImpulseConstraintSolver ();

            this.wld = new DiscreteDynamicsWorld (dispatcher, broadphase, null, cc);

            this.prevContacts = new List<OverlappingPair> ();
            this.currContacts = new List<OverlappingPair> ();
        }
        public void Cast(CollisionWorld cw, float frameDelta)
        {
            using (var cb = new ClosestConvexResultCallback())
            {
                for (int i = 0; i < NumRays; i++)
                {
                    cb.ClosestHitFraction = 1.0f;
                    cb.ConvexFromWorld = _source[i];
                    cb.ConvexToWorld = _destination[i];

                    Matrix from = _fromRotation * Matrix.Translation(_source[i]);
                    Matrix to = _toRotation * Matrix.Translation(_destination[i]);
                    cw.ConvexSweepTestRef(_boxShape, ref from, ref to, cb);
                    if (cb.HasHit)
                    {
                        _hitPoint[i] = cb.HitPointWorld;
                        Vector3.Lerp(ref _source[i], ref _destination[i], cb.ClosestHitFraction, out _hitCenterOfMass[i]);
                        _hitFraction[i] = cb.ClosestHitFraction;
                        _normal[i] = cb.HitNormalWorld;
                        _normal[i].Normalize();
                    }
                    else
                    {
                        _hitCenterOfMass[i] = _destination[i];
                        _hitPoint[i] = _destination[i];
                        _hitFraction[i] = 1.0f;
                        _normal[i] = new Vector3(1.0f, 0.0f, 0.0f);
                    }
                }
            }

            _time += frameDelta;
            _frameCount++;
            if (_frameCount > 50)
            {
                if (_time < _timeMin) _timeMin = _time;
                if (_time > _timeMax) _timeMax = _time;
                _timeTotal += _time;
                _sampleCount++;
                float timeMean = _timeTotal / _sampleCount;
                Console.WriteLine("{0} rays in {1} s, min {2}, max {3}, mean {4}",
                    NumRays * _frameCount,
                    _time.ToString("0.000", CultureInfo.InvariantCulture),
                    _timeMin.ToString("0.000", CultureInfo.InvariantCulture),
                    _timeMax.ToString("0.000", CultureInfo.InvariantCulture),
                    timeMean.ToString("0.000", CultureInfo.InvariantCulture));
                _time = 0;
                _frameCount = 0;
            }
        }
Esempio n. 4
0
        static void Main(string[] args)
        {
            var config     = new BulletSharp.DefaultCollisionConfiguration();
            var dispatcher = new BulletSharp.CollisionDispatcher(config);
            var pair       = new BulletSharp.DbvtBroadphase();
            var world      = new BulletSharp.CollisionWorld(dispatcher, pair, config);

            var players = new Dictionary <Guid, RigidBody>();

            var ci = new RigidBodyConstructionInfo(1, new DefaultMotionState(), new SphereShape(.513037f));
            var rb = new RigidBody(ci);

            rb.Gravity = Vector3.Zero;
            rb.Translate(new Vector3(0f, 1.5f, 0f));
            world.AddCollisionObject(rb);
        }
Esempio n. 5
0
        void OnGround(Kart kart, CollisionWorld.ClosestRayResultCallback callback)
        {
            // we need to wait two "ticks" of the ray casting (0.1s total at time of writing) before we stop the emitter again
            // we could just wait one, but that's too short
            // the little boolean stuff is just a sort of "toggle" between the two ticks

            // we can't really unhook from the events because we've got multiple karts
            bool wait;
            if (waitDict.TryGetValue(kart, out wait)) {
                if (!wait)
                    particles[kart].Emitting = false;
                else
                    waitDict[kart] = true;
            }
            else
                waitDict[kart] = true;
        }
        /*
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (vertexBuffer != null)
                {
                    vertexBuffer.Dispose();
                    vertexBuffer = null;
                }
            }

            base.Dispose(disposing);
        }
        */
        public void DrawDebugWorld(CollisionWorld world)
        {
            world.DebugDrawWorld();

            if (lines.Count == 0)
                return;

            inputAssembler.InputLayout = inputLayout;

            if (lineArray.Length != lines.Count)
            {
                lineArray = new PositionColored[lines.Count];
                lines.CopyTo(lineArray);

                if (vertexBuffer != null)
                {
                    vertexBuffer.Dispose();
                }
                vertexBufferDesc.SizeInBytes = PositionColored.Stride * lines.Count;
                using (var data = new DataStream(vertexBufferDesc.SizeInBytes, false, true))
                {
                    data.WriteRange(lineArray);
                    data.Position = 0;
                    vertexBuffer = new Buffer(device, data, vertexBufferDesc);
                }
                vertexBufferBinding.Buffer = vertexBuffer;
            }
            else
            {
                lines.CopyTo(lineArray);
                using (var map = vertexBuffer.Map(MapMode.WriteDiscard))
                {
                    map.WriteRange(lineArray);
                }
                vertexBuffer.Unmap();
            }

            inputAssembler.SetVertexBuffers(0, vertexBufferBinding);
            inputAssembler.PrimitiveTopology = global::SharpDX.Direct3D.PrimitiveTopology.LineList;

            device.Draw(lines.Count, 0);

            lines.Clear();
        }
 public void OnPhysicsStep(CollisionWorld world)
 {
     Dispatcher dispatcher = world.Dispatcher;
     int numManifolds = dispatcher.NumManifolds;
     for (int i = 0; i < numManifolds; i++)
     {
         PersistentManifold contactManifold = dispatcher.GetManifoldByIndexInternal(i);
         CollisionObject a = contactManifold.Body0;
         CollisionObject b = contactManifold.Body1;
         if (a is CollisionObject && a.UserObject is BCollisionObject && ((BCollisionObject)a.UserObject).collisionCallbackEventHandler != null)
         {
             ((BCollisionObject)a.UserObject).collisionCallbackEventHandler.OnVisitPersistentManifold(contactManifold);
         }
         if (b is CollisionObject && b.UserObject is BCollisionObject && ((BCollisionObject)b.UserObject).collisionCallbackEventHandler != null)
         {
             ((BCollisionObject)b.UserObject).collisionCallbackEventHandler.OnVisitPersistentManifold(contactManifold);
         }
     }
     foreach (BCollisionObject.BICollisionCallbackEventHandler coeh in collisionCallbackListeners)
     {
         if (coeh != null) coeh.OnFinishedVisitingManifolds();
     }
 }
        public void PreStep(CollisionWorld collisionWorld)
        {
            int numPenetrationLoops = 0;
            m_touchingContact = false;
            while (RecoverFromPenetration(collisionWorld))
            {
                numPenetrationLoops++;
                m_touchingContact = true;
                if (numPenetrationLoops > 4)
                {
                    //			printf("character could not recover from penetration = %d\n", numPenetrationLoops);
                    break;
                }
            }

            m_currentPosition = m_ghostObject.WorldTransform.Origin;
            m_targetPosition = m_currentPosition;

        }
        public void Reset(CollisionWorld collisionWorld)
        {
            m_verticalVelocity = 0.0f;
            m_verticalOffset = 0.0f;
            m_wasOnGround = false;
            m_wasJumping = false;
            m_walkDirection = Vector3.Zero;
            m_velocityTimeInterval = 0.0f;

            //clear pair cache
            HashedOverlappingPairCache cache = m_ghostObject.OverlappingPairCache;
            while (cache.OverlappingPairArray.Count > 0)
            {
                cache.RemoveOverlappingPair(cache.OverlappingPairArray[0].Proxy0, cache.OverlappingPairArray[0].Proxy1, collisionWorld.Dispatcher);
            }
        }
 ///btActionInterface interface
 public virtual void UpdateAction(CollisionWorld collisionWorld, float deltaTime)
 {
     PreStep(collisionWorld);
     PlayerStep(collisionWorld, deltaTime);
 }
        protected void StepDown(CollisionWorld collisionWorld, float dt)
        {
            Matrix start, end, end_double;
            bool runonce = false;

            // phase 3: down
            /*float additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
            btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + additionalDownStep);
            float downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt;
            btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity; 
            m_targetPosition -= (step_drop + gravity_drop);*/

            Vector3 orig_position = m_targetPosition;

            float downVelocity = (m_verticalVelocity < 0.0f ? -m_verticalVelocity : 0.0f) * dt;
            if (downVelocity > 0.0 && downVelocity > m_fallSpeed
                && (m_wasOnGround || !m_wasJumping))
            {
                downVelocity = m_fallSpeed;
            }

            Vector3 step_drop = upAxisDirection[m_upAxis] * (m_currentStepOffset + downVelocity);
            m_targetPosition -= step_drop;

            KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, upAxisDirection[m_upAxis], m_maxSlopeCosine);
            callback.CollisionFilterGroup = GhostObject.BroadphaseHandle.CollisionFilterGroup;
            callback.CollisionFilterMask = GhostObject.BroadphaseHandle.CollisionFilterMask;

            KinematicClosestNotMeConvexResultCallback callback2 = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, upAxisDirection[m_upAxis], m_maxSlopeCosine);
            callback2.CollisionFilterGroup = GhostObject.BroadphaseHandle.CollisionFilterGroup;
            callback2.CollisionFilterMask = GhostObject.BroadphaseHandle.CollisionFilterMask;

            while (true)
            {
                start = Matrix.Translation(m_currentPosition);
                end = Matrix.Translation(m_targetPosition);

                //set double test for 2x the step drop, to check for a large drop vs small drop
                end_double = Matrix.Translation(m_targetPosition - step_drop);

                if (m_useGhostObjectSweepTest)
                {
                    m_ghostObject.ConvexSweepTestRef(m_convexShape, ref start, ref end, callback, collisionWorld.DispatchInfo.AllowedCcdPenetration);

                    if (!callback.HasHit)
                    {
                        //test a double fall height, to see if the character should interpolate it's fall (full) or not (partial)
                        m_ghostObject.ConvexSweepTest(m_convexShape, start, end_double, callback2, collisionWorld.DispatchInfo.AllowedCcdPenetration);
                    }
                }
                else
                {
                    // this works....
                    collisionWorld.ConvexSweepTestRef(m_convexShape, ref start, ref end, callback, collisionWorld.DispatchInfo.AllowedCcdPenetration);

                    if (!callback.HasHit)
                    {
                        //test a double fall height, to see if the character should interpolate it's fall (large) or not (small)
                        m_ghostObject.ConvexSweepTest(m_convexShape, start, end_double, callback2, collisionWorld.DispatchInfo.AllowedCcdPenetration);
                    }
                }

                float downVelocity2 = (m_verticalVelocity < 0.0f ? -m_verticalVelocity : 0.0f) * dt;
                bool has_hit = false;
                if (bounce_fix == true)
                    has_hit = callback.HasHit || callback2.HasHit;
                else
                    has_hit = callback2.HasHit;

                if (downVelocity2 > 0.0f && downVelocity2 < m_stepHeight && has_hit == true && runonce == false
                            && (m_wasOnGround || !m_wasJumping))
                {
                    //redo the velocity calculation when falling a small amount, for fast stairs motion
                    //for larger falls, use the smoother/slower interpolated movement by not touching the target position

                    m_targetPosition = orig_position;
                    downVelocity = m_stepHeight;

                    Vector3 step_drop2 = upAxisDirection[m_upAxis] * (m_currentStepOffset + downVelocity);
                    m_targetPosition -= step_drop2;
                    runonce = true;
                    continue; //re-run previous tests
                }
                break;
            }

            if (callback.HasHit || runonce == true)
            {
                // we dropped a fraction of the height -> hit floor
                float fraction = (m_currentPosition.Y - callback.HitPointWorld.Y) / 2;

                //printf("hitpoint: %g - pos %g\n", callback.m_hitPointWorld.getY(), m_currentPosition.getY());

                if (bounce_fix == true)
                {
                    if (full_drop == true)
                    {
                        Vector3.Lerp(ref m_currentPosition, ref m_targetPosition, callback.ClosestHitFraction, out m_currentPosition);
                    }
                    else
                    {
                        //due to errors in the closestHitFraction variable when used with large polygons, calculate the hit fraction manually
                        Vector3.Lerp(ref m_currentPosition, ref m_targetPosition, fraction, out m_currentPosition);
                    }
                }
                else
                {
                    Vector3.Lerp(ref m_currentPosition, ref m_targetPosition, callback.ClosestHitFraction, out m_currentPosition);
                }

                full_drop = false;

                m_verticalVelocity = 0.0f;
                m_verticalOffset = 0.0f;
                m_wasJumping = false;

            }
            else
            {
                // we dropped the full height
                full_drop = true;

                if (bounce_fix == true)
                {
                    downVelocity = (m_verticalVelocity < 0.0f ? -m_verticalVelocity : 0.0f) * dt;
                    if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping))
                    {
                        m_targetPosition += step_drop; //undo previous target change
                        downVelocity = m_fallSpeed;
                        step_drop = upAxisDirection[m_upAxis] * (m_currentStepOffset + downVelocity);
                        m_targetPosition -= step_drop;
                    }
                }
                //printf("full drop - %g, %g\n", m_currentPosition.getY(), m_targetPosition.getY());

                m_currentPosition = m_targetPosition;
            }
        }
        /// <summary>
        /// update the particle emission rates depending on speed
        /// </summary>
        void OnGround(Kart kart, CollisionWorld.ClosestRayResultCallback callback)
        {
            float speed = System.Math.Abs(kart.VehicleSpeed);

            // if the kart is moving slowly, then just turn the particles completely off
            if (speed < 6) {
                if (kartSpeedStates[kart.OwnerID] != KartSpeedState.Slow) {
                    // update this if we need to
                    kartSpeedStates[kart.OwnerID] = KartSpeedState.Slow;
                    BothEmitting(kart.OwnerID, false);
                }
            }
            // if we're moving at a medium speed
            else if (speed >= 6 && speed < 30) {
                if (kartSpeedStates[kart.OwnerID] != KartSpeedState.Medium) {
                    // update this if we need to
                    kartSpeedStates[kart.OwnerID] = KartSpeedState.Medium;

                    if (callback.CollisionObject == dirtBody)
                        DirtEmitting(kart.OwnerID, true);
                    else if (callback.CollisionObject == grassBody)
                        GrassEmitting(kart.OwnerID, true);
                }

                // make some new emission rates
                float dustEmissionRate = (speed / 30) * defaultDustEmissionRate;
                float grassEmissionRate = (speed / 30) * defaultGrassEmissionRate;
                float mudEmissionRate = (speed / 30) * defaultMudEmissionRate;

                // and update the particles
                Pair<WheelHelper, WheelHelper> pair = wheelHelpers[kart.OwnerID];
                pair.first.dust.GetEmitter(0).EmissionRate = dustEmissionRate;
                pair.second.dust.GetEmitter(0).EmissionRate = dustEmissionRate;
                pair.first.grass.GetEmitter(0).EmissionRate = grassEmissionRate;
                pair.second.grass.GetEmitter(0).EmissionRate = grassEmissionRate;
                pair.first.mud.GetEmitter(0).EmissionRate = mudEmissionRate;
                pair.second.mud.GetEmitter(0).EmissionRate = mudEmissionRate;
            }
            // and if we're moving at a fast speed
            else {
                if (kartSpeedStates[kart.OwnerID] != KartSpeedState.Fast) {
                    kartSpeedStates[kart.OwnerID] = KartSpeedState.Fast;

                    // and update the particles
                    Pair<WheelHelper, WheelHelper> pair = wheelHelpers[kart.OwnerID];
                    pair.first.dust.GetEmitter(0).EmissionRate = defaultDustEmissionRate;
                    pair.second.dust.GetEmitter(0).EmissionRate = defaultDustEmissionRate;
                    pair.first.grass.GetEmitter(0).EmissionRate = defaultGrassEmissionRate;
                    pair.second.grass.GetEmitter(0).EmissionRate = defaultGrassEmissionRate;
                    pair.first.mud.GetEmitter(0).EmissionRate = defaultMudEmissionRate;
                    pair.second.mud.GetEmitter(0).EmissionRate = defaultMudEmissionRate;
                }
            }
        }
        public void Cast(CollisionWorld cw)
        {
            for (int i = 0; i < NUMRAYS_IN_BAR; i++)
            {
                using (var cb = new ClosestConvexResultCallback(ref source[i], ref dest[i]))
                {
                    Quaternion qFrom = Quaternion.RotationAxis(new Vector3(1.0f, 0.0f, 0.0f), 0.0f);
                    Quaternion qTo = Quaternion.RotationAxis(new Vector3(1.0f, 0.0f, 0.0f), 0.7f);
                    Matrix from = Matrix.RotationQuaternion(qFrom) * Matrix.Translation(source[i]);
                    Matrix to = Matrix.RotationQuaternion(qTo) * Matrix.Translation(dest[i]);
                    cw.ConvexSweepTestRef(boxShape, ref from, ref to, cb);
                    if (cb.HasHit)
                    {
                        hit_surface[i] = cb.HitPointWorld;
                        hit_com[i] = Vector3.Lerp(source[i], dest[i], cb.ClosestHitFraction);
                        hit_fraction[i] = cb.ClosestHitFraction;
                        normal[i] = cb.HitNormalWorld;
                        normal[i].Normalize();
                    }
                    else
                    {
                        hit_com[i] = dest[i];
                        hit_surface[i] = dest[i];
                        hit_fraction[i] = 1.0f;
                        normal[i] = new Vector3(1.0f, 0.0f, 0.0f);
                    }
                }
            }

            frame_counter++;
            if (frame_counter > 50)
            {
                min_ms = ms < min_ms ? ms : min_ms;
                max_ms = ms > max_ms ? ms : max_ms;
                sum_ms += ms;
                sum_ms_samples++;
                float mean_ms = (float)sum_ms / (float)sum_ms_samples;
                Console.WriteLine("{0} rays in {1} ms {2} {3} {4}", NUMRAYS_IN_BAR * frame_counter, ms, min_ms, max_ms, mean_ms);
                ms = 0;
                frame_counter = 0;
            }
        }
        /*
        Does not set any local variables. Is safe to use to create duplicate physics worlds for independant simulation.
        */
        public bool CreatePhysicsWorld( out CollisionWorld world, 
            out CollisionConfiguration collisionConfig,
            out CollisionDispatcher dispatcher,
            out BroadphaseInterface broadphase,
            out SequentialImpulseConstraintSolver solver,
            out SoftBodyWorldInfo softBodyWorldInfo)
        {
            bool success = true;
            if (m_worldType == WorldType.SoftBodyAndRigidBody && m_collisionType == CollisionConfType.DefaultDynamicsWorldCollisionConf)
            {
                BDebug.LogError(debugType, "For World Type = SoftBodyAndRigidBody collisionType must be collisionType=SoftBodyRigidBodyCollisionConf. Switching");
                m_collisionType = CollisionConfType.SoftBodyRigidBodyCollisionConf;
                success = false;
            }

            collisionConfig = null;
            if (m_collisionType == CollisionConfType.DefaultDynamicsWorldCollisionConf)
            {
                collisionConfig = new DefaultCollisionConfiguration();
            }
            else if (m_collisionType == CollisionConfType.SoftBodyRigidBodyCollisionConf)
            {
                collisionConfig = new SoftBodyRigidBodyCollisionConfiguration();
            }

            dispatcher = new CollisionDispatcher(collisionConfig);

            if (m_broadphaseType == BroadphaseType.DynamicAABBBroadphase)
            {
                broadphase = new DbvtBroadphase();
            }
            else if (m_broadphaseType == BroadphaseType.Axis3SweepBroadphase)
            {
                broadphase = new AxisSweep3(m_axis3SweepBroadphaseMin.ToBullet(), m_axis3SweepBroadphaseMax.ToBullet(), axis3SweepMaxProxies);
            }
            else if (m_broadphaseType == BroadphaseType.Axis3SweepBroadphase_32bit)
            {
                broadphase = new AxisSweep3_32Bit(m_axis3SweepBroadphaseMin.ToBullet(), m_axis3SweepBroadphaseMax.ToBullet(), axis3SweepMaxProxies);
            }
            else
            {
                broadphase = null;
            }
            world = null;
            softBodyWorldInfo = null;
            solver = null;
            if (m_worldType == WorldType.CollisionOnly)
            {
                world = new CollisionWorld(dispatcher, broadphase, collisionConfig);
            }
            else if (m_worldType == WorldType.RigidBodyDynamics)
            {
                world = new DiscreteDynamicsWorld(dispatcher, broadphase, null, collisionConfig);
            }
            else if (m_worldType == WorldType.MultiBodyWorld)
            {
                world = new MultiBodyDynamicsWorld(dispatcher, broadphase, null, collisionConfig);
            }
            else if (m_worldType == WorldType.SoftBodyAndRigidBody)
            {
                solver = new SequentialImpulseConstraintSolver();
                solver.RandSeed = sequentialImpulseConstraintSolverRandomSeed;
                softBodyWorldInfo = new SoftBodyWorldInfo
                {
                    AirDensity = 1.2f,
                    WaterDensity = 0,
                    WaterOffset = 0,
                    WaterNormal = BulletSharp.Math.Vector3.Zero,
                    Gravity = UnityEngine.Physics.gravity.ToBullet(),
                    Dispatcher = dispatcher,
                    Broadphase = broadphase
                };
                softBodyWorldInfo.SparseSdf.Initialize();

                world = new SoftRigidDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);

                world.DispatchInfo.EnableSpu = true;
                softBodyWorldInfo.SparseSdf.Reset();
                softBodyWorldInfo.AirDensity = 1.2f;
                softBodyWorldInfo.WaterDensity = 0;
                softBodyWorldInfo.WaterOffset = 0;
                softBodyWorldInfo.WaterNormal = BulletSharp.Math.Vector3.Zero;
                softBodyWorldInfo.Gravity = m_gravity.ToBullet();
            }
            if (world is DiscreteDynamicsWorld)
            {
                ((DiscreteDynamicsWorld)world).Gravity = m_gravity.ToBullet();
            }
            if (_doDebugDraw)
            {
                DebugDrawUnity db = new DebugDrawUnity();
                db.DebugMode = _debugDrawMode;
                world.DebugDrawer = db;
            }
            return success;
        }
		public void BuildIslands(Dispatcher dispatcher, CollisionWorld colWorld)
		{
			btSimulationIslandManager_buildIslands(_native, dispatcher._native, colWorld._native);
		}
		public void FindUnions(Dispatcher dispatcher, CollisionWorld colWorld)
		{
			btSimulationIslandManager_findUnions(_native, dispatcher._native, colWorld._native);
		}
		public void BuildAndProcessIslands(Dispatcher dispatcher, CollisionWorld collisionWorld,
			IslandCallback callback)
		{
			btSimulationIslandManager_buildAndProcessIslands(_native, dispatcher._native,
				collisionWorld._native, callback._native);
		}
 /// <summary>
 /// turn on the appropriate particles
 /// </summary>
 void OnTouchdown(Kart kart, CollisionWorld.ClosestRayResultCallback callback)
 {
     if (kart.VehicleSpeed > 4f || kart.VehicleSpeed < -4f) {
         if (callback.CollisionObject == dirtBody)
             DirtEmitting(kart.OwnerID, true);
         else if (callback.CollisionObject == grassBody)
             GrassEmitting(kart.OwnerID, true);
     }
     else {
         DirtEmitting(kart.OwnerID, false);
         GrassEmitting(kart.OwnerID, false);
     }
 }
 /// <summary>
 /// turn off all particles
 /// </summary>
 void OnLiftoff(Kart kart, CollisionWorld.ClosestRayResultCallback callback)
 {
     BothEmitting(kart.OwnerID, false);
 }
        public void PlayerStep(CollisionWorld collisionWorld, float dt)
        {
            // quick check...
            if (!m_useWalkDirection && m_velocityTimeInterval <= 0.0)
            {
                //		printf("\n");
                return;		// no motion
            }

            m_wasOnGround = OnGround;

            // Update fall velocity.
            m_verticalVelocity -= Gravity * dt;
            if (m_verticalVelocity > 0.0f && m_verticalVelocity > m_jumpSpeed)
            {
                m_verticalVelocity = m_jumpSpeed;
            }
            if (m_verticalVelocity < 0.0f && System.Math.Abs(m_verticalVelocity) > System.Math.Abs(m_fallSpeed))
            {
                m_verticalVelocity = -System.Math.Abs(m_fallSpeed);
            }
            m_verticalOffset = m_verticalVelocity * dt;


            Matrix xform = m_ghostObject.WorldTransform;

            //	printf("walkDirection(%f,%f,%f)\n",walkDirection[0],walkDirection[1],walkDirection[2]);
            //	printf("walkSpeed=%f\n",walkSpeed);

            StepUp(collisionWorld);
            if (m_useWalkDirection)
            {
                StepForwardAndStrafe(collisionWorld, ref m_walkDirection);
            }
            else
            {
                //printf("  time: %f", m_velocityTimeInterval);
                // still have some time left for moving!
                float dtMoving =
                   (dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval;
                m_velocityTimeInterval -= dt;

                // how far will we move while we are moving?
                Vector3 move = m_walkDirection * dtMoving;

                // printf("  dtMoving: %f", dtMoving);

                // okay, step
                StepForwardAndStrafe(collisionWorld, ref move);
            }
            StepDown(collisionWorld, dt);

            xform.Origin = m_currentPosition;
            m_ghostObject.WorldTransform = xform;
        }
        protected void Dispose(bool disposing)
        {
            if (debugType >= BDebug.DebugType.Debug) Debug.Log("BDynamicsWorld Disposing physics.");

            if (lateUpdateHelper != null)
            {
                lateUpdateHelper.m_ddWorld = null;
                lateUpdateHelper.m_world = null;
            }
            if (m_world != null)
            {
                //remove/dispose constraints
                int i;
                if (_ddWorld != null)
                {
                    if (debugType >= BDebug.DebugType.Debug) Debug.LogFormat("Removing Constraints {0}", _ddWorld.NumConstraints);
                    for (i = _ddWorld.NumConstraints - 1; i >= 0; i--)
                    {
                        TypedConstraint constraint = _ddWorld.GetConstraint(i);
                        _ddWorld.RemoveConstraint(constraint);
                        if (constraint.Userobject is BTypedConstraint) ((BTypedConstraint)constraint.Userobject).m_isInWorld = false;
                        if (debugType >= BDebug.DebugType.Debug) Debug.LogFormat("Removed Constaint {0}", constraint.Userobject);
                        constraint.Dispose();
                    }
                }

                if (debugType >= BDebug.DebugType.Debug) Debug.LogFormat("Removing Collision Objects {0}", _ddWorld.NumCollisionObjects);
                //remove the rigidbodies from the dynamics world and delete them
                for (i = m_world.NumCollisionObjects - 1; i >= 0; i--)
                {
                    CollisionObject obj = m_world.CollisionObjectArray[i];
                    RigidBody body = obj as RigidBody;
                    if (body != null && body.MotionState != null)
                    {
                        Debug.Assert(body.NumConstraintRefs == 0, "Rigid body still had constraints");
                        body.MotionState.Dispose();
                    }
                    m_world.RemoveCollisionObject(obj);
                    if (obj.UserObject is BCollisionObject) ((BCollisionObject)obj.UserObject).isInWorld = false;
                    if (debugType >= BDebug.DebugType.Debug) Debug.LogFormat("Removed CollisionObject {0}", obj.UserObject);
                    obj.Dispose();
                }

                if (m_world.DebugDrawer != null)
                {
                    if (m_world.DebugDrawer is IDisposable)
                    {
                        IDisposable dis = (IDisposable)m_world.DebugDrawer;
                        dis.Dispose();
                    }
                }

                m_world.Dispose();
                Broadphase.Dispose();
                Dispatcher.Dispose();
                CollisionConf.Dispose();
                _ddWorld = null;
                m_world = null;
            }

            if (Broadphase != null)
            {
                Broadphase.Dispose();
                Broadphase = null;
            }
            if (Dispatcher != null)
            {
                Dispatcher.Dispose();
                Dispatcher = null;
            }
            if (CollisionConf != null)
            {
                CollisionConf.Dispose();
                CollisionConf = null;
            }
            if (Solver != null)
            {
                Solver.Dispose();
                Solver = null;
            }
            if (softBodyWorldInfo != null)
            {
                softBodyWorldInfo.Dispose();
                softBodyWorldInfo = null;
            }
            _isDisposed = true;
            singleton = null;
        }
        protected void StepUp(CollisionWorld collisionWorld)
        {
            // phase 1: up
            Matrix start, end;
            m_targetPosition = m_currentPosition + upAxisDirection[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0.0f ? m_verticalOffset : 0.0f));

            /* FIXME: Handle penetration properly */
            start = Matrix.Translation(m_currentPosition + upAxisDirection[m_upAxis] * (m_convexShape.Margin + m_addedMargin));
            end = Matrix.Translation(m_targetPosition);

            KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, -upAxisDirection[m_upAxis], 0.7071f);
            callback.CollisionFilterGroup = GhostObject.BroadphaseHandle.CollisionFilterGroup;
            callback.CollisionFilterMask = GhostObject.BroadphaseHandle.CollisionFilterMask;

            if (m_useGhostObjectSweepTest)
            {
                m_ghostObject.ConvexSweepTestRef(m_convexShape, ref start, ref end, callback, collisionWorld.DispatchInfo.AllowedCcdPenetration);
            }
            else
            {
                collisionWorld.ConvexSweepTestRef(m_convexShape, ref start, ref end, callback, 0f);
            }

            if (callback.HasHit)
            {
                // Only modify the position if the hit was a slope and not a wall or ceiling.
                if (Vector3.Dot(callback.HitNormalWorld, upAxisDirection[m_upAxis]) > 0.0)
                {
                    // we moved up only a fraction of the step height
                    m_currentStepOffset = m_stepHeight * callback.ClosestHitFraction;
                    if (m_interpolateUp)
                    {
                        Vector3.Lerp(ref m_currentPosition, ref m_targetPosition, callback.ClosestHitFraction, out m_currentPosition);
                    }
                    else
                    {
                        m_currentPosition = m_targetPosition;
                    }
                }
                m_verticalVelocity = 0.0f;
                m_verticalOffset = 0.0f;
            }
            else
            {
                m_currentStepOffset = m_stepHeight;
                m_currentPosition = m_targetPosition;
            }

        }
Esempio n. 23
0
 public void UpdateAction(CollisionWorld collisionWorld, float deltaTimeStep)
 {
     Updated = true;
 }
        public void Cast(CollisionWorld cw)
        {
            #if BATCH_RAYCASTER
            if (!gBatchRaycaster)
                return;

            gBatchRaycaster->clearRays ();
            for (int i = 0; i < NUMRAYS_IN_BAR; i++)
            {
                gBatchRaycaster->addRay (source[i], dest[i]);
            }
            gBatchRaycaster->performBatchRaycast ();
            for (int i = 0; i < gBatchRaycaster->getNumRays (); i++)
            {
                    const SpuRaycastTaskWorkUnitOut& out = (*gBatchRaycaster)[i];
                    hit[i].setInterpolate3(source[i],dest[i],out.HitFraction);
                    normal[i] = out.hitNormal;
                    normal[i].Normalize();
            }
            #else
            for (int i = 0; i < NUMRAYS_IN_BAR; i++)
            {
                using (var cb = new ClosestRayResultCallback(ref source[i], ref dest[i]))
                {
                    cw.RayTest(ref source[i], ref dest[i], cb);
                    if (cb.HasHit)
                    {
                        hit[i] = cb.HitPointWorld;
                        normal[i] = cb.HitNormalWorld;
                        normal[i].Normalize();
                    }
                    else
                    {
                        hit[i] = dest[i];
                        normal[i] = new Vector3(1.0f, 0.0f, 0.0f);
                    }
                }
            }

            frame_counter++;
            if (frame_counter > 50)
            {
                min_ms = ms < min_ms ? ms : min_ms;
                max_ms = ms > max_ms ? ms : max_ms;
                sum_ms += ms;
                sum_ms_samples++;
                float mean_ms = (float)sum_ms / (float)sum_ms_samples;
                Console.WriteLine("{0} rays in {1} ms {2} {3} {4}", NUMRAYS_IN_BAR * frame_counter, ms, min_ms, max_ms, mean_ms);
                ms = 0;
                frame_counter = 0;
            }
            #endif
        }
        protected bool RecoverFromPenetration(CollisionWorld collisionWorld)
        {
            Vector3 minAabb, maxAabb;
            m_convexShape.GetAabb(m_ghostObject.WorldTransform, out minAabb, out maxAabb);
            collisionWorld.Broadphase.SetAabbRef(m_ghostObject.BroadphaseHandle,
                         ref minAabb,
                         ref maxAabb,
                         collisionWorld.Dispatcher);

            bool penetration = false;

            collisionWorld.Dispatcher.DispatchAllCollisionPairs(m_ghostObject.OverlappingPairCache, collisionWorld.DispatchInfo, collisionWorld.Dispatcher);

            m_currentPosition = m_ghostObject.WorldTransform.Origin;

            float maxPen = 0f;
            for (int i = 0; i < m_ghostObject.OverlappingPairCache.NumOverlappingPairs; i++)
            {
                m_manifoldArray.Clear();

                BroadphasePair collisionPair = m_ghostObject.OverlappingPairCache.OverlappingPairArray[i];

                CollisionObject obj0 = collisionPair.Proxy0.ClientObject as CollisionObject;
                CollisionObject obj1 = collisionPair.Proxy1.ClientObject as CollisionObject;

                if ((obj0 != null && !obj0.HasContactResponse) || (obj1 != null && !obj1.HasContactResponse))
                    continue;

                if (collisionPair.Algorithm != null)
                {
                    collisionPair.Algorithm.GetAllContactManifolds(m_manifoldArray);
                }

                for (int j = 0; j < m_manifoldArray.Count; j++)
                {
                    PersistentManifold manifold = m_manifoldArray[j];
                    float directionSign = manifold.Body0 == m_ghostObject ? -1f : 1f;
                    for (int p = 0; p < manifold.NumContacts; p++)
                    {
                        ManifoldPoint pt = manifold.GetContactPoint(p);

                        float dist = pt.Distance;

                        if (dist < 0.0f)
                        {
                            if (dist < maxPen)
                            {
                                maxPen = dist;
                                m_touchingNormal = pt.NormalWorldOnB * directionSign;//??

                            }
                            m_currentPosition += pt.NormalWorldOnB * directionSign * dist * 0.2f;
                            penetration = true;
                        }
                        else
                        {
                            //printf("touching %f\n", dist);
                        }
                    }

                    //manifold.ClearManifold();
                }
            }
            Matrix newTrans = m_ghostObject.WorldTransform;
            newTrans.Origin = m_currentPosition;
            m_ghostObject.WorldTransform = newTrans;
            //	printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);
            return penetration;
        }
		public void StoreIslandActivationState(CollisionWorld world)
		{
			btSimulationIslandManager_storeIslandActivationState(_native, world._native);
		}
Esempio n. 27
0
 void OnTouchdown(Kart kart, CollisionWorld.ClosestRayResultCallback callback)
 {
     particles[kart].Emitting = true;
     waitDict[kart] = false;
 }
Esempio n. 28
0
 public void UpdateAction(CollisionWorld collisionWorld, float deltaTimeStep)
 {
     UpdateVehicle(deltaTimeStep);
 }
		public void UpdateActivationState(CollisionWorld colWorld, Dispatcher dispatcher)
		{
			btSimulationIslandManager_updateActivationState(_native, colWorld._native,
				dispatcher._native);
		}
Esempio n. 30
0
        /// <inheritdoc/>
        void System.IDisposable.Dispose()
        {
            if (wld != null) {
                foreach (var obj in wld.CollisionObjectArray.ToArray()) {
                    var col = obj as BulletSharp.CollisionObject;
                    wld.RemoveCollisionObject (col);
                    col.Dispose ();
                }

                wld.Dispose ();
                this.wld = null;
            }
        }
        protected void StepForwardAndStrafe(CollisionWorld collisionWorld, ref Vector3 walkMove)
        {
            //	printf("originalDir=%f,%f,%f\n",originalDir[0],originalDir[1],originalDir[2]);
            // phase 2: forward and strafe
            Matrix start = Matrix.Identity, end = Matrix.Identity;
            m_targetPosition = m_currentPosition + walkMove;

            float fraction = 1.0f;
            float distance2 = (m_currentPosition - m_targetPosition).LengthSquared;
            //	printf("distance2=%f\n",distance2);

            if (m_touchingContact)
            {
                float dot;
                Vector3.Dot(ref m_normalizedDirection, ref m_touchingNormal, out dot);
                if (dot > 0.0f)
                {
                    //interferes with step movement
                    //UpdateTargetPositionBasedOnCollision(ref m_touchingNormal, 0.0f, 1.0f);
                }
            }

            int maxIter = 10;

            while (fraction > 0.01f && maxIter-- > 0)
            {
                start.Origin = (m_currentPosition);
                end.Origin = (m_targetPosition);

                Vector3 sweepDirNegative = m_currentPosition - m_targetPosition;

                KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, sweepDirNegative, 0f);
                callback.CollisionFilterGroup = GhostObject.BroadphaseHandle.CollisionFilterGroup;
                callback.CollisionFilterMask = GhostObject.BroadphaseHandle.CollisionFilterMask;


                float margin = m_convexShape.Margin;
                m_convexShape.Margin = margin + m_addedMargin;


                if (m_useGhostObjectSweepTest)
                {
                    m_ghostObject.ConvexSweepTestRef(m_convexShape, ref start, ref end, callback, collisionWorld.DispatchInfo.AllowedCcdPenetration);
                }
                else
                {
                    collisionWorld.ConvexSweepTestRef(m_convexShape, ref start, ref end, callback, collisionWorld.DispatchInfo.AllowedCcdPenetration);
                }

                m_convexShape.Margin = margin;


                fraction -= callback.ClosestHitFraction;

                if (callback.HasHit)
                {
                    // we moved only a fraction
                    float hitDistance = (callback.HitPointWorld - m_currentPosition).Length;

                    Vector3 hitNormalWorld = callback.HitNormalWorld;
                    UpdateTargetPositionBasedOnCollision(ref hitNormalWorld, 0f, 1f);
                    Vector3 currentDir = m_targetPosition - m_currentPosition;
                    distance2 = currentDir.LengthSquared;
                    if (distance2 > MathUtil.SIMD_EPSILON)
                    {
                        currentDir.Normalize();
                        /* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
                        float dot;
                        Vector3.Dot(ref currentDir, ref m_normalizedDirection, out dot);
                        if (dot <= 0.0f)
                        {
                            break;
                        }
                    }
                    else
                    {
                        //				printf("currentDir: don't normalize a zero vector\n");
                        break;
                    }
                }
                else
                {
                    // we moved whole way
                    m_currentPosition = m_targetPosition;
                }

                //	if (callback.m_closestHitFraction == 0.f)
                //		break;

            }

        }