2010-05-21 11 views
7

Tôi vẽ các mặt phẳng bằng các hình khối diễu hành, (hoặc có thể là các hình vuông diễu hành vì đây là 2D) và tôi muốn thực hiện các hoạt động thiết lập như sự khác biệt, giao lộ và công đoàn. Tôi nghĩ điều này rất dễ thực hiện, đơn giản bằng cách chọn giữa hai đỉnh vô hướng từ hai bề mặt ngầm khác nhau, nhưng nó không phải.Hoạt động CSG trên các bề mặt ngầm với các khối hành hình

Để thử nghiệm ban đầu, tôi đã thử với hai hình cầu sphere và hoạt động được đặt khác biệt. tức là A - B. Một vòng tròn đang chuyển động và một vòng tròn khác là tĩnh. Đây là phương pháp tôi đã thử khi chọn các đỉnh vô hướng và khi phân loại các đỉnh góc như bên trong hoặc bên ngoài. Mã được viết bằng C++. OpenGL được sử dụng để hiển thị, nhưng điều đó không quan trọng. Hiển thị bình thường mà không có bất kỳ hoạt động CSG nào đưa ra kết quả mong đợi.



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

này mang lại cho tôi răng cưa lạ: here http://www.mechcore.net/images/gfx/csgbug2.png
Dường như các hoạt động CSG được thực hiện mà không cần suy. Nó chỉ "loại bỏ" toàn bộ tam giác. Tôi có cần phải nội suy theo một cách khác hay kết hợp các giá trị vô hướng đỉnh? Tôi rất muốn giúp đỡ với điều này. Một testcase đầy đủ có thể được tải về HERE

EDIT: Về cơ bản, thực hiện của tôi vuông diễu hành hoạt động tốt. Đây là trường vô hướng vô hướng của tôi bị hỏng và tôi tự hỏi cách chính xác sẽ như thế nào. Tốt hơn là tôi đang tìm cách tiếp cận chung để thực hiện ba hoạt động thiết lập mà tôi đã thảo luận ở trên, cho các nguyên thủy thông thường (hình tròn, hình chữ nhật/hình vuông, mặt phẳng)

EDIT 2: Sau đây là một số hình ảnh mới sau khi thực hiện trình trả lời whitepaper:

1.Difference
2.Intersection
3.Union

EDIT 3: Tôi thực hiện điều này trong không gian 3D quá, với đúng bóng/chiếu sáng:

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.

Trả lời

3

Đây không phải là cách bạn kết hợp các trường vô hướng. Scalars của bạn nói một điều, nhưng cờ của bạn cho dù bạn đang ở trong hoặc không nói khác. Đầu tiên hợp nhất các trường, sau đó kết xuất như thể bạn đang làm một đối tượng hợp chất đơn lẻ:

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

Bài viết này có thể hữu ích: Combining CSG modeling with soft blending using Lipschitz-based implicit surfaces.

+0

Hm, lạ. Điều này thực sự làm việc, nhưng các cạnh có được loại kỳ lạ. Tôi sẽ điều tra xem đây có phải là vấn đề chính xác hay không. Nó không hiển thị cho các vòng tròn bình thường mặc dù. Đây là ảnh chụp màn hình của lưới 100x100: http://www.mechcore.net/images/gfx/csgbug3.png –

+0

Phải, đó là vấn đề chính xác. Các vòng tròn lớn hơn hoạt động tốt, nhưng tăng cường tesselation lưới không (tôi đang sử dụng phao). Câu trả lời tuyệt vời và bài viết tuyệt vời. Lời cảm ơn sâu sắc nhất của tôi đối với bạn. –

+0

Bạn được chào đón! Chúc may mắn với dự án của bạn, bề mặt tiềm ẩn thật thú vị! –