From e9df1544271bc90a1f91079dbfd62a9335aed3f5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 21 Nov 2003 19:33:09 +0000 Subject: [PATCH] From John Tan, support for offset and scale tex coords via TexMat. --- src/osgPlugins/obj/ReaderWriterOBJ.cpp | 54 ++++++++++---- src/osgPlugins/obj/glm.cpp | 99 +++++++++++++++++++++++++- src/osgPlugins/obj/glm.h | 4 ++ 3 files changed, 140 insertions(+), 17 deletions(-) diff --git a/src/osgPlugins/obj/ReaderWriterOBJ.cpp b/src/osgPlugins/obj/ReaderWriterOBJ.cpp index 69bbc0ea8..da068c728 100644 --- a/src/osgPlugins/obj/ReaderWriterOBJ.cpp +++ b/src/osgPlugins/obj/ReaderWriterOBJ.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -242,16 +243,13 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(const std::string& fil if (titr==textureMap.end()) { -// std::string fileName = osgDB::findFileInDirectory(omtl->textureName,directory,true); -// -// std::cout << "omtl->textureName "<textureName<textureName); + std::string fileName = osgDB::findFileInDirectory(omtl->textureName,directory,osgDB::CASE_INSENSITIVE); + if (!fileName.empty()) fileName = osgDB::findDataFile(omtl->textureName,osgDB::CASE_INSENSITIVE); + + if (!fileName.empty()) + { + + osg::Image* osg_image = osgDB::readImageFile(fileName.c_str()); if (osg_image) { osg::Texture2D* osg_texture = new osg::Texture2D; @@ -260,16 +258,42 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(const std::string& fil textureMap[omtl->textureName] = osg_texture; + // Adjust the texture matrix if necessary + bool needsUVScaling = (1.0 != omtl->textureUScale) || (1.0 != omtl->textureVScale); + bool needsUVOffsetting = (0.0 != omtl->textureUOffset) || (0.0 != omtl->textureVOffset); + + if (needsUVScaling || needsUVOffsetting) + { + osg::TexMat* osg_texmat = new osg::TexMat; + + osg::Matrix scale; + osg::Matrix translate; + scale.makeIdentity(); + translate.makeIdentity(); + + if (needsUVScaling) + { + scale.makeScale(omtl->textureUScale, omtl->textureVScale, 1.0f); + } + + if (needsUVOffsetting) + { + translate.makeTranslate(omtl->textureUOffset, omtl->textureVOffset, 0.0f); + } + + osg_texmat->setMatrix(scale * translate); + stateset->setTextureAttributeAndModes(0,osg_texmat,osg::StateAttribute::ON); + } } else { osg::notify(osg::NOTICE) << "Warning: Cannot create texture "<textureName<< std::endl; } -// } -// else -// { -// osg::notify(osg::WARN) << "texture '"<textureName<<"' not found"<< std::endl; -// } + } + else + { + osg::notify(osg::WARN) << "texture '"<textureName<<"' not found"<< std::endl; + } } else diff --git a/src/osgPlugins/obj/glm.cpp b/src/osgPlugins/obj/glm.cpp index ac5b6ea9a..31991ea97 100644 --- a/src/osgPlugins/obj/glm.cpp +++ b/src/osgPlugins/obj/glm.cpp @@ -265,6 +265,98 @@ _glmDirName(char* path) } +/* _glmReadMTLTextureOptions: parses the given line for texture options + * and applies the options to the given model/material + * + * model - properly initialized GLMmodel structure + * materialIndex - the material affected in the given model + * line - white-space separated options + */ +GLvoid +_glmReadMTLTextureOptions(GLMmodel* model, unsigned int materialIndex, char* line) +{ + char *token; + char seps[] = " \t\n\r\f\v"; + std::cout<<"line ["< + case 's': + float uScale, vScale; + token = ::strtok(NULL, seps); + uScale = token ? (float)::atof(token) : 1.0f; + + token = ::strtok(NULL, seps); + vScale = token ? (float)::atof(token) : 1.0f; + + if ((0.0f != uScale) && (0.0f != vScale)) + { + uScale = 1.0f / uScale; + vScale = 1.0f / vScale; + model->materials[materialIndex].textureUScale = uScale; + model->materials[materialIndex].textureVScale = vScale; + } + break; + + // Offset: -o + case 'o': + float uOffset, vOffset; + token = ::strtok(NULL, seps); + uOffset = token ? (float)::atof(token) : 0.0f; + + token = ::strtok(NULL, seps); + vOffset = token ? (float)::atof(token) : 0.0f; + + model->materials[materialIndex].textureUOffset = uOffset; + model->materials[materialIndex].textureVOffset = vOffset; + break; + + // These options are not handled - so just advance to the next + // valid token + // ================================================================== + // + + // Clamping: -clamp + case 'c': + token = ::strtok(NULL, seps); + break; + + // Bias and gain: -mm + case 'm': + // Turbulence/Noise: -t + case 't': + token = ::strtok(NULL, seps); + token = ::strtok(NULL, seps); + break; + + default: + break; + } + break; + + // Image filename + default: + if (0 != strlen(token)) + { + model->materials[materialIndex].textureName = strdup(token); + std::cout<<"token ["<materials[materialIndex].textureName<<"]"<materials[i].specular[2] = 0.0f; model->materials[i].textureName = NULL; model->materials[i].textureReflection = false; + model->materials[i].textureUScale = 1.0f; + model->materials[i].textureVScale = 1.0f; + model->materials[i].textureUOffset = 0.0f; + model->materials[i].textureVOffset = 0.0f; model->materials[i].alpha = 1.0f; } model->materials[0].name = strdup("default"); @@ -398,8 +494,7 @@ _glmReadMTL(GLMmodel* model, char* name) if (strcmp(buf,"map_Kd")==0) { fgets(buf, sizeof(buf), file); - sscanf(buf, "%s %s", buf, buf); - model->materials[nummaterials].textureName = strdup(buf); + _glmReadMTLTextureOptions(model, nummaterials, buf); } else if (strcmp(buf,"refl")==0) { diff --git a/src/osgPlugins/obj/glm.h b/src/osgPlugins/obj/glm.h index 3956f51fd..737b7cd2e 100644 --- a/src/osgPlugins/obj/glm.h +++ b/src/osgPlugins/obj/glm.h @@ -48,6 +48,10 @@ struct GLMmaterial char* textureName; /* name of any attached texture, add by RO */ bool textureReflection; /* true if texture is a reflection map */ float alpha; /* alpha */ + float textureUScale; /* Scaling along U */ + float textureVScale; /* Scaling along V */ + float textureUOffset; /* Offset along U */ + float textureVOffset; /* Offset along V */ void init() {