Add basic support for the IZWARE NENDO file format (extension: ndo). The loader has been tested with files in format version 1.0, 1.1 and 1.2. Materials and textures are read but ignored for now.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@791 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
8fef884dbc
commit
81bebcd0ec
|
@ -113,8 +113,9 @@ void BaseImporter::SetupProperties(const Importer* pImp)
|
|||
boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
|
||||
char* buffer = _buffer.get();
|
||||
|
||||
unsigned int read = (unsigned int)pStream->Read(buffer,1,searchBytes);
|
||||
if (!read)return false;
|
||||
const unsigned int read = pStream->Read(buffer,1,searchBytes);
|
||||
if (!read)
|
||||
return false;
|
||||
|
||||
for (unsigned int i = 0; i < read;++i)
|
||||
buffer[i] = ::tolower(buffer[i]);
|
||||
|
|
|
@ -266,6 +266,11 @@ SOURCE_GROUP( NFF FILES
|
|||
NFFLoader.h
|
||||
)
|
||||
|
||||
SOURCE_GROUP( NDO FILES
|
||||
NDOLoader.cpp
|
||||
NDOLoader.h
|
||||
)
|
||||
|
||||
SOURCE_GROUP( OFFFormat FILES
|
||||
OFFLoader.cpp
|
||||
OFFLoader.h
|
||||
|
@ -722,6 +727,8 @@ ADD_LIBRARY( assimp SHARED
|
|||
BlenderModifier.h
|
||||
BlenderModifier.cpp
|
||||
Profiler.h
|
||||
NDOLoader.cpp
|
||||
NDOLoader.h
|
||||
|
||||
# Necessary to show the headers in the project when using the VC++ generator:
|
||||
BoostWorkaround/boost/math/common_factor_rt.hpp
|
||||
|
|
|
@ -43,12 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
#ifndef INCLUDED_AI_CSM_LOADER_H
|
||||
#define INCLUDED_AI_CSM_LOADER_H
|
||||
|
||||
#include "BaseImporter.h"
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief Importer class to load MOCAPs in CharacterStudio Motion format.
|
||||
/** Importer class to load MOCAPs in CharacterStudio Motion format.
|
||||
*
|
||||
* A very rudimentary loader for the moment. No support for the hierarchy,
|
||||
* every marker is returned as child of root.
|
||||
|
@ -59,7 +57,6 @@ namespace Assimp {
|
|||
class CSMImporter : public BaseImporter
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
protected:
|
||||
/** Constructor to be privately used by Importer */
|
||||
CSMImporter();
|
||||
|
@ -68,7 +65,6 @@ protected:
|
|||
~CSMImporter();
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||
bool checkSig) const;
|
||||
|
@ -78,19 +74,15 @@ protected:
|
|||
// -------------------------------------------------------------------
|
||||
void GetExtensionList(std::set<std::string>& extensions);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void SetupProperties(const Importer* pImp);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||
IOSystem* pIOHandler);
|
||||
|
||||
private:
|
||||
|
||||
}; // !class CSMImporter
|
||||
|
||||
}; // end of class CSMImporter
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif // AI_AC3DIMPORTER_H_INC
|
||||
|
||||
|
|
|
@ -180,6 +180,9 @@ using namespace Assimp::Profiling;
|
|||
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||
# include "Q3BSPFileImporter.h"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
|
||||
# include "NDOLoader.h"
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Post processing-Steps
|
||||
|
@ -417,7 +420,10 @@ Importer::Importer()
|
|||
// pimpl->mImporter.push_back( new SomImporter());
|
||||
//#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER)
|
||||
pimpl->mImporter.push_back( new Q3BSPFileImporter );
|
||||
pimpl->mImporter.push_back( new Q3BSPFileImporter() );
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER)
|
||||
pimpl->mImporter.push_back( new NDOImporter() );
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (ASSIMP)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2009, ASSIMP Development Team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file NDOLoader.cpp
|
||||
* Implementation of the NDO importer class.
|
||||
*/
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
#ifndef AI_BUILD_NO_NDO_IMPORTER
|
||||
#include "NDOLoader.h"
|
||||
|
||||
using namespace Assimp;
|
||||
#define for_each BOOST_FOREACH
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
NDOImporter::NDOImporter()
|
||||
{}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
NDOImporter::~NDOImporter()
|
||||
{}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
||||
{
|
||||
// check file extension
|
||||
const std::string extension = GetExtension(pFile);
|
||||
|
||||
if( extension == "ndo")
|
||||
return true;
|
||||
|
||||
if ((checkSig || !extension.length()) && pIOHandler) {
|
||||
const char* tokens[] = {"nendo"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,5);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Build a string of all file extensions supported
|
||||
void NDOImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||
{
|
||||
extensions.insert("ndo");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setup configuration properties for the loader
|
||||
void NDOImporter::SetupProperties(const Importer* pImp)
|
||||
{
|
||||
// nothing to be done for the moment
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Imports the given file into the given scene structure.
|
||||
void NDOImporter::InternReadFile( const std::string& pFile,
|
||||
aiScene* pScene, IOSystem* pIOHandler)
|
||||
{
|
||||
StreamReaderBE reader(pIOHandler->Open( pFile, "rb"));
|
||||
|
||||
// first 9 bytes are nendo file format ("nendo 1.n")
|
||||
const char* head = (const char*)reader.GetPtr();
|
||||
reader.IncPtr(9);
|
||||
|
||||
if (strncmp("nendo ",head,6)) {
|
||||
throw DeadlyImportError("Not a Nendo file; magic signature missing");
|
||||
}
|
||||
// check if this is a supported version. if not, continue, too -- users,
|
||||
// please don't complain if it doesn't work then ...
|
||||
unsigned int file_format = 12;
|
||||
if (!strncmp("1.0",head+6,3)) {
|
||||
file_format = 10;
|
||||
DefaultLogger::get()->info("NDO file format is 1.0");
|
||||
}
|
||||
else if (!strncmp("1.1",head+6,3)) {
|
||||
file_format = 11;
|
||||
DefaultLogger::get()->info("NDO file format is 1.1");
|
||||
}
|
||||
else if (!strncmp("1.2",head+6,3)) {
|
||||
file_format = 12;
|
||||
DefaultLogger::get()->info("NDO file format is 1.2");
|
||||
}
|
||||
else {
|
||||
DefaultLogger::get()->warn(std::string("Unrecognized nendo file format version, continuing happily ... :") + (head+6));
|
||||
}
|
||||
|
||||
reader.IncPtr(2); /* skip flags */
|
||||
if (file_format >= 12) {
|
||||
reader.IncPtr(2);
|
||||
}
|
||||
unsigned int temp = reader.GetU1();
|
||||
|
||||
std::vector<Object> objects(temp); /* buffer to store all the loaded objects in */
|
||||
|
||||
// read all objects
|
||||
for (unsigned int o = 0; o < objects.size(); ++o) {
|
||||
|
||||
// if (file_format < 12) {
|
||||
if (!reader.GetI1()) {
|
||||
continue; /* skip over empty object */
|
||||
}
|
||||
// reader.GetI2();
|
||||
// }
|
||||
Object& obj = objects[o];
|
||||
|
||||
temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
head = (const char*)reader.GetPtr();
|
||||
reader.IncPtr(temp + 76); /* skip unknown stuff */
|
||||
|
||||
obj.name = std::string(head, temp);
|
||||
|
||||
// read edge table
|
||||
temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
obj.edges.reserve(temp);
|
||||
for (unsigned int e = 0; e < temp; ++e) {
|
||||
|
||||
obj.edges.push_back(Edge());
|
||||
Edge& edge = obj.edges.back();
|
||||
|
||||
for (unsigned int i = 0; i< 8; ++i) {
|
||||
edge.edge[i] = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
}
|
||||
edge.hard = file_format >= 11 ? reader.GetU1() : 0;
|
||||
for (unsigned int i = 0; i< 8; ++i) {
|
||||
edge.color[i] = reader.GetU1();
|
||||
}
|
||||
}
|
||||
|
||||
// read face table
|
||||
temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
obj.faces.reserve(temp);
|
||||
for (unsigned int e = 0; e < temp; ++e) {
|
||||
|
||||
obj.faces.push_back(Face());
|
||||
Face& face = obj.faces.back();
|
||||
|
||||
face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
}
|
||||
|
||||
// read vertex table
|
||||
temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
obj.vertices.reserve(temp);
|
||||
for (unsigned int e = 0; e < temp; ++e) {
|
||||
|
||||
obj.vertices.push_back(Vertex());
|
||||
Vertex& v = obj.vertices.back();
|
||||
|
||||
v.num = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
v.val.x = reader.GetF4();
|
||||
v.val.y = reader.GetF4();
|
||||
v.val.z = reader.GetF4();
|
||||
}
|
||||
|
||||
// read UVs
|
||||
temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
for (unsigned int e = 0; e < temp; ++e) {
|
||||
file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
}
|
||||
|
||||
temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
for (unsigned int e = 0; e < temp; ++e) {
|
||||
file_format >= 12 ? reader.GetU4() : reader.GetU2();
|
||||
}
|
||||
|
||||
if (reader.GetU1()) {
|
||||
const unsigned int x = reader.GetU2(), y = reader.GetU2();
|
||||
temp = 0;
|
||||
while (temp < x*y) {
|
||||
unsigned int repeat = reader.GetU1();
|
||||
reader.GetU1();
|
||||
reader.GetU1();
|
||||
reader.GetU1();
|
||||
temp += repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// construct a dummy node graph and add all named objects as child nodes
|
||||
aiNode* root = pScene->mRootNode = new aiNode("$NDODummyRoot");
|
||||
aiNode** cc = root->mChildren = new aiNode* [ root->mNumChildren = static_cast<unsigned int>( objects.size()) ] ();
|
||||
pScene->mMeshes = new aiMesh* [ root->mNumChildren] ();
|
||||
|
||||
for_each(const Object& obj,objects) {
|
||||
aiNode* nd = *cc++ = new aiNode(obj.name);
|
||||
nd->mParent = root;
|
||||
|
||||
// translated from a python dict() - a vector might be sufficient as well
|
||||
typedef std::map<unsigned int, unsigned int> FaceTable;
|
||||
FaceTable face_table;
|
||||
|
||||
unsigned int n = 0;
|
||||
for_each(const Edge& edge, obj.edges) {
|
||||
|
||||
face_table[edge.edge[2]] = n;
|
||||
face_table[edge.edge[3]] = n;
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
aiMesh* mesh = new aiMesh();
|
||||
aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces=face_table.size()];
|
||||
|
||||
std::vector<aiVector3D> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
|
||||
vertices.reserve(4 * face_table.size()); // arbitrarily choosen
|
||||
for_each(FaceTable::value_type& v, face_table) {
|
||||
indices.clear();
|
||||
|
||||
aiFace& f = *faces++;
|
||||
|
||||
const unsigned int key = v.first;
|
||||
unsigned int cur_edge = v.second;
|
||||
while (1) {
|
||||
unsigned int next_edge, next_vert;
|
||||
if (key == obj.edges[cur_edge].edge[3]) {
|
||||
next_edge = obj.edges[cur_edge].edge[5];
|
||||
next_vert = obj.edges[cur_edge].edge[1];
|
||||
}
|
||||
else {
|
||||
next_edge = obj.edges[cur_edge].edge[4];
|
||||
next_vert = obj.edges[cur_edge].edge[0];
|
||||
}
|
||||
indices.push_back( vertices.size() );
|
||||
vertices.push_back(obj.vertices[ next_vert ].val);
|
||||
|
||||
cur_edge = next_edge;
|
||||
if (cur_edge == v.second) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f.mIndices = new unsigned int[f.mNumIndices = indices.size()];
|
||||
std::copy(indices.begin(),indices.end(),f.mIndices);
|
||||
}
|
||||
|
||||
mesh->mVertices = new aiVector3D[mesh->mNumVertices = vertices.size()];
|
||||
std::copy(vertices.begin(),vertices.end(),mesh->mVertices);
|
||||
|
||||
if (mesh->mNumVertices) {
|
||||
pScene->mMeshes[pScene->mNumMeshes] = mesh;
|
||||
|
||||
(nd->mMeshes = new unsigned int[nd->mNumMeshes=1])[0]=pScene->mNumMeshes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file NDOLoader.h
|
||||
* Declaration of the Nendo importer class.
|
||||
*/
|
||||
#ifndef INCLUDED_AI_NDO_LOADER_H
|
||||
#define INCLUDED_AI_NDO_LOADER_H
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief Importer class to load meshes from Nendo.
|
||||
*
|
||||
* Basing on
|
||||
* <blender>/blender/release/scripts/nendo_import.py by Anthony D'Agostino.
|
||||
*/
|
||||
class NDOImporter : public BaseImporter
|
||||
{
|
||||
friend class Importer;
|
||||
protected:
|
||||
/** Constructor to be privately used by Importer */
|
||||
NDOImporter();
|
||||
|
||||
/** Destructor, private as well */
|
||||
~NDOImporter();
|
||||
|
||||
public:
|
||||
|
||||
//! Represents a single edge
|
||||
struct Edge
|
||||
{
|
||||
unsigned int edge[8];
|
||||
unsigned int hard;
|
||||
uint8_t color[8];
|
||||
};
|
||||
|
||||
//! Represents a single face
|
||||
struct Face
|
||||
{
|
||||
unsigned int elem;
|
||||
};
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
unsigned int num;
|
||||
aiVector3D val;
|
||||
};
|
||||
|
||||
//! Represents a single object
|
||||
struct Object
|
||||
{
|
||||
std::string name;
|
||||
|
||||
std::vector<Edge> edges;
|
||||
std::vector<Face> faces;
|
||||
std::vector<Vertex> vertices;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||
bool checkSig) const;
|
||||
|
||||
protected:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void GetExtensionList(std::set<std::string>& extensions);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void SetupProperties(const Importer* pImp);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||
IOSystem* pIOHandler);
|
||||
|
||||
private:
|
||||
|
||||
}; // end of class NDOImporter
|
||||
} // end of namespace Assimp
|
||||
#endif // INCLUDED_AI_NDO_LOADER_H
|
|
@ -130,20 +130,17 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2)
|
|||
#if (defined _MSC_VER)
|
||||
|
||||
return ::_stricmp(s1,s2);
|
||||
|
||||
#elif defined( __GNUC__ )
|
||||
|
||||
|
||||
return ::strcasecmp(s1,s2);
|
||||
|
||||
#else
|
||||
|
||||
register char c1, c2;
|
||||
do
|
||||
{
|
||||
do {
|
||||
c1 = tolower(*s1++);
|
||||
c2 = tolower(*s2++);
|
||||
}
|
||||
while ( c1 && (c1 == c2) );
|
||||
|
||||
return c1 - c2;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1794,6 +1794,18 @@
|
|||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ndo"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\code\NDOLoader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\NDOLoader.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ogre"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue