Re: pfMorph under 2.2

New Message Reply Date view Thread view Subject view Author view

Sharon Clay (src++at++rose.engr.sgi.com)
Fri, 30 Jan 1998 02:19:34 -0800


+>---- On Jan 30, 8:38am, Kenneth B Russell wrote:
> Subject: pfMorph under 2.2
->From guest++at++holodeck Fri Jan 30 02:07:28 1998
->
->I saw from the release notes and manual pages that pfMorph is
->obsolete. But *should* it work if it's used? The reason I ask is
->we reimplemented our morphing code to use pfFlux/pfEngine as in
->morph_engine.C, but see garbage: the same sort of garbage, in
->fact, that we see if we use our old code which uses the pfMorph
->node. I'm afraid we're corrupting memory somewhere in our app,
->and our version of purify (4.0.1) hangs in _r4kup_setlock when
->run with a Performer application (currently working on getting an
->upgrade...)
->
->Thanks for the sanity check,

We did nothing to break pfMorph. Here is the old morph.c pguide example
morph.c that still works to use as sanity check on your side.
You might grab dmalloc off our web site to help detect memory corruption.

/*
 * Copyright 1995, Silicon Graphics, Inc.
 * ALL RIGHTS RESERVED
 *
 * UNPUBLISHED -- Rights reserved under the copyright laws of the United
 * States. Use of a copyright notice is precautionary only and does not
 * imply publication or disclosure.
 *
 * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to restrictions
 * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
 * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
 * in similar or successor clauses in the FAR, or the DOD or NASA FAR
 * Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
 * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without
 * fee, provided that (i) the above copyright notices and this
 * permission notice appear in all copies of the software and related
 * documentation, and (ii) the name of Silicon Graphics may not be
 * used in any advertising or publicity relating to the software
 * without the specific, prior written permission of Silicon Graphics.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL,
 * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
 * THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OR PERFORMANCE OF THIS SOFTWARE.
 *
 * morph.c: Performer program to demonstrate use of pfMorph node.
 * Based on simple.c
 *
 * $Revision: 1.5 $ $Date: 1995/11/22 14:36:00 $
 *
 */

#include <stdlib.h>
#include <math.h>
#include <Performer/pf.h>
#include <Performer/pfdu.h>

int nSph;
pfCycleBuffer *cbuf;

/*------------------------------------------------------------------*/

static void
breatheMorph(pfMorph *morph, double t)
{
    float s = (sinf(t) + 1.0f) / 2.0f;
    float weights[2];
    int i;
    pfVec4 *colors;

    weights[0] = s;
    weights[1] = 1.0f - s;

    pfMorphWeights(morph, 0, weights);
    pfMorphWeights(morph, 1, weights);

    colors = (pfVec4*)pfGetData(cbuf);
    for (i=0; i<nSph; i++)
        colors[i][0] = s;

    pfCBufferChanged(cbuf);
}

static pfMorph*
initMorph(void)
{
    pfGeoSet *gset;
    pfGeode *geode;
    pfGeoState *gstate;
    pfMaterial *mtl;
    pfMorph *morph;
    ushort *icoords, *inorms;
    pfVec3 *coords, *ncoords, *norms, *nnorms;
    pfVec4 *colors;
    float *srcs[2];
    int i;
    void *arena = pfGetSharedArena();

    morph = pfNewMorph();
    geode = pfNewGeode();
    gset = pfdNewSphere(400, arena);
    gstate = pfNewGState(arena);

    mtl = pfNewMtl(arena);
    pfMtlColor(mtl, PFMTL_DIFFUSE, 1.0f, 0.0f, 0.0f);
    pfMtlColor(mtl, PFMTL_SPECULAR, 1.0f, 1.0f, 1.0f);
    pfMtlColorMode(mtl, PFMTL_BOTH, PFMTL_CMODE_AD);
    pfMtlShininess(mtl, 32);

    pfGStateAttr(gstate, PFSTATE_FRONTMTL, mtl);
    pfGStateMode(gstate, PFSTATE_ENLIGHTING, 1);
    pfGSetGState(gset, gstate);

    pfAddGSet(geode, gset);
    pfAddChild(morph, geode);

    /*
     * NULL forces recomputation of bound. Force it to be static
     * to avoid expensive recomputation. Static bound should encompass
     * the extent of all morph possibilities.
    */
    pfGSetBBox(gset, NULL, PFBOUND_STATIC);
    pfNodeBSphere(geode, NULL, PFBOUND_STATIC);

    pfGetGSetAttrLists(gset, PFGS_COORD3, (void**)&coords, &icoords);
    pfGetGSetAttrLists(gset, PFGS_NORMAL3, (void**)&norms, &inorms);
    nSph = pfGetSize(coords) / sizeof(pfVec3);

    cbuf = pfNewCBuffer(nSph * sizeof(pfVec4), arena);

    ncoords = pfMalloc(pfGetSize(coords), arena);
    nnorms = pfMalloc(pfGetSize(norms), arena);

    colors = (pfVec4*) pfGetData(cbuf);
    for (i=0; i<nSph; i++)
    {
        int max;
        float t;

        /* Find which face of the cube this vertex maps to */
        if (PF_ABS(coords[i][PF_X]) > PF_ABS(coords[i][PF_Y]))
        {
            if (PF_ABS(coords[i][PF_X]) > PF_ABS(coords[i][PF_Z]))
                max = PF_X;
            else
                max = PF_Z;
        }
        else
        {
            if (PF_ABS(coords[i][PF_Y]) > PF_ABS(coords[i][PF_Z]))
                max = PF_Y;
            else
                max = PF_Z;
        }

        pfSetVec4(colors[i], 0.0f, 0.0f, 0.0f, 1.0f);
        colors[i][max] = 1.0f;

        /* Compute cube normals and coordinates */
        pfSetVec3(nnorms[i], 0.0f, 0.0f, 0.0f);
        if (coords[i][max] < 0.0f)
        {
            t = -1.0f / coords[i][max];
            pfScaleVec3(ncoords[i], t, coords[i]);
            nnorms[i][max] = -1.0f;
        }
        else
        {
            t = 1.0f / coords[i][max];
            pfScaleVec3(ncoords[i], t, coords[i]);
            nnorms[i][max] = 1.0f;
        }
    }
    /* Set all pfCycleMemories to the same colors */
    pfInitCBuffer(cbuf, pfGetData(cbuf));

    pfGSetAttr(gset, PFGS_COLOR4, PFGS_PER_VERTEX,
               (void*)cbuf, NULL);

    /* Morph attribute 0 is coordinates */
    srcs[0] = (float*)coords;
    srcs[1] = (float*)ncoords;
    pfMorphAttr(morph, 0, 3, nSph, NULL, 2, srcs, NULL, NULL);

    pfGSetAttr(gset, PFGS_COORD3, PFGS_PER_VERTEX,
               (void*)pfGetMorphDst(morph, 0), icoords);

    /* Morph attribute 1 is normals */
    srcs[0] = (float*)norms;
    srcs[1] = (float*)nnorms;
    pfMorphAttr(morph, 1, 3, nSph, NULL, 2, srcs, NULL, NULL);

    pfGSetAttr(gset, PFGS_NORMAL3, PFGS_PER_VERTEX,
               (void*)pfGetMorphDst(morph, 1), inorms);

    return morph;
}

void
OpenPipeWin (pfPipeWindow *pw)
{
    pfOpenPWin(pw);
    pfApplyLModel(pfNewLModel(NULL));
}

void
DrawChannel (pfChannel *chan, void *data)
{
    pfVec4 clr;

    pfSetVec4(clr, .2f, .2f, .2f, 1.0f);
    pfClear(PFCL_COLOR|PFCL_DEPTH, clr);
    pfDraw();
}

int
main (int argc, char *argv[])
{
    double t = 0.;
    pfScene *scene;
    pfDCS *morphDCS;
    pfMorph *morph;
    pfPipe *p;
    pfPipeWindow *pw;
    pfChannel *chan;
    pfSphere bsphere;
    pfCoord view;
    pfLightSource *ls;

    /* Initialize Performer */
    pfInit();

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

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

    /* Create and attach morph to a pfScene. */
    scene = pfNewScene();
    morphDCS = pfNewDCS();
    morph = initMorph();
    pfAddChild(morphDCS, morph);
    pfAddChild(scene, morphDCS);

    /* determine extent of scene's geometry */
    pfGetNodeBSphere (scene, &bsphere);

    /* Configure and open GL window */
    p = pfGetPipe(0);
    pw = pfNewPWin(p);
    pfPWinName(pw, argv[0]);
    pfPWinConfigFunc(pw, OpenPipeWin);
    pfPWinOriginSize(pw, 0, 0, 500, 500);
    pfConfigPWin(pw);

    /* Create and configure a pfChannel. */
    chan = pfNewChan(p);
    pfChanScene(chan, scene);
    pfChanNearFar(chan, 1.0f, 10.0f * bsphere.radius);
    pfChanFOV(chan, 45.0f, 0.0f);
    pfCopyVec3(view.xyz, bsphere.center);
    view.xyz[PF_Y] -= 3.0f * bsphere.radius;
    pfSetVec3(view.hpr, 0.0f, 0.0f, 0.0f);
    pfChanView(chan, view.xyz, view.hpr);
    pfChanTravFunc(chan, PFTRAV_DRAW, DrawChannel);

    /* Create a pfLightSource and attach it to scene. */
    ls = pfNewLSource();
    pfLSourcePos(ls, view.xyz[0], view.xyz[1], view.xyz[2], 1.0f);
    pfAddChild(scene, ls);

    /* Simulate for twenty seconds. */
    while (1)
    {
        pfMatrix mat;

        /* Spin morph object */
        t = pfGetTime();
        pfMakeRotMat(mat, t*57.0f, 1.0f, -0.3f, 1.0f);
        pfDCSMat(morphDCS, mat);

        /* Update morph */
        breatheMorph(morph, t);

        /* Initiate cull/draw for this frame. */
        pfFrame();
    }

    /* Terminate parallel processes and exit. */
    pfExit();

    return 0;
}

-- 
-----{-----{---++at++   -----{----{---++at++   -----{----{---++at++   -----{----{---++at++
Sharon Rose Clay - Silicon Graphics, Advanced Systems Dev.
src++at++sgi.com  (650) 933 - 1002  FAX: (650) 965 - 2658  MS 8U-590
-----{-----{---++at++   -----{----{---++at++   -----{----{---++at++   -----{----{---++at++
=======================================================================
List Archives, FAQ, FTP:  http://www.sgi.com/Technology/Performer/
            Submissions:  info-performer++at++sgi.com
        Admin. requests:  info-performer-request++at++sgi.com

New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:56:39 PDT

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