Loading...
Searching...
No Matches
LevelSetUtils-Impl.hpp
Go to the documentation of this file.
1// This code is based on Jet framework.
2// Copyright (c) 2018 Doyub Kim
3// CubbyFlow is voxel-based fluid simulation engine for computer games.
4// Copyright (c) 2020 CubbyFlow Team
5// Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6// AI Part: Dongheon Cho, Minseo Kim
7// We are making my contributions/submissions to this project solely in our
8// personal capacity and are not conveying any rights to any intellectual
9// property of any third parties.
10
11// Function fractionInside is originally from Christopher Batty's code:
12//
13// http://www.cs.ubc.ca/labs/imager/tr/2007/Batty_VariationalFluids/
14//
15// and
16//
17// https://github.com/christopherbatty/Fluid3D
18
19#ifndef CUBBYFLOW_LEVEL_SET_UTILS_IMPL_HPP
20#define CUBBYFLOW_LEVEL_SET_UTILS_IMPL_HPP
21
23
24#include <cmath>
25
26namespace CubbyFlow
27{
28template <typename T>
30{
31 return phi < 0;
32}
33
34template <typename T>
36{
37 if (phi > 1.5)
38 {
39 return 1;
40 }
41
42 if (phi < -1.5)
43 {
44 return 0;
45 }
46
47 return 0.5 + phi / 3.0 +
48 0.5 * (1 / PI<T>()) * std::sin(PI<T>() * phi / 1.5);
49}
50
51template <typename T>
53{
54 if (std::fabs(phi) > 1.5)
55 {
56 return 0;
57 }
58
59 return 1.0 / 3.0 + 1.0 / 3.0 * std::cos(PI<T>() * phi / 1.5);
60}
61
62template <typename T>
64{
66 {
67 return 1;
68 }
69
71 {
72 return phi0 / (phi0 - phi1);
73 }
74
76 {
77 return phi1 / (phi1 - phi0);
78 }
79
80 return 0;
81}
82
83template <typename T>
84void CycleArray(T* arr, int size)
85{
86 T t = arr[0];
87
88 for (int i = 0; i < size - 1; ++i)
89 {
90 arr[i] = arr[i + 1];
91 }
92
93 arr[size - 1] = t;
94}
95
96template <typename T>
98{
99 const int insideCount =
100 (phiBottomLeft < 0 ? 1 : 0) + (phiTopLeft < 0 ? 1 : 0) +
101 (phiBottomRight < 0 ? 1 : 0) + (phiTopRight < 0 ? 1 : 0);
103
104 if (insideCount == 4)
105 {
106 return 1;
107 }
108
109 if (insideCount == 3)
110 {
111 // Rotate until the positive value is in the first position
112 while (list[0] < 0)
113 {
114 CycleArray(list, 4);
115 }
116
117 // Work out the area of the exterior triangle
118 T side0 = 1 - FractionInsideSDF(list[0], list[3]);
119 T side1 = 1 - FractionInsideSDF(list[0], list[1]);
120
121 return 1 - 0.5f * side0 * side1;
122 }
123
124 if (insideCount == 2)
125 {
126 // Rotate until a negative value is in the first position, and the next
127 // negative is in either slot 1 or 2.
128 while (list[0] >= 0 || !(list[1] < 0 || list[2] < 0))
129 {
130 CycleArray(list, 4);
131 }
132
133 // The matching signs are adjacent
134 if (list[1] < 0)
135 {
138
139 return 0.5f * (side_left + side_right);
140 }
141
142 // Matching signs are diagonally opposite
143 // determine the center point's sign to disambiguate this case
144 T middle_point = 0.25f * (list[0] + list[1] + list[2] + list[3]);
145 if (middle_point < 0)
146 {
147 T area = 0;
148
149 // First triangle (top left)
150 T side1 = 1 - FractionInsideSDF(list[0], list[3]);
151 T side3 = 1 - FractionInsideSDF(list[2], list[3]);
152
153 area += 0.5f * side1 * side3;
154
155 // Second triangle (top right)
156 T side2 = 1 - FractionInsideSDF(list[2], list[1]);
157 T side0 = 1 - FractionInsideSDF(list[0], list[1]);
158
159 area += 0.5f * side0 * side2;
160
161 return 1 - area;
162 }
163
164 T area = 0;
165
166 // First triangle (bottom left)
169 area += 0.5f * side0 * side1;
170
171 // Second triangle (top right)
174 area += 0.5f * side2 * side3;
175 return area;
176 }
177
178 if (insideCount == 1)
179 {
180 // Rotate until the negative value is in the first position
181 while (list[0] >= 0)
182 {
183 CycleArray(list, 4);
184 }
185
186 // Work out the area of the interior triangle, and subtract from 1.
189
190 return 0.5f * side0 * side1;
191 }
192
193 return 0;
194}
195
196template <typename T>
198{
199 if (std::fabs(phi0) + std::fabs(phi1) >
200 std::numeric_limits<double>::epsilon())
201 {
202 return std::fabs(phi0) / (std::fabs(phi0) + std::fabs(phi1));
203 }
204
205 return static_cast<T>(0.5);
206}
207} // namespace CubbyFlow
208
209#endif
Definition Matrix.hpp:30
Definition pybind11Utils.hpp:21
T DistanceToZeroLevelSet(T phi0, T phi1)
Definition LevelSetUtils-Impl.hpp:197
void CycleArray(T *arr, int size)
Definition LevelSetUtils-Impl.hpp:84
bool IsInsideSDF(T phi)
Returns true if phi is inside the implicit surface (< 0).
Definition LevelSetUtils-Impl.hpp:29
T SmearedDeltaSDF(T phi)
Returns smeared delta function.
Definition LevelSetUtils-Impl.hpp:52
T SmearedHeavisideSDF(T phi)
Returns smeared Heaviside function.
Definition LevelSetUtils-Impl.hpp:35
T FractionInsideSDF(T phi0, T phi1)
Returns the fraction occupied by the implicit surface.
Definition LevelSetUtils-Impl.hpp:63
T FractionInside(T phiBottomLeft, T phiBottomRight, T phiTopLeft, T phiTopRight)
Returns the fraction occupied by the implicit surface.
Definition LevelSetUtils-Impl.hpp:97
Matrix< T, Rows, 1 > Vector
Definition Matrix.hpp:738