blob: f3abf45d68ba4038aea6aab16633e0a800a034ec [file] [log] [blame]
//#####################################################################
// Copyright 2004-2005, Ron Fedkiw, Geoffrey Irving, Joseph Teran.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class TETRAHEDRON_COLLISION_BODY
//#####################################################################
#ifndef __TETRAHEDRON_COLLISION_BODY__
#define __TETRAHEDRON_COLLISION_BODY__
#include "COLLISION_BODY_3D.h"
#include "../Particles/SOLIDS_PARTICLE.h"
#include "../Geometry/TETRAHEDRALIZED_VOLUME.h"
#include "../Geometry/LEVELSET_IMPLICIT_SURFACE.h"
namespace PhysBAM
{
template<class T> class DEFORMABLE_OBJECT_3D;
template<class T>
class TETRAHEDRON_COLLISION_BODY: public COLLISION_BODY_3D<T>
{
public:
using COLLISION_BODY_3D<T>::body_type;
using COLLISION_BODY_3D<T>::Set_Collision_Thickness;
using COLLISION_BODY_3D<T>::collision_thickness;
TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume;
TRIANGULATED_SURFACE<T>* triangulated_surface;
LEVELSET_IMPLICIT_SURFACE<T>* implicit_surface;
SOLIDS_PARTICLE<T, VECTOR_3D<T> >* undeformed_tetrahedron_particles;
TRIANGULATED_SURFACE<T>* undeformed_triangulated_surface;
DEFORMABLE_OBJECT_3D<T>* deformable_object; // for use in embedded/embedded tetrahedron collisions
T max_min_barycentric_weight_tolerance;
T friction_coefficient;
T relaxation_factor;
T normal_interpolation_scale_factor;
T self_collision_normal_angle_tolerance;
T min_tet_volume_tolerance;
TETRAHEDRON_COLLISION_BODY (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume_input, TRIANGULATED_SURFACE<T>* triangulated_surface_input = 0)
: tetrahedralized_volume (tetrahedralized_volume_input), triangulated_surface (triangulated_surface_input), implicit_surface (0),
undeformed_tetrahedron_particles (0), undeformed_triangulated_surface (0), deformable_object (0)
{
body_type = COLLISION_BODY_3D<T>::TETRAHEDRON_TYPE;
Set_Collision_Thickness();
Set_Max_Min_Barycentric_Weight_Tolerance();
Set_Min_Tet_Volume_Tolerance();
Set_Relaxation_Factor();
Set_Friction_Coefficient();
Set_Normal_Interpolation_Scale_Factor();
Set_Self_Collision_Normal_Angle_Tolerance();
if (!triangulated_surface)
{
if (!tetrahedralized_volume.triangulated_surface) tetrahedralized_volume.Initialize_Triangulated_Surface();
triangulated_surface = tetrahedralized_volume.triangulated_surface;
}
tetrahedralized_volume.Initialize_Tetrahedron_Hierarchy();
triangulated_surface->Initialize_Triangle_Hierarchy();
triangulated_surface->avoid_normal_interpolation_across_sharp_edges = false;
}
VECTOR_3D<T> Surface_Normal (const int triangle, const VECTOR_3D<T>& weights) const
{
int i, j, k;
triangulated_surface->triangle_mesh.triangles.Get (triangle, i, j, k);
VECTOR_3D<T> n1 = (*triangulated_surface->vertex_normals) (1, i), n2 = (*triangulated_surface->vertex_normals) (1, j), n3 = (*triangulated_surface->vertex_normals) (1, k);
return (weights.x * n1 + weights.y * n2 + weights.z * n3).Robust_Normalized();
}
VECTOR_3D<T> Depth_Interpolated_Normal (const T unsigned_depth, const VECTOR_3D<T>& outward_direction, const VECTOR_3D<T>& surface_normal) const
{
T lambda = min (unsigned_depth / normal_interpolation_scale_factor, (T) 1);
return (lambda * outward_direction + (1 - lambda) * surface_normal).Robust_Normalized();
}
void Set_Min_Tet_Volume_Tolerance (const T min_tet_volume_tolerance_input = - (T) 1e-6)
{
min_tet_volume_tolerance = min_tet_volume_tolerance_input;
}
void Set_Normal_Interpolation_Scale_Factor (const T collision_thickness_scaling = (T) 2)
{
normal_interpolation_scale_factor = collision_thickness_scaling * collision_thickness;
}
void Set_Implicit_Surface (LEVELSET_IMPLICIT_SURFACE<T>* implicit_surface_input)
{
implicit_surface = implicit_surface_input;
}
void Set_Undeformed_Triangulated_Surface (TRIANGULATED_SURFACE<T>* undeformed_triangulated_surface_input)
{
undeformed_triangulated_surface = undeformed_triangulated_surface_input;
undeformed_triangulated_surface->Update_Triangle_List();
undeformed_triangulated_surface->Initialize_Triangle_Hierarchy();
if (!undeformed_tetrahedron_particles) undeformed_tetrahedron_particles = &undeformed_triangulated_surface->particles;
}
void Set_Undeformed_Tetrahedron_Particles (SOLIDS_PARTICLE<T, VECTOR_3D<T> >* undeformed_tetrahedron_particles_input)
{
undeformed_tetrahedron_particles = undeformed_tetrahedron_particles_input;
}
void Set_Deformable_Object (DEFORMABLE_OBJECT_3D<T>* deformable_object_input = 0)
{
deformable_object = deformable_object_input;
}
void Set_Self_Collision_Normal_Angle_Tolerance (const T self_collision_normal_angle_tolerance_input = - (T) 1e-5)
{
self_collision_normal_angle_tolerance = self_collision_normal_angle_tolerance_input;
}
void Set_Friction_Coefficient (const T friction_coefficient_input = (T).1)
{
friction_coefficient = friction_coefficient_input;
}
void Set_Max_Min_Barycentric_Weight_Tolerance (const T max_min_barycentric_weight_tolerance_input = (T) - 1e-6)
{
max_min_barycentric_weight_tolerance = max_min_barycentric_weight_tolerance_input;
}
void Set_Relaxation_Factor (const T relaxation_factor_input = (T).25)
{
relaxation_factor = relaxation_factor_input;
}
//#####################################################################
bool Implicit_Surface_Lazy_Inside_And_Value (const VECTOR_3D<T>& location, T& phi, T contour_value = 0) const;
bool Implicit_Surface_Lazy_Outside_Extended_Levelset_And_Value (const VECTOR_3D<T>& location, T& phi_value, T contour_value = 0) const;
VECTOR_3D<T> Implicit_Surface_Normal (const VECTOR_3D<T>& location, const int aggregate = -1) const;
VECTOR_3D<T> Implicit_Surface_Normal (const VECTOR_3D<T>& location, T& phi_value, const int aggregate = -1, const int location_particle_index = 0) const;
VECTOR_3D<T> Implicit_Surface_Extended_Normal (const VECTOR_3D<T>& location, T& phi_value, const int aggregate = -1, const int location_particle_index = 0) const;
int Get_Tetrahedron_Near_Point (const VECTOR_3D<T>& point, VECTOR_3D<T>& weights, const int particle_index = 0) const;
int Get_Surface_Triangle (const int tetrahedron_index, const VECTOR_3D<T>& tetrahedron_weights, VECTOR_3D<T>& surface_weights, const bool omit_outside_points = false,
const bool omit_inside_points = false, bool* inside = 0) const;
void Adjust_Point_Face_Collision_Position_And_Velocity (const int triangle_index, VECTOR_3D<T>& X, VECTOR_3D<T>& V, const T mass, const T dt, const VECTOR_3D<T>& weights,
VECTOR_3D<T>& position_change);
//#####################################################################
};
}
#endif