677 lines
26 KiB
C++
677 lines
26 KiB
C++
|
// GEO format (carbon graphics Inc) loader for the OSG real time scene graph
|
||
|
// www.carbongraphics.com for more information about the Geo animation+ modeller
|
||
|
// 2002
|
||
|
// actions & behaviours for Geo loader in OSG
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <math.h>
|
||
|
#include <osg/Image>
|
||
|
#include <osg/Group>
|
||
|
#include <osg/LOD>
|
||
|
#include <osg/Billboard>
|
||
|
#include <osg/Sequence>
|
||
|
#include <osg/Switch>
|
||
|
#include <osg/Geode>
|
||
|
#include <osg/Geometry>
|
||
|
#include <osg/MatrixTransform>
|
||
|
#include <osg/Material>
|
||
|
#include <osg/Notify>
|
||
|
#include <osg/Texture2D>
|
||
|
#include <osg/TexEnv>
|
||
|
#include <osg/StateSet>
|
||
|
#include <osgDB/Input>
|
||
|
#include <osgDB/Output>
|
||
|
|
||
|
// specific to GEO
|
||
|
|
||
|
#include "geoFormat.h"
|
||
|
#include "geoTypes.h"
|
||
|
#include "geoUnits.h"
|
||
|
#include "osgGeoAnimation.h"
|
||
|
#include "osgGeoStructs.h"
|
||
|
#include "osgGeoNodes.h"
|
||
|
#include "osgGeoAction.h"
|
||
|
#include <osgText/Text> // needed for text nodes
|
||
|
#include <osg/Timer>
|
||
|
|
||
|
|
||
|
void geoArithBehaviour::setType(uint iop) {
|
||
|
switch (iop) {
|
||
|
case 1: op=addv; break; /* op=addv; addv is a function so the operation can be accessed without a switch(type)... */
|
||
|
case 2: op=subv; break;
|
||
|
case 3: op=mulv; break;
|
||
|
case 4: op=divv; break;
|
||
|
case 5: op=equa; break;
|
||
|
}
|
||
|
}
|
||
|
void geoArithBehaviour::doaction(void) const { // do math operation
|
||
|
if (in && out && op) {
|
||
|
(*out)=op(*in,acon.get());
|
||
|
// std::cout << " math sum " << out<< " " << (*out) << " " << in <<" " << (*in) << std::endl;
|
||
|
}
|
||
|
}
|
||
|
bool geoArithBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
in=theHeader->getVar(fid); // returns address of input var with fid
|
||
|
//std::cout<< "Input " << fid << " : " << theHeader->getVarname(fid) ;
|
||
|
if (in) {
|
||
|
gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OUTPUT_VAR);
|
||
|
if (gfd) {
|
||
|
fid= gfd->getUInt(); // field identifier
|
||
|
out=theHeader->getVar(fid); // returns address of output var with fid
|
||
|
//std::cout<< " Output " << fid << " : " << theHeader->getVarname(fid) << std::endl;
|
||
|
gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OP_TYPE);
|
||
|
uint iop=gfd?gfd->getUInt():1;
|
||
|
setType(iop); // default add?
|
||
|
gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OPERAND_VALUE);
|
||
|
if (gfd) {
|
||
|
acon.set(gfd->getFloat()); // field identifier
|
||
|
ok=true;
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OPERAND_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
ok=acon.set(theHeader->getVar(fid));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void geoAr3Behaviour::setType(uint iact) {
|
||
|
switch (iact) {
|
||
|
case DB_DSK_LINEAR_ACTION: op=linear; break; /* op=addv; */
|
||
|
case DB_DSK_INVERSE_ACTION: op=lininv; break;
|
||
|
// case 3: op=linmod; break;
|
||
|
// case 4: op=linsqr; break;
|
||
|
case DB_DSK_TRUNCATE_ACTION: op=trunc; break;
|
||
|
case DB_DSK_PERIODIC_ACTION: op=linabs; break;
|
||
|
case DB_DSK_IF_THEN_ELSE_ACTION: op=ifelse; break;
|
||
|
}
|
||
|
}
|
||
|
void geoAr3Behaviour::setTrigType(int iop) {
|
||
|
switch (iop) {
|
||
|
case 1: op=trigsin; break; /* op=trigonometric, sine; */
|
||
|
case 2: op=trigcos; break;
|
||
|
case 3: op=trigtan; break;
|
||
|
case 4: op=trigasin; break;
|
||
|
case 5: op=trigacos; break;
|
||
|
case 6: op=trigatan; break;
|
||
|
case 7: op=trigatan2; break;
|
||
|
case 8: op=trighypot; break;
|
||
|
}
|
||
|
}
|
||
|
void geoAr3Behaviour::setPeriodicType(int iop) {
|
||
|
switch (iop) {
|
||
|
case 1: op=period_1; break; /* op=period type 1; */
|
||
|
case 2: op=period_2; break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void geoAr3Behaviour::doaction(void) { // do math operation
|
||
|
if (in && out && op) {
|
||
|
double var3=bcon.get();
|
||
|
*out=op(*in,getconstant(),var3);
|
||
|
//std::cout << " ar3 sum " << out<< " " << (*out) << " con " << getconstant() <<" b: " << bcon.get() << std::endl;
|
||
|
}
|
||
|
}
|
||
|
bool geoAr3Behaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader, const uint act) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd=grec->getField(GEO_DB_EQUATION_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
in=theHeader->getVar(fid); // returns address of input var with fid
|
||
|
if (in) {
|
||
|
gfd=grec->getField(GEO_DB_EQUATION_ACTION_OUTPUT_VAR);
|
||
|
if (gfd) {
|
||
|
fid= gfd->getUInt(); // field identifier
|
||
|
out=theHeader->getVar(fid); // returns address of output var with fid
|
||
|
if (act==DB_DSK_TRIG_ACTION) {
|
||
|
gfd=grec->getField(GEO_DB_TRIG_ACTION_OP);
|
||
|
int iop=gfd?gfd->getInt():1;
|
||
|
setTrigType(iop); // one of sin...
|
||
|
} else if (act==DB_DSK_PERIODIC_ACTION) {
|
||
|
gfd=grec->getField(GEO_DB_PERIODIC_ACTION_TYPE);
|
||
|
int iop=gfd?gfd->getInt():1; // type 1 or 2 periodic
|
||
|
setPeriodicType(iop); // one of period 1 or 2...
|
||
|
} else if (act==DB_DSK_IF_THEN_ELSE_ACTION) {
|
||
|
setType(act); // if..else if (a is in range (-1,1) =b else=c
|
||
|
} else {
|
||
|
setType(act); // default linear, inverse, mod.. a.b+c
|
||
|
setConstant(1);
|
||
|
ok=true;
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_EQUATION_ACTION_A_VAL);
|
||
|
if (gfd) {
|
||
|
setConstant(gfd->getFloat()); // field identifier
|
||
|
ok=true;
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_EQUATION_ACTION_A_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
ok=setVariable(theHeader->getVar(fid));
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_EQUATION_ACTION_C_VAL);
|
||
|
if (gfd) {
|
||
|
bcon.set(gfd->getFloat()); // field identifier
|
||
|
ok=true;
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_EQUATION_ACTION_C_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
ok=bcon.set(theHeader->getVar(fid));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void geoCompareBehaviour::setType(uint iop) {
|
||
|
switch (iop) {
|
||
|
case 1: oper=LESS;break;
|
||
|
case 2: oper=LESSOREQ; break;
|
||
|
case 3: oper=GREATER; break;
|
||
|
case 4: oper=GREATOREQ; break;
|
||
|
case 5: oper=EQUALTO; break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void geoCompareBehaviour::doaction(void) const { // do compare operation
|
||
|
if (in && out) {
|
||
|
double var2=varop? *varop : constant;
|
||
|
switch (oper) {
|
||
|
case 1: oper; *out = (*in < var2) ? 1.0: -1.0; break;// Less
|
||
|
case 2: oper; *out = (*in <= var2) ? 1.0: -1.0; break;//=LessOREQ
|
||
|
case 3: oper; *out = (*in > var2) ? 1.0: -1.0; break; // greater...
|
||
|
case 4: oper; *out = (*in >= var2) ? 1.0: -1.0; break;
|
||
|
case 5: oper; *out = (*in == var2) ? 1.0: -1.0; break;
|
||
|
case UNKNOWN: break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
bool geoCompareBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd=grec->getField(GEO_DB_COMPARE_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
in=theHeader->getVar(fid); // returns address of input var with fid
|
||
|
if (in) {
|
||
|
gfd=grec->getField(GEO_DB_COMPARE_ACTION_OUTPUT_VAR);
|
||
|
if (gfd) {
|
||
|
fid= gfd->getUInt(); // field identifier
|
||
|
out=theHeader->getVar(fid); // returns address of output var with fid
|
||
|
gfd=grec->getField(GEO_DB_COMPARE_ACTION_OP_TYPE);
|
||
|
uint iop=gfd?gfd->getUInt():1;
|
||
|
setType(iop); // default add?
|
||
|
gfd=grec->getField(GEO_DB_COMPARE_ACTION_OPERAND_VALUE);
|
||
|
if (gfd) {
|
||
|
constant= gfd->getFloat(); // field identifier
|
||
|
ok=true;
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_COMPARE_ACTION_OPERAND_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
varop=theHeader->getVar(fid);
|
||
|
ok=varop != NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void geoRangeBehaviour::doaction(void) const { // do math operation
|
||
|
if (in && out) {
|
||
|
float v=*in;
|
||
|
if (v<inmin) v=inmin;
|
||
|
if (v>inmax) v=inmax;
|
||
|
v=(v-inmin)/(inmax-inmin);
|
||
|
*out = outmin+v*(outmax-outmin);
|
||
|
}
|
||
|
}
|
||
|
bool geoRangeBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd=grec->getField(GEO_DB_RANGE_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
in=theHeader->getVar(fid); // returns address of input var with fid
|
||
|
if (in) {
|
||
|
gfd=grec->getField(GEO_DB_RANGE_ACTION_OUTPUT_VAR);
|
||
|
if (gfd) {
|
||
|
fid= gfd->getUInt(); // field identifier
|
||
|
out=theHeader->getVar(fid); // returns address of output var with fid
|
||
|
gfd=grec->getField(GEO_DB_RANGE_ACTION_IN_MIN_VAL);
|
||
|
inmin=gfd?gfd->getFloat():-1.e32;
|
||
|
gfd=grec->getField(GEO_DB_RANGE_ACTION_IN_MAX_VAL);
|
||
|
inmax= gfd?gfd->getFloat() : 1.e32; // field identifier
|
||
|
gfd=grec->getField(GEO_DB_RANGE_ACTION_OUT_MIN_VAL);
|
||
|
outmin=gfd?gfd->getFloat():-1.e32;
|
||
|
gfd=grec->getField(GEO_DB_RANGE_ACTION_OUT_MAX_VAL);
|
||
|
outmax= gfd?gfd->getFloat() : 1.e32; // field identifier
|
||
|
ok=true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void geoClampBehaviour::doaction(void) const { // do math operation
|
||
|
if (in && out) {
|
||
|
float v=*in;
|
||
|
if (v<min) v=min;
|
||
|
if (v>max) v=max;
|
||
|
*out = v;
|
||
|
}
|
||
|
}
|
||
|
bool geoClampBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd=grec->getField(GEO_DB_CLAMP_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
in=theHeader->getVar(fid); // returns address of input var with fid
|
||
|
if (in) {
|
||
|
gfd=grec->getField(GEO_DB_CLAMP_ACTION_OUTPUT_VAR);
|
||
|
if (gfd) {
|
||
|
fid= gfd->getUInt(); // field identifier
|
||
|
out=theHeader->getVar(fid); // returns address of output var with fid
|
||
|
gfd=grec->getField(GEO_DB_CLAMP_ACTION_MIN_VAL);
|
||
|
min=gfd?gfd->getFloat():-1.e32;
|
||
|
gfd=grec->getField(GEO_DB_CLAMP_ACTION_MAX_VAL);
|
||
|
max= gfd?gfd->getFloat() : 1.e32; // field identifier
|
||
|
ok=true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void geoDiscreteBehaviour::doaction(void) const { // do math operation
|
||
|
if (in && out) {
|
||
|
float v=*in;
|
||
|
*out=rangelist.begin()->getVal();
|
||
|
for (std::vector<geoRange>::const_iterator itr=rangelist.begin();
|
||
|
itr<rangelist.end(); itr++) {
|
||
|
if (v>=itr->getMin() && v<=itr->getMax()) *out=itr->getVal();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
bool geoDiscreteBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd=grec->getField(GEO_DB_DISCRETE_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
in=theHeader->getVar(fid); // returns address of input var with fid
|
||
|
if (in) {
|
||
|
gfd=grec->getField(GEO_DB_DISCRETE_ACTION_OUTPUT_VAR);
|
||
|
if (gfd) {
|
||
|
fid= gfd->getUInt(); // field identifier
|
||
|
out=theHeader->getVar(fid); // returns address of output var with fid
|
||
|
gfd=grec->getField(GEO_DB_DISCRETE_ACTION_NUM_ITEMS);
|
||
|
uint nr=gfd?gfd->getUInt():1;
|
||
|
uint i;
|
||
|
for (i=0; i<nr; i++) {
|
||
|
geoRange gr;
|
||
|
rangelist.push_back(gr);
|
||
|
}
|
||
|
const geoField *gfdmin=grec->getField(GEO_DB_DISCRETE_ACTION_MIN_VALS);
|
||
|
const geoField *gfdmax=grec->getField(GEO_DB_DISCRETE_ACTION_MAX_VALS);
|
||
|
const geoField *gfdval=grec->getField(GEO_DB_DISCRETE_ACTION_MAP_VALS);
|
||
|
if (gfdmin) {
|
||
|
float *fmin=gfdmin->getFloatArr();
|
||
|
float *fmax=gfdmax->getFloatArr();
|
||
|
float *fval=gfdval->getFloatArr();
|
||
|
if (fmin && fmax && fval) {
|
||
|
for (i=0; i<nr; i++) {
|
||
|
rangelist[i].setMin(fmin[i]);
|
||
|
rangelist[i].setMax(fmax[i]);
|
||
|
rangelist[i].setVal(fval[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ok=true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
|
||
|
void geoMoveBehaviour::doaction(osg::Node *node) {
|
||
|
if (getVar()) {
|
||
|
MatrixTransform *mtr=dynamic_cast<MatrixTransform *> (node);
|
||
|
switch (getType()) {
|
||
|
case DB_DSK_SCALE_ACTION:
|
||
|
mtr->preMult( osg::Matrix::scale(axis*(getValue())) );
|
||
|
break;
|
||
|
case DB_DSK_TRANSLATE_ACTION:
|
||
|
mtr->preMult( osg::Matrix::translate(axis*(getValue())) );
|
||
|
break;
|
||
|
case DB_DSK_ROTATE_ACTION:
|
||
|
//std::cout << node->getName() << " v: " << getVar() << " rotion " << DEG2RAD(getValue()) << std::endl;
|
||
|
mtr->preMult( osg::Matrix::translate(-centre)*
|
||
|
osg::Matrix::rotate(DEG2RAD(getValue()),axis)*
|
||
|
osg::Matrix::translate(centre));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool geoMoveBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *theHeader, const uint act) {
|
||
|
bool ok=false;
|
||
|
setType(act);
|
||
|
if (act==DB_DSK_ROTATE_ACTION) {
|
||
|
const geoField *gfd=grec->getField(GEO_DB_ROTATE_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
double *vcon=theHeader->getVar(fid); // returns address of var with fid
|
||
|
if (vcon) {
|
||
|
// std::cout<< "rotInput " << fid << " : " << theHeader->getVarname(fid)<< std::endl ;
|
||
|
setVar(vcon);
|
||
|
gfd=grec->getField(GEO_DB_ROTATE_ACTION_VECTOR);
|
||
|
if (gfd) {
|
||
|
float *ax= gfd->getVec3Arr(); // field identifier
|
||
|
setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_ROTATE_ACTION_ORIGIN);
|
||
|
if (gfd) {
|
||
|
float *ct= gfd->getVec3Arr(); // field identifier
|
||
|
setCentre(osg::Vec3(ct[0],ct[1],ct[2]));
|
||
|
}
|
||
|
ok=true;
|
||
|
}
|
||
|
}
|
||
|
} else if (act==DB_DSK_TRANSLATE_ACTION) {
|
||
|
const geoField *gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
double *vcon=theHeader->getVar(fid); // returns address of var with fid
|
||
|
if (vcon) {
|
||
|
setVar(vcon);
|
||
|
gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_VECTOR);
|
||
|
if (gfd) {
|
||
|
float *ax= gfd->getVec3Arr(); // field identifier
|
||
|
setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_ORIGIN);
|
||
|
if (gfd) {
|
||
|
float *ct= gfd->getVec3Arr(); // field identifier
|
||
|
setCentre(osg::Vec3(ct[0],ct[1],ct[2]));
|
||
|
}
|
||
|
ok=true;
|
||
|
}
|
||
|
}
|
||
|
} else if (act==DB_DSK_SCALE_ACTION) { // Nov 2002 not yet implemented in the modeller!
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
void geoMoveVertexBehaviour::doaction(Matrix &mtr,osg::Drawable *dr) {
|
||
|
// update the matrix mtr
|
||
|
if (getVar()) {
|
||
|
switch (getType()) {
|
||
|
case DB_DSK_SCALE_ACTION:
|
||
|
mtr = mtr*osg::Matrix::scale(movb.getAxis()*(getValue())) ;
|
||
|
break;
|
||
|
case DB_DSK_TRANSLATE_ACTION:
|
||
|
mtr = mtr*osg::Matrix::translate(movb.getAxis()*(getValue())) ;
|
||
|
break;
|
||
|
case DB_DSK_ROTATE_ACTION:
|
||
|
//std::cout << dr->getName() << " v: " << getVar() << " rotion " << DEG2RAD(getValue()) << std::endl;
|
||
|
mtr = mtr*osg::Matrix::translate(-movb.getCentre())*
|
||
|
osg::Matrix::rotate(DEG2RAD(getValue()),movb.getAxis())*
|
||
|
osg::Matrix::translate(movb.getCentre());
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool geoMoveVertexBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *theHeader, const uint act) {
|
||
|
bool ok=false;
|
||
|
setType(act);
|
||
|
if (act==DB_DSK_ROTATE_ACTION) {
|
||
|
const geoField *gfd=grec->getField(GEO_DB_ROTATE_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
double *vcon=theHeader->getVar(fid); // returns address of var with fid
|
||
|
if (vcon) {
|
||
|
// std::cout<< "rotInput " << fid << " : " << theHeader->getVarname(fid)<< std::endl ;
|
||
|
setVar(vcon);
|
||
|
gfd=grec->getField(GEO_DB_ROTATE_ACTION_VECTOR);
|
||
|
if (gfd) {
|
||
|
float *ax= gfd->getVec3Arr(); // field identifier
|
||
|
movb.setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_ROTATE_ACTION_ORIGIN);
|
||
|
if (gfd) {
|
||
|
float *ct= gfd->getVec3Arr(); // field identifier
|
||
|
movb.setCentre(osg::Vec3(ct[0],ct[1],ct[2]));
|
||
|
}
|
||
|
ok=true;
|
||
|
}
|
||
|
}
|
||
|
} else if (act==DB_DSK_TRANSLATE_ACTION) {
|
||
|
const geoField *gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
double *vcon=theHeader->getVar(fid); // returns address of var with fid
|
||
|
if (vcon) {
|
||
|
setVar(vcon);
|
||
|
gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_VECTOR);
|
||
|
if (gfd) {
|
||
|
float *ax= gfd->getVec3Arr(); // field identifier
|
||
|
movb.setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_ORIGIN);
|
||
|
if (gfd) {
|
||
|
float *ct= gfd->getVec3Arr(); // field identifier
|
||
|
movb.setCentre(osg::Vec3(ct[0],ct[1],ct[2]));
|
||
|
}
|
||
|
ok=true;
|
||
|
}
|
||
|
}
|
||
|
} else if (act==DB_DSK_SCALE_ACTION) { // Nov 2002 not yet implemented in the modeller!
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
bool geoVisibBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader, const uint act) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd= grec->getField(GEO_DB_VISIBILITY_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
setVar(theHeader->getVar(fid)); // returns address of input var with fid
|
||
|
ok=true; // all data supplied
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
void geoVisibBehaviour::doaction(osg::Node *node) const
|
||
|
{ // do visibility operation on Node
|
||
|
if (getVar()) {
|
||
|
if (getValue() <0.0) {
|
||
|
node->setNodeMask(0x0); // invisible
|
||
|
} else {
|
||
|
node->setNodeMask(0xffffffff); // visible
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool geoColourBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *theHeader) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd= grec->getField(GEO_DB_COLOR_RAMP_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
setVar(theHeader->getVar(fid)); // returns address of input var with fid
|
||
|
gfd=grec->getField(GEO_DB_COLOR_RAMP_ACTION_COLOR_FROM_PALETTE);
|
||
|
if (gfd) {}
|
||
|
gfd=grec->getField(GEO_DB_COLOR_RAMP_ACTION_TOP_COLOR_INDEX);
|
||
|
topcindx=(gfd? gfd->getUInt():4096);
|
||
|
gfd=grec->getField(GEO_DB_COLOR_RAMP_ACTION_BOTTOM_COLOR_INDEX);
|
||
|
botcindx=(gfd? gfd->getUInt():0);
|
||
|
//also available: GEO_DB_COLOR_RAMP_ACTION_MATCH_COLUMNS
|
||
|
ok=true; // all data supplied
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
void geoColourBehaviour::doaction(osg::Drawable *dr) const
|
||
|
{ // do visibility operation on Node
|
||
|
if (getVar()) {
|
||
|
uint idx=getValue();
|
||
|
osg::Geometry *gm=dynamic_cast<osg::Geometry *>(dr);
|
||
|
if (gm) {
|
||
|
osg::Vec4Array* cla = dynamic_cast<osg::Vec4Array*>(gm->getColorArray());
|
||
|
if (cla) { // traps a colour behaviour added when using material for colour.
|
||
|
for (uint i=nstart; i<(nend); i++) {
|
||
|
unsigned char col[4];
|
||
|
uint idxtop=idx/128;
|
||
|
(*colours)[idxtop].get(col); // from the colour palette
|
||
|
float frac=(float)(idx-idxtop*128)/128.0f;
|
||
|
(*cla)[i].set(col[0]*frac/255.0,col[1]*frac/255.0,col[2]*frac/255.0,1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void geoStrContentBehaviour::doaction(osg::Drawable *node) { // do new text
|
||
|
osgText::Text *txt=dynamic_cast<osgText::Text *>(node);
|
||
|
char content[32];
|
||
|
switch (vt) {
|
||
|
case INT:
|
||
|
sprintf(content, format, (int)getValue());
|
||
|
break;
|
||
|
case FLOAT:
|
||
|
sprintf(content, format, (float)getValue());
|
||
|
break;
|
||
|
case DOUBLE:
|
||
|
sprintf(content, format, getValue());
|
||
|
break;
|
||
|
case CHAR:
|
||
|
sprintf(content, format, (char *)getVar());
|
||
|
break;
|
||
|
default:
|
||
|
sprintf(content, format, (char *)getVar());
|
||
|
}
|
||
|
txt->setText(std::string(content));
|
||
|
}
|
||
|
bool geoStrContentBehaviour::makeBehave(const georecord *grec, geoHeaderGeo *theHeader) {
|
||
|
bool ok=false;
|
||
|
const geoField *gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_INPUT_VAR);
|
||
|
if (gfd) {
|
||
|
unsigned fid= gfd->getUInt(); // field identifier
|
||
|
setVar(theHeader->getVar(fid)); // returns address of input var with fid
|
||
|
if (getVar()) {
|
||
|
gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_FORMAT);
|
||
|
if (gfd) {
|
||
|
char *ch=gfd->getChar();
|
||
|
format=new char[strlen(ch)+1];
|
||
|
strcpy(format, ch);
|
||
|
{
|
||
|
char *ctmp=format;
|
||
|
while (*ctmp) {
|
||
|
if (*ctmp=='d') vt=INT;
|
||
|
if (*ctmp=='f' && vt!=DOUBLE) vt=FLOAT;
|
||
|
if (*ctmp=='l') vt=DOUBLE;
|
||
|
ctmp++;
|
||
|
}
|
||
|
}
|
||
|
gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_PADDING_TYPE);
|
||
|
gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_PADDING_TYPE);
|
||
|
ok=true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void geoBehaviourCB::operator() (osg::Node *node, osg::NodeVisitor* nv)
|
||
|
{ // callback updates the transform, colour, string content...
|
||
|
MatrixTransform *mtr=dynamic_cast<MatrixTransform *> (node);
|
||
|
if (mtr) mtr->setMatrix(Matrix::identity()); // all actions are multiplied to this
|
||
|
for (std::vector<geoBehaviour *>::const_iterator itr=gblist.begin();
|
||
|
itr<gblist.end();
|
||
|
itr++) { // motion behaviour
|
||
|
geoArithBehaviour *ab=dynamic_cast<geoArithBehaviour *>(*itr);
|
||
|
if (ab) ab->doaction();
|
||
|
geoAr3Behaviour *a3=dynamic_cast<geoAr3Behaviour *>(*itr);
|
||
|
if (a3) a3->doaction();
|
||
|
geoClampBehaviour *cb=dynamic_cast<geoClampBehaviour *>(*itr);
|
||
|
if (cb) cb->doaction();
|
||
|
geoRangeBehaviour *cr=dynamic_cast<geoRangeBehaviour *>(*itr);
|
||
|
if (cr) cr->doaction();
|
||
|
geoCompareBehaviour *cmb=dynamic_cast<geoCompareBehaviour *>(*itr);
|
||
|
if (cmb) cmb->doaction();
|
||
|
geoDiscreteBehaviour *db=dynamic_cast<geoDiscreteBehaviour *>(*itr);
|
||
|
if (db) db->doaction();
|
||
|
geoMoveBehaviour *mb=dynamic_cast<geoMoveBehaviour *>(*itr);
|
||
|
if (mb) mb->doaction(node);
|
||
|
// or visibility..
|
||
|
geoVisibBehaviour *vb=dynamic_cast<geoVisibBehaviour *>(*itr);
|
||
|
if (vb) vb->doaction(node);
|
||
|
}
|
||
|
traverse(node,nv);
|
||
|
}
|
||
|
|
||
|
void geoBehaviourDrawableCB::app(osg::NodeVisitor *,osg::Drawable *dr) {
|
||
|
Matrix mtr;
|
||
|
int prevvtr=-1; // previously moved vertex
|
||
|
Vec3 pos;
|
||
|
mtr.identity();
|
||
|
std::vector<geoBehaviour *>::const_iterator itr;
|
||
|
for (itr=gblist.begin();
|
||
|
itr<gblist.end();
|
||
|
itr++)
|
||
|
{ // color or string action behaviour, can also do maths...
|
||
|
geoArithBehaviour *ab=dynamic_cast<geoArithBehaviour *>(*itr);
|
||
|
if (ab) ab->doaction();
|
||
|
geoAr3Behaviour *a3=dynamic_cast<geoAr3Behaviour *>(*itr);
|
||
|
if (a3) a3->doaction();
|
||
|
geoClampBehaviour *cb=dynamic_cast<geoClampBehaviour *>(*itr);
|
||
|
if (cb) cb->doaction();
|
||
|
geoRangeBehaviour *cr=dynamic_cast<geoRangeBehaviour *>(*itr);
|
||
|
if (cr) cr->doaction();
|
||
|
geoStrContentBehaviour *sb=dynamic_cast<geoStrContentBehaviour *>(*itr);
|
||
|
if (sb) sb->doaction(dr);
|
||
|
// colorbehaviour may be for 1 or all vertices
|
||
|
geoColourBehaviour *clrb=dynamic_cast<geoColourBehaviour *>(*itr);
|
||
|
if (clrb) clrb->doaction(dr);
|
||
|
geoMoveVertexBehaviour *mvvb=dynamic_cast<geoMoveVertexBehaviour *>(*itr);
|
||
|
if (mvvb && (prevvtr<0 || prevvtr==mvvb->getindex())) {
|
||
|
mvvb->doaction(mtr,dr);
|
||
|
pos=mvvb->getpos();
|
||
|
prevvtr=mvvb->getindex();
|
||
|
}
|
||
|
}
|
||
|
osg::Geometry *gm=dynamic_cast<osg::Geometry *>(dr);
|
||
|
if (gm && prevvtr>=0) {
|
||
|
osg::Vec3Array* vtxa = dynamic_cast<osg::Vec3Array*>(gm->getVertexArray());
|
||
|
bool newpos=false;
|
||
|
(*vtxa)[prevvtr]=pos*mtr;
|
||
|
do { // check for other vertices that may be animated
|
||
|
newpos=false;
|
||
|
mtr.identity();
|
||
|
for (itr=gblist.begin();
|
||
|
itr<gblist.end();
|
||
|
itr++) { // color or string action behaviour, can also do maths...
|
||
|
geoMoveVertexBehaviour *mvvb=dynamic_cast<geoMoveVertexBehaviour *>(*itr);
|
||
|
if (mvvb) {
|
||
|
int vidx=mvvb->getindex();
|
||
|
if (mvvb && (prevvtr<vidx || (newpos && prevvtr==vidx))) {
|
||
|
mvvb->doaction(mtr,dr);
|
||
|
prevvtr=vidx;
|
||
|
pos=mvvb->getpos();
|
||
|
newpos=true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (newpos) {
|
||
|
osg::Vec3Array* vtxa = dynamic_cast<osg::Vec3Array*>(gm->getVertexArray());
|
||
|
(*vtxa)[prevvtr]=pos*mtr;
|
||
|
}
|
||
|
} while (newpos);
|
||
|
}
|
||
|
}
|