Commit 78b8c37c authored by Alexis Girault's avatar Alexis Girault
Browse files

WIP: begin collision API

parent 06453757
#-----------------------------------------------------------------------------
# Create target
#-----------------------------------------------------------------------------
include(imstkAddLibrary)
imstk_add_library( Collision
DEPENDS
Scene
)
#-----------------------------------------------------------------------------
# Testing
#-----------------------------------------------------------------------------
if( iMSTK_BUILD_TESTING )
add_subdirectory( Testing )
endif()
/*=========================================================================
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.
=========================================================================*/
#ifndef imstkCollisionData_h
#define imstkCollisionData_h
#include "imstkMath.h"
namespace imstk {
struct VertexNormalCollisionData
{
size_t vertexId;
Vec3d normal;
double penetrationDepth;
};
struct VertexTriangleCollisionData
{
size_t vertexId;
size_t triangleId;
double penetrationDepth;
};
struct EdgeEdgeCollisionData
{
size_t edgeId1;
size_t edgeId2;
double shortestDistance;
};
struct CollisionData
{
std::vector<VertexNormalCollisionData> VNColData; //!< Vertex Normal collision data
std::vector<VertexTriangleCollisionData> VTColData; //!< Vertex Triangle collision data
std::vector<EdgeEdgeCollisionData> EEColData; //!< Edge Edge collision data
};
}
#endif // ifndef imstkCollisionData_h
/*=========================================================================
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.
=========================================================================*/
#ifndef imstkContactForces_h
#define imstkContactForces_h
#include "imstkMath.h"
namespace imstk {
struct ContactForces
{
std::vector<std::pair<Vec3d,Vec3d>> posForces; //!< Pairs of positions/forces (Analytic geom)
VecNd nodesForces; //!< NbrOfNodes*3 size vector of forces (Mesh)
};
}
#endif // ifndef imstkContactForces_h
/*=========================================================================
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.
=========================================================================*/
#include "imstkCollisionDetection.h"
#include <g3log/g3log.hpp>
namespace imstk {
std::shared_ptr<CollisionDetection>
CollisionDetection::make_collision_detection(const Type& type,
std::shared_ptr<CollidingObject> objA,
std::shared_ptr<CollidingObject> objB)
{
LOG(WARNING) << "CollisionDetection::make_collision_detection not implemented.";
return nullptr;
}
}
/*=========================================================================
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.
=========================================================================*/
#ifndef imstkCollisionDetection_h
#define imstkCollisionDetection_h
#include <memory>
#include "imstkCollidingObject.h"
#include "imstkCollisionData.h"
namespace imstk {
class CollidingObject;
class CollisionData;
class CollisionDetection
{
public:
enum class Type
{
PlaneToMesh,
CubeToMesh,
SphereToMesh,
MeshToMesh
};
///
/// \brief Static factory for collision detection sub classes
///
static std::shared_ptr<CollisionDetection> make_collision_detection(
const Type& type,
std::shared_ptr<CollidingObject> objA,
std::shared_ptr<CollidingObject> objB);
///
/// \brief Constructor
///
CollisionDetection(const Type& type) : m_type(type) {}
///
/// \brief Destructor
///
~CollisionDetection() = default;
///
/// \brief Detect collision and compute collision data (pure virtual)
///
virtual void computeCollisionData(std::shared_ptr<CollidingObject> objA,
std::shared_ptr<CollidingObject> objB,
CollisionData& colDataA,
CollisionData& colDataB) = 0;
///
/// \brief Returns collision detection type
///
const Type& getType() const;
protected:
Type m_type; //!< Collision detection algorithm type
};
}
#endif // ifndef imstkCollisionDetection_h
/*=========================================================================
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.
=========================================================================*/
#include "imstkCollisionHandling.h"
#include "imstkCameraController.h"
#include <g3log/g3log.hpp>
namespace imstk {
std::shared_ptr<CollisionHandling>
CollisionHandling::make_collision_handling(const Type& type,
std::shared_ptr<CollidingObject> obj)
{
LOG(WARNING) << "CollisionHandling::make_collision_handling not implemented.";
return nullptr;
}
}
/*=========================================================================
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.
=========================================================================*/
#ifndef imstkCollisionHandling_h
#define imstkCollisionHandling_h
#include <memory>
#include "imstkCollidingObject.h"
#include "imstkCollisionData.h"
#include "imstkContactForces.h"
namespace imstk {
class InteractionPair;
class CollisionHandling
{
public:
enum class Type
{
None,
LCP,
LPC,
Penalty
};
///
/// \brief Static factory for collision handling sub classes
///
static std::shared_ptr<CollisionHandling> make_collision_handling(
const Type& type,
std::shared_ptr<CollidingObject> obj);
///
/// \brief Constructor
///
CollisionHandling(const Type& type) : m_type(type) {}
///
/// \brief Destructor
///
~CollisionHandling() = default;
///
/// \brief Compute forces based on collision data (pure virtual)
///
virtual void computeContactForces(std::shared_ptr<CollidingObject> obj,
CollisionData& colData,
ContactForces& contactForces) = 0;
///
/// \brief Returns collision handling type
///
const Type& getType() const;
protected:
Type m_type; //!< Collision handling algorithm type
};
}
#endif // ifndef imstkCollisionHandling_h
/*=========================================================================
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.
=========================================================================*/
#include "imstkInteractionPair.h"
#include <g3log/g3log.hpp>
namespace imstk {
InteractionPair::InteractionPair(std::shared_ptr<CollidingObject> A,
std::shared_ptr<CollidingObject> B,
CollisionDetection::Type CDType,
CollisionHandling::Type CHAType,
CollisionHandling::Type CHBType)
{
m_valid = false;
// Check that objects exist
if (A == nullptr || B == nullptr)
{
LOG(WARNING) << "InteractionPair error: invalid objects (nullptr).";
return;
}
// Check if objects are differents
if (A == B)
{
LOG(WARNING) << "InteractionPair error: object cannot interact with itself.";
return;
}
// Check that at least one object is not static
if (A->getType() == SceneObject::Type::Static &&
B->getType() == SceneObject::Type::Static)
{
LOG(WARNING) << "InteractionPair error: can not create interaction between two static objects.";
return;
}
// Collision Detection
std::shared_ptr<CollisionDetection> CD = CollisionDetection::make_collision_detection(CDType, A, B);
if (CD == nullptr)
{
LOG(WARNING) << "InteractionPair error: can not instantiate collision detection algorithm.";
return;
}
// Collision Handling A
std::shared_ptr<CollisionHandling> CHA;
if (A->getType() != SceneObject::Type::Static)
{
CHA = CollisionHandling::make_collision_handling(CHAType, A);
if (CHA == nullptr)
{
LOG(WARNING) << "InteractionPair error: can not instantiate collision handling for object A.";
return;
}
}
// Collision Handling B
std::shared_ptr<CollisionHandling> CHB;
if (B->getType() != SceneObject::Type::Static)
{
CHB = CollisionHandling::make_collision_handling(CHBType, B);
if (CHB == nullptr)
{
LOG(WARNING) << "InteractionPair error: can not instantiate collision handling for object B.";
return;
}
}
// Init interactionPair
m_objects = ObjectsPair(A, B);
m_colDetect = CD;
m_colHandlingMap[A] = CHA;
m_colHandlingMap[B] = CHB;
m_colDataMap[A] = CollisionData();
m_colDataMap[B] = CollisionData();
m_contactForcesMap[A] = ContactForces();
m_contactForcesMap[B] = ContactForces();
m_valid = true;
}
void
InteractionPair::computeCollisionData()
{
if (!m_valid)
{
LOG(WARNING) << "InteractionPair::computeCollisionData error: interaction not valid.";
return;
}
m_colDetect->computeCollisionData(m_objects.first,
m_objects.second,
m_colDataMap.at(m_objects.first),
m_colDataMap.at(m_objects.second));
}
void
InteractionPair::computeContactForces(std::shared_ptr<CollidingObject> obj)
{
if (!m_valid)
{
LOG(WARNING) << "InteractionPair::computeContactForces error: interaction not valid.";
return;
}
if (obj != m_objects.first && obj != m_objects.second)
{
LOG(WARNING) << "InteractionPair::computeContactForces error: "
<< obj->getName() << " is not part of this interaction Pair.";
return;
}
m_colHandlingMap.at(obj)->computeContactForces(obj, m_colDataMap.at(obj),
m_contactForcesMap.at(obj));
}
const bool&
InteractionPair::isValid()
{
return m_valid;
}
}
/*=========================================================================
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.
=========================================================================*/
#ifndef imstkInteractionPair_h
#define imstkInteractionPair_h
#include <map>
#include <memory>
#include "imstkCollidingObject.h"
#include "imstkCollisionDetection.h"
#include "imstkCollisionData.h"
#include "imstkCollisionHandling.h"
#include "imstkContactForces.h"
namespace imstk {
class InteractionPair
{
using ObjectsPair = std::pair<std::shared_ptr<CollidingObject>, std::shared_ptr<CollidingObject>>;
using CollisionDataMap = std::map<std::shared_ptr<CollidingObject>, CollisionData>;
using CollisionHandlingMap = std::map<std::shared_ptr<CollidingObject>, std::shared_ptr<CollisionHandling>>;
using ContactForcesMap = std::map<std::shared_ptr<CollidingObject>, ContactForces>;
public:
///
/// \brief Constructor
///
InteractionPair(std::shared_ptr<CollidingObject> A,
std::shared_ptr<CollidingObject> B,
CollisionDetection::Type CDType,
CollisionHandling::Type CHAType,
CollisionHandling::Type CHBType);
///
/// \brief Destructor
///
~InteractionPair() = default;
///
/// \brief Call collision detection algorithm to compute collision data
///
void computeCollisionData();
///
/// \brief Call collision handling algorithm to compute contact forces for an object
///
void computeContactForces(std::shared_ptr<CollidingObject> A);
///
/// \brief Call collision handling algorithm to compute contact forces for an object
///
const bool& isValid();
protected:
ObjectsPair m_objects; //!< Colliding objects
std::shared_ptr<CollisionDetection> m_colDetect; //!< Collision detection algorithm
CollisionDataMap m_colDataMap; //!< Map of collision data per colliding object
CollisionHandlingMap m_colHandlingMap; //!< Map of collision handling algorithm per colliding object
ContactForcesMap m_contactForcesMap; //!< Map of contact forces per colliding object
bool m_valid;
};
}
#endif // ifndef imstkInteractionPair_h
......@@ -6,6 +6,7 @@ imstk_add_library( SimulationManager
DEPENDS
Rendering
Devices
Collision
)
#-----------------------------------------------------------------------------
......
......@@ -144,6 +144,7 @@ add_subdirectory(Base/Core)
add_subdirectory(Base/Geometry)
add_subdirectory(Base/Devices)
add_subdirectory(Base/Scene)
add_subdirectory(Base/Collision)
add_subdirectory(Base/Rendering)
add_subdirectory(Base/SimulationManager)
......
......@@ -32,8 +32,14 @@
#include "imstkVRPNDeviceServer.h"
#include "imstkCameraController.h"