Spaces:
Sleeping
Sleeping
import trimesh | |
import numpy as np | |
import mesh2sdf | |
def mesh_to_sdf_glsl(path, resolution=64): | |
# Load mesh | |
mesh = trimesh.load(path) | |
# Center and scale the mesh to fit in [-1, 1] cube | |
mesh.vertices -= mesh.centroid | |
# Calculate the maximum extent of the mesh | |
max_extent = np.max(np.abs(mesh.vertices)) | |
scale = 1.0 / max_extent | |
mesh.vertices *= scale | |
# Create a grid of points | |
x = np.linspace(-1.0, 1.0, resolution) | |
y = np.linspace(-1.0, 1.0, resolution) | |
z = np.linspace(-1.0, 1.0, resolution) | |
X, Y, Z = np.meshgrid(x, y, z) | |
# Flatten the grid and reshape to (n,3) | |
query_points = np.column_stack((X.ravel(), Y.ravel(), Z.ravel())) | |
# Calculate signed distances using mesh2sdf | |
distances = mesh2sdf.compute( | |
mesh.vertices, mesh.faces, query_points, return_gradients=False | |
) | |
# Normalize distances to [-1, 1] | |
distances = np.clip(distances, -1.0, 1.0) | |
# Convert to GLSL array | |
glsl_array = ", ".join(f"{v:.6f}" for v in distances) | |
glsl_code = f"""// Auto-generated SDF GLSL from mesh | |
float sdfData[{resolution**3}] = float[]( | |
{glsl_array} | |
); | |
float SDF(vec3 p) {{ | |
vec3 dim = vec3({resolution}.0); | |
vec3 uv = (p + 1.0) * 0.5 * dim; | |
ivec3 idx = ivec3(clamp(floor(uv), vec3(0.0), dim - 1.0)); | |
int i = idx.x + idx.y * {resolution} + idx.z * {resolution * resolution}; | |
return sdfData[i]; | |
}} | |
""" | |
return glsl_code | |