Hello Renan,

Now I'm asking for that example code you've offered me, if that still
stands...  I haven't tried hard enough, to be honest, but I sure have no
extra time to deal with this properly right now. Not to mention the guy I
work with, which is breathing down my neck... I would appreciate that favor
very much.

As I said, for the part about feeding the data to OSG, there are good resources and I can't really step you through it, unless you give us the specific part you're having trouble with.

On the other hand, if you're having trouble calculating the data itself, I attached a source file that might help for spheres and cylinders. Now, it's not a silver bullet, as it's pretty old, straight OpenGL code, and some of the comments are in French (you might use a translation web site for that ;-) ). But still, it may help you.

In a nutshell, to construct a sphere, I first build a display list with 1/6 of a sphere, pointing in one direction (say positive X). Then, I call that display list 6 times with a rotation each time. The reason for doing it that way is to avoid the singularity at the poles of the sphere.

For the cylinder, it's basically just making as many circles as needed, and then capping the tube. (come to think of it, I'm not even sure these cylinders were capped, as they were meant to represent a quadric...)

In both cases, I guess the more complicated part is figuring out how to make faces out of the vertices, rather than calculating the position of the vertices themselves. So the code may help you out with that part.

As I said, it's old code, so if you have trouble figuring it out, I'm afraid I won't be able to help much. But it may be what you need to nudge you in the right direction.

Good luck,

J-S
--
______________________________________________________
Jean-Sebastien Guay     [EMAIL PROTECTED]
                        http://whitestar02.webhop.org/

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

/*--------------------------------------------------------------------------*/
/*                                                                          */
/*    *** INF4702 COMPLEMENT D'INFOGRAPHIE ***                              */
/*        Travaux Pratiques                                                 */
/*                                                                          */
/*    fichier     b_quad.cpp                                                */
/*                                                                          */
/*    Traitement des surfaces quadriques                                    */
/*                                                                          */
/*    Rev:        07/01/2002    y.m.                                        */
/*                                                                          */
/*--------------------------------------------------------------------------*/

#include    "class.h"
#include    "if540.h"
#include    "Vector3.h"
#include    "Quaternion.h"

#include    "texture.h"
#include    "texture_image.h"
#include    "texture_procedural.h"

using namespace math;
using namespace std;
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*    PreProc    (Pre-processing: differents calculs...)                    */
/*                                                                          */
/*    Params:    (void)                                                     */
/*                                                                          */
/*    Return:    (void)                                                     */
/*                                                                          */
/*    Note: Cette methode est appelee apres la lecture des donnees et avant */
/*          le calcul des images.  C'est l'endroit ideal pour effectuer     */
/*          les transformations de la surface et calculer des constantes.   */
/*                                                                          */
/*--------------------------------------------------------------------------*/

#ifdef    OPEN_GL

extern General general;

void    Quadric::PreProc( void )
{
    /*
    Matrix Q( this->quad.x,    this->mix.z / 2, this->mix.y / 2, this->lin.x / 
2,
              this->mix.z / 2, this->quad.y,    this->mix.x / 2, this->lin.y / 
2,
              this->mix.y / 2, this->mix.x / 2, this->quad.z,    this->lin.z / 
2,
              this->lin.x / 2, this->lin.y / 2, this->lin.z / 2, this->cst      
  );

    Matrix S = this->transfo;
    Matrix Q2 = !S * Q * ~(!S);

    this->quad.x = Q2[0][0];
    this->quad.y = Q2[1][1];
    this->quad.z = Q2[2][2];
    this->cst    = Q2[3][3];
    this->mix.x  = Q2[1][2] + Q2[2][1];
    this->mix.y  = Q2[2][0] + Q2[0][2];
    this->mix.z  = Q2[1][0] + Q2[0][1];
    this->lin.x  = Q2[0][3] + Q2[3][0];
    this->lin.y  = Q2[1][3] + Q2[3][1];
    this->lin.z  = Q2[2][3] + Q2[3][2];
    */

    int sphere_dlist;           // Display list temporaire pour les 1/6 de 
sphere...

    if ( ! this->precision_u )
         this->precision_u = 10;
    if ( ! this->precision_v )
         this->precision_v = 10;

    
//----------------------------------------------------------------------------------
    // Si c'est une sphere, on fera une display list pour 1/6 de sphere
    if ( this->quad.x != 0.0 && this->quad.y != 0.0 && this->quad.z != 0.0 ) {
        sphere_dlist = glGenLists( 1 );

        glNewList( sphere_dlist, GL_COMPILE );
        glPushMatrix();

        double step_u = 1.0 / double(this->precision_u);
        double step_v = 1.0 / double(this->precision_v);
        double bounds = 0.5;
        Vect v1;

        // Chaque 1/6 de sphere va de -bounds a +bounds en X et en Y.
        for ( double u = - bounds; u < bounds; u += step_u ) {

            glBegin( GL_QUAD_STRIP );
                for ( double v = - bounds; v <= bounds; v += step_v ) {
                    v1.set( u, v, bounds );
                    // Pour que la distance de l'origine soit 1 ==> plan 
arrondi et non pas plat
                    v1 = v1.normalise();

                    // These texture coords aren't perfect, but they're better 
than the
                    // alternatives. They make the texture appear once at the 
middle of
                    // the 1/6 of the sphere, square and with small rounded 
borders at
                    // each edge to fill the rest of the 1/6 sphere.
                    // I tried (u + bounds, v + bounds), but that gave a 
"scissor cut"
                    // appearance, because there aren't enough faces on the 1/6 
sphere,
                    // but if there were, that would be the way to make the 
texture appear
                    // exactly once on the 1/6 sphere.
                    glTexCoord2d( v1[0] + bounds, v1[1] + bounds );
                    glNormal3dv( &(v1[0]) );
                    glVertex3dv( &(v1[0]) );

                    v1.set( u + step_u, v, bounds );
                    v1 = v1.normalise();

                    glTexCoord2d( v1[0] + bounds, v1[1] + bounds );
                    glNormal3dv( &(v1[0]) );
                    glVertex3dv( &(v1[0]) );

                }
            glEnd();
        }

        glPopMatrix();
        glEndList();
    }
    
//----------------------------------------------------------------------------------

    // --- cree le display-list ---
    this->display_list = glGenLists( 1 );

    if ( ! glIsList( this->display_list ) ) {
        cerr << "ERREUR: incapable de creer la liste pour " << this->name << 
endl;
        return;
    }

    glNewList( this->display_list, GL_COMPILE );

    // --- proprietes du materiel ---
    GLfloat val[1], vect[4];
    vect[0] = (this->kAmb * this->col[0]) / 255.0;
    vect[1] = (this->kAmb * this->col[1]) / 255.0;
    vect[2] = (this->kAmb * this->col[2]) / 255.0;
    vect[3] = 1.0;
    glMaterialfv( GL_FRONT, GL_AMBIENT, vect );
    vect[0] = (this->kDiff * this->col[0]) / 255.0;
    vect[1] = (this->kDiff * this->col[1]) / 255.0;
    vect[2] = (this->kDiff * this->col[2]) / 255.0;
    glMaterialfv( GL_FRONT, GL_DIFFUSE, vect );
    vect[0] = this->kSpec;
    vect[1] = this->kSpec;
    vect[2] = this->kSpec;
    glMaterialfv( GL_FRONT, GL_SPECULAR, vect );
    val[0] = this->shini;
    glMaterialfv( GL_FRONT, GL_SHININESS, val );


    // --- si texture Bitmap ---
    if ( this->texture != 0 ) {
        glBindTexture( GL_TEXTURE_2D, this->texture->getTextureID() );
    }

    // --- sauve la matrice ---
    glPushMatrix();

    // --- applique la matrice courante ---
    glMultMatrixd( &(this->transfo.mat[0][0]) );

    float scale_s = ( this->texture == 0 ? 1.0 : this->texture->getParameterA() 
);
    float scale_t = ( this->texture == 0 ? 1.0 : this->texture->getParameterB() 
);

//     // --- c'est un cylindre ou une sphere ? ---
    if ( this->quad.x == 0.0 || this->quad.y == 0.0 || this->quad.z == 0.0 ) {

        // ======================================================
        // ======================================================
        // ================ c'est un cylindre ===================
        // ======================================================
        // ======================================================

        // Le tube aura 20 unites de longueur, de -10 a 10, selon l'axe 
specifie.

        // Effectuer la bonne transformation pour que le tube soit a la
        // position et ait la grosseur prevues.
        glTranslated( -(this->lin.x / 2), -(this->lin.y / 2), -(this->lin.z / 
2) );
        double radius = sqrt( (this->lin.x / 2) * (this->lin.x / 2) - this->cst 
);
        glScaled( radius, 1.0, radius );

        // Placer le tube selon le bon axe
        // Par exemple, si quad = [1.0, 0.0, 1.0] alors le tube est oriente
        // selon l'axe des Y. Pour l'avoir, on fait :
        // [1.0, 0.0, 1.0] * -1 = [-1.0, 0.0, -1.0]
        // [-1.0, 0.0, -1.0] + [1.0, 1.0, 1.0] = [0.0, 1.0, 0.0]
        Vector3 axis( this->quad.x, this->quad.y, this->quad.z );
        axis *= -1;
        axis += Vector3( 1.0, 1.0, 1.0 );
        // Puisqu'on deplace v1, on ne peut pas l'utiliser comme normale.
        Vector3 n1( axis[1], axis[0], axis[2] );
        Vector3 v1( n1 + (axis * -10.0) );   // On commence a -(precision_v/2).

        // Le tube sera forme en faisant une rotation autour de l'axe 'axis'
        // pour placer des points a distance egale de celui-ci.
        double angle_u = (( 2 * M_PI ) / this->precision_u) * DEG;
        Quaternion qu( angle_u, axis );

        Vector3 vstep( axis * ( 20.0 / this->precision_v ) );
        glPushMatrix();
            // Les strips font le tour du tube
            for ( int u = 0; u < this->precision_u; u++ ) {
                Vector3 v2 = v1;
                Vector3 n2 = n1;

                // Chaque strip fait toute la longueur du tube.
                glBegin( GL_QUAD_STRIP );
                    for ( int v = 0; v < this->precision_v + 1; v++ ) {
                        Vector3 temp = v2;
                        Vector3 nt = n2;

                        Vector3 nt_bumped = nt;
                        Vector3 temp_displaced = temp;

                        float s = float( u ) / ( float( this->precision_u ) / 
scale_s );
                        float t = float( v ) / ( float( this->precision_v ) / 
scale_t );

                        if ( this->displacement_map != 0 ) {
                            displacement_map->displace( temp_displaced, 
nt_bumped, axis, s, t );
                        }
                        if ( this->bump_map != 0 ) {
                            bump_map->displace( temp_displaced, nt_bumped, 
axis, s, t );
                        }

                        glTexCoord2f( -s, t );
                        glNormal3dv( &(nt_bumped[0]) );
                        glVertex3dv( &(temp_displaced[0]) );

                        qu.rot( temp );
                        qu.rot( nt );

                        nt_bumped = nt;
                        temp_displaced = temp;

                        s = float( u + 1 ) / ( float( this->precision_u ) / 
scale_s );
                        t = float( v )     / ( float( this->precision_v ) / 
scale_t );

                        if ( this->displacement_map != 0 ) {
                            displacement_map->displace( temp_displaced, 
nt_bumped, axis, s, t );
                        }
                        if ( this->bump_map != 0 ) {
                            bump_map->displace( temp_displaced, nt_bumped, 
axis, s, t );
                        }

                        glTexCoord2f( -s, t );
                        glNormal3dv( &(nt_bumped[0]) );
                        glVertex3dv( &(temp_displaced[0]) );

                        v2 += vstep;
                    }
                glEnd();

                qu.rot( v1 );
                qu.rot( n1 );
            }

        glPopMatrix();
    }
    else {

        // ======================================================
        // ======================================================
        // ================ c'est une sphere ====================
        // ======================================================
        // ======================================================

        // Effectuer la bonne transformation pour que la sphere soit a la
        // position et ait la grosseur prevues.
        glTranslated( -(this->lin.x / 2), -(this->lin.y / 2), -(this->lin.z / 
2) );
        double radius = sqrt( (this->lin.x / 2) * (this->lin.x / 2) - this->cst 
);
        glScaled( radius, radius, radius );

        // Maintenant, on appelle la liste precompilee, en faisant des rotations
        // pour placer les 1/6 de sphere aux bonnes positions.
        // [0.0, 0.0, 1.0]
        glCallList( sphere_dlist );

        // [0.0, 0.0, -1.0]
        glPushMatrix();
        glRotated( 180.0, 1.0, 0.0, 0.0 );
        glCallList( sphere_dlist );
        glPopMatrix();

        // [0.0, 1.0, 0.0]
        glPushMatrix();
        glRotated( 90.0, 1.0, 0.0, 0.0 );
        glCallList( sphere_dlist );
        glPopMatrix();

        // [0.0, -1.0, 0.0]
        glPushMatrix();
        glRotated( -90.0, 1.0, 0.0, 0.0 );
        glCallList( sphere_dlist );
        glPopMatrix();

        // [1.0, 0.0, 0.0]
        glPushMatrix();
        glRotated( 90.0, 0.0, 1.0, 0.0 );
        glCallList( sphere_dlist );
        glPopMatrix();

        // [-1.0, 0.0, 0.0]
        glPushMatrix();
        glRotated( -90.0, 0.0, 1.0, 0.0 );
        glCallList( sphere_dlist );
        glPopMatrix();
    }

    glPopMatrix();

    // Unbind texture
    if ( this->texture != 0 ) {
        glBindTexture( GL_TEXTURE_2D, 0 );
    }

    glEndList();
}

#endif
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to