Re: User Engines

New Message Reply Date view Thread view Subject view Author view

Yair Kurzion (yair++at++polygon.engr.sgi.com)
Fri, 20 Aug 1999 11:09:20 -0700 (PDT)


Hello Neil !

> Can someone direct me somewhere that has an example of a user engine which is well documented. I have tried to user the morph_engine, user_engine examples but they are not documented and are confusing. What I am tring to do is create an engine which will move a camera view from on position to another position smoothly. Basically I want to give it two matrices the start and end and have the inbetween taken care of my the engine.

First, you can try the code in pguide/libpf/C/ASD_decal.c
It creates a user-function pfEngine in line 334, and uses it to set the contents
of a Fluxed GeoSet (in function decal_engine). Just in case it is not documented
enough (OK, it probably isn't), here are some notes.

pfEngines are useful for computing functions on a collection of input buffers
(may be fluxed) and store the result in a single output buffer (may also be
fluxed). Using an engine makes sense when some of the inputs are generated by
a different process, and you want to re-compute the pfEngine result when its
inputs change.

So, I am guessing that you want to connect three inputs to your pfEngine:
   o Matrix # 0 (M0).
   o Matrix # 1 (M1).
   o A float 't' in the range [0,1] - the interpolation weight.

Assume the result of the computation goes into a matrix M2.

For the example let's say the sources and the destination are Fluxed. Your code
should look something like the following.

Initialization code:

    ... Create a Fluxed matrix.
    M0_flux = pfNewFlux( ... );

    ... Force re-computation of pfEngine when this Flux changes.
    pfFluxMode(M0_flux, PFFLUX_PUSH, PF_ON );

    ... Same for second matrix

    M1_flux = pfNewFlux( ... );
    pfFluxMode(M1_flux, PFFLUX_PUSH, PF_ON );

    ... Create fluxed interpolation weight.

    t_flux = pfNewFlux( ... );
    pfFluxMode(t_flux, PFFLUX_PUSH, PF_ON );

    ... Create fluxed result (a new matrix).

    M2_flux = pfNewFlux( ... );

    ... Create the engine.
    engine = pfNewEngine (PFENG_USER_FUNCTION, pfGetSharedArena());

    ... viewpoint_interpolation is your user-function.
    pfEngineUserFunction (engine, viewpoint_interpolation);

    ... Connect all sources/destination to the Engine.

    pfEngineSrc (engine, 0, M0_flux, 0, 0, 0, 0);
    pfEngineSrc (engine, 1, M1_flux, 0, 0, 0, 0);
    pfEngineSrc (engine, 2, t_flux, 0, 0, 0, 0);

    pfEngineDst (engine, M2_flux, 0, 0, 0);

    ... You can use M2_flux as the matrix of a pfFCS. The geometry under this
    ... FCS node will be transformed by the result of your engine.

    fcs = pfNewFCS (M2_flux);

Your user-function:

    void viewpoint_interpolation(pfEngine *_engine)
    {
        void *M0_f, M1_f, M2_f, t_f;
        int d_offset, s_offset;
        ushort *d_ilist, *s_ilist;
        int d_stride, s_stride;
        float *t, *M0, *M1;

        ... Get a hold of Engine destination

        pfGetEngineDst (_engine, &M2_f, &d_ilist, &d_offset, &d_stride);

        ... Get a hold of Engine sources.

        pfGetEngineSrc
            (_engine, 0, &M0_f, &s_ilist, &s_icount, &s_offset, &s_stride);
        pfGetEngineSrc
            (_engine, 1, &M1_f, &s_ilist, &s_icount, &s_offset, &s_stride);
        pfGetEngineSrc
            (_engine, 2, &t_f, &s_ilist, &s_icount, &s_offset, &s_stride);

        ... Since all sources are Fluxes, we must get their current value:

        M0 = (float *) pfGetFluxCurData ((pfFlux *) M0_f);
        M1 = (float *) pfGetFluxCurData ((pfFlux *) M1_f);
        t = (float *) pfGetFluxCurData ((pfFlux *) t_f);

        ... Since destination is a Flux, must get a writable copy:

        M2 = (float *) pfGetFluxWritableData ((pfFlux *) M2_f);

        ... Now, compute the interpolation you want

        compute_viewpoint_interpolation (M0, M1, t, M2);

        ... You must NOT call writeComplete on M2_f.
    }

Whenever you call pfGetFluxWritableData on any of the source fluxes, modify
its contents and call pfFluxWriteComplete, the value of the destination Flux
will be re-computed. You may modify the sources in any Performer process
including DBASE and COMPUTE.

-yair

-- 
\_________  \_____  \__    \__  \_____         Yair Kurzion
\_________  \_____   \__   \__  \_____         yair++at++sgi.com
       \__     \__   \____\__      \__   http://reality.sgi.com/yair
       \__          \__  \__                Work: (650) 933-6502
       \__          \__   \__               Home: (408) 226-9771
       \__          \__    \__             

New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Fri Aug 20 1999 - 11:09:36 PDT

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