root/OpenSceneGraph/trunk/src/osgPlugins/geo/geoActions.cpp @ 13041

Revision 13041, 27.1 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// GEO format (carbon graphics Inc) loader for the OSG real time scene graph
2// www.carbongraphics.com for more information about the Geo animation+ modeller
3// 2002
4// actions & behaviours for Geo loader in OSG
5
6#include <string>
7
8#include <stdio.h>
9#include <math.h>
10#include <osg/Image>
11#include <osg/Group>
12#include <osg/LOD>
13#include <osg/Billboard>
14#include <osg/Sequence>
15#include <osg/Switch>
16#include <osg/Geode>
17#include <osg/Geometry>
18#include <osg/MatrixTransform>
19#include <osg/Material>
20#include <osg/Notify>
21#include <osg/Texture2D>
22#include <osg/TexEnv>
23#include <osg/StateSet>
24#include <osgDB/Input>
25#include <osgDB/Output>
26
27// specific to GEO
28
29#include "geoFormat.h"
30#include "geoTypes.h"
31#include "geoUnits.h"
32#include "osgGeoAnimation.h"
33#include "osgGeoStructs.h"
34#include "osgGeoNodes.h"
35#include "osgGeoAction.h"
36#include <osgText/Text> // needed for text nodes
37#include <osg/Timer>
38
39
40void geoArithBehaviour::setType(unsigned int iop) {
41    switch (iop) {
42    case 1: op=addv; break; /* op=addv; addv is a function so the operation can be accessed without a switch(type)... */
43    case 2: op=subv; break;
44    case 3: op=mulv; break;
45    case 4: op=divv; break;
46    case 5: op=equa; break;
47    }
48}
49void geoArithBehaviour::doaction(osg::Node *) { // do math operation
50    if (in && out && op) {
51        (*out)=op(*in,acon.get());
52        //    std::cout << " math sum " << out<< " " << (*out) << " " << in <<" " << (*in) << std::endl;
53    }
54}
55bool geoArithBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
56    bool ok=false;
57    const geoField *gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_INPUT_VAR);
58    if (gfd) {
59        unsigned fid= gfd->getUInt(); // field identifier
60        in=theHeader->getVar(fid); // returns address of input var with fid
61        //std::cout<< "Input " << fid << " : " << theHeader->getVarname(fid) ;
62        if (in) {
63            gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OUTPUT_VAR);
64            if (gfd) {
65                fid= gfd->getUInt(); // field identifier
66                out=theHeader->getVar(fid); // returns address of output var with fid
67                //std::cout<< " Output " <<  fid << " : " << theHeader->getVarname(fid) << std::endl;
68                gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OP_TYPE);
69                unsigned int iop=gfd?gfd->getUInt():1;
70                setType(iop); // default add?
71                gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OPERAND_VALUE);
72                if (gfd) {
73                    acon.set(gfd->getFloat()); // field identifier
74                    ok=true;
75                }
76                gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OPERAND_VAR);
77                if (gfd) {
78                    unsigned fid= gfd->getUInt(); // field identifier
79                    ok=acon.set(theHeader->getVar(fid));
80                }
81            }
82        }
83    }
84    return ok;
85}
86
87void geoAr3Behaviour::setType(unsigned int iact) {
88    switch (iact) {
89    case DB_DSK_LINEAR_ACTION: op=linear; break; /* op=addv; */
90    case DB_DSK_INVERSE_ACTION: op=lininv; break;
91        //    case 3: op=linmod; break;
92        //    case 4: op=linsqr; break;
93    case DB_DSK_TRUNCATE_ACTION: op=trunc; break;
94    case DB_DSK_PERIODIC_ACTION: op=linabs; break;
95    case DB_DSK_IF_THEN_ELSE_ACTION: op=ifelse; break;
96    }
97}
98void geoAr3Behaviour::setTrigType(int iop) {
99    switch (iop) {
100    case 1: op=trigsin; break; /* op=trigonometric, sine; */
101    case 2: op=trigcos; break;
102    case 3: op=trigtan; break;
103    case 4: op=trigasin; break;
104    case 5: op=trigacos; break;
105    case 6: op=trigatan; break;
106    case 7: op=trigatan2; break;
107    case 8: op=trighypot; break;
108    }
109}
110void geoAr3Behaviour::setPeriodicType(int iop) {
111    switch (iop) {
112    case 1: op=period_1; break; /* op=period type 1; */
113    case 2: op=period_2; break;
114    }
115}
116
117void geoAr3Behaviour::doaction(osg::Node *) { // do math operation
118    if (in && out && op) {
119        double var3=bcon.get();
120        *out=op(*in,getconstant(),var3);
121        //std::cout << " ar3 sum " << out<< " " << (*out) << " con " << getconstant() <<" b: " << bcon.get() << std::endl;
122    }
123}
124bool geoAr3Behaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
125    bool ok=false;
126    const geoField *gfd=grec->getField(GEO_DB_EQUATION_ACTION_INPUT_VAR);
127    const unsigned int act=grec->getType();
128    if (gfd) {
129        unsigned fid= gfd->getUInt(); // field identifier
130        in=theHeader->getVar(fid); // returns address of input var with fid
131        if (in) {
132            gfd=grec->getField(GEO_DB_EQUATION_ACTION_OUTPUT_VAR);
133            if (gfd) {
134                fid= gfd->getUInt(); // field identifier
135                out=theHeader->getVar(fid); // returns address of output var with fid
136                if (act==DB_DSK_TRIG_ACTION) {
137                    gfd=grec->getField(GEO_DB_TRIG_ACTION_OP);
138                    int iop=gfd?gfd->getInt():1;
139                    setTrigType(iop); // one of sin...
140                } else if (act==DB_DSK_PERIODIC_ACTION) {
141                    gfd=grec->getField(GEO_DB_PERIODIC_ACTION_TYPE);
142                    int iop=gfd?gfd->getInt():1; // type 1 or 2 periodic
143                    setPeriodicType(iop); // one of period 1 or 2...
144                } else if (act==DB_DSK_IF_THEN_ELSE_ACTION) {
145                    setType(act); // if..else if (a is in range (-1,1) =b else=c
146                } else {
147                    setType(act); // default linear, inverse, mod.. a.b+c
148                    setConstant(1);
149                    ok=true;
150                }
151                gfd=grec->getField(GEO_DB_EQUATION_ACTION_A_VAL);
152                if (gfd) {
153                    setConstant(gfd->getFloat()); // field identifier
154                    ok=true;
155                }
156                gfd=grec->getField(GEO_DB_EQUATION_ACTION_A_VAR);
157                if (gfd) {
158                    unsigned fid= gfd->getUInt(); // field identifier
159                    ok=setVariable(theHeader->getVar(fid));
160                }
161                gfd=grec->getField(GEO_DB_EQUATION_ACTION_C_VAL);
162                if (gfd) {
163                    bcon.set(gfd->getFloat()); // field identifier
164                    ok=true;
165                }
166                gfd=grec->getField(GEO_DB_EQUATION_ACTION_C_VAR);
167                if (gfd) {
168                    unsigned fid= gfd->getUInt(); // field identifier
169                    ok=bcon.set(theHeader->getVar(fid));
170                }
171            }
172        }
173    }
174    return ok;
175}
176
177void geoCompareBehaviour::setType(unsigned int iop) {
178    switch (iop) {
179    case 1: oper=LESS;break;
180    case 2: oper=LESSOREQ; break;
181    case 3: oper=GREATER; break;
182    case 4: oper=GREATOREQ; break;
183    case 5: oper=EQUALTO; break;
184    }
185}
186
187void geoCompareBehaviour::doaction(osg::Node *) { // do compare operation
188    if (in && out) {
189        double var2=varop? *varop : constant;
190        switch (oper) {
191        case 1: *out = (*in < var2) ? 1.0: -1.0; break;// Less
192        case 2: *out = (*in <= var2) ? 1.0: -1.0; break;//=LessOREQ
193        case 3: *out = (*in > var2) ? 1.0: -1.0; break; // greater...
194        case 4: *out = (*in >= var2) ? 1.0: -1.0; break;
195        case 5: *out = (*in == var2) ? 1.0: -1.0; break;
196        case UNKNOWN: break;
197        }
198    }
199}
200bool geoCompareBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
201    bool ok=false;
202    const geoField *gfd=grec->getField(GEO_DB_COMPARE_ACTION_INPUT_VAR);
203    if (gfd) {
204        unsigned fid= gfd->getUInt(); // field identifier
205        in=theHeader->getVar(fid); // returns address of input var with fid
206        if (in) {
207            gfd=grec->getField(GEO_DB_COMPARE_ACTION_OUTPUT_VAR);
208            if (gfd) {
209                fid= gfd->getUInt(); // field identifier
210                out=theHeader->getVar(fid); // returns address of output var with fid
211                gfd=grec->getField(GEO_DB_COMPARE_ACTION_OP_TYPE);
212                unsigned int iop=gfd?gfd->getUInt():1;
213                setType(iop); // default add?
214                gfd=grec->getField(GEO_DB_COMPARE_ACTION_OPERAND_VALUE);
215                if (gfd) {
216                    constant= gfd->getFloat(); // field identifier
217                    ok=true;
218                }
219                gfd=grec->getField(GEO_DB_COMPARE_ACTION_OPERAND_VAR);
220                if (gfd) {
221                    unsigned fid= gfd->getUInt(); // field identifier
222                    varop=theHeader->getVar(fid);
223                    ok=varop != NULL;
224                }
225            }
226        }
227    }
228    return ok;
229}
230
231void geoRangeBehaviour::doaction(osg::Node *) { // do math operation
232    if (in && out) {
233        float v=*in;
234        if (v<inmin) v=inmin;
235        if (v>inmax) v=inmax;
236        v=(v-inmin)/(inmax-inmin);
237        *out = outmin+v*(outmax-outmin);
238    }
239}
240bool geoRangeBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
241    bool ok=false;
242    const geoField *gfd=grec->getField(GEO_DB_RANGE_ACTION_INPUT_VAR);
243    if (gfd) {
244        unsigned fid= gfd->getUInt(); // field identifier
245        in=theHeader->getVar(fid); // returns address of input var with fid
246        if (in) {
247            gfd=grec->getField(GEO_DB_RANGE_ACTION_OUTPUT_VAR);
248            if (gfd) {
249                fid= gfd->getUInt(); // field identifier
250                out=theHeader->getVar(fid); // returns address of output var with fid
251                gfd=grec->getField(GEO_DB_RANGE_ACTION_IN_MIN_VAL);
252                inmin=gfd?gfd->getFloat():-1.e32;
253                gfd=grec->getField(GEO_DB_RANGE_ACTION_IN_MAX_VAL);
254                inmax= gfd?gfd->getFloat() : 1.e32; // field identifier
255                gfd=grec->getField(GEO_DB_RANGE_ACTION_OUT_MIN_VAL);
256                outmin=gfd?gfd->getFloat():-1.e32;
257                gfd=grec->getField(GEO_DB_RANGE_ACTION_OUT_MAX_VAL);
258                outmax= gfd?gfd->getFloat() : 1.e32; // field identifier
259                ok=true;
260            }
261        }
262    }
263    return ok;
264}
265
266void geoClampBehaviour::doaction(osg::Node *) { // do math operation
267    if (in && out) {
268        float v=*in;
269        if (v<min) v=min;
270        if (v>max) v=max;
271        *out = v;
272    }
273}
274bool geoClampBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
275    bool ok=false;
276    const geoField *gfd=grec->getField(GEO_DB_CLAMP_ACTION_INPUT_VAR);
277    if (gfd) {
278        unsigned fid= gfd->getUInt(); // field identifier
279        in=theHeader->getVar(fid); // returns address of input var with fid
280        if (in) {
281            gfd=grec->getField(GEO_DB_CLAMP_ACTION_OUTPUT_VAR);
282            if (gfd) {
283                fid= gfd->getUInt(); // field identifier
284                out=theHeader->getVar(fid); // returns address of output var with fid
285                gfd=grec->getField(GEO_DB_CLAMP_ACTION_MIN_VAL);
286                min=gfd?gfd->getFloat():-1.e32;
287                gfd=grec->getField(GEO_DB_CLAMP_ACTION_MAX_VAL);
288                max= gfd?gfd->getFloat() : 1.e32; // field identifier
289                ok=true;
290            }
291        }
292    }
293    return ok;
294}
295
296void geoDiscreteBehaviour::doaction(osg::Node *) { // do math operation
297    if (in && out) {
298        float v=*in;
299        *out=rangelist.begin()->getVal();
300        for (std::vector<geoRange>::const_iterator itr=rangelist.begin();
301        itr<rangelist.end(); itr++) {
302            if (v>=itr->getMin() && v<=itr->getMax()) *out=itr->getVal();
303        }
304    }
305}
306bool geoDiscreteBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
307    bool ok=false;
308    const geoField *gfd=grec->getField(GEO_DB_DISCRETE_ACTION_INPUT_VAR);
309    if (gfd) {
310        unsigned fid= gfd->getUInt(); // field identifier
311        in=theHeader->getVar(fid); // returns address of input var with fid
312        if (in) {
313            gfd=grec->getField(GEO_DB_DISCRETE_ACTION_OUTPUT_VAR);
314            if (gfd) {
315                fid= gfd->getUInt(); // field identifier
316                out=theHeader->getVar(fid); // returns address of output var with fid
317                gfd=grec->getField(GEO_DB_DISCRETE_ACTION_NUM_ITEMS);
318                unsigned int nr=gfd?gfd->getUInt():1;
319                unsigned int i;
320                for (i=0; i<nr; i++) {
321                    geoRange gr;
322                    rangelist.push_back(gr);
323                }
324                const geoField *gfdmin=grec->getField(GEO_DB_DISCRETE_ACTION_MIN_VALS);
325                const geoField *gfdmax=grec->getField(GEO_DB_DISCRETE_ACTION_MAX_VALS);
326                const geoField *gfdval=grec->getField(GEO_DB_DISCRETE_ACTION_MAP_VALS);
327                if (gfdmin) {
328                    float *fmin=gfdmin->getFloatArr();
329                    float *fmax=gfdmax->getFloatArr();
330                    float *fval=gfdval->getFloatArr();
331                    if (fmin && fmax && fval) {
332                        for (i=0; i<nr; i++) {
333                            rangelist[i].setMin(fmin[i]);
334                            rangelist[i].setMax(fmax[i]);
335                            rangelist[i].setVal(fval[i]);
336                        }
337                    }
338                }
339                ok=true;
340            }
341        }
342    }
343    return ok;
344}
345
346
347void geoMoveBehaviour::doaction(osg::Node *node) {
348    if (getVar()) {
349        MatrixTransform *mtr=dynamic_cast<MatrixTransform *> (node);
350        switch (getType()) {
351        case DB_DSK_SCALE_ACTION:
352            mtr->preMult( osg::Matrix::scale(axis*(getValue())) );
353            break;
354        case DB_DSK_TRANSLATE_ACTION:
355            mtr->preMult( osg::Matrix::translate(axis*(getValue())) );
356            break;
357        case DB_DSK_ROTATE_ACTION:
358            //std::cout << node->getName() << " v: " << getVar() << " rotion " << DEG2RAD(getValue()) << std::endl;
359            mtr->preMult( osg::Matrix::translate(-centre)*
360                osg::Matrix::rotate(DEG2RAD(getValue()),axis)* // nov 2003 negative rotation convention
361                osg::Matrix::translate(centre));
362            break;
363        }
364    }
365}
366
367bool geoMoveBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *theHeader) {
368    bool ok=false;
369    const unsigned int act=grec->getType();
370    setType(act);
371    if (act==DB_DSK_ROTATE_ACTION) {
372        const geoField *gfd=grec->getField(GEO_DB_ROTATE_ACTION_INPUT_VAR);
373        if (gfd) {
374            unsigned fid= gfd->getUInt(); // field identifier
375            double *vcon=theHeader->getVar(fid); // returns address of var with fid
376            if (vcon) {
377                // std::cout<< "rotInput " << fid << " : " << theHeader->getVarname(fid)<< std::endl ;
378                setVar(vcon);
379                const geoField *gfdir=grec->getField(GEO_DB_ROTATE_ACTION_DIR);
380                int flip=gfdir!=NULL; // ?(gfdir->getInt()):false;
381//                printf("Flip %d gfdir %x\n",flip, gfdir);
382                gfd=grec->getField(GEO_DB_ROTATE_ACTION_VECTOR);
383                if (gfd) {
384                    float *ax= gfd->getVec3Arr(); // field identifier
385                    if (flip) setAxis(-osg::Vec3(ax[0],ax[1],ax[2]));
386                    else setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
387                }
388                gfd=grec->getField(GEO_DB_ROTATE_ACTION_ORIGIN);
389                if (gfd) {
390                    float *ct= gfd->getVec3Arr(); // field identifier
391                    setCentre(osg::Vec3(ct[0],ct[1],ct[2]));
392                }
393                ok=true;
394            }
395        }
396    } else if (act==DB_DSK_TRANSLATE_ACTION) {
397        const geoField *gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_INPUT_VAR);
398        if (gfd) {
399            unsigned fid= gfd->getUInt(); // field identifier
400            double *vcon=theHeader->getVar(fid); // returns address of var with fid
401            if (vcon) {
402                setVar(vcon);
403                gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_VECTOR);
404                if (gfd) {
405                    float *ax= gfd->getVec3Arr(); // field identifier
406                    setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
407                }
408                gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_ORIGIN);
409                if (gfd) {
410                    float *ct= gfd->getVec3Arr(); // field identifier
411                    setCentre(osg::Vec3(ct[0],ct[1],ct[2]));
412                }
413                ok=true;
414            }
415        }
416    } else if (act==DB_DSK_SCALE_ACTION) {     // Nov 2002 not yet implemented in the modeller!
417    }
418    return ok;
419}
420void geoMoveVertexBehaviour::doaction(osg::Matrix *mtr) {
421    // update the matrix mtr
422    if (getVar()) {
423            switch (getType()) {
424            case DB_DSK_SCALE_ACTION:
425                *mtr = (*mtr)*osg::Matrix::scale(getAxis()*(getValue())) ;
426                break;
427            case DB_DSK_TRANSLATE_ACTION:
428                *mtr = (*mtr)*osg::Matrix::translate(getAxis()*(getValue())) ;
429                break;
430            case DB_DSK_ROTATE_ACTION:
431                //std::cout << dr->getName() << " v: " << getVar() << " rotion " << DEG2RAD(getValue()) << std::endl;
432                *mtr = (*mtr)*osg::Matrix::translate(-getCentre())*
433                    osg::Matrix::rotate(DEG2RAD(getValue()),getAxis())*
434                    osg::Matrix::translate(getCentre());
435                break;
436            }
437    }
438}
439
440bool geoMoveVertexBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *theHeader)
441{
442    const unsigned int act=grec->getType();
443    bool ok=false;
444    setType(act);
445    if (act==DB_DSK_ROTATE_ACTION) {
446        const geoField *gfd=grec->getField(GEO_DB_ROTATE_ACTION_INPUT_VAR);
447        if (gfd) {
448            unsigned fid= gfd->getUInt(); // field identifier
449            double *vcon=theHeader->getVar(fid); // returns address of var with fid
450            if (vcon) {
451                // std::cout<< "rotInput " << fid << " : " << theHeader->getVarname(fid)<< std::endl ;
452                setVar(vcon);
453                gfd=grec->getField(GEO_DB_ROTATE_ACTION_VECTOR);
454                if (gfd) {
455                    float *ax= gfd->getVec3Arr(); // field identifier
456                    setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
457                }
458                gfd=grec->getField(GEO_DB_ROTATE_ACTION_ORIGIN);
459                if (gfd) {
460                    float *ct= gfd->getVec3Arr(); // field identifier
461                    setCentre(osg::Vec3(ct[0],ct[1],ct[2]));
462                }
463                ok=true;
464            }
465        }
466    } else if (act==DB_DSK_TRANSLATE_ACTION) {
467        const geoField *gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_INPUT_VAR);
468        if (gfd) {
469            unsigned fid= gfd->getUInt(); // field identifier
470            double *vcon=theHeader->getVar(fid); // returns address of var with fid
471            if (vcon) {
472                setVar(vcon);
473                gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_VECTOR);
474                if (gfd) {
475                    float *ax= gfd->getVec3Arr(); // field identifier
476                    setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
477                }
478                gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_ORIGIN);
479                if (gfd) {
480                    float *ct= gfd->getVec3Arr(); // field identifier
481                    setCentre(osg::Vec3(ct[0],ct[1],ct[2]));
482                }
483                ok=true;
484            }
485        }
486    } else if (act==DB_DSK_SCALE_ACTION) {     // Nov 2002 not yet implemented in the modeller!
487    }
488    return ok;
489}
490
491bool geoVisibBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *theHeader) {
492    bool ok=false;
493    const geoField *gfd= grec->getField(GEO_DB_VISIBILITY_ACTION_INPUT_VAR);
494    if (gfd) {
495        unsigned fid= gfd->getUInt(); // field identifier
496        setVar(theHeader->getVar(fid)); // returns address of input var with fid
497        ok=true; // all data supplied
498    }
499    return ok;
500}
501void geoVisibBehaviour::doaction(osg::Node *node)
502{ // do visibility operation on Node
503    if (getVar()) {
504        if (getValue() <0.0) {
505            node->setNodeMask(0x0); // invisible
506        } else {
507            node->setNodeMask(0xffffffff); // visible
508        }
509    }
510}
511
512bool geoColourBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *theHeader) {
513    bool ok=false;
514    const geoField *gfd= grec->getField(GEO_DB_COLOR_RAMP_ACTION_INPUT_VAR);
515    if (gfd) {
516        unsigned fid= gfd->getUInt(); // field identifier
517        setVar(theHeader->getVar(fid)); // returns address of input var with fid
518        gfd=grec->getField(GEO_DB_COLOR_RAMP_ACTION_COLOR_FROM_PALETTE);
519        if (gfd) {}
520        gfd=grec->getField(GEO_DB_COLOR_RAMP_ACTION_TOP_COLOR_INDEX);
521        topcindx=(gfd? gfd->getUInt():4096);
522        gfd=grec->getField(GEO_DB_COLOR_RAMP_ACTION_BOTTOM_COLOR_INDEX);
523        botcindx=(gfd? gfd->getUInt():0);
524        //also available: GEO_DB_COLOR_RAMP_ACTION_MATCH_COLUMNS
525        ok=true; // all data supplied
526    }
527    return ok;
528}
529void geoColourBehaviour::doaction(osg::Drawable *dr)
530{ // do visibility operation on Node
531    if (getVar()) {
532        double val=getValue();
533        unsigned int idx=(unsigned int)val;
534        osg::Geometry *gm=dynamic_cast<osg::Geometry *>(dr);
535        if (gm) {
536            osg::Vec4Array* cla = dynamic_cast<osg::Vec4Array*>(gm->getColorArray());
537            if (cla) { // traps a colour behaviour added when using material for colour.
538                for (unsigned int i=nstart; i<(nend); i++) {
539                    unsigned char col[4];
540                    unsigned int idxtop=idx/128;
541                    (*colours)[idxtop].get(col); // from the colour palette
542                    float frac=(float)(idx-idxtop*128)/128.0f;
543                    (*cla)[i].set(col[0]*frac/255.0,col[1]*frac/255.0,col[2]*frac/255.0,1);
544                }
545            }
546        }
547    }
548}
549
550void geoStrContentBehaviour::doaction(osg::Drawable* /*node*/)
551{ // do new text
552#ifdef USETEXT // buggy text feb 2003
553    osgText::Text *txt=dynamic_cast<osgText::Text *>(node);
554    char content[32];
555    switch (vt) {
556    case INT:
557        sprintf(content, format, (int)getValue());
558        break;
559    case FLOAT:
560        sprintf(content, format, (float)getValue());
561        break;
562    case DOUBLE:
563        sprintf(content, format, getValue());
564        break;
565    case CHAR:
566        sprintf(content, format, (char *)getVar());
567        break;
568    default:
569        sprintf(content, format, (char *)getVar());
570    }
571    txt->setText(std::string(content));
572#endif
573}
574bool geoStrContentBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *theHeader) {
575    bool ok=false;
576    const geoField *gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_INPUT_VAR);
577    if (gfd) {
578        unsigned fid= gfd->getUInt(); // field identifier
579        setVar(theHeader->getVar(fid)); // returns address of input var with fid
580        if (getVar()) {
581            gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_FORMAT);
582            if (gfd) {
583                char *ch=gfd->getChar();
584                format=new char[strlen(ch)+1];
585                strcpy(format, ch);
586                {
587                    char *ctmp=format;
588                    while (*ctmp) {
589                        if (*ctmp=='d') vt=INT;
590                        if (*ctmp=='f' && vt!=DOUBLE) vt=FLOAT;
591                        if (*ctmp=='l') vt=DOUBLE;
592                        ctmp++;
593                    }
594                }
595                //gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_PADDING_TYPE);
596                //gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_PADDING_TYPE);
597                ok=true;
598            }
599        }
600    }
601    return ok;
602}
603
604void geoBehaviourCB::operator() (osg::Node *node, osg::NodeVisitor* nv)
605{ // callback updates the transform, colour, string content...
606    MatrixTransform *mtr=dynamic_cast<MatrixTransform *> (node);
607    if (mtr) mtr->setMatrix(Matrix::identity()); // all actions are multiplied to this
608//        printf("setting matrix %x\n", mtr);
609 //   PositionAttitudeTransform *patr=dynamic_cast<PositionAttitudeTransform *> (node);
610   // if (patr) patr->setMatrix(Matrix::identity()); // all actions are multiplied to this
611    for (std::vector<geoBehaviour *>::const_iterator itr=gblist.begin();
612    itr<gblist.end();
613    itr++) { // motion behaviour
614         (*itr)->doaction(node);
615/* === the above is equivalent to my old code with lots of tests in: */
616/*      geoArithBehaviour *ab=dynamic_cast<geoArithBehaviour *>(*itr);
617        if (ab) ab->doaction(node);
618        geoAr3Behaviour *a3=dynamic_cast<geoAr3Behaviour *>(*itr);
619        if (a3) a3->doaction(node);
620        geoClampBehaviour *cb=dynamic_cast<geoClampBehaviour *>(*itr);
621        if (cb) cb->doaction(node);
622        geoRangeBehaviour *cr=dynamic_cast<geoRangeBehaviour *>(*itr);
623        if (cr) cr->doaction(node);
624        geoCompareBehaviour *cmb=dynamic_cast<geoCompareBehaviour *>(*itr);
625        if (cmb) cmb->doaction(node);
626        geoDiscreteBehaviour *db=dynamic_cast<geoDiscreteBehaviour *>(*itr);
627        if (db) db->doaction(node);
628        geoMoveBehaviour *mb=dynamic_cast<geoMoveBehaviour *>(*itr);
629        if (mb) mb->doaction(node);
630        // or visibility..
631        geoVisibBehaviour *vb=dynamic_cast<geoVisibBehaviour *>(*itr);
632        if (vb) vb->doaction(node);  */
633    }
634    traverse(node,nv);
635}
636
637void geoBehaviourDrawableCB::update(osg::NodeVisitor *,osg::Drawable *dr) {
638    Matrix mtr;
639    int prevvtr=-1; // previously moved vertex
640    Vec3 pos;
641    mtr.identity();
642    std::vector<geoBehaviour *>::const_iterator itr;
643    for (itr=gblist.begin();
644         itr<gblist.end();
645         itr++)
646        { // color or string action behaviour, can also do maths...
647        //     (*itr)->doaction(dr);
648             Node *nd=NULL;
649        geoArithBehaviour *ab=dynamic_cast<geoArithBehaviour *>(*itr);
650        if (ab) ab->doaction(nd);
651        geoAr3Behaviour *a3=dynamic_cast<geoAr3Behaviour *>(*itr);
652        if (a3) a3->doaction(nd);
653        geoClampBehaviour *cb=dynamic_cast<geoClampBehaviour *>(*itr);
654        if (cb) cb->doaction(nd);
655        geoRangeBehaviour *cr=dynamic_cast<geoRangeBehaviour *>(*itr);
656        if (cr) cr->doaction(nd);
657        geoStrContentBehaviour *sb=dynamic_cast<geoStrContentBehaviour *>(*itr);
658        if (sb) sb->doaction(dr);
659        // colorbehaviour may be for 1 or all vertices
660        geoColourBehaviour *clrb=dynamic_cast<geoColourBehaviour *>(*itr);
661        if (clrb) clrb->doaction(dr);
662        geoMoveVertexBehaviour *mvvb=dynamic_cast<geoMoveVertexBehaviour *>(*itr);
663        if (mvvb && (prevvtr<0 || prevvtr==mvvb->getindex())) {
664            mvvb->doaction(&mtr);
665            pos=mvvb->getpos();
666            prevvtr=mvvb->getindex();
667        }
668    }
669    osg::Geometry *gm=dynamic_cast<osg::Geometry *>(dr);
670    if (gm && prevvtr>=0) {
671        osg::Vec3Array* vtxa = dynamic_cast<osg::Vec3Array*>(gm->getVertexArray());
672        bool newpos=false;
673        (*vtxa)[prevvtr]=pos*mtr;
674        do { // check for other vertices that may be animated
675            newpos=false;
676            mtr.identity();
677            for (itr=gblist.begin();
678            itr<gblist.end();
679            itr++) { // color or string action behaviour, can also do maths...
680                geoMoveVertexBehaviour *mvvb=dynamic_cast<geoMoveVertexBehaviour *>(*itr);
681                if (mvvb) {
682                    int vidx=mvvb->getindex();
683                    if (mvvb && (prevvtr<vidx || (newpos && prevvtr==vidx))) {
684                        mvvb->doaction(&mtr);
685                        prevvtr=vidx;
686                        pos=mvvb->getpos();
687                        newpos=true;
688                    }
689                }
690            }
691            if (newpos) {
692                osg::Vec3Array* vtxa = dynamic_cast<osg::Vec3Array*>(gm->getVertexArray());
693                (*vtxa)[prevvtr]=pos*mtr;
694            }
695        } while (newpos);
696    }
697}
Note: See TracBrowser for help on using the browser.