John McCrea (john++at++sense8.com)
Mon, 02 Feb 1998 09:02:05 -0800
Thank You.
At 10:04 PM 1/31/98 -0500, Kenneth B Russell wrote:
>
>If either coordinates OR normals are specified as either pfFluxes
>or pfCycleBuffers (the latter from the output of the now-obsolete
>pfMorph node), then:
> - the color attribute for the GeoSet must be set, and
> - the colors must be specified PER_VERTEX, and
> - the colors must be allocated out of a pfFlux/pfCycleBuffer.
> They can not be allocated even using pfMalloc().
>
>I found this bug because we never specify the PFGS_COLOR4
>attribute in our geometry (instead using a pfMaterial to do so),
>and our morphing code broke under 2.2. A rewrite using the
>pfFlux/pfEngine mechanism had the same problem. See the attached
>example (derived from the old morph.c, but visible in
>morph_engine.C as well) which demonstrates the bug.
>
>The only workaround is to specify per-vertex colors in a
>pfCycleBuffer/pfFlux, which is a waste of space if the color is
>the same across the piece of geometry.
>
>Any chance we could get this fixed in a patch?
>
>Thanks much.
>
>-Ken
>
>
>__________________________________________________________________________
>Kenneth B. Russell Synthetic Characters Group, MIT Media Lab
>kbrussel++at++media.mit.edu http://www.media.mit.edu/~kbrussel
>
>
>------
>/*
> * 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>
>#include <Performer/pr/pfLinMath.h>
>#include <Performer/pr/pfGeoSet.h>
>#include <Performer/pr/pfGeoState.h>
>#include <Performer/pr/pfMaterial.h>
>#include <Performer/pr/pfLight.h>
>#include <Performer/pf/pfGeode.h>
>#include <Performer/pf/pfDCS.h>
>#include <Performer/pf/pfScene.h>
>#include <Performer/pf/pfMorph.h>
>#include <Performer/pf/pfLightSource.h>
>#include <Performer/pf/pfChannel.h>
>#include <Performer/pf/pfPipeWindow.h>
>
>// Bug in pfGeoSet, Performer 2.2.
>// Demonstrated by Kenneth B. Russell (kbrussel++at++media.mit.edu)
>
>// Switches for the two instances of the bug.
>#define MORPH_NORMALS // Turns on morphing of normals
>#define MORPH_COORDS // Turns on morphing of coordinates
>#define COLORS_AS_CBUF // Makes colors a CycleBuffer. Turning
> // this off makes colors malloced using
> // pfMalloc. But see NOTE: below.
>#define NO_COLORS // Gives GeoSet no colors (inherits from
> // pfMaterial)
>
>// Combinations Bug?
>// N_C No
>// (M_N || M_C) && (C_A_C && N_C) YES
>
>// Neither of these attempted workarounds work properly. The only
>// workaround, therefore, is to specify per-vertex colors in every
>// GeoSet for which either the normals or the coordinates are morphing
>// (either using the pfMorph node OR the pfFlux/pfEngine mechanism).
>//#define OVERALL_COLORS
>//#define PER_PRIM_COLORS
>
>int nSph;
>pfCycleBuffer *cbuf;
>
>/*------------------------------------------------------------------*/
>
>static void
>breatheMorph(pfMorph *morph, double t)
>{
> float s = (sinf(t) + 1.0f) / 2.0f;
> float weights[2];
> int i;
>
> weights[0] = s;
> weights[1] = 1.0f - s;
>
> morph->setWeights(-1, weights);
>}
>
>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 = new pfMorph;
> geode = new pfGeode;
> gset = pfdNewSphere(400, arena);
> gstate = new(arena) pfGeoState;
>
> mtl = new(arena) pfMaterial;
> mtl->setColor(PFMTL_DIFFUSE, 0.0f, 1.0f, 1.0f);
> mtl->setColor(PFMTL_SPECULAR, 1.0f, 1.0f, 1.0f);
> mtl->setColorMode(PFMTL_BOTH, PFMTL_CMODE_AD);
> mtl->setShininess(32);
>
> gstate->setAttr(PFSTATE_FRONTMTL, mtl);
> gstate->setMode(PFSTATE_ENLIGHTING, 1);
> gset->setGState(gstate);
>
> geode->addGSet(gset);
> morph->addChild(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.
> */
> gset->setBound(NULL, PFBOUND_STATIC);
> geode->setBound(NULL, PFBOUND_STATIC);
>
> gset->getAttrLists(PFGS_COORD3, (void**)&coords, &icoords);
> gset->getAttrLists(PFGS_NORMAL3, (void**)&norms, &inorms);
> nSph = pfGetSize(coords) / sizeof(pfVec3);
>
> cbuf = new(arena) pfCycleBuffer(nSph * sizeof(pfVec4));
>
> ncoords = (pfVec3 *)pfMalloc(pfGetSize(coords), arena);
> nnorms = (pfVec3 *)pfMalloc(pfGetSize(norms), arena);
>
>#ifdef COLORS_AS_CBUF
> colors = (pfVec4*) cbuf->getCurData();
>#else
> colors = (pfVec4*) pfMalloc(nSph * sizeof(pfVec4));
>#endif
> for (i = 0; i < nSph; i++)
> {
> colors[i].set(0.0f, 1.0f, 1.0f, 1.0f);
> ncoords[i].scale(2.0f, coords[i]);
> nnorms[i] = norms[i];
> }
> /* Set all pfCycleMemories to the same colors */
> cbuf->init(cbuf->getCurData());
>
>#ifndef NO_COLORS
># ifdef COLORS_AS_CBUF
> gset->setAttr(PFGS_COLOR4, PFGS_PER_VERTEX,
> (void*)cbuf, NULL);
># else
> // NOTE: this DOES work if
> // colors = (pfVec4*) cbuf->getCurData();
> gset->setAttr(PFGS_COLOR4, PFGS_PER_VERTEX,
> (void*)colors, NULL);
># endif
>#endif
>
>#ifdef OVERALL_COLORS
> pfCycleBuffer *tmpBuf = new(arena) pfCycleBuffer(sizeof(pfVec4));
> pfVec4 *tmpColors = (pfVec4 *) cbuf->getCurData();
> tmpColors[0].set(0.0f, 1.0f, 0.0f, 1.0f);
> cbuf->init(cbuf->getCurData());
> gset->setAttr(PFGS_COLOR4, PFGS_OVERALL, tmpBuf, NULL);
>#endif
>
>#ifdef PER_PRIM_COLORS
> int numPrims = gset->getNumPrims();
> pfCycleBuffer *tmpBuf = new(arena) pfCycleBuffer(numPrims *
sizeof(pfVec4));
>
> pfVec4 *tmpColors = (pfVec4 *) cbuf->getCurData();
> for (int q = 0; q < numPrims; q++)
> tmpColors[q].set(0.0f, 1.0f, 0.0f, 1.0f);
> cbuf->init(cbuf->getCurData());
> gset->setAttr(PFGS_COLOR4, PFGS_PER_PRIM, tmpBuf, NULL);
>#endif
>
>#ifdef MORPH_COORDS
> /* Morph attribute 0 is coordinates */
> srcs[0] = (float*)coords;
> srcs[1] = (float*)ncoords;
> morph->setAttr(0, 3, nSph, NULL, 2, srcs, NULL, NULL);
>
> gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX,
> (void*)morph->getDst(0), icoords);
>#endif
>
>#ifdef MORPH_NORMALS
> /* Morph attribute 1 is normals */
> srcs[0] = (float*)norms;
> srcs[1] = (float*)nnorms;
> morph->setAttr(1, 3, nSph, NULL, 2, srcs, NULL, NULL);
>
> gset->setAttr(PFGS_NORMAL3, PFGS_PER_VERTEX,
> (void*)morph->getDst(1), inorms);
>#endif
>
> return morph;
>}
>
>void
>OpenPipeWin (pfPipeWindow *pw)
>{
> pw->open();
> (new pfLightModel)->apply();
>}
>
>void
>DrawChannel (pfChannel *chan, void *data)
>{
> pfVec4 clr;
>
> clr.set(.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 = new pfScene;
> morphDCS = new pfDCS;
> morph = initMorph();
> morphDCS->addChild(morph);
> scene->addChild(morphDCS);
>
> /* determine extent of scene's geometry */
> scene->getBound(&bsphere);
>
> /* Configure and open GL window */
> p = pfGetPipe(0);
> pw = new pfPipeWindow(p);
> pw->setName(argv[0]);
> pw->setConfigFunc(OpenPipeWin);
> pw->setOriginSize(0, 0, 500, 500);
> pw->config();
>
> /* Create and configure a pfChannel. */
> chan = new pfChannel(p);
> chan->setScene(scene);
> chan->setNearFar(1.0f, 10.0f * bsphere.radius);
> chan->setFOV(45.0f, 0.0f);
> view.xyz = bsphere.center;
> view.xyz[PF_Y] -= 3.0f * bsphere.radius;
> view.hpr.set(0.0f, 0.0f, 0.0f);
> chan->setView(view.xyz, view.hpr);
>
> chan->setTravFunc(PFTRAV_DRAW, DrawChannel);
>
> /* Create a pfLightSource and attach it to scene. */
> ls = new pfLightSource;
> ls->setPos(view.xyz[0], view.xyz[1], view.xyz[2], 1.0f);
> scene->addChild(ls);
>
> /* Simulate for twenty seconds. */
> while (1)
> {
> pfMatrix mat;
>
> t = pfGetTime();
>
> /* Update morph */
> breatheMorph(morph, t);
>
> /* Initiate cull/draw for this frame. */
> pfFrame();
> }
>
> /* Terminate parallel processes and exit. */
> pfExit();
>
> return 0;
>}
>=======================================================================
>List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
> Submissions: info-performer++at++sgi.com
> Admin. requests: info-performer-request++at++sgi.com
>
>
==================================================================
John McCrea Sense8 Corporation
Vice President of Worldwide 100 Shoreline Hwy., Suite 282
Sales and Marketing Mill Valley, CA 94941
Direct: (415) 289-7716 Main: (415) 331-6318
john++at++sense8.com Fax: (415) 331-9148
==================================================================
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
Submissions: info-performer++at++sgi.com
Admin. requests: info-performer-request++at++sgi.com
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:56:42 PDT