Re: Problem of pfHit for triangle with strips

New Message Reply Date view Thread view Subject view Author view

From: Yigang Wang (yigang.wang++at++gmd.de)
Date: 12/07/2000 00:41:23


Here is code. Please note what change i have made after the line
//***************.

//
/////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <math.h>
#include <X11/keysym.h>
#include <stdlib.h>

#include <Performer/pf/pfChannel.h>
#include <Performer/pf/pfEarthSky.h>
#include <Performer/pf/pfGeode.h>
#include <Performer/pf/pfSCS.h>
#include <Performer/pr/pfGeoSet.h>

typedef struct SharedData
{
    int exitFlag;
    int showStats;
    float yval;
    float zval;
} SharedData;

static void DrawChannel (pfChannel *chan, void *data);
static void OpenPipeWin (pfPipeWindow *pw);

SharedData *shared;

int
main(int argc, char *argv[])
{
    pfSCS *scs[10];
    pfMatrix mat;
    pfCoord view;
    pfSegSet segset;
    int loop;

    // Initialize Performer
    pfInit();

    // Use default multiprocessing mode based on number of processors.
    pfMultiprocess(PFMP_DEFAULT);

    // Malloc storage in shared memory region for shared data
    shared = (SharedData *) pfMalloc(sizeof(SharedData),pfGetSharedArena());

    // Configure multiprocessing mode and start parallel processes
    pfConfig();

    shared->exitFlag = 0;
    shared->showStats = 0;

    //
    // Configure and open GL window
    //
    pfPipe *pipe = pfGetPipe(0);
    pfPipeWindow *pw = new pfPipeWindow(pipe);
    pw->setWinType(PFPWIN_TYPE_X);
    pw->setName(argv[0]);
    pw->setOriginSize(0, 0, 500, 500);
    // Open and configure the GL window.
    pw->setConfigFunc(OpenPipeWin);
    pw->config();

    pfFrameRate(30.0f);

    // Create & configure channel
    pfChannel *chan = new pfChannel(pipe);
    chan->setTravFunc(PFTRAV_DRAW, DrawChannel);
    chan->setNearFar(0.1f, 10000.0f);
    chan->setFOV(45.0f, -1.0f);

    // Add an earth/sky effect
    pfEarthSky *esky = new pfEarthSky();
    esky->setMode(PFES_BUFFER_CLEAR, PFES_SKY_GRND);
    esky->setAttr(PFES_GRND_HT, 0.0f);
    esky->setColor(PFES_GRND_FAR, 0.3f, 0.1f, 0.0f, 1.0f);
    esky->setColor(PFES_GRND_NEAR, 0.5f, 0.3f, 0.1f, 1.0f);
    chan->setESky(esky);

    //
    // Create pfScene node, attach it to channel
    //
    pfScene *scene = new pfScene();
    chan->setScene(scene);

    // Create group node to hold SCS's; attach it to scene
    pfGroup *root = new pfGroup();
    scene->addChild(root);

    // Create 10 SCS nodes, spaced equally apart. Make each one
    // a child of 'root', and make 'geode' a child of each SCS
    pfGeode *geode = new pfGeode();
    for (loop=0; loop < 10; loop++)
    {
        mat.makeTrans(0.0f, (float) loop * 10.0f + 10.0f, 0.0f);
        scs[loop] = new pfSCS(mat);
        scs[loop]->addChild(geode);
        root->addChild(scs[loop]);

        // set up SCS's (and their children) for intersections
        scs[loop]->setTravMask(PFTRAV_ISECT, 1, PFTRAV_SELF,
                               PF_SET);
    }

    // Create a GeoSet to hold the ramp geometry
    // pfGeoSet *gset = new pfGeoSet(pfGetSharedArena());

    pfVec3 *verts = (pfVec3*) new(8*sizeof(pfVec3)) pfMemory;
    verts[0].set(-1.0f, -1.0f, 1.0f);
    verts[1].set( 1.0f, -1.0f, 1.0f);
    verts[2].set( 1.0f, 1.0f, 1.0f);
    verts[3].set(-1.0f, 1.0f, 1.0f);
    verts[4].set(-2.0f, -2.0f, 0.0f);
    verts[5].set( 2.0f, -2.0f, 0.0f);
    verts[6].set( 2.0f, 2.0f, 0.0f);
    verts[7].set(-2.0f, 2.0f, 0.0f);

    //*********************************************************************
    // Following is Changed

    ushort *vindex = (ushort*) new(24*sizeof(ushort)) pfMemory;
    vindex[0] = 0; vindex[1] = 1; vindex[2] = 3; vindex[3] = 2; // top
    vindex[4] = 0; vindex[5] = 3; vindex[6] = 4; vindex[7] = 7; // left
    vindex[8] = 4; vindex[9] = 7; vindex[10] = 5; vindex[11] = 6; // bottom

    vindex[12] = 1; vindex[13] = 5; vindex[14] = 2; vindex[15] = 6; // right
    vindex[16] = 3; vindex[17] = 2; vindex[18] = 7; vindex[19] = 6; // back
    vindex[20] = 0; vindex[21] = 4; vindex[22] = 1; vindex[23] = 5; // front

    pfVec4 *colors = (pfVec4*) new(4*sizeof(pfVec4)) pfMemory;
    colors[0].set(1.0f, 0.0f, 0.0f, 0.5f);
    colors[1].set(0.0f, 1.0f, 0.0f, 0.5f);
    colors[2].set(0.0f, 0.0f, 1.0f, 0.5f);
    colors[3].set(1.0f, 1.0f, 1.0f, 0.5f);

    ushort *cindex = (ushort*) new(24*sizeof(ushort)) pfMemory;
    cindex[0] = 0; cindex[1] = 1; cindex[2] = 3; cindex[3] = 2;
    cindex[4] = 0; cindex[5] = 1; cindex[6] = 3; cindex[7] = 2;
    cindex[8] = 0; cindex[9] = 1; cindex[10] = 3; cindex[11] = 2;
    cindex[12] = 0; cindex[13] = 1; cindex[14] = 3; cindex[15] = 2;
    cindex[16] = 0; cindex[17] = 1; cindex[18] = 3; cindex[19] = 2;
    cindex[20] = 0; cindex[21] = 1; cindex[22] = 3; cindex[23] = 2;

    int *length = (int *) new(6*sizeof(int)) pfMemory;
    for(uint i=0; i<6; i++)
        length[i] = 4;

    pfGeoSet *gset = new pfGeoSet;
    gset->setPrimType(PFGS_TRISTRIPS);
    gset->setPrimLengths(length);
    gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, verts, vindex);
    gset->setAttr(PFGS_COLOR4, PFGS_PER_VERTEX, colors, cindex);
    gset->setNumPrims(6);

//****************************************************************************

    // attach it to the parent geode
    geode->addGSet(gset);

    //
    // set initial view position
    //
    shared->yval=0.0f;
    shared->zval=0.5f;

    // set up intersection segment, pointing down
    // for "terrain" following
    segset.activeMask = 1;
    segset.isectMask = 0xFFFF;
    segset.discFunc = NULL;
    segset.bound = NULL;

    //*************************************************************
    //You also don't discard the CULL_BACK
    //segset.mode = PFTRAV_IS_PRIM|PFTRAV_IS_NORM|PFTRAV_IS_CULL_BACK;
    //After change
    segset.mode = PFTRAV_IS_PRIM|PFTRAV_IS_NORM;
    //***************************************************************

    segset.segs[0].dir.set(0.0f, 0.0f, -1.0f);
    segset.segs[0].length = 50000.0f;

    //
    // main loop
    //
    while (!shared->exitFlag)
    {
        pfHit **hits[32];
        int isect;

        view.xyz.set(0.0f, shared->yval, shared->zval);
        view.hpr.set(0.0f, -5.0f, 0.0f);

        chan->setView(view.xyz, view.hpr);
        pfFrame();

        // increment view position; if too far, reset
        shared->yval += 0.1f;
        if (shared->yval > 110.0f) shared->yval = 0.0f;

        // update location of intersection segment
        segset.segs[0].pos.set(0.0f, shared->yval,shared->zval);

        // do an intersection test against the scene graph
        isect = root->isect(&segset, hits);

        // if successful, set our height to that of
        // the point of contact, plus a small offset
        if (isect)
        {
            pfVec3 pnt, xpnt;
            pfMatrix xmat;
            (*hits[0])->query(PFQHIT_POINT, pnt.vec);
            // transform object point into scene coordinates
            (*hits[0])->query(PFQHIT_XFORM, (float*)xmat.mat);

            //****************************************************
            //Following are added

            unsigned int flag;
            (*hits[0])->query(PFQHIT_FLAGS, &flag);
            if( !(flag&PFHIT_PRIM))
                 printf("error!\n");

            int prim_index, tri_index;
            (*hits[0])->query(PFQHIT_PRIM, &prim_index);
            (*hits[0])->query(PFQHIT_TRI, &tri_index);
            printf("prim_index = %d\t tri_index = %d\n", prim_index,
tri_index);

            //****************************************************

            xpnt.xformPt(pnt, xmat);
            shared->zval = xpnt[PF_Z] + 0.5f;
        }
    }

    pfExit();
    return 0;
}

//
// Pipe Initialization Callback to open and configure
// GL window, and set up GL event handling
//

static void
OpenPipeWin(pfPipeWindow *pw)
{
    Display *dsp;
    Window win;

    pw->open();

    dsp = pfGetCurWSConnection();
    win = pw->getWSWindow();
    XSelectInput(dsp, win, KeyPressMask);
    XMapWindow(dsp, win);
}

//
// Draw Process Callback to draw the channel and handle GL events
//
static void DrawChannel (pfChannel *chan, void *)
{
    Display *dsp;

    // clear and draw the channel
    chan->clear();
    pfDraw();

    dsp = pfGetCurWSConnection();
    if (XEventsQueued(dsp, QueuedAfterFlush))
    while (XEventsQueued(dsp, QueuedAlready))
    {
        XEvent event;
        XNextEvent(dsp, &event);
        switch (event.type)
        {
        case KeyPress:
            {
                char buf[100];
                int rv;
                KeySym ks;
                rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
                switch(ks)
                {
                case XK_Escape:
                    exit(0);
                    break;
                case XK_F1:
                case XK_g:
                    shared->showStats = !shared->showStats;
                    break;
                default:
                    break;
                }
            }
        }
    }

    if (shared->showStats) chan->drawStats();
}

/////////////////////////////////////////////////////////////////////////

Angus Dorbie wrote:

> Could you post your intersection code?
>
> Cheers,Angus.
>
> Yigang Wang wrote:
> >
> > Hello,
> > If you like, i hope you to see the program
> > /usr/share/Performer/src/pguide/libpf/C++/intersect.C. The pfGeoSet is
> > a Cube-similar object, which is made by 6 QUAD faces. I change the
> > representation of each face with strips , so i have 6 strips instead
> > of a single strip, and length of each strip is 4. In the original case
> > ( not changed by me), the parameters corresponding to PFQHIT_PRIM and
> > PFQHIT_TRI changed correctly, that is, prim_index changed with
> > intersection points. However, it doesn't change after my changing.
> >
> > Here is what i have made change to the pfGeoSet.
> >
> > Original,
> >
> > pfVec3 *verts = (pfVec3*) new(8*sizeof(pfVec3)) pfMemory;
> > verts[0].set(-1.0f, -1.0f, 1.0f);
> > verts[1].set( 1.0f, -1.0f, 1.0f);
> > verts[2].set( 1.0f, 1.0f, 1.0f);
> > verts[3].set(-1.0f, 1.0f, 1.0f);
> > verts[4].set(-2.0f, -2.0f, 0.0f);
> > verts[5].set( 2.0f, -2.0f, 0.0f);
> > verts[6].set( 2.0f, 2.0f, 0.0f);
> > verts[7].set(-2.0f, 2.0f, 0.0f);
> >
> > ushort *vindex = (ushort*) new(24*sizeof(ushort)) pfMemory;
> > vindex[0] = 0; vindex[1] = 1; vindex[2] = 2; vindex[3] = 3; //
> > front
> > vindex[4] = 0; vindex[5] = 3; vindex[6] = 7; vindex[7] = 4; //
> > left
> > vindex[8] = 4; vindex[9] = 7; vindex[10] = 6; vindex[11] = 5; //
> > back
> > vindex[12] = 1; vindex[13] = 5; vindex[14] = 6; vindex[15] = 2; //
> > right
> > vindex[16] = 3; vindex[17] = 2; vindex[18] = 6; vindex[19] = 7; //
> > top
> > vindex[20] = 0; vindex[21] = 4; vindex[22] = 5; vindex[23] = 1; //
> > bottom
> >
> > pfVec4 *colors = (pfVec4*) new(4*sizeof(pfVec4)) pfMemory;
> > colors[0].set(1.0f, 0.0f, 0.0f, 0.5f);
> > colors[1].set(0.0f, 1.0f, 0.0f, 0.5f);
> > colors[2].set(0.0f, 0.0f, 1.0f, 0.5f);
> > colors[3].set(1.0f, 1.0f, 1.0f, 0.5f);
> >
> > ushort *cindex = (ushort*) new(24*sizeof(ushort)) pfMemory;
> > cindex[0] = 0; cindex[1] = 1; cindex[2] = 2; cindex[3] = 3;
> > cindex[4] = 0; cindex[5] = 1; cindex[6] = 2; cindex[7] = 3;
> > cindex[8] = 0; cindex[9] = 1; cindex[10] = 2; cindex[11] = 3;
> > cindex[12] = 0; cindex[13] = 1; cindex[14] = 2; cindex[15] = 3;
> > cindex[16] = 0; cindex[17] = 1; cindex[18] = 2; cindex[19] = 3;
> > cindex[20] = 0; cindex[21] = 1; cindex[22] = 2; cindex[23] = 3;
> >
> > pfGeoSet *gset = new pfGeoSet;
> > gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, verts, vindex);
> > gset->setAttr(PFGS_COLOR4, PFGS_PER_VERTEX, colors, cindex);
> > gset->setPrimType(PFGS_QUADS);
> > gset->setNumPrims(6);
> >
> > My changes, (Note: the index order is different from QUAD case)
> >
> > pfVec3 *verts = (pfVec3*) new(8*sizeof(pfVec3)) pfMemory;
> > verts[0].set(-1.0f, -1.0f, 1.0f)
> > verts[1].set( 1.0f, -1.0f, 1.0f);
> > verts[2].set( 1.0f, 1.0f, 1.0f);
> > verts[3].set(-1.0f, 1.0f, 1.0f);
> > verts[4].set(-2.0f, -2.0f, 0.0f);
> > verts[5].set( 2.0f, -2.0f, 0.0f);
> > verts[6].set( 2.0f, 2.0f, 0.0f);
> > verts[7].set(-2.0f, 2.0f, 0.0f);
> >
> > ushort *vindex = (ushort*) new(24*sizeof(ushort)) pfMemory;
> > vindex[0] = 0; vindex[1] = 1; vindex[2] = 3; vindex[3] = 2; //
> > top
> > vindex[4] = 0; vindex[5] = 3; vindex[6] = 4; vindex[7] = 7; //
> > left
> > vindex[8] = 4; vindex[9] = 7; vindex[10] = 5; vindex[11] = 6; //
> > bottom
> > vindex[12] = 1; vindex[13] = 5; vindex[14] = 2; vindex[15] = 6; //
> > right
> > vindex[16] = 3; vindex[17] = 2; vindex[18] = 7; vindex[19] = 6; //
> > back
> > vindex[20] = 0; vindex[21] = 4; vindex[22] = 1; vindex[23] = 5; //
> > front
> >
> > pfVec4 *colors = (pfVec4*) new(4*sizeof(pfVec4)) pfMemory;
> > colors[0].set(1.0f, 0.0f, 0.0f, 0.5f);
> > colors[1].set(0.0f, 1.0f, 0.0f, 0.5f);
> > colors[2].set(0.0f, 0.0f, 1.0f, 0.5f);
> > colors[3].set(1.0f, 1.0f, 1.0f, 0.5f);
> >
> > ushort *cindex = (ushort*) new(24*sizeof(ushort)) pfMemory;
> > cindex[0] = 0; cindex[1] = 1; cindex[2] = 3; cindex[3] = 2;
> > cindex[4] = 0; cindex[5] = 1; cindex[6] = 3; cindex[7] = 2;
> > cindex[8] = 0; cindex[9] = 1; cindex[10] = 3; cindex[11] = 2;
> > cindex[12] = 0; cindex[13] = 1; cindex[14] = 3; cindex[15] = 2;
> > cindex[16] = 0; cindex[17] = 1; cindex[18] = 3; cindex[19] = 2;
> > cindex[20] = 0; cindex[21] = 1; cindex[22] = 3; cindex[23] = 2;
> >
> >
> > int *length = (int *) new(6*sizeof(int)) pfMemory;
> > for(uint i=0; i<6; i++)
> > length[i] = 4;
> >
> > pfGeoSet *gset = new pfGeoSet;
> >
> > gset->setPrimType(PFGS_TRISTRIPS);
> > gset->setPrimLengths(length);
> > gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, verts, vindex);
> > gset->setAttr(PFGS_COLOR4, PFGS_PER_VERTEX, colors, cindex);
> > gset->setNumPrims(6);
> >
> > After the change, please get the value of PFQHIT_PRIM, it always is 0.
> > In fact, in my application, it is always a constant value.
> >
> > Thank you for your reconsideration.
> >
> > Best regards
> >
> > Yigang
> >
> >
> > Angus Dorbie wrote:
> >
> > > You say you set a strip, a strip is a single primitive with several
> > > triangles. You may optionally have more than one triangle primitive
> > > and
> > > set the associated lengths array when you create the geoset so, to
> > > narrow everything down fully if you use multiple strips you need to
> > > look
> > > at PFQHIT_PRIM and PFQHIT_TRI, the former telling you which tristrip
> > > and
> > > the latter telling you which triangle in the strip. As things stand
> > > you
> > > probably only have the one primitive (and a single value in lengths)
> > >
> > > which is obviously always 0 and so PFQHIT_TRI will be the number you
> > >
> > > need indicating which triangle in strip 0 you have hit.
> > >
> > > Cheers,Angus.
> > >
> > > Yigang Wang wrote:
> > > >
> > > > Hi, all.
> > > >
> > > > I am making a program to select some parts of the triangle mesh
> > > with
> > > > Performer. I need the returned parameters of the index of strip
> > > > primitive (PFHIT_PRIM) and the index of triangle in the strip
> > > > (PFHIT_TRI). But it result in an error in my program. So i check
> > > the
> > > > example program
> > > /usr/share/Performer/src/pguide/libpf/C++/intersect.C
> > > >
> > > > I made a small change of the programe
> > > > /usr/share/Performer/src/pguide/libpf/C++/intersect.C, there
> > > appear an
> > > > strange result. In the example, i change the primitive of the
> > > pfGeoSet
> > > > (QUADS) to strips representation ( not change the real geometry),
> > > and
> > > > then i get the result of intersection from the fuuctions:
> > > > pfHit::query(&prim_index, PFHIT_PRIM) and
> > > pfHit::mQuery(&tri_index,
> > > > PFHIT_TRI), I found that the prim_index is always 0. However it
> > > > changed correctly for QUADS case or POLYS case.
> > > >
> > > > Is it a bug or not? Do i need to set more parameters for pfHit?
> > > >
> > > > Thanks for your reply.
> > > >
> > > > Yigang
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > --
> > > >
> > > **********************************************************************
> > >
> > > > Yigang Wang tel: +49 (2241) 14
> > > 2980
> > > > http://www.viswiz.gmd.de fax: +49 (2241) 14
> > > 2040
> > > > email:
> > > yigang.wang++at++gmd.de
> > > > GMD - The German National Research Center for Information
> > > Technology
> > > >
> > > >
> > >
> > > --
> > > For Performer+OpenGL tutorials http://www.dorbie.com/
> > >
> > > "In the middle of difficulty lies opportunity."
> > > --Albert Einstein
> >
> > --
> > **********************************************************************
> > Yigang Wang tel: +49 (2241) 14 2980
> > http://www.viswiz.gmd.de fax: +49 (2241) 14 2040
> > email: yigang.wang++at++gmd.de
> > GMD - The German National Research Center for Information Technology
> >
> >
>
> --
> For Performer+OpenGL tutorials http://www.dorbie.com/
>
> "In the middle of difficulty lies opportunity."
> --Albert Einstein

--
**********************************************************************
 Yigang Wang                                  tel: +49 (2241) 14 2980
 http://www.viswiz.gmd.de                     fax: +49 (2241) 14 2040
                                            email: yigang.wang++at++gmd.de
 GMD - The German National Research Center for Information Technology


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Thu Dec 07 2000 - 00:41:31 PST

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.