Pull from upstream, 5/17/2016
This commit is contained in:
@@ -60,7 +60,8 @@ __Importers__:
|
||||
- Ogre XML
|
||||
- Q3D
|
||||
- ASSBIN (Assimp custom format)
|
||||
- glTF
|
||||
- glTF (partial)
|
||||
- 3MF
|
||||
|
||||
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
|
||||
|
||||
@@ -76,7 +77,8 @@ __Exporters__:
|
||||
- 3DS
|
||||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||
- ASSBIN
|
||||
- glTF
|
||||
- STEP
|
||||
- glTF (partial)
|
||||
|
||||
### Building ###
|
||||
Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace AssxmlExport {
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
static int ioprintf( IOStream * io, const char *format, ... ) {
|
||||
using namespace std;
|
||||
if ( nullptr == io ) {
|
||||
return -1;
|
||||
}
|
||||
@@ -77,7 +78,7 @@ static int ioprintf( IOStream * io, const char *format, ... ) {
|
||||
::memset( sz, '\0', Size );
|
||||
va_list va;
|
||||
va_start( va, format );
|
||||
int nSize = std::vsnprintf( sz, Size-1, format, va );
|
||||
int nSize = vsnprintf( sz, Size-1, format, va );
|
||||
ai_assert( nSize < Size );
|
||||
va_end( va );
|
||||
|
||||
|
||||
+12
-2
@@ -1,6 +1,6 @@
|
||||
# Open Asset Import Library (assimp)
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2006-2016, assimp team
|
||||
# All rights reserved.
|
||||
#
|
||||
@@ -608,11 +608,21 @@ ADD_ASSIMP_IMPORTER(GLTF
|
||||
|
||||
glTFImporter.cpp
|
||||
glTFImporter.h
|
||||
|
||||
|
||||
glTFExporter.h
|
||||
glTFExporter.cpp
|
||||
)
|
||||
|
||||
|
||||
ADD_ASSIMP_IMPORTER(3MF
|
||||
D3MFImporter.h
|
||||
D3MFImporter.cpp
|
||||
D3MFOpcPackage.h
|
||||
D3MFOpcPackage.cpp
|
||||
|
||||
)
|
||||
|
||||
|
||||
SET( Step_SRCS
|
||||
StepExporter.h
|
||||
StepExporter.cpp
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp 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 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.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "D3MFImporter.h"
|
||||
|
||||
#include "../include/assimp/scene.h"
|
||||
#include "../contrib/unzip/unzip.h"
|
||||
#include "../include/assimp/IOStream.hpp"
|
||||
#include "../include/assimp/IOSystem.hpp"
|
||||
#include "../include/assimp/DefaultLogger.hpp"
|
||||
#include "irrXMLWrapper.h"
|
||||
#include "StringComparison.h"
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
#include "../include/assimp/ai_assert.h"
|
||||
|
||||
#include "D3MFOpcPackage.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
namespace D3MF {
|
||||
|
||||
|
||||
namespace XmlTag {
|
||||
|
||||
const std::string model = "model";
|
||||
const std::string metadata = "metadata";
|
||||
const std::string resources = "resources";
|
||||
const std::string object = "object";
|
||||
const std::string mesh = "mesh";
|
||||
const std::string vertices = "vertices";
|
||||
const std::string vertex = "vertex";
|
||||
const std::string triangles = "triangles";
|
||||
const std::string triangle = "triangle";
|
||||
const std::string x = "x";
|
||||
const std::string y = "y";
|
||||
const std::string z = "z";
|
||||
const std::string v1 = "v1";
|
||||
const std::string v2 = "v2";
|
||||
const std::string v3 = "v3";
|
||||
const std::string id = "id";
|
||||
const std::string name = "name";
|
||||
const std::string type = "type";
|
||||
const std::string build = "build";
|
||||
const std::string item = "item";
|
||||
const std::string objectid = "objectid";
|
||||
const std::string transform = "transform";
|
||||
|
||||
}
|
||||
|
||||
|
||||
class XmlSerializer
|
||||
{
|
||||
public:
|
||||
XmlSerializer(XmlReader* xmlReader)
|
||||
: xmlReader(xmlReader)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ImportXml(aiScene* scene)
|
||||
{
|
||||
|
||||
scene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
||||
|
||||
scene->mRootNode = new aiNode();
|
||||
std::vector<aiNode*> children;
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::model))
|
||||
{
|
||||
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::object)
|
||||
{
|
||||
children.push_back(ReadObject(scene));
|
||||
}
|
||||
else if(xmlReader->getNodeName() == D3MF::XmlTag::build)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(scene->mRootNode->mName.length == 0)
|
||||
scene->mRootNode->mName.Set("3MF");
|
||||
|
||||
|
||||
scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
||||
scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
|
||||
|
||||
std::copy(meshes.begin(), meshes.end(), scene->mMeshes);
|
||||
|
||||
scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
|
||||
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
|
||||
|
||||
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
aiNode* ReadObject(aiScene* scene)
|
||||
{
|
||||
ScopeGuard<aiNode> node(new aiNode());
|
||||
|
||||
std::vector<unsigned long> meshIds;
|
||||
|
||||
int id = std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::id.c_str()));
|
||||
std::string name(xmlReader->getAttributeValue(D3MF::XmlTag::name.c_str()));
|
||||
std::string type(xmlReader->getAttributeValue(D3MF::XmlTag::type.c_str()));
|
||||
|
||||
node->mParent = scene->mRootNode;
|
||||
node->mName.Set(name);
|
||||
|
||||
unsigned long meshIdx = meshes.size();
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::object))
|
||||
{
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::mesh)
|
||||
{
|
||||
auto mesh = ReadMesh();
|
||||
|
||||
mesh->mName.Set(name);
|
||||
meshes.push_back(mesh);
|
||||
meshIds.push_back(meshIdx);
|
||||
meshIdx++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
node->mNumMeshes = static_cast<unsigned int>(meshIds.size());
|
||||
|
||||
node->mMeshes = new unsigned int[node->mNumMeshes];
|
||||
|
||||
std::copy(meshIds.begin(), meshIds.end(), node->mMeshes);
|
||||
|
||||
return node.dismiss();
|
||||
|
||||
}
|
||||
|
||||
aiMesh* ReadMesh()
|
||||
{
|
||||
aiMesh* mesh = new aiMesh();
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::mesh))
|
||||
{
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::vertices)
|
||||
{
|
||||
ImportVertices(mesh);
|
||||
}
|
||||
else if(xmlReader->getNodeName() == D3MF::XmlTag::triangles)
|
||||
{
|
||||
ImportTriangles(mesh);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void ImportVertices(aiMesh* mesh)
|
||||
{
|
||||
std::vector<aiVector3D> vertices;
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::vertices))
|
||||
{
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::vertex)
|
||||
{
|
||||
vertices.push_back(ReadVertex());
|
||||
}
|
||||
}
|
||||
mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
|
||||
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
||||
|
||||
std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
|
||||
|
||||
}
|
||||
aiVector3D ReadVertex()
|
||||
{
|
||||
aiVector3D vertex;
|
||||
vertex.x = std::strtof(xmlReader->getAttributeValue(D3MF::XmlTag::x.c_str()), nullptr);
|
||||
vertex.y = std::strtof(xmlReader->getAttributeValue(D3MF::XmlTag::y.c_str()), nullptr);
|
||||
vertex.z = std::strtof(xmlReader->getAttributeValue(D3MF::XmlTag::z.c_str()), nullptr);
|
||||
|
||||
return vertex;
|
||||
}
|
||||
|
||||
void ImportTriangles(aiMesh* mesh)
|
||||
{
|
||||
std::vector<aiFace> faces;
|
||||
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::triangles))
|
||||
{
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::triangle)
|
||||
{
|
||||
faces.push_back(ReadTriangle());
|
||||
}
|
||||
}
|
||||
|
||||
mesh->mNumFaces = static_cast<unsigned int>(faces.size());
|
||||
mesh->mFaces = new aiFace[mesh->mNumFaces];
|
||||
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||
|
||||
|
||||
std::copy(faces.begin(), faces.end(), mesh->mFaces);
|
||||
|
||||
}
|
||||
|
||||
aiFace ReadTriangle()
|
||||
{
|
||||
aiFace face;
|
||||
|
||||
face.mNumIndices = 3;
|
||||
face.mIndices = new unsigned int[face.mNumIndices];
|
||||
face.mIndices[0] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v1.c_str())));
|
||||
face.mIndices[1] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v2.c_str())));
|
||||
face.mIndices[2] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v3.c_str())));
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool ReadToStartElement(const std::string& startTag)
|
||||
{
|
||||
while(xmlReader->read())
|
||||
{
|
||||
if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && xmlReader->getNodeName() == startTag)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END &&
|
||||
xmlReader->getNodeName() == startTag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReadToEndElement(const std::string& closeTag)
|
||||
{
|
||||
while(xmlReader->read())
|
||||
{
|
||||
if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
||||
return true;
|
||||
}
|
||||
else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END
|
||||
&& xmlReader->getNodeName() == closeTag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::vector<aiMesh*> meshes;
|
||||
XmlReader* xmlReader;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} //namespace D3MF
|
||||
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
"3mf Importer",
|
||||
"",
|
||||
"",
|
||||
"http://3mf.io/",
|
||||
aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"3mf"
|
||||
};
|
||||
|
||||
|
||||
D3MFImporter::D3MFImporter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
D3MFImporter::~D3MFImporter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const
|
||||
{
|
||||
const std::string extension = GetExtension(pFile);
|
||||
|
||||
if(extension == "3mf")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if(!extension.length() || checkSig)
|
||||
{
|
||||
if(!pIOHandler)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void D3MFImporter::SetupProperties(const Importer *pImp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const aiImporterDesc *D3MFImporter::GetInfo() const
|
||||
{
|
||||
return &desc;
|
||||
}
|
||||
|
||||
void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler)
|
||||
{
|
||||
|
||||
|
||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, pFile);
|
||||
|
||||
std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream()));
|
||||
std::unique_ptr<D3MF::XmlReader> xmlReader(irr::io::createIrrXMLReader(xmlStream.get()));
|
||||
|
||||
D3MF::XmlSerializer xmlSerializer(xmlReader.get());
|
||||
|
||||
|
||||
xmlSerializer.ImportXml(pScene);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp 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 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.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef AI_D3MFLOADER_H_INCLUDED
|
||||
#define AI_D3MFLOADER_H_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
#include "BaseImporter.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
class D3MFImporter : public BaseImporter
|
||||
{
|
||||
public:
|
||||
D3MFImporter();
|
||||
~D3MFImporter();
|
||||
|
||||
// BaseImporter interface
|
||||
public:
|
||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
|
||||
void SetupProperties(const Importer *pImp);
|
||||
const aiImporterDesc *GetInfo() const;
|
||||
|
||||
protected:
|
||||
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
||||
|
||||
};
|
||||
}
|
||||
#endif // AI_D3MFLOADER_H_INCLUDED
|
||||
@@ -0,0 +1,598 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp 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 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.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "D3MFOpcPackage.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
#include "../contrib/unzip/unzip.h"
|
||||
#include "../include/assimp/IOStream.hpp"
|
||||
#include "../include/assimp/IOSystem.hpp"
|
||||
#include "../include/assimp/DefaultLogger.hpp"
|
||||
|
||||
|
||||
#include "../include/assimp/ai_assert.h"
|
||||
|
||||
#include "Exceptional.h"
|
||||
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
namespace D3MF {
|
||||
|
||||
|
||||
|
||||
namespace XmlTag {
|
||||
|
||||
const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
|
||||
const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
|
||||
const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
|
||||
const std::string SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
||||
const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships";
|
||||
const std::string RELS_RELATIONSHIP_NODE = "Relationship";
|
||||
const std::string RELS_ATTRIB_TARGET = "Target";
|
||||
const std::string RELS_ATTRIB_TYPE = "Type";
|
||||
const std::string RELS_ATTRIB_ID = "Id";
|
||||
const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
|
||||
const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
|
||||
const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
|
||||
const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
||||
const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
||||
|
||||
|
||||
}
|
||||
|
||||
class IOSystem2Unzip {
|
||||
|
||||
public:
|
||||
|
||||
static voidpf open(voidpf opaque, const char* filename, int mode);
|
||||
|
||||
static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size);
|
||||
|
||||
static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size);
|
||||
|
||||
static long tell(voidpf opaque, voidpf stream);
|
||||
|
||||
static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
|
||||
|
||||
static int close(voidpf opaque, voidpf stream);
|
||||
|
||||
static int testerror(voidpf opaque, voidpf stream);
|
||||
|
||||
static zlib_filefunc_def get(IOSystem* pIOHandler);
|
||||
};
|
||||
|
||||
voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) {
|
||||
IOSystem* io_system = reinterpret_cast<IOSystem*>(opaque);
|
||||
|
||||
const char* mode_fopen = NULL;
|
||||
if((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) {
|
||||
mode_fopen = "rb";
|
||||
} else {
|
||||
if(mode & ZLIB_FILEFUNC_MODE_EXISTING) {
|
||||
mode_fopen = "r+b";
|
||||
} else {
|
||||
if(mode & ZLIB_FILEFUNC_MODE_CREATE) {
|
||||
mode_fopen = "wb";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (voidpf) io_system->Open(filename, mode_fopen);
|
||||
}
|
||||
|
||||
uLong IOSystem2Unzip::read(voidpf /*opaque*/, voidpf stream, void* buf, uLong size) {
|
||||
IOStream* io_stream = (IOStream*) stream;
|
||||
|
||||
return io_stream->Read(buf, 1, size);
|
||||
}
|
||||
|
||||
uLong IOSystem2Unzip::write(voidpf /*opaque*/, voidpf stream, const void* buf, uLong size) {
|
||||
IOStream* io_stream = (IOStream*) stream;
|
||||
|
||||
return io_stream->Write(buf, 1, size);
|
||||
}
|
||||
|
||||
long IOSystem2Unzip::tell(voidpf /*opaque*/, voidpf stream) {
|
||||
IOStream* io_stream = (IOStream*) stream;
|
||||
|
||||
return io_stream->Tell();
|
||||
}
|
||||
|
||||
long IOSystem2Unzip::seek(voidpf /*opaque*/, voidpf stream, uLong offset, int origin) {
|
||||
IOStream* io_stream = (IOStream*) stream;
|
||||
|
||||
aiOrigin assimp_origin;
|
||||
switch (origin) {
|
||||
default:
|
||||
case ZLIB_FILEFUNC_SEEK_CUR:
|
||||
assimp_origin = aiOrigin_CUR;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_END:
|
||||
assimp_origin = aiOrigin_END;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_SET:
|
||||
assimp_origin = aiOrigin_SET;
|
||||
break;
|
||||
}
|
||||
|
||||
return (io_stream->Seek(offset, assimp_origin) == aiReturn_SUCCESS ? 0 : -1);
|
||||
}
|
||||
|
||||
int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
|
||||
IOSystem* io_system = (IOSystem*) opaque;
|
||||
IOStream* io_stream = (IOStream*) stream;
|
||||
|
||||
io_system->Close(io_stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IOSystem2Unzip::testerror(voidpf /*opaque*/, voidpf /*stream*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
zlib_filefunc_def IOSystem2Unzip::get(IOSystem* pIOHandler) {
|
||||
zlib_filefunc_def mapping;
|
||||
|
||||
mapping.zopen_file = open;
|
||||
mapping.zread_file = read;
|
||||
mapping.zwrite_file = write;
|
||||
mapping.ztell_file = tell;
|
||||
mapping.zseek_file = seek;
|
||||
mapping.zclose_file = close;
|
||||
mapping.zerror_file = testerror;
|
||||
mapping.opaque = reinterpret_cast<voidpf>(pIOHandler);
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
|
||||
class ZipFile : public IOStream
|
||||
{
|
||||
friend class D3MFZipArchive;
|
||||
|
||||
public:
|
||||
explicit ZipFile(size_t size);
|
||||
|
||||
~ZipFile();
|
||||
|
||||
size_t Read(void* pvBuffer, size_t pSize, size_t pCount );
|
||||
|
||||
size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/);
|
||||
|
||||
size_t FileSize() const;
|
||||
|
||||
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/);
|
||||
|
||||
size_t Tell() const;
|
||||
|
||||
void Flush();
|
||||
|
||||
private:
|
||||
|
||||
void* m_Buffer;
|
||||
|
||||
size_t m_Size;
|
||||
|
||||
};
|
||||
|
||||
ZipFile::ZipFile(size_t size) : m_Size(size) {
|
||||
ai_assert(m_Size != 0);
|
||||
|
||||
m_Buffer = malloc(m_Size);
|
||||
}
|
||||
|
||||
ZipFile::~ZipFile() {
|
||||
free(m_Buffer);
|
||||
m_Buffer = NULL;
|
||||
}
|
||||
|
||||
size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) {
|
||||
const size_t size = pSize * pCount;
|
||||
assert(size <= m_Size);
|
||||
|
||||
std::memcpy(pvBuffer, m_Buffer, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t ZipFile::Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ZipFile::FileSize() const {
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
aiReturn ZipFile::Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) {
|
||||
return aiReturn_FAILURE;
|
||||
}
|
||||
|
||||
size_t ZipFile::Tell() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ZipFile::Flush() {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
class D3MFZipArchive : public IOSystem
|
||||
{
|
||||
public:
|
||||
|
||||
static const unsigned int FileNameSize = 256;
|
||||
|
||||
public:
|
||||
|
||||
D3MFZipArchive(IOSystem* pIOHandler, const std::string & rFile);
|
||||
|
||||
~D3MFZipArchive();
|
||||
|
||||
bool Exists(const char* pFile) const;
|
||||
|
||||
char getOsSeparator() const;
|
||||
|
||||
IOStream* Open(const char* pFile, const char* pMode = "rb");
|
||||
|
||||
void Close(IOStream* pFile);
|
||||
|
||||
bool isOpen() const;
|
||||
|
||||
void getFileList(std::vector<std::string> &rFileList);
|
||||
|
||||
private:
|
||||
|
||||
bool mapArchive();
|
||||
|
||||
private:
|
||||
|
||||
unzFile m_ZipFileHandle;
|
||||
|
||||
std::map<std::string, ZipFile*> m_ArchiveMap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor.
|
||||
D3MFZipArchive::D3MFZipArchive(IOSystem* pIOHandler, const std::string& rFile)
|
||||
: m_ZipFileHandle(NULL), m_ArchiveMap()
|
||||
{
|
||||
if (! rFile.empty())
|
||||
{
|
||||
zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);
|
||||
|
||||
m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping);
|
||||
|
||||
if(m_ZipFileHandle != NULL) {
|
||||
mapArchive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor.
|
||||
D3MFZipArchive::~D3MFZipArchive() {
|
||||
for( std::map<std::string, ZipFile*>::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it ) {
|
||||
delete it->second;
|
||||
}
|
||||
m_ArchiveMap.clear();
|
||||
|
||||
if(m_ZipFileHandle != NULL) {
|
||||
unzClose(m_ZipFileHandle);
|
||||
m_ZipFileHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns true, if the archive is already open.
|
||||
bool D3MFZipArchive::isOpen() const {
|
||||
return (m_ZipFileHandle != NULL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns true, if the filename is part of the archive.
|
||||
bool D3MFZipArchive::Exists(const char* pFile) const {
|
||||
ai_assert(pFile != NULL);
|
||||
|
||||
bool exist = false;
|
||||
|
||||
if (pFile != NULL) {
|
||||
std::string rFile(pFile);
|
||||
std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile);
|
||||
|
||||
if(it != m_ArchiveMap.end()) {
|
||||
exist = true;
|
||||
}
|
||||
}
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns the separator delimiter.
|
||||
char D3MFZipArchive::getOsSeparator() const {
|
||||
#ifndef _WIN32
|
||||
return '/';
|
||||
#else
|
||||
return '\\';
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Opens a file, which is part of the archive.
|
||||
IOStream *D3MFZipArchive::Open(const char* pFile, const char* /*pMode*/) {
|
||||
ai_assert(pFile != NULL);
|
||||
|
||||
IOStream* result = NULL;
|
||||
|
||||
std::map<std::string, ZipFile*>::iterator it = m_ArchiveMap.find(pFile);
|
||||
|
||||
if(it != m_ArchiveMap.end()) {
|
||||
result = static_cast<IOStream*>(it->second);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Close a filestream.
|
||||
void D3MFZipArchive::Close(IOStream *pFile) {
|
||||
ai_assert(pFile != NULL);
|
||||
|
||||
// We don't do anything in case the file would be opened again in the future
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns the file-list of the archive.
|
||||
void D3MFZipArchive::getFileList(std::vector<std::string> &rFileList) {
|
||||
rFileList.clear();
|
||||
|
||||
for(std::map<std::string, ZipFile*>::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it) {
|
||||
rFileList.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Maps the archive content.
|
||||
bool D3MFZipArchive::mapArchive() {
|
||||
bool success = false;
|
||||
|
||||
if(m_ZipFileHandle != NULL) {
|
||||
if(m_ArchiveMap.empty()) {
|
||||
// At first ensure file is already open
|
||||
if(unzGoToFirstFile(m_ZipFileHandle) == UNZ_OK) {
|
||||
// Loop over all files
|
||||
do {
|
||||
char filename[FileNameSize];
|
||||
unz_file_info fileInfo;
|
||||
|
||||
if(unzGetCurrentFileInfo(m_ZipFileHandle, &fileInfo, filename, FileNameSize, NULL, 0, NULL, 0) == UNZ_OK) {
|
||||
// The file has EXACTLY the size of uncompressed_size. In C
|
||||
// you need to mark the last character with '\0', so add
|
||||
// another character
|
||||
if(fileInfo.uncompressed_size != 0 && unzOpenCurrentFile(m_ZipFileHandle) == UNZ_OK) {
|
||||
std::pair<std::map<std::string, ZipFile*>::iterator, bool> result = m_ArchiveMap.insert(std::make_pair(filename, new ZipFile(fileInfo.uncompressed_size)));
|
||||
|
||||
if(unzReadCurrentFile(m_ZipFileHandle, result.first->second->m_Buffer, fileInfo.uncompressed_size) == (long int) fileInfo.uncompressed_size) {
|
||||
if(unzCloseCurrentFile(m_ZipFileHandle) == UNZ_OK) {
|
||||
// Nothing to do anymore...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(unzGoToNextFile(m_ZipFileHandle) != UNZ_END_OF_LIST_OF_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
struct OpcPackageRelationship
|
||||
{
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string target;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
|
||||
|
||||
class OpcPackageRelationshipReader
|
||||
{
|
||||
public:
|
||||
|
||||
OpcPackageRelationshipReader(XmlReader* xmlReader)
|
||||
{
|
||||
|
||||
while(xmlReader->read())
|
||||
{
|
||||
if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
|
||||
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER)
|
||||
{
|
||||
ParseRootNode(xmlReader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void ParseRootNode(XmlReader* xmlReader)
|
||||
{
|
||||
ParseAttributes(xmlReader);
|
||||
|
||||
while(xmlReader->read())
|
||||
{
|
||||
if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
|
||||
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE)
|
||||
{
|
||||
ParseChildNode(xmlReader);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ParseAttributes(XmlReader*)
|
||||
{
|
||||
|
||||
}
|
||||
void ParseChildNode(XmlReader* xmlReader)
|
||||
{
|
||||
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
|
||||
|
||||
relPtr->id = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_ID.c_str());
|
||||
relPtr->type = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TYPE.c_str());
|
||||
relPtr->target = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TARGET.c_str());
|
||||
|
||||
m_relationShips.push_back(relPtr);
|
||||
}
|
||||
std::vector<OpcPackageRelationshipPtr> m_relationShips;
|
||||
|
||||
};
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
|
||||
: m_RootStream(nullptr)
|
||||
{
|
||||
|
||||
zipArchive.reset(new D3MF::D3MFZipArchive( pIOHandler, rFile ));
|
||||
if(!zipArchive->isOpen())
|
||||
throw DeadlyImportError("Failed to open file " + rFile+ ".");
|
||||
|
||||
std::vector<std::string> fileList;
|
||||
zipArchive->getFileList(fileList);
|
||||
|
||||
for(auto& file: fileList){
|
||||
|
||||
if(file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE)
|
||||
{
|
||||
|
||||
//PkgRelationshipReader pkgRelReader(file, archive);
|
||||
ai_assert(zipArchive->Exists(file.c_str()));
|
||||
|
||||
IOStream *fileStream = zipArchive->Open(file.c_str());
|
||||
|
||||
ai_assert(fileStream != nullptr);
|
||||
|
||||
std::string rootFile = ReadPackageRootRelationship(fileStream);
|
||||
if(rootFile.size() > 0 && rootFile[0] == '/')
|
||||
rootFile = rootFile.substr(1);
|
||||
|
||||
DefaultLogger::get()->debug(rootFile);
|
||||
|
||||
m_RootStream = zipArchive->Open(rootFile.c_str());
|
||||
|
||||
ai_assert(m_RootStream != nullptr);
|
||||
|
||||
|
||||
|
||||
|
||||
// const size_t size = zipArchive->FileSize();
|
||||
// m_Data.resize( size );
|
||||
|
||||
// const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
|
||||
// if ( readSize != size )
|
||||
// {
|
||||
// m_Data.clear();
|
||||
// return false;
|
||||
// }
|
||||
zipArchive->Close( fileStream );
|
||||
|
||||
}
|
||||
else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D3MFOpcPackage::~D3MFOpcPackage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IOStream* D3MFOpcPackage::RootStream() const
|
||||
{
|
||||
return m_RootStream;
|
||||
}
|
||||
|
||||
|
||||
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream)
|
||||
{
|
||||
|
||||
std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
|
||||
std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
|
||||
|
||||
OpcPackageRelationshipReader reader(xml.get());
|
||||
|
||||
|
||||
auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr& rel){
|
||||
return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
||||
});
|
||||
|
||||
|
||||
|
||||
if(itr == reader.m_relationShips.end())
|
||||
throw DeadlyImportError("Cannot find" + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
|
||||
|
||||
return (*itr)->target;
|
||||
}
|
||||
|
||||
} //namespace D3MF
|
||||
|
||||
}
|
||||
|
||||
#endif //ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp 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 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.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef D3MFOPCPACKAGE_H
|
||||
#define D3MFOPCPACKAGE_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "../include/assimp/IOSystem.hpp"
|
||||
#include "irrXMLWrapper.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
namespace D3MF {
|
||||
|
||||
typedef irr::io::IrrXMLReader XmlReader;
|
||||
typedef std::shared_ptr<XmlReader> XmlReaderPtr;
|
||||
|
||||
class D3MFZipArchive;
|
||||
|
||||
class D3MFOpcPackage
|
||||
{
|
||||
public:
|
||||
D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile);
|
||||
~D3MFOpcPackage();
|
||||
|
||||
IOStream* RootStream() const;
|
||||
private:
|
||||
std::string ReadPackageRootRelationship(IOStream* stream);
|
||||
private:
|
||||
IOStream* m_RootStream;
|
||||
std::unique_ptr<D3MFZipArchive> zipArchive;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // D3MFOPCPACKAGE_H
|
||||
@@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "BaseImporter.h"
|
||||
#include "IRRShared.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -92,4 +94,6 @@ protected:
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
||||
|
||||
#endif // AI_IRRMESHIMPORTER_H_INC
|
||||
|
||||
@@ -179,6 +179,9 @@ corresponding preprocessor flag to selectively disable formats.
|
||||
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||
# include "C4DImporter.h"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
# include "D3MFImporter.h"
|
||||
#endif
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
@@ -319,6 +322,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
||||
#if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER )
|
||||
out.push_back( new C4DImporter() );
|
||||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_3MF_IMPORTER )
|
||||
out.push_back(new D3MFImporter() );
|
||||
#endif
|
||||
}
|
||||
|
||||
/** will delete all registered importers. */
|
||||
|
||||
+269
-119
@@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "DefaultIOSystem.h"
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include "MakeVerboseFormat.h"
|
||||
#include "StringComparison.h"
|
||||
|
||||
#include <openddlparser/OpenDDLParser.h>
|
||||
#include <assimp/scene.h>
|
||||
@@ -50,6 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <vector>
|
||||
|
||||
static const std::string OpenGexExt = "ogex";
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
"Open Game Engine Exchange",
|
||||
"",
|
||||
@@ -60,7 +63,7 @@ static const aiImporterDesc desc = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"ogex"
|
||||
OpenGexExt.c_str()
|
||||
};
|
||||
|
||||
namespace Grammar {
|
||||
@@ -87,6 +90,7 @@ namespace Grammar {
|
||||
static const std::string ColorType = "Color";
|
||||
static const std::string ParamType = "Param";
|
||||
static const std::string TextureType = "Texture";
|
||||
static const std::string AttenType = "Atten";
|
||||
|
||||
static const std::string DiffuseColorToken = "diffuse";
|
||||
static const std::string SpecularColorToken = "specular";
|
||||
@@ -119,8 +123,9 @@ namespace Grammar {
|
||||
IndexArrayToken,
|
||||
MaterialToken,
|
||||
ColorToken,
|
||||
Paramtype,
|
||||
ParamToken,
|
||||
TextureToken,
|
||||
AttenToken
|
||||
};
|
||||
|
||||
static const std::string ValidMetricToken[ 4 ] = {
|
||||
@@ -131,7 +136,7 @@ namespace Grammar {
|
||||
};
|
||||
|
||||
static int isValidMetricType( const char *token ) {
|
||||
if( NULL == token ) {
|
||||
if( nullptr == token ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -163,8 +168,12 @@ namespace Grammar {
|
||||
return CameraNodeToken;
|
||||
} else if ( LightNodeType == tokenType ) {
|
||||
return LightNodeToken;
|
||||
} else if( GeometryObjectType == tokenType ) {
|
||||
} else if ( GeometryObjectType == tokenType ) {
|
||||
return GeometryObjectToken;
|
||||
} else if ( CameraObjectType == tokenType ) {
|
||||
return CameraObjectToken;
|
||||
} else if ( LightObjectType == tokenType ) {
|
||||
return LightObjectToken;
|
||||
} else if( TransformType == tokenType ) {
|
||||
return TransformToken;
|
||||
} else if( MeshType == tokenType ) {
|
||||
@@ -175,10 +184,14 @@ namespace Grammar {
|
||||
return IndexArrayToken;
|
||||
} else if( MaterialType == tokenType ) {
|
||||
return MaterialToken;
|
||||
} else if( ColorType == tokenType ) {
|
||||
} else if ( ColorType == tokenType ) {
|
||||
return ColorToken;
|
||||
} else if ( ParamType == tokenType ) {
|
||||
return ParamToken;
|
||||
} else if( TextureType == tokenType ) {
|
||||
return TextureToken;
|
||||
} else if ( AttenType == tokenType ) {
|
||||
return AttenToken;
|
||||
}
|
||||
|
||||
return NoneType;
|
||||
@@ -191,12 +204,27 @@ namespace OpenGEX {
|
||||
|
||||
USE_ODDLPARSER_NS
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static void propId2StdString( Property *prop, std::string &name, std::string &key ) {
|
||||
name = key = "";
|
||||
if ( nullptr == prop ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( nullptr != prop->m_key ) {
|
||||
name = prop->m_key->m_buffer;
|
||||
if ( Value::ddl_string == prop->m_value->m_type ) {
|
||||
key = prop->m_value->getString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::VertexContainer::VertexContainer()
|
||||
: m_numVerts( 0 )
|
||||
, m_vertices(NULL)
|
||||
, m_vertices( nullptr )
|
||||
, m_numNormals( 0 )
|
||||
, m_normals(NULL)
|
||||
, m_normals( nullptr )
|
||||
, m_numUVComps()
|
||||
, m_textureCoords()
|
||||
{
|
||||
@@ -228,16 +256,18 @@ OpenGEXImporter::RefInfo::~RefInfo() {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::OpenGEXImporter()
|
||||
: m_root( NULL )
|
||||
: m_root( nullptr )
|
||||
, m_nodeChildMap()
|
||||
, m_meshCache()
|
||||
, m_mesh2refMap()
|
||||
, m_ctx( NULL )
|
||||
, m_ctx( nullptr )
|
||||
, m_metrics()
|
||||
, m_currentNode( NULL )
|
||||
, m_currentNode( nullptr )
|
||||
, m_currentVertices()
|
||||
, m_currentMesh( NULL )
|
||||
, m_currentMaterial( NULL )
|
||||
, m_currentMesh( nullptr )
|
||||
, m_currentMaterial( nullptr )
|
||||
, m_currentLight( nullptr )
|
||||
, m_currentCamera( nullptr )
|
||||
, m_tokenType( Grammar::NoneType )
|
||||
, m_materialCache()
|
||||
, m_cameraCache()
|
||||
@@ -256,7 +286,7 @@ OpenGEXImporter::~OpenGEXImporter() {
|
||||
bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const {
|
||||
bool canRead( false );
|
||||
if( !checkSig ) {
|
||||
canRead = SimpleExtensionCheck( file, "ogex" );
|
||||
canRead = SimpleExtensionCheck( file, OpenGexExt.c_str() );
|
||||
} else {
|
||||
static const char *token[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" };
|
||||
canRead = BaseImporter::SearchFileHeaderForToken( pIOHandler, file, token, 4 );
|
||||
@@ -287,6 +317,8 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce
|
||||
}
|
||||
|
||||
copyMeshes( pScene );
|
||||
copyCameras( pScene );
|
||||
copyLights( pScene );
|
||||
resolveReferences();
|
||||
createNodeTree( pScene );
|
||||
}
|
||||
@@ -298,14 +330,14 @@ const aiImporterDesc *OpenGEXImporter::GetInfo() const {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::SetupProperties( const Importer *pImp ) {
|
||||
if( NULL == pImp ) {
|
||||
if( nullptr == pImp ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == node ) {
|
||||
if( nullptr == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -348,6 +380,14 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
|
||||
handleGeometryObject( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::CameraObjectToken:
|
||||
handleCameraObject( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::LightObjectToken:
|
||||
handleLightObject( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::TransformToken:
|
||||
handleTransformNode( *it, pScene );
|
||||
break;
|
||||
@@ -371,6 +411,10 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
|
||||
case Grammar::ColorToken:
|
||||
handleColorNode( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::ParamToken:
|
||||
handleParamNode( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::TextureToken:
|
||||
handleTextureNode( *it, pScene );
|
||||
@@ -384,7 +428,7 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == node || NULL == m_ctx ) {
|
||||
if( nullptr == node || nullptr == m_ctx ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -393,14 +437,14 @@ void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) {
|
||||
}
|
||||
|
||||
Property *prop( node->getProperties() );
|
||||
while( NULL != prop ) {
|
||||
if( NULL != prop->m_key ) {
|
||||
while( nullptr != prop ) {
|
||||
if( nullptr != prop->m_key ) {
|
||||
if( Value::ddl_string == prop->m_value->m_type ) {
|
||||
std::string valName( ( char* ) prop->m_value->m_data );
|
||||
int type( Grammar::isValidMetricType( valName.c_str() ) );
|
||||
if( Grammar::NoneType != type ) {
|
||||
Value *val( node->getValue() );
|
||||
if( NULL != val ) {
|
||||
if( nullptr != val ) {
|
||||
if( Value::ddl_float == val->m_type ) {
|
||||
m_metrics[ type ].m_floatValue = val->getFloat();
|
||||
} else if( Value::ddl_int32 == val->m_type ) {
|
||||
@@ -447,10 +491,10 @@ static void getRefNames( DDLNode *node, std::vector<std::string> &names ) {
|
||||
ai_assert( NULL != node );
|
||||
|
||||
Reference *ref = node->getReferences();
|
||||
if( NULL != ref ) {
|
||||
if( nullptr != ref ) {
|
||||
for( size_t i = 0; i < ref->m_numRefs; i++ ) {
|
||||
Name *currentName( ref->m_referencedName[ i ] );
|
||||
if( NULL != currentName && NULL != currentName->m_id ) {
|
||||
if( nullptr != currentName && nullptr != currentName->m_id ) {
|
||||
const std::string name( currentName->m_id->m_buffer );
|
||||
if( !name.empty() ) {
|
||||
names.push_back( name );
|
||||
@@ -462,23 +506,27 @@ static void getRefNames( DDLNode *node, std::vector<std::string> &names ) {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == m_currentNode ) {
|
||||
if( nullptr == m_currentNode ) {
|
||||
throw DeadlyImportError( "No parent node for name." );
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> objRefNames;
|
||||
getRefNames( node, objRefNames );
|
||||
m_currentNode->mNumMeshes = objRefNames.size();
|
||||
m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ];
|
||||
if( !objRefNames.empty() ) {
|
||||
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) );
|
||||
|
||||
// when we are dealing with a geometry node prepare the mesh cache
|
||||
if ( m_tokenType == Grammar::GeometryNodeToken ) {
|
||||
m_currentNode->mNumMeshes = objRefNames.size();
|
||||
m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ];
|
||||
if ( !objRefNames.empty() ) {
|
||||
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == m_currentNode ) {
|
||||
if( nullptr == m_currentNode ) {
|
||||
throw DeadlyImportError( "No parent node for name." );
|
||||
return;
|
||||
}
|
||||
@@ -506,7 +554,18 @@ void OpenGEXImporter::handleCameraNode( DDLNode *node, aiScene *pScene ) {
|
||||
aiCamera *camera( new aiCamera );
|
||||
const size_t camIdx( m_cameraCache.size() );
|
||||
m_cameraCache.push_back( camera );
|
||||
m_currentCamera = camera;
|
||||
|
||||
aiNode *newNode = new aiNode;
|
||||
pushNode( newNode, pScene );
|
||||
m_tokenType = Grammar::CameraNodeToken;
|
||||
m_currentNode = newNode;
|
||||
|
||||
handleNodes( node, pScene );
|
||||
|
||||
popNode();
|
||||
|
||||
m_currentCamera->mName.Set( newNode->mName.C_Str() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
@@ -514,6 +573,7 @@ void OpenGEXImporter::handleLightNode( ODDLParser::DDLNode *node, aiScene *pScen
|
||||
aiLight *light( new aiLight );
|
||||
const size_t lightIdx( m_lightCache.size() );
|
||||
m_lightCache.push_back( light );
|
||||
m_currentLight = light;
|
||||
|
||||
aiNode *newNode = new aiNode;
|
||||
m_tokenType = Grammar::LightNodeToken;
|
||||
@@ -524,7 +584,7 @@ void OpenGEXImporter::handleLightNode( ODDLParser::DDLNode *node, aiScene *pScen
|
||||
|
||||
popNode();
|
||||
|
||||
light->mName.Set( newNode->mName.C_Str() );
|
||||
m_currentLight->mName.Set( newNode->mName.C_Str() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
@@ -536,26 +596,41 @@ void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleCameraObject( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
// parameters will be parsed normally in the tree, so just go for it
|
||||
|
||||
handleNodes( node, pScene );
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleLightObject( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
|
||||
Property *prop( node->findPropertyByName( "type" ) );
|
||||
if ( nullptr != prop ) {
|
||||
if ( nullptr != prop->m_value ) {
|
||||
std::string typeStr( prop->m_value->getString() );
|
||||
if ( "point" == typeStr ) {
|
||||
m_currentLight->mType = aiLightSource_POINT;
|
||||
} else if ( "spot" == typeStr ) {
|
||||
m_currentLight->mType = aiLightSource_SPOT;
|
||||
} else if ( "infinite" == typeStr ) {
|
||||
m_currentLight->mType = aiLightSource_DIRECTIONAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parameters will be parsed normally in the tree, so just go for it
|
||||
handleNodes( node, pScene );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static void setMatrix( aiNode *node, DataArrayList *transformData ) {
|
||||
ai_assert( NULL != node );
|
||||
ai_assert( NULL != transformData );
|
||||
ai_assert( nullptr != node );
|
||||
ai_assert( nullptr != transformData );
|
||||
|
||||
float m[ 16 ];
|
||||
size_t i( 1 );
|
||||
Value *next( transformData->m_dataList->m_next );
|
||||
m[ 0 ] = transformData->m_dataList->getFloat();
|
||||
while( next != NULL ) {
|
||||
while( next != nullptr ) {
|
||||
m[ i ] = next->getFloat();
|
||||
next = next->m_next;
|
||||
i++;
|
||||
@@ -584,13 +659,13 @@ static void setMatrix( aiNode *node, DataArrayList *transformData ) {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == m_currentNode ) {
|
||||
if( nullptr == m_currentNode ) {
|
||||
throw DeadlyImportError( "No parent node for name." );
|
||||
return;
|
||||
}
|
||||
|
||||
DataArrayList *transformData( node->getDataArrayList() );
|
||||
if( NULL != transformData ) {
|
||||
if( nullptr != transformData ) {
|
||||
if( transformData->m_numItems != 16 ) {
|
||||
throw DeadlyImportError( "Invalid number of data for transform matrix." );
|
||||
return;
|
||||
@@ -599,21 +674,6 @@ void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene *p
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static void propId2StdString( Property *prop, std::string &name, std::string &key ) {
|
||||
name = key = "";
|
||||
if( NULL == prop ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( NULL != prop->m_key ) {
|
||||
name = prop->m_key->m_buffer;
|
||||
if( Value::ddl_string == prop->m_value->m_type ) {
|
||||
key = prop->m_value->getString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
m_currentMesh = new aiMesh;
|
||||
@@ -621,7 +681,7 @@ void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene
|
||||
m_meshCache.push_back( m_currentMesh );
|
||||
|
||||
Property *prop = node->getProperties();
|
||||
if( NULL != prop ) {
|
||||
if( nullptr != prop ) {
|
||||
std::string propName, propKey;
|
||||
propId2StdString( prop, propName, propKey );
|
||||
if( "primitive" == propName ) {
|
||||
@@ -642,7 +702,7 @@ void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene
|
||||
handleNodes( node, pScene );
|
||||
|
||||
DDLNode *parent( node->getParent() );
|
||||
if( NULL != parent ) {
|
||||
if( nullptr != parent ) {
|
||||
const std::string &name = parent->getName();
|
||||
m_mesh2refMap[ name ] = meshidx;
|
||||
}
|
||||
@@ -658,7 +718,7 @@ enum MeshAttribute {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static MeshAttribute getAttributeByName( const char *attribName ) {
|
||||
ai_assert( NULL != attribName );
|
||||
ai_assert( nullptr != attribName );
|
||||
|
||||
if( 0 == strncmp( "position", attribName, strlen( "position" ) ) ) {
|
||||
return Position;
|
||||
@@ -673,8 +733,8 @@ static MeshAttribute getAttributeByName( const char *attribName ) {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static void fillVector3( aiVector3D *vec3, Value *vals ) {
|
||||
ai_assert( NULL != vec3 );
|
||||
ai_assert( NULL != vals );
|
||||
ai_assert( nullptr != vec3 );
|
||||
ai_assert( nullptr != vals );
|
||||
|
||||
float x( 0.0f ), y( 0.0f ), z( 0.0f );
|
||||
Value *next( vals );
|
||||
@@ -682,7 +742,7 @@ static void fillVector3( aiVector3D *vec3, Value *vals ) {
|
||||
next = next->m_next;
|
||||
y = next->getFloat();
|
||||
next = next->m_next;
|
||||
if( NULL != next ) {
|
||||
if( nullptr != next ) {
|
||||
z = next->getFloat();
|
||||
}
|
||||
|
||||
@@ -692,13 +752,13 @@ static void fillVector3( aiVector3D *vec3, Value *vals ) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static size_t countDataArrayListItems( DataArrayList *vaList ) {
|
||||
size_t numItems( 0 );
|
||||
if( NULL == vaList ) {
|
||||
if( nullptr == vaList ) {
|
||||
return numItems;
|
||||
}
|
||||
|
||||
DataArrayList *next( vaList );
|
||||
while( NULL != next ) {
|
||||
if( NULL != vaList->m_dataList ) {
|
||||
while( nullptr != next ) {
|
||||
if( nullptr != vaList->m_dataList ) {
|
||||
numItems++;
|
||||
}
|
||||
next = next->m_next;
|
||||
@@ -718,13 +778,13 @@ static void copyVectorArray( size_t numItems, DataArrayList *vaList, aiVector3D
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == node ) {
|
||||
if( nullptr == node ) {
|
||||
throw DeadlyImportError( "No parent node for name." );
|
||||
return;
|
||||
}
|
||||
|
||||
Property *prop( node->getProperties() );
|
||||
if( NULL != prop ) {
|
||||
if( nullptr != prop ) {
|
||||
std::string propName, propKey;
|
||||
propId2StdString( prop, propName, propKey );
|
||||
MeshAttribute attribType( getAttributeByName( propKey.c_str() ) );
|
||||
@@ -733,7 +793,7 @@ void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene
|
||||
}
|
||||
|
||||
DataArrayList *vaList = node->getDataArrayList();
|
||||
if( NULL == vaList ) {
|
||||
if( nullptr == vaList ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -757,18 +817,18 @@ void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == node ) {
|
||||
if( nullptr == node ) {
|
||||
throw DeadlyImportError( "No parent node for name." );
|
||||
return;
|
||||
}
|
||||
|
||||
if( NULL == m_currentMesh ) {
|
||||
if( nullptr == m_currentMesh ) {
|
||||
throw DeadlyImportError( "No current mesh for index data found." );
|
||||
return;
|
||||
}
|
||||
|
||||
DataArrayList *vaList = node->getDataArrayList();
|
||||
if( NULL == vaList ) {
|
||||
if( nullptr == vaList ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -777,9 +837,16 @@ void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *
|
||||
m_currentMesh->mFaces = new aiFace[ numItems ];
|
||||
m_currentMesh->mNumVertices = numItems * 3;
|
||||
m_currentMesh->mVertices = new aiVector3D[ m_currentMesh->mNumVertices ];
|
||||
m_currentMesh->mNormals = new aiVector3D[ m_currentMesh->mNumVertices ];
|
||||
m_currentMesh->mNumUVComponents[ 0 ] = 3;
|
||||
m_currentMesh->mTextureCoords[ 0 ] = new aiVector3D[ m_currentMesh->mNumVertices ];
|
||||
bool hasNormalCoords( false );
|
||||
if ( m_currentVertices.m_numNormals > 0 ) {
|
||||
m_currentMesh->mNormals = new aiVector3D[ m_currentMesh->mNumVertices ];
|
||||
hasNormalCoords = true;
|
||||
}
|
||||
bool hasTexCoords( false );
|
||||
if ( m_currentVertices.m_numUVComps[ 0 ] > 0 ) {
|
||||
m_currentMesh->mTextureCoords[ 0 ] = new aiVector3D[ m_currentMesh->mNumVertices ];
|
||||
hasTexCoords = true;
|
||||
}
|
||||
|
||||
unsigned int index( 0 );
|
||||
for( size_t i = 0; i < m_currentMesh->mNumFaces; i++ ) {
|
||||
@@ -790,15 +857,17 @@ void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *
|
||||
for( size_t indices = 0; indices < current.mNumIndices; indices++ ) {
|
||||
const int idx( next->getUnsignedInt32() );
|
||||
ai_assert( static_cast<size_t>( idx ) <= m_currentVertices.m_numVerts );
|
||||
|
||||
aiVector3D &pos = ( m_currentVertices.m_vertices[ idx ] );
|
||||
aiVector3D &normal = ( m_currentVertices.m_normals[ idx ] );
|
||||
aiVector3D &tex = ( m_currentVertices.m_textureCoords[ 0 ][ idx ] );
|
||||
|
||||
ai_assert( index < m_currentMesh->mNumVertices );
|
||||
aiVector3D &pos = ( m_currentVertices.m_vertices[ idx ] );
|
||||
m_currentMesh->mVertices[ index ].Set( pos.x, pos.y, pos.z );
|
||||
m_currentMesh->mNormals[ index ].Set( normal.x, normal.y, normal.z );
|
||||
m_currentMesh->mTextureCoords[0][ index ].Set( tex.x, tex.y, tex.z );
|
||||
if ( hasNormalCoords ) {
|
||||
aiVector3D &normal = ( m_currentVertices.m_normals[ idx ] );
|
||||
m_currentMesh->mNormals[ index ].Set( normal.x, normal.y, normal.z );
|
||||
}
|
||||
if ( hasTexCoords ) {
|
||||
aiVector3D &tex = ( m_currentVertices.m_textureCoords[ 0 ][ idx ] );
|
||||
m_currentMesh->mTextureCoords[ 0 ][ index ].Set( tex.x, tex.y, tex.z );
|
||||
}
|
||||
current.mIndices[ indices ] = index;
|
||||
index++;
|
||||
|
||||
@@ -810,7 +879,7 @@ void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static void getColorRGB( aiColor3D *pColor, DataArrayList *colList ) {
|
||||
if( NULL == pColor || NULL == colList ) {
|
||||
if( nullptr == pColor || nullptr == colList ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -828,12 +897,13 @@ enum ColorType {
|
||||
NoneColor = 0,
|
||||
DiffuseColor,
|
||||
SpecularColor,
|
||||
EmissionColor
|
||||
EmissionColor,
|
||||
LightColor
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static ColorType getColorType( Text *id ) {
|
||||
if ( NULL == id ) {
|
||||
if ( nullptr == id ) {
|
||||
return NoneColor;
|
||||
}
|
||||
|
||||
@@ -843,6 +913,8 @@ static ColorType getColorType( Text *id ) {
|
||||
return SpecularColor;
|
||||
} else if( *id == Grammar::EmissionColorToken ) {
|
||||
return EmissionColor;
|
||||
} else if ( *id == "light" ) {
|
||||
return LightColor;
|
||||
}
|
||||
|
||||
return NoneColor;
|
||||
@@ -858,15 +930,15 @@ void OpenGEXImporter::handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pS
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == node ) {
|
||||
if( nullptr == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Property *prop = node->findPropertyByName( "attrib" );
|
||||
if( NULL != prop ) {
|
||||
if( NULL != prop->m_value ) {
|
||||
if( nullptr != prop ) {
|
||||
if( nullptr != prop->m_value ) {
|
||||
DataArrayList *colList( node->getDataArrayList() );
|
||||
if( NULL == colList ) {
|
||||
if( nullptr == colList ) {
|
||||
return;
|
||||
}
|
||||
aiColor3D col;
|
||||
@@ -878,6 +950,8 @@ void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene *pScen
|
||||
m_currentMaterial->AddProperty( &col, 1, AI_MATKEY_COLOR_SPECULAR );
|
||||
} else if( EmissionColor == colType ) {
|
||||
m_currentMaterial->AddProperty( &col, 1, AI_MATKEY_COLOR_EMISSIVE );
|
||||
} else if ( LightColor == colType ) {
|
||||
m_currentLight->mColorDiffuse = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -885,15 +959,15 @@ void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene *pScen
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == node ) {
|
||||
if( nullptr == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Property *prop = node->findPropertyByName( "attrib" );
|
||||
if( NULL != prop ) {
|
||||
if( NULL != prop->m_value ) {
|
||||
if( nullptr != prop ) {
|
||||
if( nullptr != prop->m_value ) {
|
||||
Value *val( node->getValue() );
|
||||
if( NULL != val ) {
|
||||
if( nullptr != val ) {
|
||||
aiString tex;
|
||||
tex.Set( val->getString() );
|
||||
if( prop->m_value->getString() == Grammar::DiffuseTextureToken ) {
|
||||
@@ -903,10 +977,8 @@ void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene *pSc
|
||||
|
||||
} else if( prop->m_value->getString() == Grammar::EmissionTextureToken ) {
|
||||
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE( 0 ) );
|
||||
|
||||
} else if( prop->m_value->getString() == Grammar::OpacyTextureToken ) {
|
||||
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_OPACITY( 0 ) );
|
||||
|
||||
} else if( prop->m_value->getString() == Grammar::TransparencyTextureToken ) {
|
||||
// ToDo!
|
||||
// m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
|
||||
@@ -920,8 +992,58 @@ void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene *pSc
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleParamNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if ( nullptr == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Property *prop = node->findPropertyByName( "attrib" );
|
||||
if ( nullptr == prop ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( nullptr != prop->m_value ) {
|
||||
Value *val( node->getValue() );
|
||||
if ( nullptr == val ) {
|
||||
return;
|
||||
}
|
||||
const float floatVal( val->getFloat() );
|
||||
if ( prop->m_value != nullptr ) {
|
||||
if ( 0 == ASSIMP_strincmp( "fov", prop->m_value->getString(), 3 ) ) {
|
||||
m_currentCamera->mHorizontalFOV = floatVal;
|
||||
} else if ( 0 == ASSIMP_strincmp( "near", prop->m_value->getString(), 3 ) ) {
|
||||
m_currentCamera->mClipPlaneNear = floatVal;
|
||||
} else if ( 0 == ASSIMP_strincmp( "far", prop->m_value->getString(), 3 ) ) {
|
||||
m_currentCamera->mClipPlaneFar = floatVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleAttenNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if ( nullptr == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Property *prop = node->findPropertyByName( "curve" );
|
||||
if ( nullptr != prop ) {
|
||||
if ( nullptr != prop->m_value ) {
|
||||
Value *val( node->getValue() );
|
||||
const float floatVal( val->getFloat() );
|
||||
if ( 0 == strncmp( "scale", prop->m_value->getString(), strlen( "scale" ) ) ) {
|
||||
//if ( "scale" == prop->m_value->getString() ) {
|
||||
m_currentLight->mAttenuationQuadratic = floatVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::copyMeshes( aiScene *pScene ) {
|
||||
ai_assert( nullptr != pScene );
|
||||
|
||||
if( m_meshCache.empty() ) {
|
||||
return;
|
||||
}
|
||||
@@ -931,6 +1053,32 @@ void OpenGEXImporter::copyMeshes( aiScene *pScene ) {
|
||||
std::copy( m_meshCache.begin(), m_meshCache.end(), pScene->mMeshes );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::copyCameras( aiScene *pScene ) {
|
||||
ai_assert( nullptr != pScene );
|
||||
|
||||
if ( m_cameraCache.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
pScene->mNumCameras = m_cameraCache.size();
|
||||
pScene->mCameras = new aiCamera*[ pScene->mNumCameras ];
|
||||
std::copy( m_cameraCache.begin(), m_cameraCache.end(), pScene->mCameras );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::copyLights( aiScene *pScene ) {
|
||||
ai_assert( nullptr != pScene );
|
||||
|
||||
if ( m_lightCache.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
pScene->mNumLights = m_lightCache.size();
|
||||
pScene->mLights = new aiLight*[ pScene->mNumLights ];
|
||||
std::copy( m_lightCache.begin(), m_lightCache.end(), pScene->mLights );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::resolveReferences() {
|
||||
if( m_unresolvedRefStack.empty() ) {
|
||||
@@ -944,7 +1092,7 @@ void OpenGEXImporter::resolveReferences() {
|
||||
aiNode *node( currentRefInfo->m_node );
|
||||
if( RefInfo::MeshRef == currentRefInfo->m_type ) {
|
||||
for( size_t i = 0; i < currentRefInfo->m_Names.size(); i++ ) {
|
||||
const std::string &name(currentRefInfo->m_Names[ i ] );
|
||||
const std::string &name( currentRefInfo->m_Names[ i ] );
|
||||
ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) );
|
||||
if( m_mesh2refMap.end() != it ) {
|
||||
unsigned int meshIdx = m_mesh2refMap[ name ];
|
||||
@@ -962,7 +1110,7 @@ void OpenGEXImporter::resolveReferences() {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::createNodeTree( aiScene *pScene ) {
|
||||
if( NULL == m_root ) {
|
||||
if( nullptr == m_root ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -977,42 +1125,44 @@ void OpenGEXImporter::createNodeTree( aiScene *pScene ) {
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
|
||||
ai_assert( NULL != pScene );
|
||||
ai_assert( nullptr != pScene );
|
||||
|
||||
if( NULL != node ) {
|
||||
ChildInfo *info( NULL );
|
||||
if( m_nodeStack.empty() ) {
|
||||
node->mParent = pScene->mRootNode;
|
||||
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
||||
if( m_nodeChildMap.end() == it ) {
|
||||
info = new ChildInfo;
|
||||
m_root = info;
|
||||
m_nodeChildMap[ node->mParent ] = info;
|
||||
} else {
|
||||
info = it->second;
|
||||
}
|
||||
info->m_children.push_back( node );
|
||||
} else {
|
||||
aiNode *parent( m_nodeStack.back() );
|
||||
ai_assert( NULL != parent );
|
||||
node->mParent = parent;
|
||||
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
||||
if( m_nodeChildMap.end() == it ) {
|
||||
info = new ChildInfo;
|
||||
m_nodeChildMap[ node->mParent ] = info;
|
||||
} else {
|
||||
info = it->second;
|
||||
}
|
||||
info->m_children.push_back( node );
|
||||
}
|
||||
m_nodeStack.push_back( node );
|
||||
if ( NULL == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ChildInfo *info( nullptr );
|
||||
if( m_nodeStack.empty() ) {
|
||||
node->mParent = pScene->mRootNode;
|
||||
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
||||
if( m_nodeChildMap.end() == it ) {
|
||||
info = new ChildInfo;
|
||||
m_root = info;
|
||||
m_nodeChildMap[ node->mParent ] = info;
|
||||
} else {
|
||||
info = it->second;
|
||||
}
|
||||
info->m_children.push_back( node );
|
||||
} else {
|
||||
aiNode *parent( m_nodeStack.back() );
|
||||
ai_assert( nullptr != parent );
|
||||
node->mParent = parent;
|
||||
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
||||
if( m_nodeChildMap.end() == it ) {
|
||||
info = new ChildInfo;
|
||||
m_nodeChildMap[ node->mParent ] = info;
|
||||
} else {
|
||||
info = it->second;
|
||||
}
|
||||
info->m_children.push_back( node );
|
||||
}
|
||||
m_nodeStack.push_back( node );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
aiNode *OpenGEXImporter::popNode() {
|
||||
if( m_nodeStack.empty() ) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
aiNode *node( top() );
|
||||
@@ -1024,7 +1174,7 @@ aiNode *OpenGEXImporter::popNode() {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
aiNode *OpenGEXImporter::top() const {
|
||||
if( m_nodeStack.empty() ) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_nodeStack.back();
|
||||
|
||||
@@ -125,7 +125,12 @@ protected:
|
||||
void handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleColorNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleTextureNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleParamNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleAttenNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void copyMeshes( aiScene *pScene );
|
||||
void copyCameras( aiScene *pScene );
|
||||
void copyLights( aiScene *pScene );
|
||||
|
||||
void resolveReferences();
|
||||
void pushNode( aiNode *node, aiScene *pScene );
|
||||
aiNode *popNode();
|
||||
@@ -186,6 +191,8 @@ private:
|
||||
VertexContainer m_currentVertices;
|
||||
aiMesh *m_currentMesh;
|
||||
aiMaterial *m_currentMaterial;
|
||||
aiLight *m_currentLight;
|
||||
aiCamera *m_currentCamera;
|
||||
int m_tokenType;
|
||||
std::vector<aiMaterial*> m_materialCache;
|
||||
std::vector<aiCamera*> m_cameraCache;
|
||||
|
||||
@@ -309,10 +309,10 @@ void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
|
||||
|
||||
for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) {
|
||||
if (m->HasTextureCoords(c)) {
|
||||
mOutput.write(reinterpret_cast<const char*>(&m->mTextureCoords[c][i].x), 6);
|
||||
mOutput.write(reinterpret_cast<const char*>(&m->mTextureCoords[c][i].x), 8);
|
||||
}
|
||||
else {
|
||||
mOutput.write(reinterpret_cast<const char*>(&defaultUV.x), 6);
|
||||
mOutput.write(reinterpret_cast<const char*>(&defaultUV.x), 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -914,10 +914,12 @@ void SIBImporter::InternReadFile(const std::string& pFile,
|
||||
for (size_t n=0;n<sib.lights.size();n++)
|
||||
{
|
||||
aiLight* light = sib.lights[n];
|
||||
aiNode* node = new aiNode;
|
||||
root->mChildren[childIdx++] = node;
|
||||
node->mName = light->mName;
|
||||
node->mParent = root;
|
||||
if ( nullptr != light ) {
|
||||
aiNode* node = new aiNode;
|
||||
root->mChildren[ childIdx++ ] = node;
|
||||
node->mName = light->mName;
|
||||
node->mParent = root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -596,11 +596,6 @@ namespace STEP {
|
||||
LazyObject(DB& db, uint64_t id, uint64_t line, const char* type,const char* args);
|
||||
~LazyObject();
|
||||
|
||||
LazyObject( LazyObject const& ) = delete;
|
||||
LazyObject operator=( LazyObject const& ) = delete;
|
||||
LazyObject( LazyObject && ) = delete;
|
||||
LazyObject operator=( LazyObject && ) = delete;
|
||||
|
||||
public:
|
||||
|
||||
Object& operator * () {
|
||||
|
||||
@@ -1211,6 +1211,11 @@ void SceneCombiner::Copy (aiNode** _dest, const aiNode* src)
|
||||
// and reallocate all arrays
|
||||
GetArrayCopy( dest->mMeshes, dest->mNumMeshes );
|
||||
CopyPtrArray( dest->mChildren, src->mChildren,dest->mNumChildren);
|
||||
|
||||
// need to set the mParent fields to the created aiNode.
|
||||
for( unsigned int i = 0; i < dest->mNumChildren; i ++ ) {
|
||||
dest->mChildren[i]->mParent = dest;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -90,7 +90,7 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene)
|
||||
|
||||
// early out
|
||||
bool isNecessary = false;
|
||||
for( size_t a = 0; a < pScene->mNumMeshes; ++a)
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
|
||||
if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount )
|
||||
isNecessary = true;
|
||||
|
||||
@@ -107,7 +107,7 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene)
|
||||
// build a new array of meshes for the scene
|
||||
std::vector<aiMesh*> meshes;
|
||||
|
||||
for( size_t a = 0; a < pScene->mNumMeshes; ++a)
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
|
||||
{
|
||||
aiMesh* srcMesh = pScene->mMeshes[a];
|
||||
|
||||
@@ -118,9 +118,9 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene)
|
||||
if( !newMeshes.empty() )
|
||||
{
|
||||
// store new meshes and indices of the new meshes
|
||||
for( size_t b = 0; b < newMeshes.size(); ++b)
|
||||
for( unsigned int b = 0; b < newMeshes.size(); ++b)
|
||||
{
|
||||
mSubMeshIndices[a].push_back( meshes.size());
|
||||
mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
|
||||
meshes.push_back( newMeshes[b]);
|
||||
}
|
||||
|
||||
@@ -130,13 +130,13 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene)
|
||||
else
|
||||
{
|
||||
// Mesh is kept unchanged - store it's new place in the mesh array
|
||||
mSubMeshIndices[a].push_back( meshes.size());
|
||||
mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
|
||||
meshes.push_back( srcMesh);
|
||||
}
|
||||
}
|
||||
|
||||
// rebuild the scene's mesh array
|
||||
pScene->mNumMeshes = meshes.size();
|
||||
pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
||||
delete [] pScene->mMeshes;
|
||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||
std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
|
||||
@@ -157,33 +157,33 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
|
||||
// necessary optimisation: build a list of all affecting bones for each vertex
|
||||
// TODO: (thom) maybe add a custom allocator here to avoid allocating tens of thousands of small arrays
|
||||
typedef std::pair<size_t, float> BoneWeight;
|
||||
typedef std::pair<unsigned int, float> BoneWeight;
|
||||
std::vector< std::vector<BoneWeight> > vertexBones( pMesh->mNumVertices);
|
||||
for( size_t a = 0; a < pMesh->mNumBones; ++a)
|
||||
for( unsigned int a = 0; a < pMesh->mNumBones; ++a)
|
||||
{
|
||||
const aiBone* bone = pMesh->mBones[a];
|
||||
for( size_t b = 0; b < bone->mNumWeights; ++b)
|
||||
for( unsigned int b = 0; b < bone->mNumWeights; ++b)
|
||||
vertexBones[ bone->mWeights[b].mVertexId ].push_back( BoneWeight( a, bone->mWeights[b].mWeight));
|
||||
}
|
||||
|
||||
size_t numFacesHandled = 0;
|
||||
unsigned int numFacesHandled = 0;
|
||||
std::vector<bool> isFaceHandled( pMesh->mNumFaces, false);
|
||||
while( numFacesHandled < pMesh->mNumFaces )
|
||||
{
|
||||
// which bones are used in the current submesh
|
||||
size_t numBones = 0;
|
||||
unsigned int numBones = 0;
|
||||
std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
|
||||
// indices of the faces which are going to go into this submesh
|
||||
std::vector<size_t> subMeshFaces;
|
||||
std::vector<unsigned int> subMeshFaces;
|
||||
subMeshFaces.reserve( pMesh->mNumFaces);
|
||||
// accumulated vertex count of all the faces in this submesh
|
||||
size_t numSubMeshVertices = 0;
|
||||
unsigned int numSubMeshVertices = 0;
|
||||
// a small local array of new bones for the current face. State of all used bones for that face
|
||||
// can only be updated AFTER the face is completely analysed. Thanks to imre for the fix.
|
||||
std::vector<size_t> newBonesAtCurrentFace;
|
||||
std::vector<unsigned int> newBonesAtCurrentFace;
|
||||
|
||||
// add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
|
||||
for( size_t a = 0; a < pMesh->mNumFaces; ++a)
|
||||
for( unsigned int a = 0; a < pMesh->mNumFaces; ++a)
|
||||
{
|
||||
// skip if the face is already stored in a submesh
|
||||
if( isFaceHandled[a] )
|
||||
@@ -191,12 +191,12 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
|
||||
const aiFace& face = pMesh->mFaces[a];
|
||||
// check every vertex if its bones would still fit into the current submesh
|
||||
for( size_t b = 0; b < face.mNumIndices; ++b )
|
||||
for( unsigned int b = 0; b < face.mNumIndices; ++b )
|
||||
{
|
||||
const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
|
||||
for( size_t c = 0; c < vb.size(); ++c)
|
||||
for( unsigned int c = 0; c < vb.size(); ++c)
|
||||
{
|
||||
size_t boneIndex = vb[c].first;
|
||||
unsigned int boneIndex = vb[c].first;
|
||||
// if the bone is already used in this submesh, it's ok
|
||||
if( isBoneUsed[boneIndex] )
|
||||
continue;
|
||||
@@ -214,7 +214,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
// mark all new bones as necessary
|
||||
while( !newBonesAtCurrentFace.empty() )
|
||||
{
|
||||
size_t newIndex = newBonesAtCurrentFace.back();
|
||||
unsigned int newIndex = newBonesAtCurrentFace.back();
|
||||
newBonesAtCurrentFace.pop_back(); // this also avoids the deallocation which comes with a clear()
|
||||
if( isBoneUsed[newIndex] )
|
||||
continue;
|
||||
@@ -242,7 +242,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
|
||||
// create all the arrays for this mesh if the old mesh contained them
|
||||
newMesh->mNumVertices = numSubMeshVertices;
|
||||
newMesh->mNumFaces = subMeshFaces.size();
|
||||
newMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size());
|
||||
newMesh->mVertices = new aiVector3D[newMesh->mNumVertices];
|
||||
if( pMesh->HasNormals() )
|
||||
newMesh->mNormals = new aiVector3D[newMesh->mNumVertices];
|
||||
@@ -251,13 +251,13 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
newMesh->mTangents = new aiVector3D[newMesh->mNumVertices];
|
||||
newMesh->mBitangents = new aiVector3D[newMesh->mNumVertices];
|
||||
}
|
||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
||||
{
|
||||
if( pMesh->HasTextureCoords( a) )
|
||||
newMesh->mTextureCoords[a] = new aiVector3D[newMesh->mNumVertices];
|
||||
newMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
|
||||
}
|
||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
|
||||
{
|
||||
if( pMesh->HasVertexColors( a) )
|
||||
newMesh->mColors[a] = new aiColor4D[newMesh->mNumVertices];
|
||||
@@ -265,9 +265,9 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
|
||||
// and copy over the data, generating faces with linear indices along the way
|
||||
newMesh->mFaces = new aiFace[subMeshFaces.size()];
|
||||
size_t nvi = 0; // next vertex index
|
||||
std::vector<size_t> previousVertexIndices( numSubMeshVertices, std::numeric_limits<size_t>::max()); // per new vertex: its index in the source mesh
|
||||
for( size_t a = 0; a < subMeshFaces.size(); ++a )
|
||||
unsigned int nvi = 0; // next vertex index
|
||||
std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
|
||||
for( unsigned int a = 0; a < subMeshFaces.size(); ++a )
|
||||
{
|
||||
const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
|
||||
aiFace& dstFace = newMesh->mFaces[a];
|
||||
@@ -275,9 +275,9 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
|
||||
|
||||
// accumulate linearly all the vertices of the source face
|
||||
for( size_t b = 0; b < dstFace.mNumIndices; ++b )
|
||||
for( unsigned int b = 0; b < dstFace.mNumIndices; ++b )
|
||||
{
|
||||
size_t srcIndex = srcFace.mIndices[b];
|
||||
unsigned int srcIndex = srcFace.mIndices[b];
|
||||
dstFace.mIndices[b] = nvi;
|
||||
previousVertexIndices[nvi] = srcIndex;
|
||||
|
||||
@@ -289,12 +289,12 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
newMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
|
||||
newMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
|
||||
}
|
||||
for( size_t c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c )
|
||||
for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c )
|
||||
{
|
||||
if( pMesh->HasTextureCoords( c) )
|
||||
newMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
|
||||
}
|
||||
for( size_t c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c )
|
||||
for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c )
|
||||
{
|
||||
if( pMesh->HasVertexColors( c) )
|
||||
newMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
|
||||
@@ -310,8 +310,8 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
newMesh->mNumBones = 0;
|
||||
newMesh->mBones = new aiBone*[numBones];
|
||||
|
||||
std::vector<size_t> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<size_t>::max());
|
||||
for( size_t a = 0; a < pMesh->mNumBones; ++a )
|
||||
std::vector<unsigned int> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<unsigned int>::max());
|
||||
for( unsigned int a = 0; a < pMesh->mNumBones; ++a )
|
||||
{
|
||||
if( !isBoneUsed[a] )
|
||||
continue;
|
||||
@@ -329,21 +329,21 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
ai_assert( newMesh->mNumBones == numBones );
|
||||
|
||||
// iterate over all new vertices and count which bones affected its old vertex in the source mesh
|
||||
for( size_t a = 0; a < numSubMeshVertices; ++a )
|
||||
for( unsigned int a = 0; a < numSubMeshVertices; ++a )
|
||||
{
|
||||
size_t oldIndex = previousVertexIndices[a];
|
||||
unsigned int oldIndex = previousVertexIndices[a];
|
||||
const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[oldIndex];
|
||||
|
||||
for( size_t b = 0; b < bonesOnThisVertex.size(); ++b )
|
||||
for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b )
|
||||
{
|
||||
size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
||||
if( newBoneIndex != std::numeric_limits<size_t>::max() )
|
||||
unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
||||
if( newBoneIndex != std::numeric_limits<unsigned int>::max() )
|
||||
newMesh->mBones[newBoneIndex]->mNumWeights++;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate all bone weight arrays accordingly
|
||||
for( size_t a = 0; a < newMesh->mNumBones; ++a )
|
||||
for( unsigned int a = 0; a < newMesh->mNumBones; ++a )
|
||||
{
|
||||
aiBone* bone = newMesh->mBones[a];
|
||||
ai_assert( bone->mNumWeights > 0 );
|
||||
@@ -352,18 +352,18 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||
}
|
||||
|
||||
// now copy all the bone vertex weights for all the vertices which made it into the new submesh
|
||||
for( size_t a = 0; a < numSubMeshVertices; ++a)
|
||||
for( unsigned int a = 0; a < numSubMeshVertices; ++a)
|
||||
{
|
||||
// find the source vertex for it in the source mesh
|
||||
size_t previousIndex = previousVertexIndices[a];
|
||||
unsigned int previousIndex = previousVertexIndices[a];
|
||||
// these bones were affecting it
|
||||
const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[previousIndex];
|
||||
// all of the bones affecting it should be present in the new submesh, or else
|
||||
// the face it comprises shouldn't be present
|
||||
for( size_t b = 0; b < bonesOnThisVertex.size(); ++b)
|
||||
for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b)
|
||||
{
|
||||
size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
||||
ai_assert( newBoneIndex != std::numeric_limits<size_t>::max() );
|
||||
unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
||||
ai_assert( newBoneIndex != std::numeric_limits<unsigned int>::max() );
|
||||
aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
|
||||
newMesh->mBones[newBoneIndex]->mNumWeights++;
|
||||
|
||||
@@ -383,22 +383,22 @@ void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
|
||||
// rebuild the node's mesh index list
|
||||
if( pNode->mNumMeshes > 0 )
|
||||
{
|
||||
std::vector<size_t> newMeshList;
|
||||
for( size_t a = 0; a < pNode->mNumMeshes; ++a)
|
||||
std::vector<unsigned int> newMeshList;
|
||||
for( unsigned int a = 0; a < pNode->mNumMeshes; ++a)
|
||||
{
|
||||
size_t srcIndex = pNode->mMeshes[a];
|
||||
const std::vector<size_t>& replaceMeshes = mSubMeshIndices[srcIndex];
|
||||
unsigned int srcIndex = pNode->mMeshes[a];
|
||||
const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex];
|
||||
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
|
||||
}
|
||||
|
||||
delete pNode->mMeshes;
|
||||
pNode->mNumMeshes = newMeshList.size();
|
||||
pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
|
||||
pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
|
||||
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
|
||||
}
|
||||
|
||||
// do that also recursively for all children
|
||||
for( size_t a = 0; a < pNode->mNumChildren; ++a )
|
||||
for( unsigned int a = 0; a < pNode->mNumChildren; ++a )
|
||||
{
|
||||
UpdateNode( pNode->mChildren[a]);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
size_t mMaxBoneCount;
|
||||
|
||||
/// Per mesh index: Array of indices of the new submeshes.
|
||||
std::vector< std::vector<size_t> > mSubMeshIndices;
|
||||
std::vector< std::vector<unsigned int> > mSubMeshIndices;
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
@@ -355,6 +355,10 @@ namespace glTF
|
||||
{ return false; }
|
||||
|
||||
virtual ~Object() {}
|
||||
|
||||
//! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
|
||||
static const char* TranslateId(Asset& r, const char* id)
|
||||
{ return id; }
|
||||
};
|
||||
|
||||
|
||||
@@ -484,6 +488,8 @@ namespace glTF
|
||||
|
||||
bool IsSpecial() const
|
||||
{ return mIsSpecial; }
|
||||
|
||||
static const char* TranslateId(Asset& r, const char* id);
|
||||
};
|
||||
|
||||
|
||||
@@ -759,12 +765,14 @@ namespace glTF
|
||||
virtual void WriteObjects(AssetWriter& writer) = 0;
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
class LazyDict;
|
||||
|
||||
//! (Implemented in glTFAssetWriter.h)
|
||||
template<class T>
|
||||
void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
|
||||
|
||||
|
||||
//! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID
|
||||
//! It is the owner the loaded objects, so when it is destroyed it also deletes them
|
||||
|
||||
+28
-9
@@ -184,6 +184,8 @@ Ref<T> LazyDict<T>::Get(unsigned int i)
|
||||
template<class T>
|
||||
Ref<T> LazyDict<T>::Get(const char* id)
|
||||
{
|
||||
id = T::TranslateId(mAsset, id);
|
||||
|
||||
typename Dict::iterator it = mObjsById.find(id);
|
||||
if (it != mObjsById.end()) { // already created?
|
||||
return Ref<T>(mObjs, it->second);
|
||||
@@ -191,7 +193,7 @@ Ref<T> LazyDict<T>::Get(const char* id)
|
||||
|
||||
// read it from the JSON object
|
||||
if (!mDict) {
|
||||
return Ref<T>(); // section is missing
|
||||
throw DeadlyImportError("GLTF: Missing section \"" + std::string(mDictId) + "\"");
|
||||
}
|
||||
|
||||
Value::MemberIterator obj = mDict->FindMember(id);
|
||||
@@ -242,6 +244,15 @@ inline Buffer::Buffer()
|
||||
: byteLength(0), type(Type_arraybuffer), mIsSpecial(false)
|
||||
{ }
|
||||
|
||||
inline const char* Buffer::TranslateId(Asset& r, const char* id)
|
||||
{
|
||||
// Compatibility with old spec
|
||||
if (r.extensionsUsed.KHR_binary_glTF && strcmp(id, "KHR_binary_glTF") == 0) {
|
||||
return "binary_glTF";
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
inline void Buffer::Read(Value& obj, Asset& r)
|
||||
{
|
||||
@@ -266,10 +277,16 @@ inline void Buffer::Read(Value& obj, Asset& r)
|
||||
this->mData.reset(data);
|
||||
|
||||
if (statedLength > 0 && this->byteLength != statedLength) {
|
||||
throw DeadlyImportError("GLTF: buffer length mismatch");
|
||||
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + std::to_string(statedLength) +
|
||||
" bytes, but found " + std::to_string(dataURI.dataLength));
|
||||
}
|
||||
}
|
||||
else { // assume raw data
|
||||
if (statedLength != dataURI.dataLength) {
|
||||
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + std::to_string(statedLength) +
|
||||
" bytes, but found " + std::to_string(dataURI.dataLength));
|
||||
}
|
||||
|
||||
this->mData.reset(new uint8_t[dataURI.dataLength]);
|
||||
memcmp(dataURI.data, this->mData.get(), dataURI.dataLength);
|
||||
}
|
||||
@@ -589,14 +606,16 @@ inline void Material::Read(Value& material, Asset& r)
|
||||
else if (strcmp(t, "CONSTANT") == 0) technique = Technique_CONSTANT;
|
||||
}
|
||||
|
||||
ReadMaterialProperty(r, *ext, "ambient", this->ambient);
|
||||
ReadMaterialProperty(r, *ext, "diffuse", this->diffuse);
|
||||
ReadMaterialProperty(r, *ext, "specular", this->specular);
|
||||
if (Value* values = FindObject(*ext, "values")) {
|
||||
ReadMaterialProperty(r, *values, "ambient", this->ambient);
|
||||
ReadMaterialProperty(r, *values, "diffuse", this->diffuse);
|
||||
ReadMaterialProperty(r, *values, "specular", this->specular);
|
||||
|
||||
ReadMember(*ext, "doubleSided", doubleSided);
|
||||
ReadMember(*ext, "transparent", transparent);
|
||||
ReadMember(*ext, "transparency", transparency);
|
||||
ReadMember(*ext, "shininess", shininess);
|
||||
ReadMember(*values, "doubleSided", doubleSided);
|
||||
ReadMember(*values, "transparent", transparent);
|
||||
ReadMember(*values, "transparency", transparency);
|
||||
ReadMember(*values, "shininess", shininess);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ namespace glTF {
|
||||
}
|
||||
|
||||
|
||||
AssetWriter::AssetWriter(Asset& a)
|
||||
inline AssetWriter::AssetWriter(Asset& a)
|
||||
: mDoc()
|
||||
, mAsset(a)
|
||||
, mAl(mDoc.GetAllocator())
|
||||
@@ -326,7 +326,7 @@ namespace glTF {
|
||||
}
|
||||
}
|
||||
|
||||
void AssetWriter::WriteFile(const char* path)
|
||||
inline void AssetWriter::WriteFile(const char* path)
|
||||
{
|
||||
bool isBinary = mAsset.extensionsUsed.KHR_binary_glTF;
|
||||
|
||||
@@ -363,7 +363,7 @@ namespace glTF {
|
||||
}
|
||||
}
|
||||
|
||||
void AssetWriter::WriteBinaryData(IOStream* outfile, size_t sceneLength)
|
||||
inline void AssetWriter::WriteBinaryData(IOStream* outfile, size_t sceneLength)
|
||||
{
|
||||
//
|
||||
// write the body data
|
||||
@@ -413,7 +413,7 @@ namespace glTF {
|
||||
}
|
||||
|
||||
|
||||
void AssetWriter::WriteMetadata()
|
||||
inline void AssetWriter::WriteMetadata()
|
||||
{
|
||||
Value asset;
|
||||
asset.SetObject();
|
||||
@@ -425,7 +425,7 @@ namespace glTF {
|
||||
mDoc.AddMember("asset", asset, mAl);
|
||||
}
|
||||
|
||||
void AssetWriter::WriteExtensionsUsed()
|
||||
inline void AssetWriter::WriteExtensionsUsed()
|
||||
{
|
||||
Value exts;
|
||||
exts.SetArray();
|
||||
|
||||
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
||||
|
||||
#include "glTFExporter.h"
|
||||
|
||||
#include "Exceptional.h"
|
||||
#include "StringComparison.h"
|
||||
#include "ByteSwapper.h"
|
||||
@@ -54,7 +55,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/material.h>
|
||||
#include <assimp/scene.h>
|
||||
|
||||
#include <memory>
|
||||
#include <memory>
|
||||
|
||||
#include "glTFAssetWriter.h"
|
||||
|
||||
+25
-5
@@ -53,6 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "MakeVerboseFormat.h"
|
||||
|
||||
#include "glTFAsset.h"
|
||||
// This is included here so WriteLazyDict<T>'s definition is found.
|
||||
#include "glTFAssetWriter.h"
|
||||
|
||||
using namespace Assimp;
|
||||
using namespace glTF;
|
||||
@@ -212,14 +214,14 @@ void glTFImporter::ImportMaterials(glTF::Asset& r)
|
||||
}
|
||||
|
||||
|
||||
inline void SetFace(aiFace& face, int a)
|
||||
static inline void SetFace(aiFace& face, int a)
|
||||
{
|
||||
face.mNumIndices = 1;
|
||||
face.mIndices = new unsigned int[1];
|
||||
face.mIndices[0] = a;
|
||||
}
|
||||
|
||||
inline void SetFace(aiFace& face, int a, int b)
|
||||
static inline void SetFace(aiFace& face, int a, int b)
|
||||
{
|
||||
face.mNumIndices = 2;
|
||||
face.mIndices = new unsigned int[2];
|
||||
@@ -227,7 +229,7 @@ inline void SetFace(aiFace& face, int a, int b)
|
||||
face.mIndices[1] = b;
|
||||
}
|
||||
|
||||
inline void SetFace(aiFace& face, int a, int b, int c)
|
||||
static inline void SetFace(aiFace& face, int a, int b, int c)
|
||||
{
|
||||
face.mNumIndices = 3;
|
||||
face.mIndices = new unsigned int[3];
|
||||
@@ -236,6 +238,18 @@ inline void SetFace(aiFace& face, int a, int b, int c)
|
||||
face.mIndices[2] = c;
|
||||
}
|
||||
|
||||
static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
|
||||
{
|
||||
for (unsigned i = 0; i < nFaces; ++i) {
|
||||
for (unsigned j = 0; j < faces[i].mNumIndices; ++j) {
|
||||
unsigned idx = faces[i].mIndices[j];
|
||||
if (idx >= nVerts)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||
{
|
||||
std::vector<aiMesh*> meshes;
|
||||
@@ -292,6 +306,11 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||
for (size_t tc = 0; tc < attr.texcoord.size() && tc <= AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
||||
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
|
||||
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
|
||||
|
||||
aiVector3D* values = aim->mTextureCoords[tc];
|
||||
for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
|
||||
values[i].y = 1 - values[i].y; // Flip Y coords
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -302,7 +321,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||
unsigned int count = prim.indices->count;
|
||||
|
||||
Accessor::Indexer data = prim.indices->GetIndexer();
|
||||
assert(data.IsValid());
|
||||
ai_assert(data.IsValid());
|
||||
|
||||
switch (prim.mode) {
|
||||
case PrimitiveMode_POINTS: {
|
||||
@@ -367,6 +386,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||
if (faces) {
|
||||
aim->mFaces = faces;
|
||||
aim->mNumFaces = nFaces;
|
||||
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,7 +484,7 @@ aiNode* ImportNode(aiScene* pScene, glTF::Asset& r, std::vector<unsigned int>& m
|
||||
}
|
||||
}
|
||||
|
||||
aiMatrix4x4 matrix = ainode->mTransformation;
|
||||
aiMatrix4x4& matrix = ainode->mTransformation;
|
||||
if (node.matrix.isPresent) {
|
||||
CopyValue(node.matrix.value, matrix);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ enum aiLightSourceType
|
||||
aiLightSource_SPOT = 0x3,
|
||||
|
||||
//! The generic light level of the world, including the bounces
|
||||
//! of all other lightsources.
|
||||
//! of all other light sources.
|
||||
//! Typically, there's at most one ambient light in a scene.
|
||||
//! This light type doesn't have a valid position, direction, or
|
||||
//! other properties, just a color.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
Metric (key = "distance") {float {1.0}}
|
||||
Metric (key = "angle") {float {1.0}}
|
||||
Metric (key = "time") {float {1.0}}
|
||||
Metric (key = "up") {string {"z"}}
|
||||
|
||||
GeometryNode $node1
|
||||
{
|
||||
Name {string {"Cube"}}
|
||||
ObjectRef {ref {$geometry1}}
|
||||
MaterialRef (index = 0) {ref {$material1}}
|
||||
|
||||
Transform
|
||||
{
|
||||
float[16]
|
||||
{
|
||||
{1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LightNode $node2
|
||||
{
|
||||
Name {string {"Lamp"}}
|
||||
ObjectRef {ref {$light1}}
|
||||
|
||||
Transform
|
||||
{
|
||||
float[16]
|
||||
{
|
||||
{-0.29086464643478394, 0.9551711678504944, -0.05518905818462372, 0.0,
|
||||
-0.7711008191108704, -0.1998833566904068, 0.6045247316360474, 0.0,
|
||||
0.5663931965827942, 0.21839119493961334, 0.7946722507476807, 0.0,
|
||||
4.076245307922363, 1.0054539442062378, 5.903861999511719, 1.0}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CameraNode $node3
|
||||
{
|
||||
Name {string {"Camera"}}
|
||||
ObjectRef {ref {$camera1}}
|
||||
|
||||
Transform
|
||||
{
|
||||
float[16]
|
||||
{
|
||||
{0.6858805418014526, 0.7276337742805481, -0.010816780850291252, 0.0,
|
||||
-0.31737011671066284, 0.31246861815452576, 0.8953432440757751, 0.0,
|
||||
0.6548618674278259, -0.6106656193733215, 0.4452453553676605, 0.0,
|
||||
7.481131553649902, -6.5076398849487305, 5.34366512298584, 1.0}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GeometryObject $geometry1 // Cube
|
||||
{
|
||||
Mesh (primitive = "triangles")
|
||||
{
|
||||
VertexArray (attrib = "position")
|
||||
{
|
||||
float[3] // 24
|
||||
{
|
||||
{1.0, 0.9999999403953552, -1.0}, {1.0, -1.0, -1.0}, {-1.0000001192092896, -0.9999998211860657, -1.0}, {-0.9999996423721313, 1.0000003576278687, -1.0}, {1.0000004768371582, 0.999999463558197, 1.0}, {-0.9999999403953552, 1.0, 1.0}, {-1.0000003576278687, -0.9999996423721313, 1.0}, {0.9999993443489075, -1.0000005960464478, 1.0},
|
||||
{1.0, 0.9999999403953552, -1.0}, {1.0000004768371582, 0.999999463558197, 1.0}, {0.9999993443489075, -1.0000005960464478, 1.0}, {1.0, -1.0, -1.0}, {1.0, -1.0, -1.0}, {0.9999993443489075, -1.0000005960464478, 1.0}, {-1.0000003576278687, -0.9999996423721313, 1.0}, {-1.0000001192092896, -0.9999998211860657, -1.0},
|
||||
{-1.0000001192092896, -0.9999998211860657, -1.0}, {-1.0000003576278687, -0.9999996423721313, 1.0}, {-0.9999999403953552, 1.0, 1.0}, {-0.9999996423721313, 1.0000003576278687, -1.0}, {1.0000004768371582, 0.999999463558197, 1.0}, {1.0, 0.9999999403953552, -1.0}, {-0.9999996423721313, 1.0000003576278687, -1.0}, {-0.9999999403953552, 1.0, 1.0}
|
||||
}
|
||||
}
|
||||
|
||||
VertexArray (attrib = "normal")
|
||||
{
|
||||
float[3] // 24
|
||||
{
|
||||
{0.0, 0.0, -1.0}, {0.0, 0.0, -1.0}, {0.0, 0.0, -1.0}, {0.0, 0.0, -1.0}, {0.0, -0.0, 1.0}, {0.0, -0.0, 1.0}, {0.0, -0.0, 1.0}, {0.0, -0.0, 1.0},
|
||||
{1.0, -2.8312206268310547e-07, 4.470341252726939e-08}, {1.0, -2.8312206268310547e-07, 4.470341252726939e-08}, {1.0, -2.8312206268310547e-07, 4.470341252726939e-08}, {1.0, -2.8312206268310547e-07, 4.470341252726939e-08}, {-2.8312206268310547e-07, -1.0, -1.0430819230577981e-07}, {-2.8312206268310547e-07, -1.0, -1.0430819230577981e-07}, {-2.8312206268310547e-07, -1.0, -1.0430819230577981e-07}, {-2.8312206268310547e-07, -1.0, -1.0430819230577981e-07},
|
||||
{-1.0, 2.2351744632942427e-07, -1.341104365337742e-07}, {-1.0, 2.2351744632942427e-07, -1.341104365337742e-07}, {-1.0, 2.2351744632942427e-07, -1.341104365337742e-07}, {-1.0, 2.2351744632942427e-07, -1.341104365337742e-07}, {2.384185791015625e-07, 1.0, 2.086162567138672e-07}, {2.384185791015625e-07, 1.0, 2.086162567138672e-07}, {2.384185791015625e-07, 1.0, 2.086162567138672e-07}, {2.384185791015625e-07, 1.0, 2.086162567138672e-07}
|
||||
}
|
||||
}
|
||||
|
||||
IndexArray
|
||||
{
|
||||
unsigned_int32[3] // 12
|
||||
{
|
||||
{0, 1, 2}, {0, 2, 3}, {4, 5, 6}, {4, 6, 7}, {8, 9, 10}, {8, 10, 11}, {12, 13, 14}, {12, 14, 15}, {16, 17, 18}, {16, 18, 19}, {20, 21, 22}, {20, 22, 23}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LightObject $light1 (type = "point") // Lamp
|
||||
{
|
||||
Color (attrib = "light") {float[3] {{1.0, 1.0, 1.0}}}
|
||||
|
||||
Atten (curve = "inverse_square")
|
||||
{
|
||||
Param (attrib = "scale") {float {5.47722400800463}}
|
||||
}
|
||||
}
|
||||
|
||||
CameraObject $camera1 // Camera
|
||||
{
|
||||
Param (attrib = "fov") {float {0.8575560450553894}}
|
||||
Param (attrib = "near") {float {0.10000000149011612}}
|
||||
Param (attrib = "far") {float {100.0}}
|
||||
}
|
||||
|
||||
Material $material1
|
||||
{
|
||||
Name {string {"Material"}}
|
||||
|
||||
Color (attrib = "diffuse") {float[3] {{0.6400000190734865, 0.6400000190734865, 0.6400000190734865}}}
|
||||
Color (attrib = "specular") {float[3] {{0.5, 0.5, 0.5}}}
|
||||
Param (attrib = "specular_power") {float {50}}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 840 B |
@@ -0,0 +1,269 @@
|
||||
{
|
||||
"accessors": {
|
||||
"accessor_21": {
|
||||
"bufferView": "bufferView_29",
|
||||
"byteOffset": 0,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 36,
|
||||
"type": "SCALAR"
|
||||
},
|
||||
"accessor_23": {
|
||||
"bufferView": "bufferView_30",
|
||||
"byteOffset": 0,
|
||||
"byteStride": 12,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"min": [
|
||||
-0.5,
|
||||
-0.5,
|
||||
-0.5
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_25": {
|
||||
"bufferView": "bufferView_30",
|
||||
"byteOffset": 288,
|
||||
"byteStride": 12,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"min": [
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_27": {
|
||||
"bufferView": "bufferView_30",
|
||||
"byteOffset": 576,
|
||||
"byteStride": 8,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
6,
|
||||
1
|
||||
],
|
||||
"min": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"type": "VEC2"
|
||||
}
|
||||
},
|
||||
"animations": {},
|
||||
"asset": {
|
||||
"generator": "collada2gltf@027f74366341d569dea42e9a68b7104cc3892054",
|
||||
"premultipliedAlpha": true,
|
||||
"profile": {
|
||||
"api": "WebGL",
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"version": "1.0"
|
||||
},
|
||||
"bufferViews": {
|
||||
"bufferView_29": {
|
||||
"buffer": "BoxTextured",
|
||||
"byteLength": 72,
|
||||
"byteOffset": 0,
|
||||
"target": 34963
|
||||
},
|
||||
"bufferView_30": {
|
||||
"buffer": "BoxTextured",
|
||||
"byteLength": 768,
|
||||
"byteOffset": 72,
|
||||
"target": 34962
|
||||
}
|
||||
},
|
||||
"buffers": {
|
||||
"BoxTextured": {
|
||||
"byteLength": 840,
|
||||
"type": "arraybuffer",
|
||||
"uri": "BoxTextured.bin"
|
||||
}
|
||||
},
|
||||
"extensionsUsed": [
|
||||
"KHR_materials_common"
|
||||
],
|
||||
"images": {
|
||||
"Image0001": {
|
||||
"name": "Image0001",
|
||||
"uri": "CesiumLogoFlat.png"
|
||||
}
|
||||
},
|
||||
"materials": {
|
||||
"Effect-Texture": {
|
||||
"extensions": {
|
||||
"KHR_materials_common": {
|
||||
"doubleSided": false,
|
||||
"jointCount": 0,
|
||||
"technique": "PHONG",
|
||||
"transparent": false,
|
||||
"values": {
|
||||
"diffuse": "texture_Image0001",
|
||||
"shininess": 256,
|
||||
"specular": [
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
1
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Texture"
|
||||
}
|
||||
},
|
||||
"meshes": {
|
||||
"Geometry-mesh002": {
|
||||
"name": "Mesh",
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"NORMAL": "accessor_25",
|
||||
"POSITION": "accessor_23",
|
||||
"TEXCOORD_0": "accessor_27"
|
||||
},
|
||||
"indices": "accessor_21",
|
||||
"material": "Effect-Texture",
|
||||
"mode": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"Geometry-mesh002Node": {
|
||||
"children": [],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"meshes": [
|
||||
"Geometry-mesh002"
|
||||
],
|
||||
"name": "Mesh"
|
||||
},
|
||||
"groupLocator030Node": {
|
||||
"children": [
|
||||
"txtrLocator026Node"
|
||||
],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"name": "Texture_Group"
|
||||
},
|
||||
"node_3": {
|
||||
"children": [
|
||||
"Geometry-mesh002Node",
|
||||
"groupLocator030Node"
|
||||
],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"name": "Y_UP_Transform"
|
||||
},
|
||||
"txtrLocator026Node": {
|
||||
"children": [],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"name": "Cesium_Logo_Flat__Image___Texture_"
|
||||
}
|
||||
},
|
||||
"samplers": {
|
||||
"sampler_0": {
|
||||
"magFilter": 9729,
|
||||
"minFilter": 9987,
|
||||
"wrapS": 10497,
|
||||
"wrapT": 10497
|
||||
}
|
||||
},
|
||||
"scene": "defaultScene",
|
||||
"scenes": {
|
||||
"defaultScene": {
|
||||
"nodes": [
|
||||
"node_3"
|
||||
]
|
||||
}
|
||||
},
|
||||
"skins": {},
|
||||
"textures": {
|
||||
"texture_Image0001": {
|
||||
"format": 6408,
|
||||
"internalFormat": 6408,
|
||||
"sampler": "sampler_0",
|
||||
"source": "Image0001",
|
||||
"target": 3553,
|
||||
"type": 5121
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 840 B |
@@ -0,0 +1,339 @@
|
||||
{
|
||||
"accessors": {
|
||||
"accessor_21": {
|
||||
"bufferView": "bufferView_29",
|
||||
"byteOffset": 0,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 36,
|
||||
"type": "SCALAR"
|
||||
},
|
||||
"accessor_23": {
|
||||
"bufferView": "bufferView_30",
|
||||
"byteOffset": 0,
|
||||
"byteStride": 12,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"min": [
|
||||
-0.5,
|
||||
-0.5,
|
||||
-0.5
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_25": {
|
||||
"bufferView": "bufferView_30",
|
||||
"byteOffset": 288,
|
||||
"byteStride": 12,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"min": [
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_27": {
|
||||
"bufferView": "bufferView_30",
|
||||
"byteOffset": 576,
|
||||
"byteStride": 8,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
6,
|
||||
1
|
||||
],
|
||||
"min": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"type": "VEC2"
|
||||
}
|
||||
},
|
||||
"animations": {},
|
||||
"asset": {
|
||||
"generator": "collada2gltf@027f74366341d569dea42e9a68b7104cc3892054",
|
||||
"premultipliedAlpha": true,
|
||||
"profile": {
|
||||
"api": "WebGL",
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"version": "1.0"
|
||||
},
|
||||
"bufferViews": {
|
||||
"bufferView_29": {
|
||||
"buffer": "BoxTextured",
|
||||
"byteLength": 72,
|
||||
"byteOffset": 0,
|
||||
"target": 34963
|
||||
},
|
||||
"bufferView_30": {
|
||||
"buffer": "BoxTextured",
|
||||
"byteLength": 768,
|
||||
"byteOffset": 72,
|
||||
"target": 34962
|
||||
}
|
||||
},
|
||||
"buffers": {
|
||||
"BoxTextured": {
|
||||
"byteLength": 840,
|
||||
"type": "arraybuffer",
|
||||
"uri": "BoxTextured.bin"
|
||||
}
|
||||
},
|
||||
"images": {
|
||||
"Image0001": {
|
||||
"name": "Image0001",
|
||||
"uri": "CesiumLogoFlat.png"
|
||||
}
|
||||
},
|
||||
"materials": {
|
||||
"Effect-Texture": {
|
||||
"name": "Texture",
|
||||
"technique": "technique0",
|
||||
"values": {
|
||||
"diffuse": "texture_Image0001",
|
||||
"shininess": 256,
|
||||
"specular": [
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
1
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"meshes": {
|
||||
"Geometry-mesh002": {
|
||||
"name": "Mesh",
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"NORMAL": "accessor_25",
|
||||
"POSITION": "accessor_23",
|
||||
"TEXCOORD_0": "accessor_27"
|
||||
},
|
||||
"indices": "accessor_21",
|
||||
"material": "Effect-Texture",
|
||||
"mode": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"Geometry-mesh002Node": {
|
||||
"children": [],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"meshes": [
|
||||
"Geometry-mesh002"
|
||||
],
|
||||
"name": "Mesh"
|
||||
},
|
||||
"groupLocator030Node": {
|
||||
"children": [
|
||||
"txtrLocator026Node"
|
||||
],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"name": "Texture_Group"
|
||||
},
|
||||
"node_3": {
|
||||
"children": [
|
||||
"Geometry-mesh002Node",
|
||||
"groupLocator030Node"
|
||||
],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"name": "Y_UP_Transform"
|
||||
},
|
||||
"txtrLocator026Node": {
|
||||
"children": [],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"name": "Cesium_Logo_Flat__Image___Texture_"
|
||||
}
|
||||
},
|
||||
"programs": {
|
||||
"program_0": {
|
||||
"attributes": [
|
||||
"a_normal",
|
||||
"a_position",
|
||||
"a_texcoord0"
|
||||
],
|
||||
"fragmentShader": "BoxTextured0FS",
|
||||
"vertexShader": "BoxTextured0VS"
|
||||
}
|
||||
},
|
||||
"samplers": {
|
||||
"sampler_0": {
|
||||
"magFilter": 9729,
|
||||
"minFilter": 9987,
|
||||
"wrapS": 10497,
|
||||
"wrapT": 10497
|
||||
}
|
||||
},
|
||||
"scene": "defaultScene",
|
||||
"scenes": {
|
||||
"defaultScene": {
|
||||
"nodes": [
|
||||
"node_3"
|
||||
]
|
||||
}
|
||||
},
|
||||
"shaders": {
|
||||
"BoxTextured0FS": {
|
||||
"type": 35632,
|
||||
"uri": "BoxTextured0FS.glsl"
|
||||
},
|
||||
"BoxTextured0VS": {
|
||||
"type": 35633,
|
||||
"uri": "BoxTextured0VS.glsl"
|
||||
}
|
||||
},
|
||||
"skins": {},
|
||||
"techniques": {
|
||||
"technique0": {
|
||||
"attributes": {
|
||||
"a_normal": "normal",
|
||||
"a_position": "position",
|
||||
"a_texcoord0": "texcoord0"
|
||||
},
|
||||
"parameters": {
|
||||
"diffuse": {
|
||||
"type": 35678
|
||||
},
|
||||
"modelViewMatrix": {
|
||||
"semantic": "MODELVIEW",
|
||||
"type": 35676
|
||||
},
|
||||
"normal": {
|
||||
"semantic": "NORMAL",
|
||||
"type": 35665
|
||||
},
|
||||
"normalMatrix": {
|
||||
"semantic": "MODELVIEWINVERSETRANSPOSE",
|
||||
"type": 35675
|
||||
},
|
||||
"position": {
|
||||
"semantic": "POSITION",
|
||||
"type": 35665
|
||||
},
|
||||
"projectionMatrix": {
|
||||
"semantic": "PROJECTION",
|
||||
"type": 35676
|
||||
},
|
||||
"shininess": {
|
||||
"type": 5126
|
||||
},
|
||||
"specular": {
|
||||
"type": 35666
|
||||
},
|
||||
"texcoord0": {
|
||||
"semantic": "TEXCOORD_0",
|
||||
"type": 35664
|
||||
}
|
||||
},
|
||||
"program": "program_0",
|
||||
"states": {
|
||||
"enable": [
|
||||
2929,
|
||||
2884
|
||||
]
|
||||
},
|
||||
"uniforms": {
|
||||
"u_diffuse": "diffuse",
|
||||
"u_modelViewMatrix": "modelViewMatrix",
|
||||
"u_normalMatrix": "normalMatrix",
|
||||
"u_projectionMatrix": "projectionMatrix",
|
||||
"u_shininess": "shininess",
|
||||
"u_specular": "specular"
|
||||
}
|
||||
}
|
||||
},
|
||||
"textures": {
|
||||
"texture_Image0001": {
|
||||
"format": 6408,
|
||||
"internalFormat": 6408,
|
||||
"sampler": "sampler_0",
|
||||
"source": "Image0001",
|
||||
"target": 3553,
|
||||
"type": 5121
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
precision highp float;
|
||||
varying vec3 v_normal;
|
||||
varying vec2 v_texcoord0;
|
||||
uniform sampler2D u_diffuse;
|
||||
uniform vec4 u_specular;
|
||||
uniform float u_shininess;
|
||||
void main(void) {
|
||||
vec3 normal = normalize(v_normal);
|
||||
vec4 color = vec4(0., 0., 0., 0.);
|
||||
vec4 diffuse = vec4(0., 0., 0., 1.);
|
||||
vec4 specular;
|
||||
diffuse = texture2D(u_diffuse, v_texcoord0);
|
||||
specular = u_specular;
|
||||
diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
|
||||
color.xyz += diffuse.xyz;
|
||||
color = vec4(color.rgb * diffuse.a, diffuse.a);
|
||||
gl_FragColor = color;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
precision highp float;
|
||||
attribute vec3 a_position;
|
||||
attribute vec3 a_normal;
|
||||
varying vec3 v_normal;
|
||||
uniform mat3 u_normalMatrix;
|
||||
uniform mat4 u_modelViewMatrix;
|
||||
uniform mat4 u_projectionMatrix;
|
||||
attribute vec2 a_texcoord0;
|
||||
varying vec2 v_texcoord0;
|
||||
void main(void) {
|
||||
vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
|
||||
v_normal = u_normalMatrix * a_normal;
|
||||
v_texcoord0 = a_texcoord0;
|
||||
gl_Position = u_projectionMatrix * pos;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 648 B |
@@ -0,0 +1,17 @@
|
||||
precision highp float;
|
||||
varying vec3 v_normal;
|
||||
uniform vec4 u_diffuse;
|
||||
uniform vec4 u_specular;
|
||||
uniform float u_shininess;
|
||||
void main(void) {
|
||||
vec3 normal = normalize(v_normal);
|
||||
vec4 color = vec4(0., 0., 0., 0.);
|
||||
vec4 diffuse = vec4(0., 0., 0., 1.);
|
||||
vec4 specular;
|
||||
diffuse = u_diffuse;
|
||||
specular = u_specular;
|
||||
diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
|
||||
color.xyz += diffuse.xyz;
|
||||
color = vec4(color.rgb * diffuse.a, diffuse.a);
|
||||
gl_FragColor = color;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
precision highp float;
|
||||
attribute vec3 a_position;
|
||||
attribute vec3 a_normal;
|
||||
varying vec3 v_normal;
|
||||
uniform mat3 u_normalMatrix;
|
||||
uniform mat4 u_modelViewMatrix;
|
||||
uniform mat4 u_projectionMatrix;
|
||||
void main(void) {
|
||||
vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
|
||||
v_normal = u_normalMatrix * a_normal;
|
||||
gl_Position = u_projectionMatrix * pos;
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
{
|
||||
"accessors": {
|
||||
"accessor_21": {
|
||||
"bufferView": "bufferView_29",
|
||||
"byteOffset": 0,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 36,
|
||||
"type": "SCALAR"
|
||||
},
|
||||
"accessor_23": {
|
||||
"bufferView": "bufferView_30",
|
||||
"byteOffset": 0,
|
||||
"byteStride": 12,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"min": [
|
||||
-0.5,
|
||||
-0.5,
|
||||
-0.5
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_25": {
|
||||
"bufferView": "bufferView_30",
|
||||
"byteOffset": 288,
|
||||
"byteStride": 12,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"min": [
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"type": "VEC3"
|
||||
}
|
||||
},
|
||||
"animations": {},
|
||||
"asset": {
|
||||
"generator": "collada2gltf@027f74366341d569dea42e9a68b7104cc3892054",
|
||||
"premultipliedAlpha": true,
|
||||
"profile": {
|
||||
"api": "WebGL",
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"version": "1.0"
|
||||
},
|
||||
"bufferViews": {
|
||||
"bufferView_29": {
|
||||
"buffer": "Box",
|
||||
"byteLength": 72,
|
||||
"byteOffset": 0,
|
||||
"target": 34963
|
||||
},
|
||||
"bufferView_30": {
|
||||
"buffer": "Box",
|
||||
"byteLength": 576,
|
||||
"byteOffset": 72,
|
||||
"target": 34962
|
||||
}
|
||||
},
|
||||
"buffers": {
|
||||
"Box": {
|
||||
"byteLength": 648,
|
||||
"type": "arraybuffer",
|
||||
"uri": "Box.bin"
|
||||
}
|
||||
},
|
||||
"materials": {
|
||||
"Effect-Red": {
|
||||
"name": "Red",
|
||||
"technique": "technique0",
|
||||
"values": {
|
||||
"diffuse": [
|
||||
0.8,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"shininess": 256,
|
||||
"specular": [
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
1
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"meshes": {
|
||||
"Geometry-mesh002": {
|
||||
"name": "Mesh",
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"NORMAL": "accessor_25",
|
||||
"POSITION": "accessor_23"
|
||||
},
|
||||
"indices": "accessor_21",
|
||||
"material": "Effect-Red",
|
||||
"mode": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"BottomBox": {
|
||||
"children": [],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"meshes": [
|
||||
"Geometry-mesh002"
|
||||
],
|
||||
"name": "BottomBox"
|
||||
},
|
||||
"TopBox": {
|
||||
"children": [],
|
||||
"matrix": [
|
||||
0.5,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0.5,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0.5,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"meshes": [
|
||||
"Geometry-mesh002"
|
||||
],
|
||||
"name": "TopBox"
|
||||
},
|
||||
"node_1": {
|
||||
"children": [
|
||||
"BottomBox",
|
||||
"TopBox"
|
||||
],
|
||||
"matrix": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"name": "Y_UP_Transform"
|
||||
}
|
||||
},
|
||||
"programs": {
|
||||
"program_0": {
|
||||
"attributes": [
|
||||
"a_normal",
|
||||
"a_position"
|
||||
],
|
||||
"fragmentShader": "Box0FS",
|
||||
"vertexShader": "Box0VS"
|
||||
}
|
||||
},
|
||||
"scene": "defaultScene",
|
||||
"scenes": {
|
||||
"defaultScene": {
|
||||
"nodes": [
|
||||
"node_1"
|
||||
]
|
||||
}
|
||||
},
|
||||
"shaders": {
|
||||
"Box0FS": {
|
||||
"type": 35632,
|
||||
"uri": "Box0FS.glsl"
|
||||
},
|
||||
"Box0VS": {
|
||||
"type": 35633,
|
||||
"uri": "Box0VS.glsl"
|
||||
}
|
||||
},
|
||||
"skins": {},
|
||||
"techniques": {
|
||||
"technique0": {
|
||||
"attributes": {
|
||||
"a_normal": "normal",
|
||||
"a_position": "position"
|
||||
},
|
||||
"parameters": {
|
||||
"diffuse": {
|
||||
"type": 35666
|
||||
},
|
||||
"modelViewMatrix": {
|
||||
"semantic": "MODELVIEW",
|
||||
"type": 35676
|
||||
},
|
||||
"normal": {
|
||||
"semantic": "NORMAL",
|
||||
"type": 35665
|
||||
},
|
||||
"normalMatrix": {
|
||||
"semantic": "MODELVIEWINVERSETRANSPOSE",
|
||||
"type": 35675
|
||||
},
|
||||
"position": {
|
||||
"semantic": "POSITION",
|
||||
"type": 35665
|
||||
},
|
||||
"projectionMatrix": {
|
||||
"semantic": "PROJECTION",
|
||||
"type": 35676
|
||||
},
|
||||
"shininess": {
|
||||
"type": 5126
|
||||
},
|
||||
"specular": {
|
||||
"type": 35666
|
||||
}
|
||||
},
|
||||
"program": "program_0",
|
||||
"states": {
|
||||
"enable": [
|
||||
2929,
|
||||
2884
|
||||
]
|
||||
},
|
||||
"uniforms": {
|
||||
"u_diffuse": "diffuse",
|
||||
"u_modelViewMatrix": "modelViewMatrix",
|
||||
"u_normalMatrix": "normalMatrix",
|
||||
"u_projectionMatrix": "projectionMatrix",
|
||||
"u_shininess": "shininess",
|
||||
"u_specular": "specular"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -53,7 +53,7 @@ import os
|
||||
# pond.0.ply - loads with 40k identical triangles, causing postprocessing
|
||||
# to have quadratic runtime.
|
||||
# -------------------------------------------------------------------------------
|
||||
files_to_ignore = ["pond.0.ply", "Example.ogex"]
|
||||
files_to_ignore = ["pond.0.ply"]
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
# List of file extensions to be excluded from the regression suite
|
||||
|
||||
Reference in New Issue
Block a user