Post Reply 
Drawing a Spherical Mesh
01-20-2014, 08:07 PM (This post was last modified: 01-20-2014 08:11 PM by jgreenb2.)
Post: #1
Drawing a Spherical Mesh
Wondering if any of you who are graphics whizzes on the Prime know how to implement a spherical mesh generator?

I tried to make a PPL version of the classical icosahedron mesh but the depth of recursion appears to flummox the prime. Here's the original OpenGL/C version that can be found in the redbook and other places:

Code:
//
//  sphereMesh.c
//
//  draws a sphercial mesh
//

#include <stdio.h>
#include <math.h>

#if !defined(__GLU_H__)
#if defined(WIN32)
#include <windows.h>
#include <GL/glu.h>
#elif defined(__MACH__)
#include <OpenGL/glu.h>
#else
#include <GL/glu.h>
#endif
#endif // !__GL_H__
#define X .525731112119133606
#define Z .850650808352039932

static GLfloat vdata[12][3] = {
    {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},
    {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},
    {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
};
static GLuint tindices[20][3] = {
    {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
    {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
    {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
    {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };

void normalize(GLfloat *a) {
    GLfloat d=sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
    a[0]/=d; a[1]/=d; a[2]/=d;
}

void drawtri(GLfloat *a, GLfloat *b, GLfloat *c, int div, float r) {
    if (div<=0) {
        glNormal3fv(a); glVertex3f(a[0]*r, a[1]*r, a[2]*r);
        glNormal3fv(b); glVertex3f(b[0]*r, b[1]*r, b[2]*r);
        glNormal3fv(c); glVertex3f(c[0]*r, c[1]*r, c[2]*r);
    } else {
        GLfloat ab[3], ac[3], bc[3];
        for (int i=0;i<3;i++) {
            ab[i]=(a[i]+b[i])/2;
            ac[i]=(a[i]+c[i])/2;
            bc[i]=(b[i]+c[i])/2;
        }
        normalize(ab); normalize(ac); normalize(bc);
        drawtri(a, ab, ac, div-1, r);
        drawtri(b, bc, ab, div-1, r);
        drawtri(c, ac, bc, div-1, r);
        drawtri(ab, bc, ac, div-1, r);  //<--Comment this line and sphere looks really cool!
    }
}

void drawsphere(int ndiv, float radius) {
    glBegin(GL_TRIANGLES);
    for (int i=0;i<20;i++)
        drawtri(vdata[tindices[i][0]], vdata[tindices[i][1]], vdata[tindices[i][2]], ndiv, radius);
    glEnd();
}

I'm assuming that the glNormal3fv calls can be converted to TRIANGLE calls on the Prime (although shading doesn't appear to be supported). But the program never gets that far -- it hangs somewhere in the drawtri recursion for values of "div" > 2 or 3.

Converted to PPL the equivalent of the above code would be
Code:

XX=.525731112119133606;
ZZ=.850650808352039932;
vdata={
    {-XX, 0.0, ZZ}, {XX, 0.0, ZZ}, {-XX, 0.0, -ZZ}, {XX, 0.0, -ZZ},
    {0.0, ZZ, XX}, {0.0, ZZ, -XX}, {0.0, -ZZ, XX}, {0.0, -ZZ, -XX},
    {ZZ, XX, 0.0}, {-ZZ, XX, 0.0}, {ZZ, -XX, 0.0}, {-ZZ, -XX, 0.0}
    };
tindices = {
    {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
    {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
    {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
    {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };

drawSphere()
begin
    local i,radius=50,ndiv=12;
    local white;
    
    white:=rgb(255,255,255);
    dimgrob_p(G1,320,240,white);

    for i from 1 to 20 do
        drawtri(vdata(tindices(i,1)+1),
                vdata(tindices(i,2)+1),
                vdata(tindices(i,3)+1),ndiv,radius);
    end;
    blit_p(G0,G1);
end;

normalize(aa)
begin
    local dd;
    dd:=sqrt(aa(1)*aa(1)+aa(2)*aa(2)+aa(3)*aa(3));
    aa(1):=aa(1)/dd; aa(2):=aa(2)/dd; aa(3):=aa(3)/dd;
    return aa;
end;

drawtri(aa,bb,cc,div,r)
begin
    local ab={},ac={},bc={};
    local grey,i;
    
    grey:=rgb(25,25,25);
    if div <= 0 then
        triangle_p(G1,{aa(1),aa(2),grey,aa(3)},{bb(1),bb(2),grey,bb(3)},{cc(1),cc(2​),grey,cc(3)});
    else
        for i from 1 to 3 do
            ab(i):=(aa(i)+bb(i))/2;
            ac(i):=(aa(i)+cc(i))/2;
            bc(i):=(bb(i)+cc(i))/2;
        end;
        ab:=normalize(ab);
        ac:=normalize(ac);
        bc:=normalize(bc);
        drawtri(aa,ab,ac,div-1,r);
        drawtri(bb,bc,ab,div-1,r);
        drawtri(cc,ac,bc,div-1,r);
        drawtri(ab,bc,ac,div-1,r);
    end;
end;

It seems likely that I've botched the TRIANGLE command since I've never used it but, again, things seem to go bad before that point. BTW, the above is only a fragment. If you want to try it you'll need to embed it in a more complete program like Han's Graph3D.

Suggestions welcome. Or is this just beyond what we can expect the Prime to do at this point?
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
Drawing a Spherical Mesh - jgreenb2 - 01-20-2014 08:07 PM
RE: Drawing a Spherical Mesh - Han - 01-20-2014, 09:47 PM
RE: Drawing a Spherical Mesh - jgreenb2 - 01-20-2014, 09:58 PM
RE: Drawing a Spherical Mesh - jgreenb2 - 01-21-2014, 12:15 AM
RE: Drawing a Spherical Mesh - patrice - 01-21-2014, 01:08 AM
RE: Drawing a Spherical Mesh - patrice - 01-23-2014, 10:11 PM



User(s) browsing this thread: 1 Guest(s)