2010-05-21 18 views
7

Ben yürüyen küpler ile isosurfaces, işlemek ve ben küme farkı, kavşak ve birlik gibi işlemleri ayarlamak yapmak istiyorum. Bu basitçe iki farklı örtük yüzeyler iki tepe skalerler arasında seçerek, uygulanması kolay olduğunu düşündüm, ama öyle değil. CSG işlemler

zaman ilk test etmek için, iki küre çevreler denenmiş ve ayar işlemi fark. A - B. Bir daire hareket ediyor, diğeri hareketsiz. Burada köşe skalerlerini seçerken ve köşe köşelerini içte veya dışta sınıflandırırken denediğim yaklaşım. Kod C++ ile yazılmıştır. OpenGL, render yapmak için kullanılır, ancak bu önemli değildir. Herhangi bir CSG işlemi olmaksızın normal render, beklenen sonucu verir.



 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]); 
    } 
} 

Bu bana verir tuhaf jaggies: here http://www.mechcore.net/images/gfx/csgbug2.png
Bu CSG operasyon gibi görünüyor interpolasyon olmadan yapılır. Sadece üçgeni "atar". Başka bir şekilde enterpolasyon yapmam veya vertex skaler değerlerini birleştirmem gerekir mi? Bununla ilgili biraz yardım isterim. Tam testcase HERE

DÜZENLEMEYİ indirilebilir: Temelde, gayet iyi çalışıyoryürüyen kareler benim uygulanması. Benim skaler alan bozuldu, ve ben doğru yolu nasıl görüneceğini merak ediyorum. Tercihen her zamanki ilkel (daire, dikdörtgen/kare, uçak)

DÜZENLEME 2 için yukarıda tartışılan üç set işlemlerini uygulamak için genel bir yaklaşım için arıyorum: Burada uyguladıktan sonra bazı yeni görüntülerdir answerer en teknik inceleme:

1.Difference
2.Intersection
3.Union

DÜZENLEME 3: düzgün gölgeleme/ışıklandırma ile de 3D olarak bu uygulamaya:

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.

cevap

3

Bu sayıl alanlar karıştırmak böyle yapmaz. Skalerleriniz bir şey söyler, ama bayraklarınız içeride olup olmadığınızı veya başka bir şey söylemediğinizi belirtir. Önce tek bir bileşik nesnesini yapıyor sanki o işlemek, birleştirme alanlarını:

for(int i=0,j=0; i<4; ++i, j+=2){ 
    s1 = cmp1(verts[j]); 
    s2 = cmp2(verts[j]); 
    s = max(s1, iso-s2); // This is the secret sauce 
    if(s < iso) { // inside circle1, but not inside circle2 
    squareindex |= (1<<i); 
    } 
    scalar[i] = s; 
} 

Bu makale yararlı olabilir: Combining CSG modeling with soft blending using Lipschitz-based implicit surfaces.

+0

Hm, garip. Bu aslında işe yarıyor ama kenar biraz garipleşiyor. Bunun hassas bir problem olup olmadığını araştıracağım. Ancak normal çevreler için görünmüyor. İşte 100x100 ızgaranın bir ekran görüntüsü: http://www.mechcore.net/images/gfx/csgbug3.png –

+0

Hakkı, bu hassas bir konudur. Büyük daireler harika çalışıyor, ancak ızgara tesselasyonunu arttırmak (şamandıra kullanıyorum) yapmıyor. Harika cevap ve harika bir kağıt. En derin teşekkürlerim efendim. –

+0

Rica ederim! Projenizde bol şanslar, örtülü yüzeyler eğlencelidir! –