imstkCollisionDetection.cpp 7.59 KB
Newer Older
Alexis Girault's avatar
Alexis Girault committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*=========================================================================

   Library: iMSTK

   Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
   & Imaging in Medicine, Rensselaer Polytechnic Institute.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

20
=========================================================================*/
Alexis Girault's avatar
Alexis Girault committed
21
22
23

#include "imstkCollisionDetection.h"

24
#include "imstkUnidirectionalPlaneToSphereCD.h"
25
#include "imstkBidirectionalPlaneToSphereCD.h"
26
#include "imstkSphereToSphereCD.h"
27
28
#include "imstkPointSetToSphereCD.h"
#include "imstkPointSetToPlaneCD.h"
29
#include "imstkMeshToMeshCD.h"
30
#include "imstkSphereCylinderCD.h"
31
#include "imstkPointSetToSpherePickingCD.h"
32
#include "imstkMeshToMeshBruteForceCD.h"
33
34

#include "imstkCollidingObject.h"
35
36
37
#include "imstkPlane.h"
#include "imstkSphere.h"
#include "imstkSurfaceMesh.h"
38

Alexis Girault's avatar
Alexis Girault committed
39
40
#include <g3log/g3log.hpp>

41
42
namespace imstk
{
Alexis Girault's avatar
Alexis Girault committed
43
std::shared_ptr<CollisionDetection>
44
45
46
47
CollisionDetection::makeCollisionDetectionObject(const Type& type,
                                                 std::shared_ptr<CollidingObject> objA,
                                                 std::shared_ptr<CollidingObject> objB,
                                                 CollisionData &colData)
Alexis Girault's avatar
Alexis Girault committed
48
{
49
50
    switch (type)
    {
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
    case Type::UnidirectionalPlaneToSphere:
    {
        auto plane = std::dynamic_pointer_cast<Plane>(objA->getCollidingGeometry());
        auto sphere = std::dynamic_pointer_cast<Sphere>(objB->getCollidingGeometry());

        // Geometries check
        if (plane == nullptr || sphere == nullptr)
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
                         << "invalid object geometries for UnidirectionalPlaneToSphere collision detection.";
            return nullptr;
        }
        return std::make_shared<UnidirectionalPlaneToSphereCD>(plane, sphere, colData);
    }
    break;
66
    case Type::BidirectionalPlaneToSphere:
67
    {
68
69
70
71
72
        auto plane = std::dynamic_pointer_cast<Plane>(objA->getCollidingGeometry());
        auto sphere = std::dynamic_pointer_cast<Sphere>(objB->getCollidingGeometry());

        // Geometries check
        if (plane == nullptr || sphere == nullptr)
73
74
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
75
                         << "invalid object geometries for BidirectionalPlaneToSphere collision detection.";
76
77
            return nullptr;
        }
78
        return std::make_shared<BidirectionalPlaneToSphere>(plane, sphere, colData);
79
80
    }
    break;
81
82
    case Type::SphereToSphere:
    {
83
84
85
86
87
        auto sphereA = std::dynamic_pointer_cast<Sphere>(objA->getCollidingGeometry());
        auto sphereB = std::dynamic_pointer_cast<Sphere>(objB->getCollidingGeometry());

        // Geometries check
        if (sphereA == nullptr || sphereB == nullptr)
88
89
90
91
92
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
                         << "invalid object geometries for SphereToSphere collision detection.";
            return nullptr;
        }
93
        return std::make_shared<SphereToSphereCD>(sphereA, sphereB, colData);
94
95
    }
    break;
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    case Type::SphereToCylinder:
    {
        auto sphere = std::dynamic_pointer_cast<Sphere>(objB->getCollidingGeometry());
        auto cylinder = std::dynamic_pointer_cast<Cylinder>(objA->getCollidingGeometry());

        // Geometries check
        if (sphere == nullptr || cylinder == nullptr)
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
                         << "invalid object geometries for SphereToCylinder collision detection.";
            return nullptr;
        }
        return std::make_shared<SphereCylinderCD>(sphere, cylinder, colData);
    }
    break;
111
    case Type::PointSetToSphere:
112
    {
113
        auto mesh = std::dynamic_pointer_cast<PointSet>(objA->getCollidingGeometry());
114
115
116
117
118
119
        auto sphere = std::dynamic_pointer_cast<Sphere>(objB->getCollidingGeometry());

        // Geometries check
        if (mesh == nullptr || sphere == nullptr)
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
120
                         << "invalid object geometries for SphereToSphere collision detection.";
121
122
            return nullptr;
        }
123
        return std::make_shared<PointSetToSphereCD>(mesh, sphere, colData);
124
125
    }
    break;
126
    case Type::PointSetToPlane:
127
    {
128
        auto mesh = std::dynamic_pointer_cast<PointSet>(objA->getCollidingGeometry());
129
130
131
132
133
134
        auto plane = std::dynamic_pointer_cast<Plane>(objB->getCollidingGeometry());

        // Geometries check
        if (mesh == nullptr || plane == nullptr)
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
135
                         << "invalid object geometries for SphereToSphere collision detection.";
136
137
            return nullptr;
        }
138
        return std::make_shared<PointSetToPlaneCD>(mesh, plane, colData);
139
140
    }
    break;
141
142
    case Type::MeshToMesh:
    {
143
144
145
146
147
        auto meshA = std::dynamic_pointer_cast<SurfaceMesh>(objA->getCollidingGeometry());
        auto meshB = std::dynamic_pointer_cast<SurfaceMesh>(objB->getCollidingGeometry());

        // Geometries check
        if (meshA == nullptr || meshB == nullptr)
148
149
150
151
152
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
                         << "invalid object geometries for MeshToMesh collision detection.";
            return nullptr;
        }
153
        return std::make_shared<MeshToMeshCD>(meshA, meshB, colData);
154
155
    }
    break;
156
    case Type::PointSetToSpherePicking:
157
    {
158
        auto mesh = std::dynamic_pointer_cast<PointSet>(objA->getCollidingGeometry());
159
160
161
162
163
164
        auto sphere = std::dynamic_pointer_cast<Sphere>(objB->getCollidingGeometry());

        // Geometries check
        if (mesh == nullptr || sphere == nullptr)
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
165
                         << "invalid object geometries for SphereToSphere collision detection.";
166
167
            return nullptr;
        }
168
        return std::make_shared<PointSetToSpherePickingCD>(mesh, sphere, colData);
169
170
    }
    break;
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    case Type::MeshToMeshBruteForce:
    {
        auto geometry1 = std::dynamic_pointer_cast<Geometry>(objA->getCollidingGeometry());
        auto surfaceGeo = std::dynamic_pointer_cast<SurfaceMesh>(objB->getCollidingGeometry());

        // Geometries check
        if (geometry1 == nullptr || surfaceGeo == nullptr)
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
                << "invalid object geometries for MeshToMeshBruteForce collision detection.";
            return nullptr;
        }
        return std::make_shared<MeshToMeshBruteForceCD>(geometry1, surfaceGeo, colData);
    }
    break;
186
187
188
189
190
191
    default:
    {
        LOG(WARNING) << "CollisionDetection::make_collision_detection error: type not implemented.";
        return nullptr;
    }
    }
Alexis Girault's avatar
Alexis Girault committed
192
193
}

194
195
196
197
198
const CollisionDetection::Type&
CollisionDetection::getType() const
{
    return m_type;
}
199
200
201
202
203
204

const CollisionData&
CollisionDetection::getCollisionData() const
{
    return m_colData;
}
Alexis Girault's avatar
Alexis Girault committed
205
}