Added support for local relative paths

This commit is contained in:
Robert Osfield 2004-11-23 10:46:37 +00:00
parent ce07879e2e
commit 5c5ceef90d
11 changed files with 95 additions and 73 deletions

View File

@ -85,7 +85,11 @@ class ReaderWriterAC : public osgDB::ReaderWriter
// Anders Backmann - correct return if path not found
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
grp=ac_load_ac3d(fileName.c_str());
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
grp=ac_load_ac3d(fileName.c_str(), local_opt.get());
return grp;
};
virtual WriteResult writeNode(const Node& node,const std::string& fileName, const osgDB::ReaderWriter::Options* /*options*/)
@ -400,7 +404,7 @@ protate(osg::Vec3 p, float m[9])
p[2]=m[6]*t[0]+m[7]*t[1]+m[8]*t[3];
}
osg::Group *ac_load_object(std::istream &f,const ACObject *parent)
osg::Group *ac_load_object(std::istream &f,const ACObject *parent,const osgDB::ReaderWriter::Options* options)
{
// most of this logic came from Andy Colebourne (developer of the AC3D editor) so it had better be right!
char t[20];
@ -507,7 +511,7 @@ osg::Group *ac_load_object(std::istream &f,const ACObject *parent)
ctmp++;
if (*ctmp == '"') *ctmp='\0'; // latest ac3d seems toa dd more quotes than older versions.
}
osg::Image *ctx= osgDB::readImageFile(tokv[1]);
osg::Image *ctx= osgDB::readImageFile(tokv[1], options);
if (ctx)
{ // image coukd be read
ob.texture = new osg::Texture2D;// ac_load_texture(tokv[1]);
@ -781,7 +785,7 @@ osg::Group *ac_load_object(std::istream &f,const ACObject *parent)
}
for (n = 0; n < num; n++)
{
osg::Group *k = ac_load_object(f,&ob); //, ob);
osg::Group *k = ac_load_object(f,&ob, options);
if (k == NULL)
{
printf("error reading expected child object %d of %d at line: %d\n", n+1, num, line);
@ -854,7 +858,7 @@ int n;
}*/
osg::Group *ac_load_ac3d(const char *fname)
osg::Group *ac_load_ac3d(const char *fname,const osgDB::ReaderWriter::Options* options)
{
osg::Group *ret = NULL;
if (strlen(fname)>0) {
@ -880,7 +884,7 @@ osg::Group *ac_load_ac3d(const char *fname)
startmatindex = palette.size(); //num_palette;
ret = ac_load_object(fin,NULL); //, NULL);
ret = ac_load_object(fin,NULL, options);
fin.close();

View File

@ -7,6 +7,12 @@
// use can be picked up in hours rather than weeks.
// Other loaders and modellers are available for OSG.
#ifndef OSGAC3D_H
#define OSGAC3D_H
#include <osgDB/ReaderWriter>
typedef struct ACSurface_t
{
int num_vertref;
@ -64,22 +70,8 @@ typedef struct ACObject_t
#define myfree free
Prototype osg::Group *ac_load_ac3d(const char *filename);
Prototype osg::Group *ac_load_ac3d(const char *filename,const osgDB::ReaderWriter::Options* options);
Prototype osg::Material *ac_palette_get_material(const unsigned int index);
#endif

View File

@ -62,7 +62,8 @@ public:
const osgDB::ReaderWriter::Options* options);
private:
osg::Geode* convertFromDX(DX::Object& obj, bool flipTexture, float creaseAngle);
osg::Geode* convertFromDX(DX::Object& obj, bool flipTexture, float creaseAngle,
const osgDB::ReaderWriter::Options* options);
};
// Register with Registry to instantiate the above reader/writer.
@ -81,10 +82,16 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string&
osg::notify(osg::INFO) << "ReaderWriterDirectX::readNode(" << fileName.c_str() << ")\n";
// Load DirectX mesh
DX::Object obj;
if (obj.load(fileName.c_str())) {
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
// Options?
bool flipTexture = true;
float creaseAngle = 80.0f;
@ -98,7 +105,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string&
}
// Convert to osg::Geode
osg::Geode* geode = convertFromDX(obj, flipTexture, creaseAngle);
osg::Geode* geode = convertFromDX(obj, flipTexture, creaseAngle, local_opt.get());
if (!geode)
return ReadResult::FILE_NOT_HANDLED;
@ -110,7 +117,8 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string&
// Convert DirectX mesh to osg::Geode
osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Object& obj,
bool flipTexture, float creaseAngle)
bool flipTexture, float creaseAngle,
const osgDB::ReaderWriter::Options* options)
{
// Fetch mesh
const DX::Mesh* mesh = obj.getMesh();
@ -198,7 +206,7 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Object& obj,
// Share image/texture pairs
osg::Texture2D* texture = texForImage[mtl.texture[j]];
if (!texture) {
osg::Image* image = osgDB::readImageFile(mtl.texture[j]);
osg::Image* image = osgDB::readImageFile(mtl.texture[j],options);
if (!image)
continue;

View File

@ -48,12 +48,12 @@ public:
_lightnum=1;
}
~dwmaterial() { }
void settexture() {
void settexture(const osgDB::ReaderWriter::Options *options) {
if (!dstate) dstate = new StateSet;
if (isTextured()) { // shares common textures
if (!ctx || !tx) { // new texture needed
if (fname.length()>0) {
ctx=osgDB::readImageFile(fname.c_str());
ctx=osgDB::readImageFile(fname.c_str(),options);
if (ctx) {
ctx->setFileName(fname);
tx=new Texture2D;
@ -71,7 +71,7 @@ public:
}
}
}
StateSet *make() { // returns the OSG material
StateSet *make(const osgDB::ReaderWriter::Options *options) { // returns the OSG material
if (!dstate) { // if it does not exist, then make it
dstate = new StateSet;
osg::Material* osgMaterial = new osg::Material;
@ -98,7 +98,7 @@ public:
dstate->setAttribute(cf);
dstate->setTextureMode(0,GL_TEXTURE_2D,StateAttribute::OFF);
settexture();
settexture(options);
}
return dstate;
}
@ -607,7 +607,7 @@ public:
}
return nfaces;
}
void buildDrawable(Group *grp); // convert dwobj into osg geosets
void buildDrawable(Group *grp, const osgDB::ReaderWriter::Options *options); // convert dwobj into osg geosets
void setcolour(const float rgb[3]) {
colour[0]=rgb[0]; colour[1]=rgb[1]; colour[2]=rgb[2];
}
@ -728,7 +728,7 @@ void prims::combine( GLdouble coords[3], avertex *d[4],
newv->idx=dwob->addvtx(coords[0], coords[1], coords[2]);
*dataOut = newv;
}
void _dwobj::buildDrawable(Group *grp)
void _dwobj::buildDrawable(Group *grp, const osgDB::ReaderWriter::Options *options)
{ // current DWobject complete; make a drawable, and add it to a osg::Group
if (nfaces>0) {
if (themat->isType(dwmaterial::PointLight) || themat->isType(dwmaterial::SpotLight)) {
@ -766,7 +766,7 @@ void _dwobj::buildDrawable(Group *grp)
prd->settmat(tmat);
osg::Geometry *gset = new osg::Geometry;
prd->setGeometry(gset);
StateSet *dstate=themat->make();
StateSet *dstate=themat->make(options);
gset->setStateSet( dstate );
grp->addChild( geode ); // add to the world outside
geode->addDrawable(gset);
@ -833,6 +833,11 @@ class ReaderWriterDW : public osgDB::ReaderWriter
}
Group *grp = new Group;
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
while( !feof( fp ) )
{ // reads the Design Workshop format in ASCII
if (dwfgets( buff, sizeof( buff ), fp )) {
@ -889,7 +894,7 @@ class ReaderWriterDW : public osgDB::ReaderWriter
strncmp(buff,"Polyline:",9)==0 ||
strncmp(buff,"Polyhedron:",11)==0) {
rdg=OBJECT;
obj.buildDrawable(grp);
obj.buildDrawable(grp, options);
obj.reset();
} else if( strncmp(buff,"Mat:",4)==0) {
int mt=atoi(buff+4);
@ -942,7 +947,7 @@ class ReaderWriterDW : public osgDB::ReaderWriter
}
fclose( fp );
obj.buildDrawable(grp); // tidy up any remaining objects
obj.buildDrawable(grp, options); // tidy up any remaining objects
return grp;

View File

@ -411,6 +411,10 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
std::ifstream fin(fileName.c_str(), std::ios::binary | std::ios::in );
if (fin.is_open() )
{ // read the input file.
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
typedef std::vector<osg::Node*> NodeList;
NodeList nodeList;
osg::Material *mt=new osg::Material;
@ -440,9 +444,9 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
output(fout,sorted);
fout.close();
#endif /**/
makeHeader(*(sorted.begin()));
makeHeader(*(sorted.begin()), local_opt.get());
nodeList=makeosg(sorted); // make a list of osg nodes
nodeList=makeosg(sorted, local_opt.get()); // make a list of osg nodes
geotxlist.clear();
geomatlist.clear();
txlist.clear();
@ -1392,7 +1396,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
return clp;
}
geoHeader *makeHeader(const georecord *gr) {
geoHeader *makeHeader(const georecord *gr, const Options* options) {
if (!theHeader.valid()) theHeader=new geoHeaderGeo();
// the header contains variables as well as a transform for the XYZup cases
const geoField *gfd;
@ -1430,7 +1434,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
std::vector<georecord *>::const_iterator itr;
for (itr=geotxlist.begin(); itr<geotxlist.end(); itr++) {
makeTexture(*itr);
makeTexture(*itr, options);
}
std::vector< georecord *>bhv=gr->getBehaviour();
if (!bhv.empty()) { // then add internal, user, extern variables
@ -1455,13 +1459,13 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
return theHeader.get();
}
void makeTexture(const georecord *gr) {
void makeTexture(const georecord *gr, const Options* options) {
// scans the fields of this record and puts a new texture & environment into 'pool' stor
const geoField *gfd=gr->getField(GEO_DB_TEX_FILE_NAME);
const char *name = gfd->getChar();
if (name) {
Texture2D *tx=new Texture2D;
Image *ctx=osgDB::readImageFile(name);
Image *ctx=osgDB::readImageFile(name,options);
if (ctx) {
ctx->setFileName(name);
tx->setImage(ctx);
@ -1693,7 +1697,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
return mtr;
}
std::vector<Node *> makeosg(const std::vector<georecord *> gr) {
std::vector<Node *> makeosg(const std::vector<georecord *> gr, const Options* options) {
// recursive traversal of records and extract osg::Nodes equivalent
Group *geodeholder=NULL;
std::vector<Node *> nodelist;
@ -1767,7 +1771,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
break; */
case DB_DSK_TEXTURE:
makeTexture(gr);
makeTexture(gr, options);
break;
case DB_DSK_BASE_GROUP: // start of a group plus extra features
holder=makeClipRegion(gr);
@ -1900,7 +1904,7 @@ class ReaderWriterGEO : public osgDB::ReaderWriter
}
if (holder) nodelist.push_back(holder);
std::vector<Node *> child=makeosg((*itr)->getchildren());
std::vector<Node *> child=makeosg((*itr)->getchildren(), options);
GeoClipRegion *clip=dynamic_cast<GeoClipRegion *>(holder);
for (std::vector<Node *>::iterator itr=child.begin();
itr!=child.end();

View File

@ -32,16 +32,10 @@ class IVEReaderWriter : public ReaderWriter
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
// code for setting up the database path so that any paged
// databases can be automatically located.
osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
if (!local_opt) local_opt = new Options;
if (local_opt.valid() && local_opt->getDatabasePathList().empty())
{
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
}
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
return readNode(istream,local_opt.get());

View File

@ -59,15 +59,19 @@ public:
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
ReadResult result = readNode_LWO1(fileName,options);
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
ReadResult result = readNode_LWO1(fileName,local_opt.get());
if (result.success()) return result;
if (!options || options->getOptionString() != "USE_OLD_READER") {
ReadResult result = readNode_LWO2(fileName, options);
ReadResult result = readNode_LWO2(fileName, local_opt.get());
if (result.success()) return result;
}
return readNode_old_LWO2(fileName, options);
return readNode_old_LWO2(fileName, local_opt.get());
}
lwosg::Converter::Options parse_options(const Options *options) const;

View File

@ -39,10 +39,14 @@ public:
std::string fileName = osgDB::findDataFile(file, options);
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
lwosg::SceneLoader::Options conv_options = parse_options(options);
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
lwosg::SceneLoader::Options conv_options = parse_options(local_opt.get());
lwosg::SceneLoader scene_loader(conv_options);
osg::ref_ptr<osg::Node> node = scene_loader.load(fileName, options);
osg::ref_ptr<osg::Node> node = scene_loader.load(fileName, local_opt.get());
if (node.valid()) {
return node.take();
}

View File

@ -38,7 +38,7 @@
#include <assert.h>
static osg::Node* load_md2 (const char *filename);
static osg::Node* load_md2 (const char *filename, const osgDB::ReaderWriter::Options* options);
class ReaderWriterMD2 : public osgDB::ReaderWriter
{
@ -66,10 +66,14 @@ ReaderWriterMD2::readNode (const std::string& file,
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string filename = osgDB::findDataFile( file, options );
if (filename.empty()) return ReadResult::FILE_NOT_FOUND;
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
return load_md2 (filename.data());
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
return load_md2 (fileName.c_str(), options);
}
@ -147,7 +151,7 @@ osg::Vec3Array *g_md2NormalsArray = NULL;
// this is also quite non-portable to non-little-endian architectures
static osg::Node*
load_md2 (const char *filename)
load_md2 (const char *filename, const osgDB::ReaderWriter::Options* options)
{
struct stat st;
void *mapbase;
@ -224,7 +228,7 @@ load_md2 (const char *filename)
std::string imgname (md2_skins[si].name);
// first try loading the imgname straight
img = osgDB::readImageFile (imgname);
img = osgDB::readImageFile (imgname, options);
if (img) {
tex = new osg::Texture2D;
tex->setImage (img);
@ -238,7 +242,7 @@ load_md2 (const char *filename)
{
// it's a pcx, so try bmp and tga, since pcx sucks
std::string basename = imgname.substr (0, imgname.size() - 3);
img = osgDB::readImageFile (basename + "bmp");
img = osgDB::readImageFile (basename + "bmp", options);
if (img) {
tex = new osg::Texture2D;
tex->setImage (img);
@ -246,7 +250,7 @@ load_md2 (const char *filename)
continue;
}
img = osgDB::readImageFile (basename + "tga");
img = osgDB::readImageFile (basename + "tga", options);
if (img) {
tex = new osg::Texture2D;
tex->setImage (img);
@ -269,7 +273,7 @@ load_md2 (const char *filename)
do {
// first try loading the imgname straight
skin_image = osgDB::readImageFile (imgname);
skin_image = osgDB::readImageFile (imgname, options);
if (skin_image) break;
// we failed, so check if it's a PCX image
@ -278,10 +282,10 @@ load_md2 (const char *filename)
{
// it's a pcx, so try bmp and tga, since pcx sucks
std::string basename = imgname.substr (0, imgname.size() - 3);
skin_image = osgDB::readImageFile (basename + "bmp");
skin_image = osgDB::readImageFile (basename + "bmp", options);
if (skin_image) break;
skin_image = osgDB::readImageFile (basename + "tga");
skin_image = osgDB::readImageFile (basename + "tga", options);
if (skin_image) break;
}
} while (0);

View File

@ -459,9 +459,14 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(const std::string& fil
if (fin)
{
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
obj::Model model;
model.setDatabasePath(osgDB::getFilePath(fileName.c_str()));
model.readOBJ(fin, options);
model.readOBJ(fin, local_opt.get());
osg::Node* node = convertModelToSceneGraph(model);
return node;

View File

@ -35,10 +35,8 @@ class OSGReaderWriter : public ReaderWriter
std::string fileName = osgDB::findDataFile( file, opt );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
// code for setting up the database path so that any paged
// databases can be automatically located.
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = opt ? static_cast<Options*>(opt->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
std::ifstream fin(fileName.c_str());