From Geoff Michel, updates to GEO plugin.

This commit is contained in:
Robert Osfield
2003-11-28 14:37:46 +00:00
parent 1c2ef7d508
commit 848e21fb98
9 changed files with 352 additions and 40 deletions

View File

@@ -101,6 +101,10 @@ SOURCE=..\..\..\src\osgPlugins\geo\geoActions.cpp
SOURCE=..\..\..\src\osgPlugins\geo\ReaderWriterGEO.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\geo\ClipRegion.cpp
# End Source File
# End Group
# Begin Group "Header Files"
@@ -133,6 +137,10 @@ SOURCE=..\..\..\src\osgPlugins\geo\osgGeoNodes.h
SOURCE=..\..\..\src\osgPlugins\geo\osgGeoStructs.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\geo\ClipRegion.h
# End Source File
# End Group
# Begin Group "Resource Files"

View File

@@ -0,0 +1,140 @@
// clip region
// GEO version, Nov 2003
// may be replaced when clipRegion accepted into OSG proper.
// i) a clipregion is class derived from Group, with a Geode and any children of the group
// ii) a special draw is made that:
// sets stencil bits by drawing the clip Geode
// draws the children of group clipped by the stencil region.
// partly derived fromt he stencil code in osgreflect example.
#include "ClipRegion.h"
#include <osg/ColorMask>
#include <osg/Geode>
#include <osg/Depth>
#include <osg/BlendFunc>
#include <osgUtil/CullVisitor>
using namespace osg;
//=====
GeoClipRegion::GeoClipRegion(int bin)
{
stencilbin=bin;
}
GeoClipRegion::~GeoClipRegion()
{
}
GeoClipRegion::GeoClipRegion(const GeoClipRegion& clr,const osg::CopyOp& copyop): osg::Group(clr,copyop)
{ //_clipNodes=clr._clipNodes;
}
void GeoClipRegion::addClipNode(osg::Node *gd) {
osg::StateSet *state=gd->getOrCreateStateSet();
// add clip node(s) to set stencil bit marking the clip area.
// stencil op so that the stencil buffer get set at the clip pixels
osg::Stencil* stencil = new osg::Stencil;
stencil->setFunction(osg::Stencil::ALWAYS,1,~0);
stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::REPLACE);
state->setAttributeAndModes(stencil,osg::StateAttribute::ON);
// switch off the writing to the color bit planes. (Dont show the clip area)
osg::ColorMask* colorMask = new osg::ColorMask;
colorMask->setMask(false,false,false,false);
state->setRenderBinDetails(stencilbin,"RenderBin");
state->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
state->setAttribute(colorMask);
// set up depth so all writing to depth goes to maximum depth. (dont want to z-clip the cull stencil)
osg::Depth* depth = new osg::Depth;
depth->setFunction(osg::Depth::ALWAYS);
depth->setRange(1.0,1.0);
state->setAttribute(depth);
Group::addChild(gd);
}
bool GeoClipRegion::addChild( osg::Node *child )
{
// bin the last - draw 'real' scenery last, using Z buffer to clip against any clip region...
osg::StateSet* statesetBin2 = child->getOrCreateStateSet();
statesetBin2->setRenderBinDetails(stencilbin+3,"RenderBin");
/* osg::Stencil* stencil = new osg::Stencil;
stencil->setFunction(osg::Stencil::ALWAYS,0,~0);
stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::REPLACE);
statesetBin2->setAttributeAndModes(stencil,osg::StateAttribute::ON);*/
return Group::addChild(child);
}
bool GeoClipRegion::addClippedChild( osg::Node *child )
{
// these children of this clipregion are drawn in stencilBin+2, clipped at the edges of the clip region
osg::StateSet *state=child->getOrCreateStateSet();
// state tests pixels against the set stencil.
osg::Stencil* stenciltest = new osg::Stencil;
stenciltest->setFunction(osg::Stencil::EQUAL,1,~0);
stenciltest->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP);
state->setAttributeAndModes(stenciltest,osg::StateAttribute::ON);
osg::ColorMask* cMask = new osg::ColorMask;
cMask->setMask(true,true,true,true);
state->setAttribute(cMask);
state->setRenderBinDetails(stencilbin+1,"RenderBin");
// use depth for rest of the scene unless overriden.
osg::Depth* rootDepth = new osg::Depth;
rootDepth->setFunction(osg::Depth::LESS);
rootDepth->setRange(0.0,1.0);
state->setAttribute(rootDepth);
return Group::addChild(child);
}
bool GeoClipRegion::addObscuredChild( osg::Node *child )
{
// other children of this node are drawn in stencilBin+2 outside the clip, hidden by the clip region
osg::StateSet *state=child->getOrCreateStateSet();
// state tests pixels against the set stencil.
osg::Stencil* stenciltest = new osg::Stencil;
stenciltest->setFunction(osg::Stencil::NOTEQUAL,1,~0);
stenciltest->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP);
state->setAttributeAndModes(stenciltest,osg::StateAttribute::ON);
osg::ColorMask* cMask = new osg::ColorMask;
cMask->setMask(true,true,true,true);
state->setAttribute(cMask);
state->setRenderBinDetails(stencilbin+1,"RenderBin");
// use depth for rest of the scene unless overriden.
osg::Depth* rootDepth = new osg::Depth;
rootDepth->setFunction(osg::Depth::LESS);
rootDepth->setRange(0.0,1.0);
state->setAttribute(rootDepth);
return Group::addChild(child);
}
void GeoClipRegion::addDrawClipNode(osg::Node *ndclip)
{
osg::StateSet *state=ndclip->getOrCreateStateSet();
// last bin - draw clip area and blend it with the clipped, visible geometry.
// set up depth so all writing to depth goes to maximum depth.
osg::Depth* depth = new osg::Depth;
depth->setFunction(osg::Depth::ALWAYS);
osg::Stencil* stencil = new osg::Stencil;
stencil->setFunction(osg::Stencil::EQUAL,1,~0);
stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::ZERO);
// set up additive blending.
osg::BlendFunc* trans = new osg::BlendFunc;
trans->setFunction(osg::BlendFunc::ONE,osg::BlendFunc::ONE);
state->setRenderBinDetails(stencilbin+2,"RenderBin");
state->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
state->setAttributeAndModes(stencil,osg::StateAttribute::ON);
state->setAttributeAndModes(trans,osg::StateAttribute::ON);
state->setAttribute(depth);
Group::addChild(ndclip);
}

View File

@@ -0,0 +1,54 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_GEOCLIPREGION
#define OSG_GEOCLIPREGION 1
#include <osg/Group>
#include <osg/Stencil>
/** A ClipRegion is a group node for which all children are clipped
* by the projection into screen coordinates of the ClipGeode.
* Used for cutouts in instrumentation.
*
*
*/
class GeoClipRegion : public osg::Group
{
public :
GeoClipRegion(int bin=osg::StateSet::TRANSPARENT_BIN+3);
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
GeoClipRegion(const GeoClipRegion&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
// clip nodes define a screen region that is protected
void addClipNode(osg::Node *gd);
/* clipped children are only drawn inside the clip Node(s) protected screen area
* Obscured Nodes are (partly) hidden where the clipNodes overlap
*/
virtual bool addClippedChild( osg::Node *child );
virtual bool addObscuredChild( osg::Node *child );
virtual bool addChild( osg::Node *child );
// drawClipNodes are special draw of geometry at the clip area which undoes the stencil value
void addDrawClipNode(osg::Node *ndclip);
void setBin(const int bin) { stencilbin=bin;}
protected :
virtual ~GeoClipRegion();
int stencilbin;
};
#endif // match OSG_GEOCLIPREGION

View File

@@ -3,6 +3,7 @@ include $(TOPDIR)/Make/makedefs
CXXFILES =\
geoActions.cpp\
ClipRegion.cpp\
ReaderWriterGEO.cpp

View File

@@ -5,7 +5,7 @@
// Loader has been divided into two parts
// 1- general geometry (here) &
// 2- animation (see geoActions.cpp).
// ver 1.1 GWM Dec 2002
// ver 1.2 GWM Nov 2003
#include <string>
@@ -27,6 +27,7 @@
#include <osg/StateSet>
#include <osg/CullFace>
#include <osg/Point>
#include "ClipRegion.h"
#include <osgSim/LightPointNode>
@@ -204,7 +205,7 @@ public:
const geoField *gfd=gr->getField(GEO_DB_VRTX_NORMAL);
if (gfd->getType()==DB_UINT) {
if (gfd) {
unsigned int idx=gfd->getUInt();
unsigned int idx=gfd->getUInt();
normindices->push_back(idx);
norms->push_back((*npool)[idx]);
} else {
@@ -351,13 +352,13 @@ private:
class geoInfo { // identifies properties required to make a new Geometry, and holds collection of vertices, indices, etc
public:
geoInfo(const int txidx=-2, const int sm=1, const bool bs=true) { texture=txidx; // will be -1 or 0-number of textures
geoInfo(const int txidx=-2, const int sm=1, const int bs=1) { texture=txidx; // will be -1 or 0-number of textures
geom=NULL; nstart=0; linewidth=1;
bothsides=bs; shademodel=sm;
}
virtual ~geoInfo() { };
inline int getShademodel(void) const { return shademodel;}
inline bool getBothsides(void) const { return bothsides;}
inline int getBothsides(void) const { return bothsides;}
inline int getTexture(void) const { return texture;}
inline vertexInfo *getVinf(void) { return &vinf;}
void setPools(const std::vector<osg::Vec3> *coord_pool, const std::vector<osg::Vec3> *normal_pool) {
@@ -377,7 +378,7 @@ public:
}
private:
int texture; // texture index
bool bothsides;
int bothsides; // none, back,front
int shademodel;
int linewidth;
vertexInfo vinf;
@@ -435,8 +436,9 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
output(fout,sorted);
fout.close();
#endif /**/
nodeList=makeosg(sorted); // make a list of osg nodes
recs.clear();
makeHeader(*(sorted.begin()));
nodeList=makeosg(sorted); // make a list of osg nodes
geotxlist.clear();
geomatlist.clear();
txlist.clear();
@@ -465,9 +467,12 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
groupnode=group;
}
(theHeader.get())->addChild(groupnode);
groupnode=theHeader.get();
#ifdef _DEBUG // output a .osg version
osgDB::writeNodeFile(*groupnode,"geoosg.osg");
#endif /**/
recs.clear();
return groupnode;
}
return 0L;
@@ -576,8 +581,13 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
case DB_DSK_ABS_ACTION:
case DB_DSK_IF_THEN_ELSE_ACTION:
case DB_DSK_DCS_ACTION:
case DB_DSK_SQRT_ACTION: // square root action
(curparent->getLastChild())->addBehaviourRecord(&(*itr));
case DB_DSK_SQRT_ACTION: // an action
if (curparent->getType()==DB_DSK_HEADER)
curparent->addBehaviourRecord(&(*itr));
else {
class georecord *cp=curparent->getLastChild();
if (cp) cp->addBehaviourRecord(&(*itr));
}
break;
case DB_DSK_PERSPECTIVE_GRID_INFO: // Feb 2003 not sure what this is yet!
(curparent)->addchild(&(*itr));
@@ -608,7 +618,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
}
}
bool allOneSided(const georecord *grec) {
/* bool allOneSided(const georecord *grec) {
bool one=false;
const std::vector<georecord *> gr=grec->getchildren();
if (gr.size()>0) {
@@ -625,23 +635,31 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
}
return one;
}
}*/
osg::Geometry *makeNewGeometry(const georecord *grec, geoInfo &ginf, int imat) {
const int shademodel=ginf.getShademodel();
const bool bothsides=ginf.getBothsides();
const int bothsides=ginf.getBothsides();
osg::Geometry *nug;
int txidx=ginf.getTexture();
nug=new osg::Geometry;
const vertexInfo *vinf=ginf.getVinf();
// nug->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
nug->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
nug->setVertexArray(vinf->getCoords());
nug->setNormalArray(vinf->getNorms());
StateSet *dstate=new StateSet;
if (!bothsides) {
StateSet *dstate=new StateSet;
if (bothsides==0) {
osg::CullFace *cf = new osg::CullFace; // to define non-default culling
cf->setMode(osg::CullFace::BACK);
dstate->setAttributeAndModes(cf,osg::StateAttribute::ON);
}
else if (bothsides==1) {
osg::CullFace *cf = new osg::CullFace; // to define non-default culling
cf->setMode(osg::CullFace::FRONT);
dstate->setAttributeAndModes(cf,osg::StateAttribute::ON);
}
else if (bothsides==2) {
osg::CullFace *cf = new osg::CullFace; // to define non-default culling
dstate->setAttributeAndModes(cf,osg::StateAttribute::OFF);
}
Point *pt=new Point;
pt->setSize(4);
dstate->setAttribute(pt);
@@ -678,7 +696,6 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
{ // reclaim the colours
gfd=grec->getField(GEO_DB_POLY_USE_MATERIAL_DIFFUSE); // true: use material...
bool usemat= gfd ? gfd->getBool() : false;
nug->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
if (!usemat) { // get the per vertex colours OR per face colours.
gfd=grec->getField(GEO_DB_POLY_USE_VERTEX_COLORS); // true: use material...
bool usevert=gfd ? gfd->getBool() : false;
@@ -693,7 +710,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
nug->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
} else if (shademodel==GEO_POLY_SHADEMODEL_LIT) {
nug->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
}
}
osg::Vec4Array *polycols=vinf->getPolcolours();
nug->setColorArray(polycols);
nug->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);
@@ -916,7 +933,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
++itr)
{
if ((*itr)->getType()==DB_DSK_LIGHTPT) { // light points ONLY
geoInfo ginf(0,0, true);
geoInfo ginf(0,0, 1);
ginf.setPools(&coord_pool, &normal_pool); // holds all types of coords, indices etc
osgSim::LightPointNode *gd=new osgSim::LightPointNode;
// to be implemented const geoField *gfd=(*itr)->getField(GEO_DB_LIGHTPT_TYPE); // omni, uni, bi
@@ -929,7 +946,9 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
// animated polygons - create a matrix & geode & poly & add to group nug
const std::vector<georecord *> gr=grec.getchildren();
int nanimations=0;
bool bothsides=allOneSided(&grec);
const geoField *gfd=grec.getField(GEO_DB_RENDERGROUP_CULLING); // back, front, none
unsigned int bothsides=gfd ? gfd->getUInt() : 0;
// int bothsides =allOneSided(&grec);
for (std::vector<georecord *>::const_iterator itr=gr.begin();
itr!=gr.end();
++itr) {
@@ -1022,7 +1041,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
return ok;
}
geoInfo *getGeometry(const georecord *grec,Geode *nug, std::vector<class geoInfo> *ia,
const unsigned int imat, const int shademodel, const bool bothsides) {
const unsigned int imat, const int shademodel, const int bothsides) {
int igidx=0, igeom=-1;
const geoField *gfd=grec->getField(GEO_DB_POLY_TEX0);
int txidx= gfd ? gfd->getInt() : -1;
@@ -1059,8 +1078,10 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
// std::vector<osg::Geometry *> geom;
if (gr.size()>0) {
std::vector<class geoInfo> ia; // list of texture indices & vinfo found in this geode; sort into new
const geoField *gfd=grec.getField(GEO_DB_RENDERGROUP_CULLING); // back, front, none
unsigned int bothsides=gfd ? gfd->getUInt() : 0;
// vertexInfo vinf(&coord_pool, &normal_pool); // holds all types of coords, indices etc
bool bothsides=allOneSided(&grec);
// bool bothsides=allOneSided(&grec);
for (std::vector<georecord *>::const_iterator itr=gr.begin();
itr!=gr.end();
++itr) {
@@ -1096,6 +1117,15 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
}
int nv=getprim((*itr), *gi);
{
const vertexInfo *vinf=gi->getVinf();
if (vinf->getNorms() && vinf->getNorms()->size()>0) {
gi->getGeom()->setNormalArray(vinf->getNorms());
gi->getGeom()->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
} else {
gi->getGeom()->setNormalBinding(osg::Geometry::BIND_OFF);
}
}
if (hasColorAction(bhv)) addPolyActions(bhv, *gi, nv);
if (dstyle==GEO_POLY_DSTYLE_SOLID_BOTH_SIDES || dstyle == GEO_POLY_DSTYLE_SOLID) {
@@ -1246,7 +1276,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
return gp;
}
osg::Group *setmatrix(const georecord *gr) { // find one of the type sof matrix supported
osg::Group *setmatrix(const georecord *gr) { // find one of the types of matrix supported
const geoField *gfd=gr->getField(GEO_DB_GRP_MATRIX_TRANSFORM);
if (!gfd) gfd=gr->getField(GEO_DB_GRP_TRANSLATE_TRANSFORM);
if (!gfd) gfd=gr->getField(GEO_DB_GRP_ROTATE_TRANSFORM);
@@ -1293,7 +1323,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
osg::notify(osg::WARN) << gr << " imask " << imask << std::endl;
} else {
sw->setSingleChildOn(0);
osg::notify(osg::WARN) << gr << " No mask " << std::endl;
osg::notify(osg::WARN) << gr << " Switch has No mask- only 1 child " << std::endl;
}
gfd=gr->getField(GEO_DB_NODE_NAME);
if (gfd) {
@@ -1324,11 +1354,44 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
gp->setName(gfd->getChar());
}
return gp;
}
osg::Drawable* createClipSurface(float xMin,float xMax,float yMin,float yMax,float z)
{ // set up the Geometry that defines the clipped region.
osg::Geometry* geom = new osg::Geometry;
osg::Vec3Array* coords = new osg::Vec3Array(4);
(*coords)[0].set(xMin,yMax,z);
(*coords)[1].set(xMin,yMin,z);
(*coords)[2].set(xMax,yMin,z);
(*coords)[3].set(xMax,yMax,z);
geom->setVertexArray(coords);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
return geom;
}
Group *makeClipRegion(const georecord *gr) {
GeoClipRegion *clp=new GeoClipRegion;
const geoField *gfd=gr->getField(GEO_DB_NODE_NAME);
if (gfd) {
clp->setName(gfd->getChar());
}
gfd=gr->getField(140);
float *lleft = (gfd) ? (gfd->getVec3Arr()):NULL;
gfd=gr->getField(141);
float *uright= (gfd) ? (gfd->getVec3Arr()):NULL;
if (uright && lleft) {
Geode *geod=new Geode;
Drawable *drw=createClipSurface(lleft[0],uright[0],lleft[1],uright[1],lleft[2]);
geod->addDrawable(drw);
clp->addClipNode(geod);
}
return clp;
}
geoHeader *makeHeader(const georecord *gr) {
if (!theHeader.valid()) theHeader=new geoHeaderGeo();
// the header contains variables as well as a transform for the XYZup cases
const geoField *gfd;
theHeader=new geoHeaderGeo();
if (cpalrec) { // global - attach to geoheader
gfd=cpalrec->getField(GEO_DB_COLOR_PALETTE_HIGHEST_INTENSITIES);
if (gfd) {
@@ -1358,7 +1421,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
case GEO_DB_UP_AXIS_Z: // no change
q.set(0,0,0,1);
q/=q.length();
theHeader->setAttitude(q);
theHeader->setAttitude(q); // set(q);
break;
}
std::vector<georecord *>::const_iterator itr;
@@ -1650,7 +1713,9 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
osg::Depth* depth = new osg::Depth;
depth->setFunction(osg::Depth::ALWAYS);
dstate->setAttribute(depth);
dstate->setRenderBinDetails(osg::StateSet::OPAQUE_BIN + 3, "UnSortedBin");
dstate->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
dstate->setRenderBinDetails(osg::StateSet::TRANSPARENT_BIN + 1,"RenderBin");
// dstate->setRenderBinDetails(osg::StateSet::TRANSPARENT_BIN + 12, "UnSortedBin");
if (geode) geode->setStateSet( dstate );
if (animatedGeodes) animatedGeodes->setStateSet( dstate );
if (lightptGeodes) lightptGeodes->setStateSet( dstate );
@@ -1681,12 +1746,33 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
switch (gr->getType()) {
case 101:
case DB_DSK_HEADER:
holder=makeHeader(gr);
holder=new osg::Group; // makeGroup(gr);
if (mtr) {
mtr->addChild(holder);
holder=mtr;
}
(*itr)->setNode(holder);
break;
break;
/* holder= theHeader.get(); // makeHeader(gr);//
(*itr)->setNode(holder);
if (mtr) {
holder->addChild(mtr);
osg::Group *grp=makeGroup(gr);
mtr->addChild(grp);
holder=mtr;
}
break; */
case DB_DSK_TEXTURE:
makeTexture(gr);
break;
case DB_DSK_BASE_GROUP: // start of a group plus extra features
holder=makeClipRegion(gr);
if (mtr) {
mtr->addChild(holder);
holder=mtr;
}
(*itr)->setNode(holder);
break;
case DB_DSK_GROUP:
holder=makeGroup(gr);
if (mtr) {
@@ -1811,10 +1897,12 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
if (holder) nodelist.push_back(holder);
std::vector<Node *> child=makeosg((*itr)->getchildren());
GeoClipRegion *clip=dynamic_cast<GeoClipRegion *>(holder);
for (std::vector<Node *>::iterator itr=child.begin();
itr!=child.end();
++itr) {
holder->addChild(*itr);
if (clip) clip->addClippedChild(*itr);
else holder->addChild(*itr);
}
}
}
@@ -2087,6 +2175,10 @@ void geoField::readfile(std::ifstream &fin, const uint id) { // is part of a rec
} else {
if (numItems>0) {
storageRead(fin); // allocate & fill the storage
if (tokenId == GEO_DB_NODE_EXT) { // added Nov 2003 to parse extension nodes
if (TypeId == DB_SHORT ||TypeId == DB_USHORT) fin.ignore(2); // skip padding
// if (TypeId == DB_CHAR ||TypeId == DB_UCHAR) fin.ignore(3); // skip padding
}
if (tokenId == GEO_DB_NODE_EXTENDED) {
if (id==DB_DSK_POLYGON || id==DB_DSK_RENDERGROUP || id==DB_DSK_GROUP
|| id==DB_DSK_LOD || id==DB_DSK_MESH || id==DB_DSK_CUBE
@@ -2100,6 +2192,7 @@ void geoField::readfile(std::ifstream &fin, const uint id) { // is part of a rec
}
}
// now register with Registry to instantiate the above
// reader/writer.
osgDB::RegisterReaderWriterProxy<ReaderWriterGEO> gReaderWriter_GEO_Proxy;

View File

@@ -357,7 +357,7 @@ void geoMoveBehaviour::doaction(osg::Node *node) {
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::rotate(DEG2RAD(getValue()),axis)* // nov 2003 negative rotation convention
osg::Matrix::translate(centre));
break;
}
@@ -376,10 +376,14 @@ bool geoMoveBehaviour::makeBehave(const georecord *grec, const geoHeaderGeo *the
if (vcon) {
// std::cout<< "rotInput " << fid << " : " << theHeader->getVarname(fid)<< std::endl ;
setVar(vcon);
gfd=grec->getField(GEO_DB_ROTATE_ACTION_VECTOR);
const geoField *gfdir=grec->getField(GEO_DB_ROTATE_ACTION_DIR);
int flip=gfdir!=NULL; // ?(gfdir->getInt()):false;
// printf("Flip %d gfdir %x\n",flip, gfdir);
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]));
if (flip) setAxis(-osg::Vec3(ax[0],ax[1],ax[2]));
else setAxis(osg::Vec3(ax[0],ax[1],ax[2]));
}
gfd=grec->getField(GEO_DB_ROTATE_ACTION_ORIGIN);
if (gfd) {
@@ -601,6 +605,9 @@ 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
// printf("setting matrix %x\n", mtr);
// PositionAttitudeTransform *patr=dynamic_cast<PositionAttitudeTransform *> (node);
// if (patr) patr->setMatrix(Matrix::identity()); // all actions are multiplied to this
for (std::vector<geoBehaviour *>::const_iterator itr=gblist.begin();
itr<gblist.end();
itr++) { // motion behaviour

View File

@@ -15,7 +15,7 @@
// User variables - may be a function of other variables, defined in the editor.
// External variables - the user written callback function extvarupdate sets these values on each frame of simulation.
// User & external variables may be defined as a mathematical or logical function of
// all teh variables (external variables, internal variables & user variables).
// all the variables (external variables, internal variables & user variables).
// as a design rule, you should not normally attach a function to uvarupdate
// these variables should be considered as local variables within a function and not accessed by the program.
@@ -35,6 +35,12 @@ public:
geoHeader() {
uvarupdate=NULL; extvarupdate=NULL;
};
geoHeader(const geoHeader &geo,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) :
PositionAttitudeTransform(geo,copyop)
{
// const geoHeaderGeo *ghg=static_cast<const geoHeaderGeo *> (&geo);
}
~geoHeader() {}
void setUserUpdate(double (*ufn)(const double time,const double val, const std::string name) )
{ // pass the address of a user written function in the Update phase.

View File

@@ -49,6 +49,8 @@ private:
class internalVars { // holds internal variables for whole model
public:
internalVars() { }
internalVars(const internalVars &iv, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY ) {
vars=iv.vars; }
~internalVars() {
}
void addInternalVars(const georecord &gr);
@@ -82,6 +84,8 @@ private:
class userVars {
public:
userVars() {}
userVars(const userVars &iv, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY ) {
vars=iv.vars; }
~userVars() {}
unsigned int number() { return vars.size();}
std::vector<geoValue> *getvars() { return &vars;}
@@ -125,6 +129,11 @@ class geoHeaderGeo: public geoHeader {
public:
geoHeaderGeo();
~geoHeaderGeo() { color_palette->clear(); }
geoHeaderGeo(const geoHeaderGeo &geo,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) :
geoHeader(geo,copyop){
intVars=new internalVars(*geo.intVars); useVars=new userVars(*geo.useVars);
extVars=new userVars(*geo.extVars);
}
void addInternalVars(const georecord &gr) { intVars->addInternalVars(gr);}
internalVars *getInternalVars(void) const { return intVars;}
const std::string getVarname(const unsigned fid) const {

View File

@@ -132,7 +132,6 @@ public:
break;
}
}
//<<<<<<< osgGeoStructs.h
void set(unsigned short id,unsigned int fid) { // to set values
TypeId=DB_UINT;
@@ -143,7 +142,6 @@ public:
memcpy(storage,&fid,SIZEOF_UINT);
}
void set(unsigned short id,float *cen,const int nsize) { // to set values
//set(GEO_DB_ROTATE_ACTION_ORIGIN,ct,3);
if (nsize==3) {
TypeId=DB_VEC3F;
tokenId=id;
@@ -163,10 +161,6 @@ public:
}
void readfile(std::ifstream &fin, const unsigned int id); // is part of a record id
void parseExt(std::ifstream &fin) const; // Feb 2003 parse node extension fields
/*=======
void readfile(std::ifstream &fin, const uint id); // is part of a record id
void parseExt(std::ifstream &fin) const; // Feb 2003 parse node extension fields
//>>>>>>> 1.10 */
void writefile(std::ofstream &fout) { // write binary file
if (numItems<32767 && tokenId<256) {
unsigned char tokid=tokenId, type=TypeId;