summaryrefslogtreecommitdiff
path: root/src/BulletSoftBody/btCGProjection.h
blob: 6c104ef2feeef2eecd1d8d7dd6aa0498189e292c (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//  btCGProjection.h
//  BulletSoftBody
//
//  Created by Xuchen Han on 7/4/19.
//

#ifndef BT_CG_PROJECTION_H
#define BT_CG_PROJECTION_H

#include "btSoftBody.h"
#include <unordered_map>

class btDeformableRigidDynamicsWorld;

struct Constraint
{
    const btSoftBody::RContact* m_contact;
    btVector3 m_direction;
    btScalar m_value;
    
    Constraint(const btSoftBody::RContact& rcontact)
    : m_contact(&rcontact)
    , m_direction(rcontact.m_cti.m_normal)
    , m_value(0)
    {
    }
    
    Constraint(const btVector3 dir)
    : m_contact(nullptr)
    , m_direction(dir)
    , m_value(0)
    {}
    
    Constraint()
    : m_contact(nullptr)
    {
        
    }
};

struct Friction
{
    btVector3 m_dv;
    btVector3 m_direction;
    Friction()
    {
        m_dv.setZero();
        m_direction.setZero();
    }
};

class btCGProjection
{
public:
//    static const int dim = 3;
    using TVStack = btAlignedObjectArray<btVector3>;
    using TVArrayStack = btAlignedObjectArray<btAlignedObjectArray<btVector3> >;
    using TArrayStack = btAlignedObjectArray<btAlignedObjectArray<btScalar> >;
    btAlignedObjectArray<btSoftBody *> m_softBodies;
    btDeformableRigidDynamicsWorld* m_world;
    std::unordered_map<btSoftBody::Node *, size_t> m_indices;
    const btScalar& m_dt;
    std::unordered_map<btSoftBody::Node *, btAlignedObjectArray<Constraint> > m_constraints;
    std::unordered_map<btSoftBody::Node *, Friction > m_frictions;
    
    btCGProjection(btAlignedObjectArray<btSoftBody *>& softBodies, const btScalar& dt)
    : m_softBodies(softBodies)
    , m_dt(dt)
    {
    }
    
    virtual ~btCGProjection()
    {
    }
    
    // apply the constraints
    virtual void operator()(TVStack& x) = 0;
    
    virtual void setConstraintDirections() = 0;
    
    // update the constraints
    virtual void update(const TVStack& dv, const TVStack& backup_v) = 0;
    
    virtual void reinitialize(bool nodeUpdated)
    {
        if (nodeUpdated)
            updateId();
        m_constraints.clear();
        m_frictions.clear();
    }
    
    void updateId()
    {
        size_t index = 0;
        m_indices.clear();
        for (int i = 0; i < m_softBodies.size(); ++i)
        {
            btSoftBody* psb = m_softBodies[i];
            for (int j = 0; j < psb->m_nodes.size(); ++j)
            {
                m_indices[&(psb->m_nodes[j])] = index++;
            }
        }
    }
    
    void setSoftBodies(btAlignedObjectArray<btSoftBody* > softBodies)
    {
        m_softBodies.copyFromArray(softBodies);
    }
    
    virtual void setWorld(btDeformableRigidDynamicsWorld* world)
    {
        m_world = world;
    }
};


#endif /* btCGProjection_h */