aboutsummaryrefslogtreecommitdiff
path: root/Client/Source/Phy2DLite/Arbiter.h
blob: 167978f166e83e5758cc3f47cc1e4a27108392d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#pragma once

#include "Math.h"
#include "Constants.h"

namespace Phy2D
{

    struct Body;

    union FeaturePair
    {
        struct Edges
        {
            char inEdge1;
            char outEdge1;
            char inEdge2;
            char outEdge2;
        } e;
        int value;
    };

    struct Contact
    {
        Contact() : Pn(_0), Pt(_0), Pnb(_0) {}

        Vec2 position;
        Vec2 normal;
        Vec2 r1, r2;
        number separation;
        number Pn;	// accumulated normal impulse
        number Pt;	// accumulated tangent impulse
        number Pnb;	// accumulated normal impulse for position bias
        number massNormal, massTangent;
        number bias;
        FeaturePair feature;
    };

    struct ArbiterKey
    {
        ArbiterKey(Body* b1, Body* b2)
        {
            if (b1 < b2)
            {
                body1 = b1; body2 = b2;
            }
            else
            {
                body1 = b2; body2 = b1;
            }
        }

        Body* body1;
        Body* body2;
    };

    struct Arbiter
    {
        enum { MAX_POINTS = 2 };

        Arbiter(Body* b1, Body* b2);

        void Update(Contact* contacts, int numContacts);

        void PreStep(number inv_dt);
        void ApplyImpulse();

        Contact contacts[MAX_POINTS];
        int numContacts;

        Body* body1;
        Body* body2;

        // Combined friction
        number friction;
    };

    // This is used by std::set
    inline bool operator < (const ArbiterKey& a1, const ArbiterKey& a2)
    {
        if (a1.body1 < a2.body1)
            return true;

        if (a1.body1 == a2.body1 && a1.body2 < a2.body2)
            return true;

        return false;
    }

    int Collide(Contact* contacts, Body* body1, Body* body2);

}