Je rends isosurfaces avec des cubes marching, (ou peut-être des carrés de défilement comme ceci est 2D) et je veux faire des opérations comme set set difference, intersection et union. Je pensais que c'était facile à implémenter, en choisissant simplement entre deux scalaires de sommet provenant de deux surfaces implicites différentes, mais ce n'est pas le cas.Opérations CSG sur des surfaces implicites avec des cubes en marche
Pour mes tests initiaux, j'ai essayé avec deux sphères
et l'opération différence. i.e A - B. Un cercle se déplace et l'autre est stationnaire. Voici l'approche que j'ai essayée en choisissant des scalaires de sommet et en classant des sommets de coin comme dedans ou dehors. Le code est écrit en C++. OpenGL est utilisé pour le rendu, mais ce n'est pas important. Le rendu normal sans aucune opération CSG donne le résultat attendu.
void march(const vec2& cmin, //min x and y for the grid cell
const vec2& cmax, //max x and y for the grid cell
std::vector<vec2>& tri,
float iso,
float (*cmp1)(const vec2&), //distance from stationary circle
float (*cmp2)(const vec2&) //distance from moving circle
)
{
unsigned int squareindex = 0;
float scalar[4];
vec2 verts[8];
/* initial setup of the grid cell */
verts[0] = vec2(cmax.x, cmax.y);
verts[2] = vec2(cmin.x, cmax.y);
verts[4] = vec2(cmin.x, cmin.y);
verts[6] = vec2(cmax.x, cmin.y);
float s1,s2;
/**********************************
********For-loop of interest******
*******Set difference between ****
*******two implicit surfaces******
**********************************/
for(int i=0,j=0; i<4; ++i, j+=2){
s1 = cmp1(verts[j]);
s2 = cmp2(verts[j]);
if((s1 < iso)){ //if inside circle1
if((s2 < iso)){ //if inside circle2
scalar[i] = s2; //then set the scalar to the moving circle
} else {
scalar[i] = s1; //only inside circle1
squareindex |= (1<<i); //mark as inside
}
}
else {
scalar[i] = s1; //inside neither circle
}
}
if(squareindex == 0)
return;
/* Usual interpolation between edge points to compute
the new intersection points */
verts[1] = mix(iso, verts[0], verts[2], scalar[0], scalar[1]);
verts[3] = mix(iso, verts[2], verts[4], scalar[1], scalar[2]);
verts[5] = mix(iso, verts[4], verts[6], scalar[2], scalar[3]);
verts[7] = mix(iso, verts[6], verts[0], scalar[3], scalar[0]);
for(int i=0; i<10; ++i){ //10 = maxmimum 3 triangles, + one end token
int index = triTable[squareindex][i]; //look up our indices for triangulation
if(index == -1)
break;
tri.push_back(verts[index]);
}
}
Cela me donne crénelage étranges: here http://www.mechcore.net/images/gfx/csgbug2.png
Il ressemble à l'opération de CSG se fait sans interpolation. Il "rejette" tout le triangle. Ai-je besoin d'interpoler d'une autre manière ou de combiner les valeurs scalaires de vertex? J'aimerais de l'aide avec ça. Un testcase complet peut être téléchargé HERE
EDIT: Fondamentalement, ma mise en œuvre de places de marche fonctionne très bien. C'est mon champ scalaire qui est cassé, et je me demande à quoi ressemblerait le bon chemin. De préférence, je suis à la recherche d'une approche générale pour mettre en œuvre les trois opérations ensemble je mentionné ci-dessus, pour les primitives habituelles (cercle, rectangle/carré, avion)
EDIT 2: Voici quelques nouvelles images après la mise en œuvre de la answerer Livre blanc:
1.Difference
2.Intersection
3.Union
EDIT 3: Je mis en œuvre ce en 3D aussi, avec ombrage/éclairage approprié:
1.Difference between a greater sphere and a smaller sphere
2.Difference between a greater sphere and a smaller sphere in the center, clipped by two planes on both sides, and then union with a sphere in the center.
3.Union between two cylinders.
Hm, bizarre. Cela fonctionne réellement, mais le bord devient un peu bizarre. Je vais examiner si c'est un problème de précision. Il n'apparaît pas pour les cercles normaux cependant. Voici une capture d'écran d'une grille 100x100: http://www.mechcore.net/images/gfx/csgbug3.png –
A droite, c'est un problème de précision. Les grands cercles fonctionnent très bien, mais l'augmentation de la tesselation de la grille ne fonctionne pas (j'utilise des flotteurs). Bonne réponse et bon papier. Mes plus sincères remerciements à vous monsieur. –
De rien! Bonne chance avec votre projet, les surfaces implicites sont amusantes! –