From Ulrich Hertlein, updates to DirectX loader
This commit is contained in:
@@ -161,6 +161,14 @@ SOURCE=..\..\..\src\osgPlugins\directx\directx.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\directx\types.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\directx\mesh.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\directx\ReaderWriterDirectX.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -171,6 +179,14 @@ SOURCE=..\..\..\src\osgPlugins\directx\ReaderWriterDirectX.cpp
|
||||
|
||||
SOURCE=..\..\..\Src\osgPlugins\directx\directx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Src\osgPlugins\directx\types.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Src\osgPlugins\directx\mesh.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
ReaderWriterDirectX.cpp\
|
||||
directx.cpp
|
||||
directx.cpp\
|
||||
mesh.cpp\
|
||||
types.cpp
|
||||
|
||||
LIBS += $(OSG_LIBS) $(OTHER_LIBS)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
@@ -10,7 +10,7 @@
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -112,7 +112,7 @@ modification follow. Pay close attention to the difference between a
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
@@ -432,7 +432,7 @@ decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
@@ -455,7 +455,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
/**
|
||||
@@ -61,8 +62,11 @@ public:
|
||||
virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const;
|
||||
|
||||
private:
|
||||
osg::Geode* convertFromDX(DX::Object& obj, bool flipTexture, float creaseAngle,
|
||||
const osgDB::ReaderWriter::Options* options) const;
|
||||
osg::Group * convertFromDX(DX::Object & obj, bool flipTexture, float creaseAngle,
|
||||
const osgDB::ReaderWriter::Options * options) const;
|
||||
|
||||
osg::Geode * convertFromDX(DX::Mesh & mesh, bool flipTexture, float creaseAngle,
|
||||
const osgDB::ReaderWriter::Options * options) const;
|
||||
};
|
||||
|
||||
// Register with Registry to instantiate the above reader/writer.
|
||||
@@ -80,8 +84,6 @@ 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())) {
|
||||
@@ -102,40 +104,55 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to osg::Geode
|
||||
osg::Geode* geode = convertFromDX(obj, flipTexture, creaseAngle, local_opt.get());
|
||||
if (!geode)
|
||||
// Convert to osg::Group
|
||||
osg::Group* group = convertFromDX(obj, flipTexture, creaseAngle, local_opt.get());
|
||||
if (!group)
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
return geode;
|
||||
return group;
|
||||
}
|
||||
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
// Convert DirectX mesh to osg::Geode
|
||||
osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Object& obj,
|
||||
bool flipTexture, float creaseAngle,
|
||||
const osgDB::ReaderWriter::Options* options) const
|
||||
// Convert DirectX object
|
||||
osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj,
|
||||
bool flipTexture, float creaseAngle,
|
||||
const osgDB::ReaderWriter::Options * options) const
|
||||
{
|
||||
// Fetch mesh
|
||||
const DX::Mesh* mesh = obj.getMesh();
|
||||
if (!mesh)
|
||||
return NULL;
|
||||
osg::Group * group = new osg::Group;
|
||||
|
||||
const DX::MeshMaterialList* meshMaterial = obj.getMeshMaterialList();
|
||||
for (unsigned int i = 0; i < obj.getNumMeshes(); ++i) {
|
||||
//std::cerr << "converting mesh " << i << std::endl;
|
||||
DX::Mesh & mesh = *obj.getMesh(i);
|
||||
osg::Geode * geode = convertFromDX(mesh, flipTexture, creaseAngle, options);
|
||||
if (geode)
|
||||
group->addChild(geode);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
// Convert DirectX mesh to osg::Geode
|
||||
osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh,
|
||||
bool flipTexture, float creaseAngle,
|
||||
const osgDB::ReaderWriter::Options * options) const
|
||||
{
|
||||
const DX::MeshMaterialList* meshMaterial = mesh.getMeshMaterialList();
|
||||
if (!meshMaterial)
|
||||
return NULL;
|
||||
|
||||
const DX::MeshNormals* meshNormals = obj.getMeshNormals();
|
||||
const DX::MeshNormals* meshNormals = mesh.getMeshNormals();
|
||||
if (!meshNormals) {
|
||||
obj.generateNormals(creaseAngle);
|
||||
meshNormals = obj.getMeshNormals();
|
||||
mesh.generateNormals(creaseAngle);
|
||||
meshNormals = mesh.getMeshNormals();
|
||||
}
|
||||
//std::cerr << "normals=" << meshNormals << std::endl;
|
||||
if (!meshNormals)
|
||||
return NULL;
|
||||
|
||||
const DX::MeshTextureCoords* meshTexCoords = obj.getMeshTextureCoords();
|
||||
const DX::MeshTextureCoords* meshTexCoords = mesh.getMeshTextureCoords();
|
||||
//std::cerr << "texcoord=" << meshTexCoords << std::endl;
|
||||
if (!meshTexCoords)
|
||||
return NULL;
|
||||
|
||||
@@ -163,6 +180,8 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Object& obj,
|
||||
unsigned int i;
|
||||
for (i = 0; i < meshMaterial->material.size(); i++) {
|
||||
|
||||
//std::cerr << "material " << i << std::endl;
|
||||
|
||||
const DX::Material& mtl = meshMaterial->material[i];
|
||||
osg::StateSet* state = new osg::StateSet;
|
||||
|
||||
@@ -201,6 +220,8 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Object& obj,
|
||||
unsigned int textureCount = mtl.texture.size();
|
||||
for (unsigned int j = 0; j < textureCount; j++) {
|
||||
|
||||
//std::cerr << "texture " << j << std::endl;
|
||||
|
||||
// Share image/texture pairs
|
||||
osg::Texture2D* texture = texForImage[mtl.texture[j]];
|
||||
if (!texture) {
|
||||
@@ -239,7 +260,8 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Object& obj,
|
||||
geom->addPrimitiveSet(new osg::DrawArrayLengths(osg::PrimitiveSet::POLYGON));
|
||||
}
|
||||
|
||||
if (mesh->faces.size() != meshMaterial->faceIndices.size())
|
||||
const std::vector<DX::MeshFace> & faces = mesh.getFaces();
|
||||
if (faces.size() != meshMaterial->faceIndices.size())
|
||||
{
|
||||
osg::notify(osg::FATAL)<<"Error: internal error in DirectX .x loader,"<<std::endl;
|
||||
osg::notify(osg::FATAL)<<" mesh->faces.size() == meshMaterial->faceIndices.size()"<<std::endl;
|
||||
@@ -254,7 +276,7 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Object& obj,
|
||||
osg::Geometry* geom = geomList[mi];
|
||||
|
||||
// #pts of this face
|
||||
unsigned int np = mesh->faces[i].size();
|
||||
unsigned int np = faces[i].size();
|
||||
((osg::DrawArrayLengths*) geom->getPrimitiveSet(0))->push_back(np);
|
||||
|
||||
if (np != meshNormals->faceNormals[i].size())
|
||||
@@ -273,10 +295,10 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Object& obj,
|
||||
unsigned int jj = (j > 0 ? np - j : j);
|
||||
|
||||
// Vertices
|
||||
unsigned int vi = mesh->faces[i][jj];
|
||||
unsigned int vi = faces[i][jj];
|
||||
if (vertexArray) {
|
||||
// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup
|
||||
const DX::Vector& v = mesh->vertices[vi];
|
||||
const DX::Vector & v = mesh.getVertices()[vi];
|
||||
vertexArray->push_back(osg::Vec3(v.x,v.z,v.y));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* $Id$
|
||||
*
|
||||
* Loader for DirectX .x files.
|
||||
* Copyright (c)2002 Ulrich Hertlein <u.hertlein@sandbox.de>
|
||||
* Copyright (c)2002-2006 Ulrich Hertlein <u.hertlein@sandbox.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -39,181 +39,62 @@ using namespace DX;
|
||||
using namespace std;
|
||||
|
||||
|
||||
// Tokenize a string
|
||||
static void tokenize(const string& str, vector<string>& tokens,
|
||||
const string& delimiters = " \t\r\n;,")
|
||||
{
|
||||
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
|
||||
string::size_type pos = str.find_first_of(delimiters, lastPos);
|
||||
/**********************************************************************
|
||||
*
|
||||
* DirectX object.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
while (string::npos != pos || string::npos != lastPos) {
|
||||
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
||||
lastPos = str.find_first_not_of(delimiters, pos);
|
||||
pos = str.find_first_of(delimiters, lastPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Constructor
|
||||
Object::Object()
|
||||
{
|
||||
_textureCoords = NULL;
|
||||
_materialList = NULL;
|
||||
_normals = NULL;
|
||||
_mesh = NULL;
|
||||
}
|
||||
|
||||
|
||||
// Clear object
|
||||
void Object::clear()
|
||||
{
|
||||
if (_textureCoords) {
|
||||
delete _textureCoords;
|
||||
_textureCoords = NULL;
|
||||
}
|
||||
|
||||
if (_materialList) {
|
||||
delete _materialList;
|
||||
_materialList = NULL;
|
||||
}
|
||||
|
||||
if (_normals) {
|
||||
delete _normals;
|
||||
_normals = NULL;
|
||||
}
|
||||
|
||||
if (_mesh) {
|
||||
delete _mesh;
|
||||
_mesh = NULL;
|
||||
for (unsigned int i = 0; i < _meshes.size(); ++i) {
|
||||
_meshes[i]->clear();
|
||||
}
|
||||
_meshes.clear();
|
||||
}
|
||||
|
||||
|
||||
// Load
|
||||
bool Object::load(const char* filename)
|
||||
{
|
||||
if (!filename)
|
||||
return false;
|
||||
|
||||
// Delete previous
|
||||
clear();
|
||||
|
||||
// Open
|
||||
ifstream fin(filename);
|
||||
if (fin.bad()) {
|
||||
osg::notify(osg::WARN) << "Object::load: Unable to open: " << filename << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse
|
||||
parseSection(fin);
|
||||
fin.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generate per-face normals
|
||||
*/
|
||||
bool Object::generateNormals(float /*creaseAngle*/)
|
||||
bool Object::generateNormals(float creaseAngle)
|
||||
{
|
||||
if (!_mesh)
|
||||
return false;
|
||||
|
||||
// Forget old normals
|
||||
if (_normals) {
|
||||
delete _normals;
|
||||
_normals = NULL;
|
||||
bool result = true;
|
||||
for (unsigned int i = 0; i < _meshes.size(); ++i) {
|
||||
result &= _meshes[i]->generateNormals(creaseAngle);
|
||||
}
|
||||
|
||||
cout << "*** generateNormals\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate per-face normals from face vertices.
|
||||
*/
|
||||
vector<Vector> faceNormals;
|
||||
faceNormals.resize(_mesh->faces.size());
|
||||
|
||||
unsigned int fi;
|
||||
for (fi = 0; fi < _mesh->faces.size(); fi++) {
|
||||
|
||||
vector<Vector> poly;
|
||||
unsigned int n = _mesh->faces[fi].size();
|
||||
|
||||
if (n < 3)
|
||||
continue;
|
||||
for (unsigned int i = 0; i < n; i++) {
|
||||
unsigned int idx = _mesh->faces[fi][i];
|
||||
poly.push_back(_mesh->vertices[idx]);
|
||||
Material * Object::findMaterial(const std::string & name)
|
||||
{
|
||||
std::vector<Material>::iterator itr;
|
||||
for (itr = _globalMaterials.begin(); itr != _globalMaterials.end(); ++itr) {
|
||||
//cerr << "search=" << name << " have=" << (*itr).name << endl;
|
||||
if ((*itr).name == name) {
|
||||
return &*itr;
|
||||
}
|
||||
|
||||
// Edge vectors
|
||||
Vector e0;
|
||||
e0.x = poly[1].x - poly[0].x;
|
||||
e0.y = poly[1].y - poly[0].y;
|
||||
e0.z = poly[1].z - poly[0].z;
|
||||
|
||||
Vector e1;
|
||||
e1.x = poly[2].x - poly[0].x;
|
||||
e1.y = poly[2].y - poly[0].y;
|
||||
e1.z = poly[2].z - poly[0].z;
|
||||
|
||||
// Cross-product of e0,e1
|
||||
Vector normal;
|
||||
normal.x = e0.y * e1.z - e0.z * e1.y;
|
||||
normal.y = e0.z * e1.x - e0.x * e1.z;
|
||||
normal.z = e0.x * e1.y - e0.y * e1.x;
|
||||
normal.normalize();
|
||||
|
||||
// Add to per-face normals
|
||||
faceNormals[fi] = normal;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate per-vertex normals as average of all per-face normals that
|
||||
* share this vertex. The index of the vertex normal is identical to the
|
||||
* vertex index for now. This means each vertex only has a single normal...
|
||||
*/
|
||||
_normals = new MeshNormals;
|
||||
_normals->normals.resize(_mesh->vertices.size());
|
||||
|
||||
for (unsigned int vi = 0; vi < _mesh->vertices.size(); vi++) {
|
||||
|
||||
Vector normal = { 0.0f, 0.0f, 0.0f };
|
||||
unsigned int polyCount = 0;
|
||||
|
||||
// Collect normals of polygons that share this vertex
|
||||
for (unsigned int fi = 0; fi < _mesh->faces.size(); fi++)
|
||||
for (unsigned int i = 0; i < _mesh->faces[fi].size(); i++) {
|
||||
unsigned int idx = _mesh->faces[fi][i];
|
||||
if (idx == vi) {
|
||||
normal.x += faceNormals[fi].x;
|
||||
normal.y += faceNormals[fi].y;
|
||||
normal.z += faceNormals[fi].z;
|
||||
polyCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//osg::notify(osg::INFO) << "vertex " << vi << " used by " << polyCount << " faces\n";
|
||||
if (polyCount > 1) {
|
||||
float polyCountRecip = 1.0f / (float) polyCount;
|
||||
normal.x *= polyCountRecip;
|
||||
normal.y *= polyCountRecip;
|
||||
normal.z *= polyCountRecip;
|
||||
normal.normalize();
|
||||
}
|
||||
|
||||
// Add vertex normal
|
||||
_normals->normals[vi] = normal;
|
||||
}
|
||||
|
||||
// Copy face mesh to normals mesh
|
||||
_normals->faceNormals.resize(_mesh->faces.size());
|
||||
for (fi = 0; fi < _mesh->faces.size(); fi++)
|
||||
_normals->faceNormals[fi] = _mesh->faces[fi];
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -223,436 +104,6 @@ bool Object::generateNormals(float /*creaseAngle*/)
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
// Read 'TextureFilename'
|
||||
void Object::readTexFilename(ifstream& fin, TextureFilename& texture)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
//cout << "*** TexFilename\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
if (token[0] == "}")
|
||||
break;
|
||||
|
||||
// Strip " if present
|
||||
std::string line = buf;
|
||||
std::string::size_type pos = line.find('"');
|
||||
if (pos != string::npos) {
|
||||
std::string::size_type end = line.rfind('"');
|
||||
int len = (end != std::string::npos ? (end-pos-1) : (line.size()-pos));
|
||||
texture = line.substr(pos+1, len);
|
||||
}
|
||||
else
|
||||
texture = token[0];
|
||||
//osg::notify(osg::INFO) << "tex=" << texture << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parse 'Material'
|
||||
void Object::parseMaterial(ifstream& fin, Material& material)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cout << "*** Material\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
if (token[0] == "}")
|
||||
break;
|
||||
if (token[0] == "TextureFilename") {
|
||||
TextureFilename tf;
|
||||
readTexFilename(fin, tf);
|
||||
material.texture.push_back(tf);
|
||||
//osg::notify(osg::INFO) << "* num tex=" << material.texture.size() << endl;
|
||||
}
|
||||
else
|
||||
switch (i) {
|
||||
case 0: {
|
||||
// ColorRGBA
|
||||
material.faceColor.red = (float) atof(token[0].c_str());
|
||||
material.faceColor.green = (float) atof(token[1].c_str());
|
||||
material.faceColor.blue = (float) atof(token[2].c_str());
|
||||
material.faceColor.alpha = (float) atof(token[3].c_str());
|
||||
i++;
|
||||
} break;
|
||||
case 1: {
|
||||
// Power
|
||||
material.power = (float) atof(token[0].c_str());
|
||||
i++;
|
||||
} break;
|
||||
case 2: {
|
||||
// ColorRGB
|
||||
material.specularColor.red = (float) atof(token[0].c_str());
|
||||
material.specularColor.green = (float) atof(token[1].c_str());
|
||||
material.specularColor.blue = (float) atof(token[2].c_str());
|
||||
i++;
|
||||
} break;
|
||||
case 3: {
|
||||
// ColorRGB
|
||||
material.emissiveColor.red = (float) atof(token[0].c_str());
|
||||
material.emissiveColor.green = (float) atof(token[1].c_str());
|
||||
material.emissiveColor.blue = (float) atof(token[2].c_str());
|
||||
i++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read 'Coords2d'
|
||||
void Object::readCoords2d(ifstream& fin, vector<Coords2d>& v, unsigned int count)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cout << "*** Coords2d\n";
|
||||
while (i < count && fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
Coords2d c;
|
||||
c.u = (float) atof(token[0].c_str());
|
||||
c.v = (float) atof(token[1].c_str());
|
||||
v.push_back(c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read 'MeshTextureCoords'
|
||||
void Object::readMeshTexCoords(ifstream& fin)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int nTextureCoords = 0;
|
||||
|
||||
//cout << "*** MeshTextureCoords\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
if (strrchr(buf, '}') != 0)
|
||||
break;
|
||||
|
||||
// Create MeshTextureCoords
|
||||
if (!_textureCoords)
|
||||
_textureCoords = new MeshTextureCoords;
|
||||
|
||||
// Texture coords
|
||||
nTextureCoords = atoi(token[0].c_str());
|
||||
readCoords2d(fin, *_textureCoords, nTextureCoords);
|
||||
|
||||
if (nTextureCoords != _textureCoords->size())
|
||||
{
|
||||
osg::notify(osg::INFO) << "DirectX loader : Error in reading texturcoords." << endl;
|
||||
delete _textureCoords;
|
||||
_textureCoords = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read index list
|
||||
void Object::readIndexList(ifstream& fin, vector<unsigned int>& v, unsigned int count)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cout << "*** IndexList\n";
|
||||
while (i < count && fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
unsigned int idx = atoi(token[0].c_str());
|
||||
v.push_back(idx);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parse 'MeshMaterialList'
|
||||
void Object::parseMeshMaterialList(ifstream& fin)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int nMaterials = 0, nFaceIndices = 0;
|
||||
|
||||
//cout << "*** MeshMaterialList\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
//
|
||||
// dgm - check for "{ <material name> }" for a
|
||||
// material which was declared globally
|
||||
//
|
||||
bool found = false;
|
||||
if (token.size() > 2) {
|
||||
std::vector<Material>::iterator itr;
|
||||
for (itr=_globalMaterials.begin();
|
||||
itr != _globalMaterials.end();
|
||||
++itr) {
|
||||
if ( (*itr).name == token[1]) {
|
||||
if (!_materialList)
|
||||
_materialList = new MeshMaterialList;
|
||||
_materialList->material.push_back(*itr);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found ) continue;
|
||||
|
||||
if (strrchr(buf, '}') != 0)
|
||||
break;
|
||||
else if (strrchr(buf, '{') != 0) {
|
||||
if (token[0] == "Material") {
|
||||
Material mm;
|
||||
parseMaterial(fin, mm);
|
||||
_materialList->material.push_back(mm);
|
||||
//osg::notify(osg::INFO) << "* num mat=" << _materialList->material.size() << endl;
|
||||
}
|
||||
else {
|
||||
osg::notify(osg::INFO) << "!!! MeshMaterialList: Section " << token[0] << endl;
|
||||
parseSection(fin);
|
||||
}
|
||||
}
|
||||
else if (nMaterials == 0) {
|
||||
// Create MeshMaterialList
|
||||
if (!_materialList)
|
||||
_materialList = new MeshMaterialList;
|
||||
|
||||
// Materials
|
||||
nMaterials = atoi(token[0].c_str());
|
||||
//osg::notify(osg::INFO) << "* nMaterials=" << nMaterials << endl;
|
||||
}
|
||||
else if (nFaceIndices == 0) {
|
||||
// Face indices
|
||||
nFaceIndices = atoi(token[0].c_str());
|
||||
readIndexList(fin, _materialList->faceIndices, nFaceIndices);
|
||||
|
||||
if (nFaceIndices != _materialList->faceIndices.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader : Error in reading face indices" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nMaterials != _materialList->material.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader : Error in reading material list." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read 'Vector'
|
||||
void Object::readVector(ifstream& fin, vector<Vector>& v, unsigned int count)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cout << "*** Vector\n";
|
||||
while (i < count && fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
Vector vec;
|
||||
vec.x = (float) atof(token[0].c_str());
|
||||
vec.y = (float) atof(token[1].c_str());
|
||||
vec.z = (float) atof(token[2].c_str());
|
||||
v.push_back(vec);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read 'MeshFace'
|
||||
void Object::readMeshFace(ifstream& fin, vector<MeshFace>& v, unsigned int count)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cout << "*** MeshFace\n";
|
||||
while (i < count && fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
MeshFace mf;
|
||||
unsigned int n = atoi(token[0].c_str());
|
||||
|
||||
for (unsigned int j = 0; j < n; j++) {
|
||||
unsigned int idx = atoi(token[j+1].c_str());
|
||||
mf.push_back(idx);
|
||||
}
|
||||
v.push_back(mf);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parse 'MeshNormals'
|
||||
void Object::parseMeshNormals(ifstream& fin)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int nNormals = 0, nFaceNormals = 0;
|
||||
|
||||
//cout << "*** MeshNormals\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
if (strrchr(buf, '}') != 0)
|
||||
break;
|
||||
else if (nNormals == 0) {
|
||||
// Create MeshNormals
|
||||
if (!_normals)
|
||||
_normals = new MeshNormals;
|
||||
|
||||
// Normals
|
||||
nNormals = atoi(token[0].c_str());
|
||||
readVector(fin, _normals->normals, nNormals);
|
||||
|
||||
if (nNormals != _normals->normals.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error in reading normals." << endl;
|
||||
}
|
||||
|
||||
#define NORMALIZE_NORMALS
|
||||
#ifdef NORMALIZE_NORMALS
|
||||
for (unsigned int i = 0; i < _normals->normals.size(); i++)
|
||||
_normals->normals[i].normalize();
|
||||
#endif
|
||||
}
|
||||
else if (nFaceNormals == 0) {
|
||||
// Face normals
|
||||
nFaceNormals = atoi(token[0].c_str());
|
||||
readMeshFace(fin, _normals->faceNormals, nFaceNormals);
|
||||
|
||||
if (nFaceNormals != _normals->faceNormals.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error in reading face normals." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parse 'Mesh'
|
||||
void Object::parseMesh(ifstream& fin)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int nVertices = 0, nFaces = 0;
|
||||
|
||||
//cout << "*** Mesh\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
if (strrchr(buf, '}') != 0) {
|
||||
break;
|
||||
}
|
||||
else if (strrchr(buf, '{') != 0) {
|
||||
if (token[0] == "MeshMaterialList")
|
||||
parseMeshMaterialList(fin);
|
||||
else if (token[0] == "MeshNormals")
|
||||
parseMeshNormals(fin);
|
||||
else if (token[0] == "MeshTextureCoords")
|
||||
readMeshTexCoords(fin);
|
||||
else {
|
||||
osg::notify(osg::INFO) << "!!! Mesh: Section " << token[0] << endl;
|
||||
parseSection(fin);
|
||||
}
|
||||
}
|
||||
else if (nVertices == 0) {
|
||||
// Create mesh
|
||||
if (!_mesh)
|
||||
_mesh = new Mesh;
|
||||
|
||||
// Vertices
|
||||
nVertices = atoi(token[0].c_str());
|
||||
readVector(fin, _mesh->vertices, nVertices);
|
||||
|
||||
if (nVertices != _mesh->vertices.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader : Error in reading vertices." << endl;
|
||||
}
|
||||
}
|
||||
else if (nFaces == 0) {
|
||||
// Faces
|
||||
nFaces = atoi(token[0].c_str());
|
||||
readMeshFace(fin, _mesh->faces, nFaces);
|
||||
|
||||
if (nFaces != _mesh->faces.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error in reading mesh." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
osg::notify(osg::INFO) << "!!! " << buf << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parse section
|
||||
void Object::parseSection(ifstream& fin)
|
||||
{
|
||||
@@ -662,7 +113,7 @@ void Object::parseSection(ifstream& fin)
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
if (strrchr(buf, '}') != 0) {
|
||||
//osg::notify(osg::INFO) << "!!! End section\n";
|
||||
//cerr << "!!! End section\n";
|
||||
break;
|
||||
}
|
||||
else if (strrchr(buf, '{') != 0) {
|
||||
@@ -672,24 +123,38 @@ void Object::parseSection(ifstream& fin)
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
//osg::notify(osg::INFO) << "!!! Section " << token[0] << endl;
|
||||
if (token[0] == "Mesh")
|
||||
parseMesh(fin);
|
||||
|
||||
//
|
||||
//dgm - In later versions of directx files, materials
|
||||
// can be declared at the top of the file (e.g. globally).
|
||||
// Keep this list of global materials in "_globalMaterials"
|
||||
//
|
||||
if (token[0] == "Mesh") {
|
||||
// create new mesh
|
||||
//cerr << "!!! Begin Mesh" << endl;
|
||||
Mesh * mesh = new Mesh(this);
|
||||
_meshes.push_back(mesh);
|
||||
mesh->parseMesh(fin);
|
||||
}
|
||||
else if (token[0] == "Material") {
|
||||
//
|
||||
// dgm - In later versions of directx files, materials
|
||||
// can be declared at the top of the file (e.g. globally).
|
||||
// Keep this list of global materials in "_globalMaterials"
|
||||
//
|
||||
Material mm;
|
||||
if (token.size() > 1 && token[1] != "") {
|
||||
mm.name = token[1];
|
||||
}
|
||||
parseMaterial(fin, mm);
|
||||
_globalMaterials.push_back(mm);
|
||||
} else
|
||||
}
|
||||
else if (token[0] == "Frame") {
|
||||
parseFrame(fin);
|
||||
}
|
||||
else {
|
||||
//cerr << "!!! Begin section " << token[0] << endl;
|
||||
parseSection(fin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse frame
|
||||
void Object::parseFrame(ifstream& /*fin*/)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,89 +31,11 @@
|
||||
#include <osg/Export>
|
||||
#include <osg/Math>
|
||||
|
||||
#include "types.h"
|
||||
#include "mesh.h"
|
||||
|
||||
namespace DX {
|
||||
|
||||
/*
|
||||
* DirectX templates
|
||||
* http://astronomy.swin.edu.au/~pbourke/geomformats/directx/
|
||||
*/
|
||||
|
||||
// Vector
|
||||
typedef struct {
|
||||
float x,y,z;
|
||||
|
||||
inline void normalize() {
|
||||
float lenRecip = 1.0f / sqrtf(x * x + y * y + z * z);
|
||||
x *= lenRecip;
|
||||
y *= lenRecip;
|
||||
z *= lenRecip;
|
||||
}
|
||||
} Vector;
|
||||
|
||||
// Coords2d
|
||||
typedef struct {
|
||||
float u,v;
|
||||
} Coords2d;
|
||||
|
||||
// ColorRGBA
|
||||
typedef struct {
|
||||
float red,green,blue,alpha;
|
||||
} ColorRGBA;
|
||||
|
||||
// ColorRGB
|
||||
typedef struct {
|
||||
float red,green,blue;
|
||||
} ColorRGB;
|
||||
|
||||
// IndexedColor
|
||||
typedef struct {
|
||||
unsigned int index;
|
||||
ColorRGBA indexColor;
|
||||
} IndexedColor;
|
||||
|
||||
// TextureFilename
|
||||
typedef std::string TextureFilename;
|
||||
|
||||
// Material (potentially with multiple textures)
|
||||
typedef struct {
|
||||
ColorRGBA faceColor;
|
||||
float power;
|
||||
ColorRGB specularColor;
|
||||
ColorRGB emissiveColor;
|
||||
//
|
||||
// dgm - - materials can have names for later reference
|
||||
//
|
||||
std::string name;
|
||||
std::vector<TextureFilename> texture;
|
||||
} Material;
|
||||
|
||||
// MeshFace
|
||||
typedef std::vector<unsigned int> MeshFace;
|
||||
|
||||
// MeshTextureCoords
|
||||
typedef std::vector<Coords2d> MeshTextureCoords;
|
||||
|
||||
// MeshNormals
|
||||
typedef struct {
|
||||
std::vector<Vector> normals;
|
||||
std::vector<MeshFace> faceNormals;
|
||||
} MeshNormals;
|
||||
|
||||
// MeshVertexColors.
|
||||
typedef std::vector<IndexedColor> MeshVertexColors;
|
||||
|
||||
// MeshMaterialList
|
||||
typedef struct {
|
||||
std::vector<unsigned int> faceIndices;
|
||||
std::vector<Material> material;
|
||||
} MeshMaterialList;
|
||||
|
||||
// Mesh
|
||||
typedef struct {
|
||||
std::vector<Vector> vertices;
|
||||
std::vector<MeshFace> faces;
|
||||
} Mesh;
|
||||
|
||||
/**
|
||||
* DirectX object.
|
||||
*/
|
||||
@@ -144,79 +66,37 @@ namespace DX {
|
||||
*/
|
||||
bool generateNormals(float creaseAngle = 80.0f);
|
||||
|
||||
/// Get MeshTextureCoords.
|
||||
inline const MeshTextureCoords* getMeshTextureCoords() const {
|
||||
return _textureCoords;
|
||||
}
|
||||
|
||||
/// Get MeshMaterialList.
|
||||
inline const MeshMaterialList* getMeshMaterialList() const {
|
||||
return _materialList;
|
||||
}
|
||||
|
||||
/// Get MeshNormals.
|
||||
inline const MeshNormals* getMeshNormals() const {
|
||||
return _normals;
|
||||
/// Get number of meshes.
|
||||
inline unsigned int getNumMeshes() const {
|
||||
return _meshes.size();
|
||||
}
|
||||
|
||||
/// Get Mesh.
|
||||
inline const Mesh* getMesh() const {
|
||||
return _mesh;
|
||||
inline Mesh* getMesh(unsigned int i) {
|
||||
return _meshes[i];
|
||||
}
|
||||
inline const Mesh* getMesh(unsigned int i) const {
|
||||
return _meshes[i];
|
||||
}
|
||||
|
||||
/// Find global material.
|
||||
Material * findMaterial(const std::string & name);
|
||||
|
||||
/// Parse section until '}'; recurse as needed.
|
||||
void parseSection(std::ifstream& fin);
|
||||
|
||||
private:
|
||||
/// Texture coordinates (per-vertex).
|
||||
MeshTextureCoords* _textureCoords;
|
||||
|
||||
/// Material list (per-face).
|
||||
MeshMaterialList* _materialList;
|
||||
|
||||
//
|
||||
// dgm keep list of materials global to the file
|
||||
//
|
||||
// dgm - keep list of materials global to the file
|
||||
std::vector<Material> _globalMaterials;
|
||||
|
||||
/// Normals (per-face).
|
||||
MeshNormals* _normals;
|
||||
|
||||
/// Mesh.
|
||||
Mesh* _mesh;
|
||||
/// Meshes.
|
||||
std::vector<Mesh*> _meshes;
|
||||
|
||||
/// Clear object.
|
||||
void clear();
|
||||
|
||||
/// Read 'TextureFilename'.
|
||||
void readTexFilename(std::ifstream& fin, TextureFilename& texture);
|
||||
|
||||
/// Parse 'Material'.
|
||||
void parseMaterial(std::ifstream& fin, Material& material);
|
||||
|
||||
/// Read 'Coords2d'.
|
||||
void readCoords2d(std::ifstream& fin, std::vector<Coords2d>& v, unsigned int count);
|
||||
|
||||
/// Read 'MeshTextureCoords'.
|
||||
void readMeshTexCoords(std::ifstream& fin);
|
||||
|
||||
/// Read index list.
|
||||
void readIndexList(std::ifstream& fin, std::vector<unsigned int>& v, unsigned int count);
|
||||
|
||||
/// Parse 'MeshMaterialList'.
|
||||
void parseMeshMaterialList(std::ifstream& fin);
|
||||
|
||||
/// Read 'Vector'.
|
||||
void readVector(std::ifstream& fin, std::vector<Vector>& v, unsigned int count);
|
||||
|
||||
/// Read 'MeshFace'.
|
||||
void readMeshFace(std::ifstream& fin, std::vector<MeshFace>& v, unsigned int count);
|
||||
|
||||
/// Parse 'MeshNormals'.
|
||||
void parseMeshNormals(std::ifstream& fin);
|
||||
|
||||
/// Parse 'Mesh'.
|
||||
void parseMesh(std::ifstream& fin);
|
||||
|
||||
/// Parse section until '}'; recurse as needed.
|
||||
void parseSection(std::ifstream& fin);
|
||||
/// Parse frame.
|
||||
void parseFrame(std::ifstream& fin);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
397
src/osgPlugins/directx/mesh.cpp
Normal file
397
src/osgPlugins/directx/mesh.cpp
Normal file
@@ -0,0 +1,397 @@
|
||||
// -*-c++-*-
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Loader for DirectX .x files.
|
||||
* Copyright (c)2002-2006 Ulrich Hertlein <u.hertlein@sandbox.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
#pragma warning (disable : 4786)
|
||||
#endif
|
||||
|
||||
#include "mesh.h"
|
||||
#include "directx.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace DX;
|
||||
using namespace std;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* DirectX mesh.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
Mesh::Mesh(Object * obj)
|
||||
{
|
||||
_obj = obj;
|
||||
_normals = 0;
|
||||
_textureCoords = 0;
|
||||
_materialList = 0;
|
||||
}
|
||||
|
||||
void Mesh::clear()
|
||||
{
|
||||
if (_normals) {
|
||||
delete _normals;
|
||||
_normals = 0;
|
||||
}
|
||||
|
||||
if (_textureCoords) {
|
||||
delete _textureCoords;
|
||||
_textureCoords = 0;
|
||||
}
|
||||
|
||||
if (_materialList) {
|
||||
delete _materialList;
|
||||
_materialList = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Mesh::generateNormals(float /*creaseAngle*/)
|
||||
{
|
||||
//cerr << "*** generateNormals\n";
|
||||
|
||||
// Forget old normals
|
||||
if (_normals) {
|
||||
delete _normals;
|
||||
_normals = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate per-face normals from face vertices.
|
||||
*/
|
||||
vector<Vector> faceNormals;
|
||||
faceNormals.resize(_faces.size());
|
||||
|
||||
unsigned int fi;
|
||||
for (fi = 0; fi < _faces.size(); fi++) {
|
||||
|
||||
vector<Vector> poly;
|
||||
unsigned int n = _faces[fi].size();
|
||||
|
||||
if (n < 3)
|
||||
continue;
|
||||
for (unsigned int i = 0; i < n; i++) {
|
||||
unsigned int idx = _faces[fi][i];
|
||||
poly.push_back(_vertices[idx]);
|
||||
}
|
||||
|
||||
// Edge vectors
|
||||
Vector e0;
|
||||
e0.x = poly[1].x - poly[0].x;
|
||||
e0.y = poly[1].y - poly[0].y;
|
||||
e0.z = poly[1].z - poly[0].z;
|
||||
|
||||
Vector e1;
|
||||
e1.x = poly[2].x - poly[0].x;
|
||||
e1.y = poly[2].y - poly[0].y;
|
||||
e1.z = poly[2].z - poly[0].z;
|
||||
|
||||
// Cross-product of e0,e1
|
||||
Vector normal;
|
||||
normal.x = e0.y * e1.z - e0.z * e1.y;
|
||||
normal.y = e0.z * e1.x - e0.x * e1.z;
|
||||
normal.z = e0.x * e1.y - e0.y * e1.x;
|
||||
normal.normalize();
|
||||
|
||||
// Add to per-face normals
|
||||
faceNormals[fi] = normal;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate per-vertex normals as average of all per-face normals that
|
||||
* share this vertex. The index of the vertex normal is identical to the
|
||||
* vertex index for now. This means each vertex only has a single normal...
|
||||
*/
|
||||
_normals = new MeshNormals;
|
||||
_normals->normals.resize(_vertices.size());
|
||||
|
||||
for (unsigned int vi = 0; vi < _vertices.size(); vi++) {
|
||||
|
||||
Vector normal = { 0.0f, 0.0f, 0.0f };
|
||||
unsigned int polyCount = 0;
|
||||
|
||||
// Collect normals of polygons that share this vertex
|
||||
for (unsigned int fi = 0; fi < _faces.size(); fi++)
|
||||
for (unsigned int i = 0; i < _faces[fi].size(); i++) {
|
||||
unsigned int idx = _faces[fi][i];
|
||||
if (idx == vi) {
|
||||
normal.x += faceNormals[fi].x;
|
||||
normal.y += faceNormals[fi].y;
|
||||
normal.z += faceNormals[fi].z;
|
||||
polyCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//osg::notify(osg::INFO) << "vertex " << vi << " used by " << polyCount << " faces\n";
|
||||
if (polyCount > 1) {
|
||||
float polyCountRecip = 1.0f / (float) polyCount;
|
||||
normal.x *= polyCountRecip;
|
||||
normal.y *= polyCountRecip;
|
||||
normal.z *= polyCountRecip;
|
||||
normal.normalize();
|
||||
}
|
||||
|
||||
// Add vertex normal
|
||||
_normals->normals[vi] = normal;
|
||||
}
|
||||
|
||||
// Copy face mesh to normals mesh
|
||||
_normals->faceNormals.resize(_faces.size());
|
||||
for (fi = 0; fi < _faces.size(); fi++)
|
||||
_normals->faceNormals[fi] = _faces[fi];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parse 'Mesh'
|
||||
void Mesh::parseMesh(ifstream& fin)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int nVertices = 0, nFaces = 0;
|
||||
|
||||
//cerr << "*** Mesh\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
//cerr << "*** Mesh token=" << token[0] << endl;
|
||||
if (strrchr(buf, '}') != 0) {
|
||||
break;
|
||||
}
|
||||
else if (strrchr(buf, '{') != 0) {
|
||||
if (token[0] == "MeshMaterialList")
|
||||
parseMeshMaterialList(fin);
|
||||
else if (token[0] == "MeshNormals")
|
||||
parseMeshNormals(fin);
|
||||
else if (token[0] == "MeshTextureCoords")
|
||||
readMeshTexCoords(fin);
|
||||
else {
|
||||
//cerr << "!!! Mesh: Begin section " << token[0] << endl;
|
||||
_obj->parseSection(fin);
|
||||
}
|
||||
}
|
||||
else if (nVertices == 0) {
|
||||
// Vertices
|
||||
nVertices = atoi(token[0].c_str());
|
||||
readVector(fin, _vertices, nVertices);
|
||||
|
||||
if (nVertices != _vertices.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error reading vertices; " << _vertices.size() << " instead of " << nVertices << endl;
|
||||
}
|
||||
}
|
||||
else if (nFaces == 0) {
|
||||
// Faces
|
||||
nFaces = atoi(token[0].c_str());
|
||||
readMeshFace(fin, _faces, nFaces);
|
||||
|
||||
if (nFaces != _faces.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error reading mesh; " << _faces.size() << " instead of " << nFaces << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
osg::notify(osg::INFO) << "!!! " << buf << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse 'MeshMaterialList'
|
||||
void Mesh::parseMeshMaterialList(ifstream& fin)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int nMaterials = 0, nFaceIndices = 0;
|
||||
|
||||
//cerr << "*** MeshMaterialList\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
// dgm - check for "{ <material name> }" for a
|
||||
// material which was declared globally
|
||||
#if 1
|
||||
Material * material = _obj->findMaterial(token[1]);
|
||||
if (material) {
|
||||
_materialList->material.push_back(*material);
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
bool found = false;
|
||||
if (token.size() > 2) {
|
||||
std::vector<Material>::iterator itr;
|
||||
for (itr = _globalMaterials.begin(); itr != _globalMaterials.end(); ++itr) {
|
||||
if ( (*itr).name == token[1]) {
|
||||
if (!_materialList)
|
||||
_materialList = new MeshMaterialList;
|
||||
_materialList->material.push_back(*itr);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (strrchr(buf, '}') != 0)
|
||||
break;
|
||||
else if (strrchr(buf, '{') != 0) {
|
||||
if (token[0] == "Material") {
|
||||
Material mm;
|
||||
parseMaterial(fin, mm);
|
||||
_materialList->material.push_back(mm);
|
||||
//cerr << "num mat=" << _materialList->material.size() << endl;
|
||||
}
|
||||
else {
|
||||
//cerr << "!!! MeshMaterialList: Begin section " << token[0] << endl;
|
||||
_obj->parseSection(fin);
|
||||
}
|
||||
}
|
||||
else if (nMaterials == 0) {
|
||||
// Create MeshMaterialList
|
||||
if (!_materialList)
|
||||
_materialList = new MeshMaterialList;
|
||||
|
||||
// Materials
|
||||
nMaterials = atoi(token[0].c_str());
|
||||
//cerr << "expecting num Materials=" << nMaterials << endl;
|
||||
}
|
||||
else if (nFaceIndices == 0) {
|
||||
// Face indices
|
||||
nFaceIndices = atoi(token[0].c_str());
|
||||
readIndexList(fin, _materialList->faceIndices, nFaceIndices);
|
||||
|
||||
if (nFaceIndices != _materialList->faceIndices.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error reading face indices; " << nFaceIndices << " instead of " << _materialList->faceIndices.size() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nMaterials != _materialList->material.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error reading material list; " << nMaterials << " instead of " << _materialList->material.size() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse 'MeshNormals'
|
||||
void Mesh::parseMeshNormals(ifstream& fin)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int nNormals = 0, nFaceNormals = 0;
|
||||
|
||||
//cerr << "*** MeshNormals\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
if (strrchr(buf, '}') != 0)
|
||||
break;
|
||||
else if (nNormals == 0) {
|
||||
// Create MeshNormals
|
||||
if (!_normals)
|
||||
_normals = new MeshNormals;
|
||||
|
||||
// Normals
|
||||
nNormals = atoi(token[0].c_str());
|
||||
readVector(fin, _normals->normals, nNormals);
|
||||
|
||||
if (nNormals != _normals->normals.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error reading normals; " << nNormals << " instead of " << _normals->normals.size() << endl;
|
||||
}
|
||||
|
||||
#define NORMALIZE_NORMALS
|
||||
#ifdef NORMALIZE_NORMALS
|
||||
for (unsigned int i = 0; i < _normals->normals.size(); i++)
|
||||
_normals->normals[i].normalize();
|
||||
#endif
|
||||
}
|
||||
else if (nFaceNormals == 0) {
|
||||
// Face normals
|
||||
nFaceNormals = atoi(token[0].c_str());
|
||||
readMeshFace(fin, _normals->faceNormals, nFaceNormals);
|
||||
|
||||
if (nFaceNormals != _normals->faceNormals.size())
|
||||
{
|
||||
osg::notify(osg::WARN) << "DirectX loader: Error reading face normals; " << nFaceNormals << " instead of " << _normals->faceNormals.size() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read 'MeshTextureCoords'
|
||||
void Mesh::readMeshTexCoords(ifstream& fin)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int nTextureCoords = 0;
|
||||
|
||||
//cerr << "*** MeshTextureCoords\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
if (strrchr(buf, '}') != 0)
|
||||
break;
|
||||
|
||||
// Create MeshTextureCoords
|
||||
if (!_textureCoords)
|
||||
_textureCoords = new MeshTextureCoords;
|
||||
|
||||
// Texture coords
|
||||
nTextureCoords = atoi(token[0].c_str());
|
||||
readCoords2d(fin, *_textureCoords, nTextureCoords);
|
||||
|
||||
if (nTextureCoords != _textureCoords->size())
|
||||
{
|
||||
osg::notify(osg::INFO) << "DirectX loader: Error reading texcoords; " << _textureCoords->size() << " instead of " << nTextureCoords << endl;
|
||||
delete _textureCoords;
|
||||
_textureCoords = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
106
src/osgPlugins/directx/mesh.h
Normal file
106
src/osgPlugins/directx/mesh.h
Normal file
@@ -0,0 +1,106 @@
|
||||
// -*-c++-*-
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Loader for DirectX .x files.
|
||||
* Copyright (c)2002-2006 Ulrich Hertlein <u.hertlein@sandbox.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _MESH_H_
|
||||
#define _MESH_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace DX {
|
||||
|
||||
class Object;
|
||||
|
||||
/**
|
||||
* DirectX mesh.
|
||||
*/
|
||||
class Mesh {
|
||||
public:
|
||||
Mesh(Object * obj);
|
||||
virtual ~Mesh() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Generate per-vertex normals for the mesh.
|
||||
* @return false if an error occurred, else true.
|
||||
*/
|
||||
bool generateNormals(float creaseAngle);
|
||||
|
||||
/// Get Vertices.
|
||||
const std::vector<Vector> & getVertices() const {
|
||||
return _vertices;
|
||||
}
|
||||
|
||||
/// Get MeshFaces.
|
||||
const std::vector<MeshFace> & getFaces() const {
|
||||
return _faces;
|
||||
}
|
||||
|
||||
/// Get MeshTextureCoords.
|
||||
inline const MeshTextureCoords* getMeshTextureCoords() const {
|
||||
return _textureCoords;
|
||||
}
|
||||
|
||||
/// Get MeshMaterialList.
|
||||
inline const MeshMaterialList* getMeshMaterialList() const {
|
||||
return _materialList;
|
||||
}
|
||||
|
||||
/// Get MeshNormals.
|
||||
inline const MeshNormals* getMeshNormals() const {
|
||||
return _normals;
|
||||
}
|
||||
|
||||
/// Parse 'Mesh'.
|
||||
void parseMesh(std::ifstream& fin);
|
||||
|
||||
private:
|
||||
Object * _obj;
|
||||
|
||||
std::vector<Vector> _vertices;
|
||||
std::vector<MeshFace> _faces;
|
||||
|
||||
/// Normals (per-face).
|
||||
MeshNormals* _normals;
|
||||
|
||||
/// Texture coordinates (per-vertex).
|
||||
MeshTextureCoords* _textureCoords;
|
||||
|
||||
/// Materials.
|
||||
MeshMaterialList* _materialList;
|
||||
|
||||
/// Parse 'MeshNormals'.
|
||||
void parseMeshNormals(std::ifstream& fin);
|
||||
|
||||
/// Parse 'MeshMaterialList'.
|
||||
void parseMeshMaterialList(std::ifstream& fin);
|
||||
|
||||
/// Read 'MeshTextureCoords'.
|
||||
void readMeshTexCoords(std::ifstream& fin);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
242
src/osgPlugins/directx/types.cpp
Normal file
242
src/osgPlugins/directx/types.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
// -*-c++-*-
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Loader for DirectX .x files.
|
||||
* Copyright (c)2002-2006 Ulrich Hertlein <u.hertlein@sandbox.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
#pragma warning (disable : 4786)
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace DX {
|
||||
|
||||
// Tokenize a string
|
||||
void tokenize(const string & str, vector<string> & tokens, const string & delimiters)
|
||||
{
|
||||
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
|
||||
string::size_type pos = str.find_first_of(delimiters, lastPos);
|
||||
|
||||
while (string::npos != pos || string::npos != lastPos) {
|
||||
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
||||
lastPos = str.find_first_not_of(delimiters, pos);
|
||||
pos = str.find_first_of(delimiters, lastPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Read 'TextureFilename'
|
||||
void readTexFilename(ifstream & fin, TextureFilename & texture)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
//cerr << "*** TexFilename\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
if (token[0] == "}")
|
||||
break;
|
||||
|
||||
// Strip " if present
|
||||
std::string line = buf;
|
||||
std::string::size_type pos = line.find('"');
|
||||
if (pos != string::npos) {
|
||||
std::string::size_type end = line.rfind('"');
|
||||
int len = (end != std::string::npos ? (end-pos-1) : (line.size()-pos));
|
||||
texture = line.substr(pos+1, len);
|
||||
}
|
||||
else
|
||||
texture = token[0];
|
||||
//cerr << "* tex='" << texture << "'" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Read 'Coords2d'
|
||||
void readCoords2d(ifstream & fin, vector<Coords2d> & v, unsigned int count)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cerr << "*** Coords2d\n";
|
||||
while (i < count && fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
Coords2d c;
|
||||
c.u = (float) atof(token[0].c_str());
|
||||
c.v = (float) atof(token[1].c_str());
|
||||
v.push_back(c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Read 'Vector'
|
||||
void readVector(ifstream & fin, vector<Vector> & v, unsigned int count)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cerr << "*** Vector\n";
|
||||
while (i < count && fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
Vector vec;
|
||||
vec.x = (float) atof(token[0].c_str());
|
||||
vec.y = (float) atof(token[1].c_str());
|
||||
vec.z = (float) atof(token[2].c_str());
|
||||
v.push_back(vec);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse 'Material'
|
||||
void parseMaterial(ifstream & fin, Material & material)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cerr << "*** Material\n";
|
||||
while (fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
if (token[0] == "}")
|
||||
break;
|
||||
if (token[0] == "TextureFilename") {
|
||||
TextureFilename tf;
|
||||
readTexFilename(fin, tf);
|
||||
material.texture.push_back(tf);
|
||||
//cerr << "* num tex=" << material.texture.size() << endl;
|
||||
} else {
|
||||
switch (i) {
|
||||
case 0: {
|
||||
// ColorRGBA
|
||||
material.faceColor.red = (float) atof(token[0].c_str());
|
||||
material.faceColor.green = (float) atof(token[1].c_str());
|
||||
material.faceColor.blue = (float) atof(token[2].c_str());
|
||||
material.faceColor.alpha = (float) atof(token[3].c_str());
|
||||
i++;
|
||||
} break;
|
||||
case 1: {
|
||||
// Power
|
||||
material.power = (float) atof(token[0].c_str());
|
||||
i++;
|
||||
} break;
|
||||
case 2: {
|
||||
// ColorRGB
|
||||
material.specularColor.red = (float) atof(token[0].c_str());
|
||||
material.specularColor.green = (float) atof(token[1].c_str());
|
||||
material.specularColor.blue = (float) atof(token[2].c_str());
|
||||
i++;
|
||||
} break;
|
||||
case 3: {
|
||||
// ColorRGB
|
||||
material.emissiveColor.red = (float) atof(token[0].c_str());
|
||||
material.emissiveColor.green = (float) atof(token[1].c_str());
|
||||
material.emissiveColor.blue = (float) atof(token[2].c_str());
|
||||
i++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read index list
|
||||
void readIndexList(ifstream & fin, vector<unsigned int> & v, unsigned int count)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cerr << "*** IndexList\n";
|
||||
while (i < count && fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
unsigned int idx = atoi(token[0].c_str());
|
||||
v.push_back(idx);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Read 'MeshFace'
|
||||
void readMeshFace(ifstream & fin, vector<MeshFace> & v, unsigned int count)
|
||||
{
|
||||
char buf[256];
|
||||
vector<string> token;
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
//cerr << "*** MeshFace\n";
|
||||
while (i < count && fin.getline(buf, sizeof(buf))) {
|
||||
|
||||
// Tokenize
|
||||
token.clear();
|
||||
tokenize(buf, token);
|
||||
if (token.size() == 0)
|
||||
continue;
|
||||
|
||||
MeshFace mf;
|
||||
unsigned int n = atoi(token[0].c_str());
|
||||
|
||||
for (unsigned int j = 0; j < n; j++) {
|
||||
unsigned int idx = atoi(token[j+1].c_str());
|
||||
mf.push_back(idx);
|
||||
}
|
||||
v.push_back(mf);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
131
src/osgPlugins/directx/types.h
Normal file
131
src/osgPlugins/directx/types.h
Normal file
@@ -0,0 +1,131 @@
|
||||
// -*-c++-*-
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Loader for DirectX .x files.
|
||||
* Copyright (c)2002-2006 Ulrich Hertlein <u.hertlein@sandbox.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TYPES_H_
|
||||
#define _TYPES_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
#include <osg/Math>
|
||||
|
||||
namespace DX {
|
||||
|
||||
/*
|
||||
* DirectX templates
|
||||
* http://astronomy.swin.edu.au/~pbourke/geomformats/directx/
|
||||
*/
|
||||
|
||||
// Vector
|
||||
typedef struct {
|
||||
float x,y,z;
|
||||
|
||||
inline void normalize() {
|
||||
float lenRecip = 1.0f / sqrtf(x * x + y * y + z * z);
|
||||
x *= lenRecip;
|
||||
y *= lenRecip;
|
||||
z *= lenRecip;
|
||||
}
|
||||
} Vector;
|
||||
|
||||
// Coords2d
|
||||
typedef struct {
|
||||
float u,v;
|
||||
} Coords2d;
|
||||
|
||||
// ColorRGBA
|
||||
typedef struct {
|
||||
float red,green,blue,alpha;
|
||||
} ColorRGBA;
|
||||
|
||||
// ColorRGB
|
||||
typedef struct {
|
||||
float red,green,blue;
|
||||
} ColorRGB;
|
||||
|
||||
// IndexedColor
|
||||
typedef struct {
|
||||
unsigned int index;
|
||||
ColorRGBA indexColor;
|
||||
} IndexedColor;
|
||||
|
||||
// TextureFilename
|
||||
typedef std::string TextureFilename;
|
||||
|
||||
// Material (potentially with multiple textures)
|
||||
typedef struct {
|
||||
// dgm - materials can have names for later reference
|
||||
std::string name;
|
||||
ColorRGBA faceColor;
|
||||
float power;
|
||||
ColorRGB specularColor;
|
||||
ColorRGB emissiveColor;
|
||||
std::vector<TextureFilename> texture;
|
||||
} Material;
|
||||
|
||||
// MeshFace
|
||||
typedef std::vector<unsigned int> MeshFace;
|
||||
|
||||
// MeshTextureCoords
|
||||
typedef std::vector<Coords2d> MeshTextureCoords;
|
||||
|
||||
// MeshNormals
|
||||
typedef struct {
|
||||
std::vector<Vector> normals;
|
||||
std::vector<MeshFace> faceNormals;
|
||||
} MeshNormals;
|
||||
|
||||
// MeshVertexColors.
|
||||
typedef std::vector<IndexedColor> MeshVertexColors;
|
||||
|
||||
// MeshMaterialList
|
||||
typedef struct {
|
||||
std::vector<unsigned int> faceIndices;
|
||||
std::vector<Material> material;
|
||||
} MeshMaterialList;
|
||||
|
||||
/// Tokenize a string.
|
||||
extern void tokenize(const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters = " \t\r\n;,");
|
||||
|
||||
/// Parse 'Material'.
|
||||
extern void parseMaterial(std::ifstream& fin, Material& material);
|
||||
|
||||
/// Read 'TextureFilename'.
|
||||
extern void readTexFilename(std::ifstream& fin, TextureFilename& texture);
|
||||
|
||||
/// Read 'Coords2d'.
|
||||
extern void readCoords2d(std::ifstream& fin, std::vector<Coords2d>& v, unsigned int count);
|
||||
|
||||
// Read 'Vector'
|
||||
extern void readVector(std::ifstream& fin, std::vector<Vector>& v, unsigned int count);
|
||||
|
||||
/// Read index list.
|
||||
extern void readIndexList(std::ifstream& fin, std::vector<unsigned int>& v, unsigned int count);
|
||||
|
||||
/// Read 'MeshFace'.
|
||||
extern void readMeshFace(std::ifstream& fin, std::vector<MeshFace>& v, unsigned int count);
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user