imstkCollisionDetection.cpp 6.91 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
33

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

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

40
41
namespace imstk
{
Alexis Girault's avatar
Alexis Girault committed
42
std::shared_ptr<CollisionDetection>
43
44
45
46
CollisionDetection::makeCollisionDetectionObject(const Type& type,
                                                 std::shared_ptr<CollidingObject> objA,
                                                 std::shared_ptr<CollidingObject> objB,
                                                 CollisionData &colData)
Alexis Girault's avatar
Alexis Girault committed
47
{
48
49
    switch (type)
    {
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    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;
65
    case Type::BidirectionalPlaneToSphere:
66
    {
67
68
69
70
71
        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)
72
73
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
74
                         << "invalid object geometries for BidirectionalPlaneToSphere collision detection.";
75
76
            return nullptr;
        }
77
        return std::make_shared<BidirectionalPlaneToSphere>(plane, sphere, colData);
78
79
    }
    break;
80
81
    case Type::SphereToSphere:
    {
82
83
84
85
86
        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)
87
88
89
90
91
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
                         << "invalid object geometries for SphereToSphere collision detection.";
            return nullptr;
        }
92
        return std::make_shared<SphereToSphereCD>(sphereA, sphereB, colData);
93
94
    }
    break;
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    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;
110
    case Type::PointSetToSphere:
111
    {
112
        auto mesh = std::dynamic_pointer_cast<PointSet>(objA->getCollidingGeometry());
113
114
115
116
117
118
        auto sphere = std::dynamic_pointer_cast<Sphere>(objB->getCollidingGeometry());

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

        // Geometries check
        if (mesh == nullptr || plane == nullptr)
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
134
                         << "invalid object geometries for SphereToSphere collision detection.";
135
136
            return nullptr;
        }
137
        return std::make_shared<PointSetToPlaneCD>(mesh, plane, colData);
138
139
    }
    break;
140
141
    case Type::MeshToMesh:
    {
142
143
144
145
146
        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)
147
148
149
150
151
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
                         << "invalid object geometries for MeshToMesh collision detection.";
            return nullptr;
        }
152
        return std::make_shared<MeshToMeshCD>(meshA, meshB, colData);
153
154
    }
    break;
155
    case Type::PointSetToSpherePicking:
156
    {
157
        auto mesh = std::dynamic_pointer_cast<PointSet>(objA->getCollidingGeometry());
158
159
160
161
162
163
        auto sphere = std::dynamic_pointer_cast<Sphere>(objB->getCollidingGeometry());

        // Geometries check
        if (mesh == nullptr || sphere == nullptr)
        {
            LOG(WARNING) << "CollisionDetection::make_collision_detection error: "
164
                         << "invalid object geometries for SphereToSphere collision detection.";
165
166
            return nullptr;
        }
167
        return std::make_shared<PointSetToSpherePickingCD>(mesh, sphere, colData);
168
169
    }
    break;
170
171
172
173
174
175
    default:
    {
        LOG(WARNING) << "CollisionDetection::make_collision_detection error: type not implemented.";
        return nullptr;
    }
    }
Alexis Girault's avatar
Alexis Girault committed
176
177
}

178
179
180
181
182
const CollisionDetection::Type&
CollisionDetection::getType() const
{
    return m_type;
}
183
184
185
186
187
188

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