Files
OpenSceneGraph/src/osgPlugins/obj/obj.h
Robert Osfield 9d260213f7 From Ulrich Hertlein, "attached are some fixes and tweaks I made to the .obj loader:
- Material class contained both 'shininess' and 'Ns' member variables
- 'Ns' and 'Ni' are initialized to 0 ('Ni' is unused at the moment)
- only 'Ns' was read from .mtl file but 'shininess' was used for osg::Material
- 'illum' was read from .mtl file but never used; it is now used as follows
-- illum==0 -> no osg::Material created/attached therefore no lighting
-- illum==1 -> osg::Material specular is set to black
-- illum==2 (default) -> specular read from .mtl file is used
- 'map_Kd' and 'map_Ks' may contain additional arguments (e.g. '-s 1 1 1'),
these are now skipped over and the texture filename is properly extracted
"
2007-12-10 20:27:06 +00:00

199 lines
5.2 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 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 OBJ_H
#define OBJ_H
#include <string>
#include <vector>
#include <map>
#include <istream>
#include <osg/ref_ptr>
#include <osg/Referenced>
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osgDB/ReaderWriter>
namespace obj
{
class Material
{
public:
Material():
ambient(0.2f,0.2f,0.2f,1.0f),
diffuse(0.8f,0.8f,0.8f,1.0f),
specular(0.0f,0.0f,0.0f,1.0f),
emissive(0.0f,0.0f,0.0f,1.0f),
sharpness(0.0f),
illum(2),
Tf(0.0f,0.0f,0.0f,1.0f),
Ni(0),
Ns(0),
textureReflection(false),
alpha(1.0f),
uScale(1.0f),
vScale(1.0f),
uOffset(1.0f),
vOffset(1.0f) {}
std::string name;
osg::Vec4 ambient;
osg::Vec4 diffuse;
osg::Vec4 specular;
osg::Vec4 emissive;
float sharpness;
int illum;
osg::Vec4 Tf;
int Ni;
int Ns; // shininess 0..1000
std::string map_Ka;
std::string map_Kd;
std::string map_Ks;
bool textureReflection;
float alpha;
float uScale;
float vScale;
float uOffset;
float vOffset;
protected:
};
class Element : public osg::Referenced
{
public:
typedef std::vector<int> IndexList;
enum DataType
{
POINTS,
POLYLINE,
POLYGON
};
Element(DataType type):
dataType(type) {}
enum CoordinateCombination
{
VERTICES,
VERTICES_NORMALS,
VERTICES_TEXCOORDS,
VERTICES_NORMALS_TEXCOORDS
};
CoordinateCombination getCoordinateCombination() const
{
if (vertexIndices.size()==normalIndices.size())
return (vertexIndices.size()==texCoordIndices.size()) ? VERTICES_NORMALS_TEXCOORDS : VERTICES_NORMALS;
else
return (vertexIndices.size()==texCoordIndices.size()) ? VERTICES_TEXCOORDS : VERTICES;
}
DataType dataType;
IndexList vertexIndices;
IndexList normalIndices;
IndexList texCoordIndices;
};
class ElementState
{
public:
ElementState():
coordinateCombination(Element::VERTICES),
smoothingGroup(0) {}
bool operator < (const ElementState& rhs) const
{
if (materialName<rhs.materialName) return true;
else if (rhs.materialName<materialName) return false;
if (objectName<rhs.objectName) return true;
else if (rhs.objectName<objectName) return false;
if (groupName<rhs.groupName) return true;
else if (rhs.groupName<groupName) return false;
if (coordinateCombination<rhs.coordinateCombination) return true;
else if (rhs.coordinateCombination<coordinateCombination) return false;
return (smoothingGroup<rhs.smoothingGroup);
}
std::string objectName;
std::string groupName;
std::string materialName;
Element::CoordinateCombination coordinateCombination;
int smoothingGroup;
};
class Model
{
public:
Model():
currentElementList(0) {}
void setDatabasePath(const std::string& path) { databasePath = path; }
const std::string& getDatabasePath() const { return databasePath; }
std::string lastComponent(const char* linep);
bool readMTL(std::istream& fin);
bool readOBJ(std::istream& fin, const osgDB::ReaderWriter::Options* options);
bool readline(std::istream& fin, char* line, const int LINE_SIZE);
void addElement(Element* element);
osg::Vec3 averageNormal(const Element& element) const;
osg::Vec3 computeNormal(const Element& element) const;
bool needReverse(const Element& element) const;
int remapVertexIndex(int vi) { return (vi<0) ? vertices.size()+vi : vi-1; }
int remapNormalIndex(int vi) { return (vi<0) ? normals.size()+vi : vi-1; }
int remapTexCoordIndex(int vi) { return (vi<0) ? texcoords.size()+vi : vi-1; }
typedef std::map<std::string,Material> MaterialMap;
typedef std::vector< osg::Vec2 > Vec2Array;
typedef std::vector< osg::Vec3 > Vec3Array;
typedef std::vector< osg::ref_ptr<Element> > ElementList;
typedef std::map< ElementState,ElementList > ElementStateMap;
std::string databasePath;
MaterialMap materialMap;
Vec3Array vertices;
Vec3Array normals;
Vec2Array texcoords;
ElementState currentElementState;
ElementStateMap elementStateMap;
ElementList* currentElementList;
};
}
#endif