Exemplo n.º 1
0
        public override void Update(float dt)
        {
            _world.Step(dt, 8, 1);
            //_world.Step(dt, 10, 3);

            foreach (CCPhysicsSprite sprite in _batch.Children)
            {
                if (sprite.Visible && sprite.PhysicsBody.Position.y < 0f)
                {
                    _world.DestroyBody(sprite.PhysicsBody);
                    sprite.Visible = false;
                }
            }

#if WINDOWS || WINDOWSGL || LINUX || MACOS
            CCInputState.Instance.Update(dt);
            PlayerIndex p;
            if (CCInputState.Instance.IsKeyPress(Microsoft.Xna.Framework.Input.Keys.D, PlayerIndex.One, out p))
            {
                _world.Dump();
#if PROFILING
                b2Profile profile = _world.Profile;
                CCLog.Log("]-----------[{0:F4}]-----------------------[", profile.step);
                CCLog.Log("Solve Time = {0:F4}", profile.solve);
                CCLog.Log("# bodies = {0}", profile.bodyCount);
                CCLog.Log("# contacts = {0}", profile.contactCount);
                CCLog.Log("# joints = {0}", profile.jointCount);
                CCLog.Log("# toi iters = {0}", profile.toiSolverIterations);
                if (profile.step > 0f)
                {
                    CCLog.Log("Solve TOI Time = {0:F4} {1:F2}%", profile.solveTOI, profile.solveTOI / profile.step * 100f);
                    CCLog.Log("Solve TOI Advance Time = {0:F4} {1:F2}%", profile.solveTOIAdvance, profile.solveTOIAdvance / profile.step * 100f);
                }

                CCLog.Log("BroadPhase Time = {0:F4}", profile.broadphase);
                CCLog.Log("Collision Time = {0:F4}", profile.collide);
                CCLog.Log("Solve Velocity Time = {0:F4}", profile.solveVelocity);
                CCLog.Log("Solve Position Time = {0:F4}", profile.solvePosition);
                CCLog.Log("Step Time = {0:F4}", profile.step);
#endif
            }
#endif
        }
Exemplo n.º 2
0
        protected virtual void Draw(Settings settings)
        {
            m_world.DrawDebugData();

            if (settings.drawStats)
            {
                int bodyCount    = m_world.BodyCount;
                int contactCount = m_world.ContactCount;
                int jointCount   = m_world.JointCount;
                m_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints = {0}/{1}/{2}", bodyCount, contactCount,
                                       jointCount);
                m_textLine += 15;

                int   proxyCount = m_world.GetProxyCount();
                int   height     = m_world.GetTreeHeight();
                int   balance    = m_world.GetTreeBalance();
                float quality    = m_world.GetTreeQuality();
                m_debugDraw.DrawString(5, m_textLine, "proxies/height/balance/quality = {0}/{1}/{2}/{3}", proxyCount,
                                       height, balance, quality);
                m_textLine += 15;
            }
#if PROFILING
            // Track maximum profile times
            {
                b2Profile p = m_world.Profile;
                m_maxProfile.step          = Math.Max(m_maxProfile.step, p.step);
                m_maxProfile.collide       = Math.Max(m_maxProfile.collide, p.collide);
                m_maxProfile.solve         = Math.Max(m_maxProfile.solve, p.solve);
                m_maxProfile.solveInit     = Math.Max(m_maxProfile.solveInit, p.solveInit);
                m_maxProfile.solveVelocity = Math.Max(m_maxProfile.solveVelocity, p.solveVelocity);
                m_maxProfile.solvePosition = Math.Max(m_maxProfile.solvePosition, p.solvePosition);
                m_maxProfile.solveTOI      = Math.Max(m_maxProfile.solveTOI, p.solveTOI);
                m_maxProfile.broadphase    = Math.Max(m_maxProfile.broadphase, p.broadphase);

                m_totalProfile.step          += p.step;
                m_totalProfile.collide       += p.collide;
                m_totalProfile.solve         += p.solve;
                m_totalProfile.solveInit     += p.solveInit;
                m_totalProfile.solveVelocity += p.solveVelocity;
                m_totalProfile.solvePosition += p.solvePosition;
                m_totalProfile.solveTOI      += p.solveTOI;
                m_totalProfile.broadphase    += p.broadphase;
            }

            if (settings.drawProfile)
            {
                b2Profile p = m_world.Profile;

                b2Profile aveProfile = new b2Profile();
                if (m_stepCount > 0)
                {
                    float scale = 1.0f / m_stepCount;
                    aveProfile.step          = scale * m_totalProfile.step;
                    aveProfile.collide       = scale * m_totalProfile.collide;
                    aveProfile.solve         = scale * m_totalProfile.solve;
                    aveProfile.solveInit     = scale * m_totalProfile.solveInit;
                    aveProfile.solveVelocity = scale * m_totalProfile.solveVelocity;
                    aveProfile.solvePosition = scale * m_totalProfile.solvePosition;
                    aveProfile.solveTOI      = scale * m_totalProfile.solveTOI;
                    aveProfile.broadphase    = scale * m_totalProfile.broadphase;
                }

                m_debugDraw.DrawString(5, m_textLine, "step [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.step,
                                       aveProfile.step, m_maxProfile.step);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "collide [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.collide,
                                       aveProfile.collide, m_maxProfile.collide);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solve [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.solve,
                                       aveProfile.solve, m_maxProfile.solve);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solve init [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.solveInit,
                                       aveProfile.solveInit, m_maxProfile.solveInit);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solve velocity [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})",
                                       p.solveVelocity, aveProfile.solveVelocity, m_maxProfile.solveVelocity);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solve position [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})",
                                       p.solvePosition, aveProfile.solvePosition, m_maxProfile.solvePosition);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solveTOI [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.solveTOI,
                                       aveProfile.solveTOI, m_maxProfile.solveTOI);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "broad-phase [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.broadphase,
                                       aveProfile.broadphase, m_maxProfile.broadphase);
                m_textLine += 15;
            }
#endif
            if (m_mouseJoint != null)
            {
                b2Vec2 p1 = m_mouseJoint.GetAnchorB();
                b2Vec2 p2 = m_mouseJoint.GetTarget();

                b2Color c = new b2Color();
                c.Set(0.0f, 1.0f, 0.0f);
                m_debugDraw.DrawPoint(p1, 4.0f, c);
                m_debugDraw.DrawPoint(p2, 4.0f, c);

                c.Set(0.8f, 0.8f, 0.8f);
                m_debugDraw.DrawSegment(p1, p2, c);
            }

            if (m_bombSpawning)
            {
                b2Color c = new b2Color();
                c.Set(0.0f, 0.0f, 1.0f);
                m_debugDraw.DrawPoint(m_bombSpawnPoint, 4.0f, c);

                c.Set(0.8f, 0.8f, 0.8f);
                m_debugDraw.DrawSegment(m_mouseWorld, m_bombSpawnPoint, c);
            }

            if (settings.drawContactPoints)
            {
                //const float32 k_impulseScale = 0.1f;
                float k_axisScale = 0.3f;

                for (int i = 0; i < m_pointCount; ++i)
                {
                    ContactPoint point = m_points[i];

                    if (point.state == b2PointState.b2_addState)
                    {
                        // Add
                        m_debugDraw.DrawPoint(point.position, 10.0f, new b2Color(0.3f, 0.95f, 0.3f));
                    }
                    else if (point.state == b2PointState.b2_persistState)
                    {
                        // Persist
                        m_debugDraw.DrawPoint(point.position, 5.0f, new b2Color(0.3f, 0.3f, 0.95f));
                    }

                    if (settings.drawContactNormals == 1)
                    {
                        b2Vec2 p1 = point.position;
                        b2Vec2 p2 = p1 + k_axisScale * point.normal;
                        m_debugDraw.DrawSegment(p1, p2, new b2Color(0.9f, 0.9f, 0.9f));
                    }
                    else if (settings.drawContactForces == 1)
                    {
                        //b2Vec2 p1 = point->position;
                        //b2Vec2 p2 = p1 + k_forceScale * point->normalForce * point->normal;
                        //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
                    }

                    if (settings.drawFrictionForces == 1)
                    {
                        //b2Vec2 tangent = b2Cross(point->normal, 1.0f);
                        //b2Vec2 p1 = point->position;
                        //b2Vec2 p2 = p1 + k_forceScale * point->tangentForce * tangent;
                        //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
                    }
                }
            }
        }
Exemplo n.º 3
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(b2Profile obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Exemplo n.º 4
0
        public b2Profile GetProfile()
        {
            b2Profile ret = new b2Profile(Box2dPINVOKE.b2World_GetProfile(swigCPtr), false);

            return(ret);
        }
Exemplo n.º 5
0
    public void Solve(b2Profile profile, b2TimeStep step, b2Vec2 gravity, bool allowSleep)
    {
        b2Timer timer = new b2Timer();

        float h = step.dt;

        // Integrate velocities and apply damping. Initialize the body state.
        for (int i = 0; i < m_bodyCount; ++i)
        {
            b2Body b = m_bodies[i];

            b2Vec2 c = new b2Vec2(b.m_sweep.c);
            float  a = b.m_sweep.a;

            b2Vec2 v = new b2Vec2(b.m_linearVelocity);
            float  w = b.m_angularVelocity;

            // Store positions for continuous collision.
            b.m_sweep.c0 = b.m_sweep.c;
            b.m_sweep.a0 = b.m_sweep.a;

            if (b.m_type == BodyType.b2_dynamicBody)
            {
                // Integrate velocities.
                v += h * (b.m_gravityScale * gravity + b.m_invMass * b.m_force);
                w += h * b.m_invI * b.m_torque;

                // Apply damping.
                // ODE: dv/dt + c * v = 0
                // Solution: v(t) = v0 * exp(-c * t)
                // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
                // v2 = exp(-c * dt) * v1
                // Pade approximation:
                // v2 = v1 * 1 / (1 + c * dt)
                v *= 1.0f / (1.0f + h * b.m_linearDamping);
                w *= 1.0f / (1.0f + h * b.m_angularDamping);
            }

            m_positions[i].c  = c;
            m_positions[i].a  = a;
            m_velocities[i].v = v;
            m_velocities[i].w = w;
        }

        timer.Reset();

        // Solver data
        b2SolverData solverData = new b2SolverData();

        solverData.step       = step;
        solverData.positions  = m_positions;
        solverData.velocities = m_velocities;

        // Initialize velocity constraints.
        b2ContactSolverDef contactSolverDef = new b2ContactSolverDef();


        contactSolverDef.step       = step;
        contactSolverDef.contacts   = m_contacts;
        contactSolverDef.count      = m_contactCount;
        contactSolverDef.positions  = m_positions;
        contactSolverDef.velocities = m_velocities;

        b2ContactSolver contactSolver = new b2ContactSolver(contactSolverDef);

        contactSolver.InitializeVelocityConstraints();

        if (step.warmStarting)
        {
            contactSolver.WarmStart();
        }

        for (int i = 0; i < m_jointCount; ++i)
        {
            m_joints[i].InitVelocityConstraints(solverData);
        }

        profile.solveInit = timer.GetMilliseconds();

        // Solve velocity constraints
        timer.Reset();
        for (int i = 0; i < step.velocityIterations; ++i)
        {
            for (int j = 0; j < m_jointCount; ++j)
            {
                m_joints[j].SolveVelocityConstraints(solverData);
            }

            contactSolver.SolveVelocityConstraints();
        }

        // Store impulses for warm starting
        contactSolver.StoreImpulses();
        profile.solveVelocity = timer.GetMilliseconds();

        // Integrate positions
        for (int i = 0; i < m_bodyCount; ++i)
        {
            b2Vec2 c = m_positions[i].c;
            float  a = m_positions[i].a;
            b2Vec2 v = m_velocities[i].v;
            float  w = m_velocities[i].w;

            // Check for large velocities
            b2Vec2 translation = h * v;
            if (Utils.b2Dot(translation, translation) > (Settings.b2_maxTranslation * Settings.b2_maxTranslation))
            {
                float ratio = Settings.b2_maxTranslation / translation.Length();
                v *= ratio;
            }

            float rotation = h * w;
            if (rotation * rotation > Settings.b2_maxRotationSquared)
            {
                float ratio = (0.5f * Settings.b2_pi) / Utils.b2Abs(rotation);
                w *= ratio;
            }

            // Integrate
            c += h * v;
            a += h * w;

            m_positions[i].c  = c;
            m_positions[i].a  = a;
            m_velocities[i].v = v;
            m_velocities[i].w = w;
        }

        // Solve position constraints
        timer.Reset();
        bool positionSolved = false;

        for (int i = 0; i < step.positionIterations; ++i)
        {
            bool contactsOkay = contactSolver.SolvePositionConstraints();

            bool jointsOkay = true;
            for (int j = 0; j < m_jointCount; ++j)
            {
                bool jointOkay = m_joints[j].SolvePositionConstraints(solverData);
                jointsOkay = jointsOkay && jointOkay;
            }

            if (contactsOkay && jointsOkay)
            {
                // Exit early if the position errors are small.
                positionSolved = true;
                break;
            }
        }

        // Copy state buffers back to the bodies
        for (int i = 0; i < m_bodyCount; ++i)
        {
            b2Body body = m_bodies[i];
            body.m_sweep.c         = m_positions[i].c;
            body.m_sweep.a         = m_positions[i].a;
            body.m_linearVelocity  = m_velocities[i].v;
            body.m_angularVelocity = m_velocities[i].w;
            body.SynchronizeTransform();
        }

        profile.solvePosition = timer.GetMilliseconds();

        Report(contactSolver.m_velocityConstraints);

        if (allowSleep)
        {
            float minSleepTime = float.MaxValue;

            const float linTolSqr = Settings.b2_linearSleepTolerance * Settings.b2_linearSleepTolerance;
            float       angTolSqr = Settings.b2_angularSlop * Settings.b2_angularSlop;

            for (int i = 0; i < m_bodyCount; ++i)
            {
                b2Body b = m_bodies[i];
                if (b.GetType() == BodyType.b2_staticBody)
                {
                    continue;
                }

                if ((b.m_flags & b2Body.BodyFlags.e_autoSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || Utils.b2Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr)
                {
                    b.m_sleepTime = 0.0f;
                    minSleepTime  = 0.0f;
                }
                else
                {
                    b.m_sleepTime += h;
                    minSleepTime   = Utils.b2Min(minSleepTime, b.m_sleepTime);
                }
            }

            if (minSleepTime >= Settings.b2_timeToSleep && positionSolved)
            {
                for (int i = 0; i < m_bodyCount; ++i)
                {
                    b2Body b = m_bodies[i];
                    b.SetAwake(false);
                }
            }
        }
    }