diff options
Diffstat (limited to 'libs/assimp/code/AssetLib/OpenGEX/OpenGEXImporter.cpp')
-rw-r--r-- | libs/assimp/code/AssetLib/OpenGEX/OpenGEXImporter.cpp | 1326 |
1 files changed, 0 insertions, 1326 deletions
diff --git a/libs/assimp/code/AssetLib/OpenGEX/OpenGEXImporter.cpp b/libs/assimp/code/AssetLib/OpenGEX/OpenGEXImporter.cpp deleted file mode 100644 index c8e4793..0000000 --- a/libs/assimp/code/AssetLib/OpenGEX/OpenGEXImporter.cpp +++ /dev/null @@ -1,1326 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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 ASSIMP_BUILD_NO_OPENGEX_IMPORTER - -#include "AssetLib/OpenGEX/OpenGEXImporter.h" -#include "PostProcessing/MakeVerboseFormat.h" - -#include <assimp/DefaultIOSystem.h> -#include <assimp/StringComparison.h> -#include <assimp/StringUtils.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/ai_assert.h> -#include <assimp/importerdesc.h> -#include <assimp/scene.h> -#include <openddlparser/OpenDDLParser.h> - -static const aiImporterDesc desc = { - "Open Game Engine Exchange", - "", - "", - "", - aiImporterFlags_SupportTextFlavour, - 0, - 0, - 0, - 0, - "ogex" -}; - -namespace Grammar { - static const char* MetricType = "Metric"; - static const char *Metric_DistanceType = "distance"; - static const char *Metric_AngleType = "angle"; - static const char *Metric_TimeType = "time"; - static const char *Metric_UpType = "up"; - static const char *NameType = "Name"; - static const char *ObjectRefType = "ObjectRef"; - static const char *MaterialRefType = "MaterialRef"; - static const char *MetricKeyType = "key"; - static const char *GeometryNodeType = "GeometryNode"; - static const char *CameraNodeType = "CameraNode"; - static const char *LightNodeType = "LightNode"; - static const char *GeometryObjectType = "GeometryObject"; - static const char *CameraObjectType = "CameraObject"; - static const char *LightObjectType = "LightObject"; - static const char *TransformType = "Transform"; - static const char *MeshType = "Mesh"; - static const char *VertexArrayType = "VertexArray"; - static const char *IndexArrayType = "IndexArray"; - static const char *MaterialType = "Material"; - static const char *ColorType = "Color"; - static const char *ParamType = "Param"; - static const char *TextureType = "Texture"; - static const char *AttenType = "Atten"; - - static const char *DiffuseColorToken = "diffuse"; - static const char *SpecularColorToken = "specular"; - static const char *EmissionColorToken = "emission"; - - static const char *DiffuseTextureToken = "diffuse"; - static const char *DiffuseSpecularTextureToken = "specular"; - static const char *SpecularPowerTextureToken = "specular_power"; - static const char *EmissionTextureToken = "emission"; - static const char *OpacyTextureToken = "opacity"; - static const char *TransparencyTextureToken = "transparency"; - static const char *NormalTextureToken = "normal"; - - enum TokenType { - NoneType = -1, - MetricToken, - NameToken, - ObjectRefToken, - MaterialRefToken, - MetricKeyToken, - GeometryNodeToken, - CameraNodeToken, - LightNodeToken, - GeometryObjectToken, - CameraObjectToken, - LightObjectToken, - TransformToken, - MeshToken, - VertexArrayToken, - IndexArrayToken, - MaterialToken, - ColorToken, - ParamToken, - TextureToken, - AttenToken - }; - - static const std::string ValidMetricToken[4] = { - Metric_DistanceType, - Metric_AngleType, - Metric_TimeType, - Metric_UpType - }; - - static int isValidMetricType(const char *token) { - if (nullptr == token) { - return false; - } - - int idx(-1); - for (size_t i = 0; i < 4; i++) { - if (ValidMetricToken[i] == token) { - idx = (int)i; - break; - } - } - - return idx; - } - - static TokenType matchTokenType(const char *tokenType) { - if (MetricType == tokenType) { - return MetricToken; - } else if (NameType == tokenType) { - return NameToken; - } else if (ObjectRefType == tokenType) { - return ObjectRefToken; - } else if (MaterialRefType == tokenType) { - return MaterialRefToken; - } else if (MetricKeyType == tokenType) { - return MetricKeyToken; - } else if (GeometryNodeType == tokenType) { - return GeometryNodeToken; - } else if (CameraNodeType == tokenType) { - return CameraNodeToken; - } else if (LightNodeType == tokenType) { - return LightNodeToken; - } 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) { - return MeshToken; - } else if (VertexArrayType == tokenType) { - return VertexArrayToken; - } else if (IndexArrayType == tokenType) { - return IndexArrayToken; - } else if (MaterialType == tokenType) { - return MaterialToken; - } 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; - } -} // Namespace Grammar - -namespace Assimp { -namespace OpenGEX { - -USE_ODDLPARSER_NS - -//------------------------------------------------------------------------------------------------ -static void propId2StdString(Property *prop, std::string &name, std::string &key) { - name = key = std::string(); - if (nullptr == prop) { - return; - } - - if (nullptr != prop->m_key) { -#ifdef ASSIMP_USE_HUNTER - name = prop->m_key->m_text.m_buffer; -#else - name = prop->m_key->m_buffer; -#endif - if (Value::ValueType::ddl_string == prop->m_value->m_type) { - key = prop->m_value->getString(); - } - } -} - -//------------------------------------------------------------------------------------------------ -static void logDDLParserMessage (LogSeverity severity, const std::string &rawmsg) { - std::string msg = ai_str_toprintable(rawmsg); - switch (severity) { - case ddl_debug_msg: ASSIMP_LOG_DEBUG(msg); break; - case ddl_info_msg: ASSIMP_LOG_INFO(msg); break; - case ddl_warn_msg: ASSIMP_LOG_WARN(msg); break; - case ddl_error_msg: ASSIMP_LOG_ERROR(msg); break; - default: ASSIMP_LOG_VERBOSE_DEBUG(msg); break; - } -} - -//------------------------------------------------------------------------------------------------ -OpenGEXImporter::VertexContainer::VertexContainer() : - m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() { - // empty -} - -//------------------------------------------------------------------------------------------------ -OpenGEXImporter::VertexContainer::~VertexContainer() { - delete[] m_colors; - - for (auto &texcoords : m_textureCoords) { - delete[] texcoords; - } -} - -//------------------------------------------------------------------------------------------------ -OpenGEXImporter::RefInfo::RefInfo(aiNode *node, Type type, std::vector<std::string> &names) : - m_node(node), - m_type(type), - m_Names(names) { - // empty -} - -//------------------------------------------------------------------------------------------------ -OpenGEXImporter::RefInfo::~RefInfo() { - // empty -} - -//------------------------------------------------------------------------------------------------ -OpenGEXImporter::OpenGEXImporter() : - m_root(nullptr), - m_nodeChildMap(), - m_meshCache(), - m_mesh2refMap(), - m_material2refMap(), - m_ctx(nullptr), - m_metrics(), - m_currentNode(nullptr), - m_currentVertices(), - m_currentMesh(nullptr), - m_currentMaterial(nullptr), - m_currentLight(nullptr), - m_currentCamera(nullptr), - m_tokenType(Grammar::NoneType), - m_materialCache(), - m_cameraCache(), - m_lightCache(), - m_nodeStack(), - m_unresolvedRefStack() { - // empty -} - -//------------------------------------------------------------------------------------------------ -OpenGEXImporter::~OpenGEXImporter() { -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool /*checkSig*/) const { - static const char *tokens[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" }; - return SearchFileHeaderForToken(pIOHandler, file, tokens, AI_COUNT_OF(tokens)); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) { - // open source file - IOStream *file = pIOHandler->Open(filename, "rb"); - if (!file) { - throw DeadlyImportError("Failed to open file ", filename); - } - - std::vector<char> buffer; - TextFileToBuffer(file, buffer); - pIOHandler->Close(file); - - OpenDDLParser myParser; - myParser.setLogCallback(&logDDLParserMessage); - myParser.setBuffer(&buffer[0], buffer.size()); - bool success(myParser.parse()); - if (success) { - m_ctx = myParser.getContext(); - pScene->mRootNode = new aiNode; - pScene->mRootNode->mName.Set(filename); - handleNodes(m_ctx->m_root, pScene); - } - - copyMeshes(pScene); - copyCameras(pScene); - copyLights(pScene); - copyMaterials(pScene); - resolveReferences(); - createNodeTree(pScene); -} - -//------------------------------------------------------------------------------------------------ -const aiImporterDesc *OpenGEXImporter::GetInfo() const { - return &desc; -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::SetupProperties(const Importer *pImp) { - if (nullptr == pImp) { - return; - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleNodes(DDLNode *node, aiScene *pScene) { - if (nullptr == node) { - return; - } - - DDLNode::DllNodeList children = node->getChildNodeList(); - for (DDLNode::DllNodeList::iterator it = children.begin(); it != children.end(); ++it) { - Grammar::TokenType tokenType(Grammar::matchTokenType((*it)->getType().c_str())); - switch (tokenType) { - case Grammar::MetricToken: - handleMetricNode(*it, pScene); - break; - - case Grammar::NameToken: - handleNameNode(*it, pScene); - break; - - case Grammar::ObjectRefToken: - handleObjectRefNode(*it, pScene); - break; - - case Grammar::MaterialRefToken: - handleMaterialRefNode(*it, pScene); - break; - - case Grammar::MetricKeyToken: - break; - - case Grammar::GeometryNodeToken: - handleGeometryNode(*it, pScene); - break; - - case Grammar::CameraNodeToken: - handleCameraNode(*it, pScene); - break; - - case Grammar::LightNodeToken: - handleLightNode(*it, pScene); - break; - - case Grammar::GeometryObjectToken: - 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; - - case Grammar::MeshToken: - handleMeshNode(*it, pScene); - break; - - case Grammar::VertexArrayToken: - handleVertexArrayNode(*it, pScene); - break; - - case Grammar::IndexArrayToken: - handleIndexArrayNode(*it, pScene); - break; - - case Grammar::MaterialToken: - handleMaterialNode(*it, pScene); - break; - - case Grammar::ColorToken: - handleColorNode(*it, pScene); - break; - - case Grammar::ParamToken: - handleParamNode(*it, pScene); - break; - - case Grammar::TextureToken: - handleTextureNode(*it, pScene); - break; - - default: - break; - } - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleMetricNode(DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == node || nullptr == m_ctx) { - return; - } - - if (m_ctx->m_root != node->getParent()) { - return; - } - - Property *prop(node->getProperties()); - while (nullptr != prop) { - if (nullptr != prop->m_key) { - if (Value::ValueType::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 (nullptr != val) { - if (Value::ValueType::ddl_float == val->m_type) { - m_metrics[type].m_floatValue = val->getFloat(); - } else if (Value::ValueType::ddl_int32 == val->m_type) { - m_metrics[type].m_intValue = val->getInt32(); - } else if (Value::ValueType::ddl_string == val->m_type) { - m_metrics[type].m_stringValue = std::string(val->getString()); - } else { - throw DeadlyImportError("OpenGEX: invalid data type for Metric node."); - } - } - } - } - } - prop = prop->m_next; - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == m_currentNode) { - throw DeadlyImportError("No current node for name."); - return; - } - - Value *val(node->getValue()); - if (nullptr != val) { - if (Value::ValueType::ddl_string != val->m_type) { - throw DeadlyImportError("OpenGEX: invalid data type for value in node name."); - return; - } - - const std::string name(val->getString()); - if (m_tokenType == Grammar::GeometryNodeToken || m_tokenType == Grammar::LightNodeToken || m_tokenType == Grammar::CameraNodeToken) { - m_currentNode->mName.Set(name.c_str()); - } else if (m_tokenType == Grammar::MaterialToken) { - aiString aiName; - aiName.Set(name); - m_currentMaterial->AddProperty(&aiName, AI_MATKEY_NAME); - m_material2refMap[name] = m_materialCache.size() - 1; - } - } -} - -//------------------------------------------------------------------------------------------------ -static void getRefNames(DDLNode *node, std::vector<std::string> &names) { - ai_assert(nullptr != node); - - Reference *ref = node->getReferences(); - if (nullptr != ref) { - for (size_t i = 0; i < ref->m_numRefs; i++) { - Name *currentName(ref->m_referencedName[i]); - if (nullptr != currentName && nullptr != currentName->m_id) { -#ifdef ASSIMP_USE_HUNTER - const std::string name(currentName->m_id->m_text.m_buffer); -#else - const std::string name(currentName->m_id->m_buffer); -#endif - if (!name.empty()) { - names.push_back(name); - } - } - } - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == m_currentNode) { - throw DeadlyImportError("No parent node for name."); - return; - } - - std::vector<std::string> objRefNames; - getRefNames(node, objRefNames); - - // when we are dealing with a geometry node prepare the mesh cache - if (m_tokenType == Grammar::GeometryNodeToken) { - m_currentNode->mNumMeshes = static_cast<unsigned int>(objRefNames.size()); - m_currentNode->mMeshes = new unsigned int[objRefNames.size()]; - if (!objRefNames.empty()) { - m_unresolvedRefStack.push_back(std::unique_ptr<RefInfo>(new RefInfo(m_currentNode, RefInfo::MeshRef, objRefNames))); - } - } else if (m_tokenType == Grammar::LightNodeToken) { - // TODO! - } else if (m_tokenType == Grammar::CameraNodeToken) { - // TODO! - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == m_currentNode) { - throw DeadlyImportError("No parent node for name."); - return; - } - - std::vector<std::string> matRefNames; - getRefNames(node, matRefNames); - if (!matRefNames.empty()) { - m_unresolvedRefStack.push_back(std::unique_ptr<RefInfo>(new RefInfo(m_currentNode, RefInfo::MaterialRef, matRefNames))); - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleGeometryNode(DDLNode *node, aiScene *pScene) { - aiNode *newNode = new aiNode; - pushNode(newNode, pScene); - m_tokenType = Grammar::GeometryNodeToken; - m_currentNode = newNode; - handleNodes(node, pScene); - - popNode(); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleCameraNode(DDLNode *node, aiScene *pScene) { - aiCamera *camera(new aiCamera); - 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()); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleLightNode(ODDLParser::DDLNode *node, aiScene *pScene) { - aiLight *light(new aiLight); - m_lightCache.push_back(light); - m_currentLight = light; - - aiNode *newNode = new aiNode; - m_tokenType = Grammar::LightNodeToken; - m_currentNode = newNode; - pushNode(newNode, pScene); - - handleNodes(node, pScene); - - popNode(); - - m_currentLight->mName.Set(newNode->mName.C_Str()); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleGeometryObject(DDLNode *node, aiScene *pScene) { - // parameters will be parsed normally in the tree, so just go for it - handleNodes(node, 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) { - aiLight *light(new aiLight); - m_lightCache.push_back(light); - std::string objName = node->getName(); - if (!objName.empty()) { - light->mName.Set(objName); - } - m_currentLight = light; - - 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(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 != nullptr) { - m[i] = next->getFloat(); - next = next->m_next; - i++; - } - - ai_assert(i == 16); - - node->mTransformation.a1 = m[0]; - node->mTransformation.a2 = m[4]; - node->mTransformation.a3 = m[8]; - node->mTransformation.a4 = m[12]; - - node->mTransformation.b1 = m[1]; - node->mTransformation.b2 = m[5]; - node->mTransformation.b3 = m[9]; - node->mTransformation.b4 = m[13]; - - node->mTransformation.c1 = m[2]; - node->mTransformation.c2 = m[6]; - node->mTransformation.c3 = m[10]; - node->mTransformation.c4 = m[14]; - - node->mTransformation.d1 = m[3]; - node->mTransformation.d2 = m[7]; - node->mTransformation.d3 = m[11]; - node->mTransformation.d4 = m[15]; -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == m_currentNode) { - throw DeadlyImportError("No parent node for name."); - return; - } - - DataArrayList *transformData(node->getDataArrayList()); - if (nullptr != transformData) { - if (transformData->m_numItems != 16) { - throw DeadlyImportError("Invalid number of data for transform matrix."); - return; - } - setMatrix(m_currentNode, transformData); - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleMeshNode(ODDLParser::DDLNode *node, aiScene *pScene) { - m_currentMesh = new aiMesh; - const size_t meshidx(m_meshCache.size()); - // ownership is transferred but a reference remains in m_currentMesh - m_meshCache.emplace_back(m_currentMesh); - - Property *prop = node->getProperties(); - if (nullptr != prop) { - std::string propName, propKey; - propId2StdString(prop, propName, propKey); - if ("primitive" == propName) { - if ("points" == propKey) { - m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - } else if ("lines" == propKey) { - m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - } else if ("triangles" == propKey) { - m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - } else if ("quads" == propKey) { - m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - } else { - ASSIMP_LOG_WARN(propKey, " is not supported primitive type."); - } - } - } - - handleNodes(node, pScene); - - DDLNode *parent(node->getParent()); - if (nullptr != parent) { - const std::string &name = parent->getName(); - m_mesh2refMap[name] = meshidx; - } -} - -//------------------------------------------------------------------------------------------------ -enum MeshAttribute { - None, - Position, - Color, - Normal, - TexCoord -}; - -constexpr auto PosToken = "position"; -constexpr auto ColToken = "color"; -constexpr auto NormalToken = "normal"; -constexpr auto TexCoordToken = "texcoord"; - -//------------------------------------------------------------------------------------------------ -static MeshAttribute getAttributeByName(const char *attribName) { - ai_assert(nullptr != attribName); - - if (0 == strcmp(PosToken, attribName)) { - return Position; - } else if (0 == strcmp(ColToken, attribName)) { - return Color; - } else if (0 == strcmp(NormalToken, attribName)) { - return Normal; - } else if (0 == strcmp(TexCoordToken, attribName)) { - return TexCoord; - } - - return None; -} - -//------------------------------------------------------------------------------------------------ -static void fillVector3(aiVector3D *vec3, Value *vals) { - ai_assert(nullptr != vec3); - ai_assert(nullptr != vals); - - float x(0.0f), y(0.0f), z(0.0f); - Value *next(vals); - x = next->getFloat(); - next = next->m_next; - y = next->getFloat(); - next = next->m_next; - if (nullptr != next) { - z = next->getFloat(); - } - - vec3->Set(x, y, z); -} - -//------------------------------------------------------------------------------------------------ -static void fillColor4(aiColor4D *col4, Value *vals) { - ai_assert(nullptr != col4); - ai_assert(nullptr != vals); - - Value *next(vals); - col4->r = next->getFloat(); - next = next->m_next; - if (!next) { - throw DeadlyImportError("OpenGEX: Not enough values to fill 4-element color, only 1"); - } - - col4->g = next->getFloat(); - next = next->m_next; - if (!next) { - throw DeadlyImportError("OpenGEX: Not enough values to fill 4-element color, only 2"); - } - - col4->b = next->getFloat(); - next = next->m_next; - if (!next) { - throw DeadlyImportError("OpenGEX: Not enough values to fill 4-element color, only 3"); - } - - col4->a = next->getFloat(); -} - -//------------------------------------------------------------------------------------------------ -static size_t countDataArrayListItems(DataArrayList *vaList) { - size_t numItems(0); - if (nullptr == vaList) { - return numItems; - } - - DataArrayList *next(vaList); - while (nullptr != next) { - if (nullptr != vaList->m_dataList) { - numItems++; - } - next = next->m_next; - } - - return numItems; -} - -//------------------------------------------------------------------------------------------------ -static void copyVectorArray(size_t numItems, DataArrayList *vaList, aiVector3D *vectorArray) { - for (size_t i = 0; i < numItems; i++) { - Value *next(vaList->m_dataList); - fillVector3(&vectorArray[i], next); - vaList = vaList->m_next; - } -} - -//------------------------------------------------------------------------------------------------ -static void copyColor4DArray(size_t numItems, DataArrayList *vaList, aiColor4D *colArray) { - for (size_t i = 0; i < numItems; i++) { - Value *next(vaList->m_dataList); - fillColor4(&colArray[i], next); - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == node) { - throw DeadlyImportError("No parent node for name."); - return; - } - - Property *prop = node->getProperties(); - if (nullptr != prop) { - std::string propName, propKey; - propId2StdString(prop, propName, propKey); - MeshAttribute attribType(getAttributeByName(propKey.c_str())); - if (None == attribType) { - return; - } - - DataArrayList *vaList = node->getDataArrayList(); - if (nullptr == vaList) { - return; - } - - const size_t numItems(countDataArrayListItems(vaList)); - - if (Position == attribType) { - m_currentVertices.m_vertices.resize(numItems); - copyVectorArray(numItems, vaList, m_currentVertices.m_vertices.data()); - } else if (Color == attribType) { - m_currentVertices.m_numColors = numItems; - m_currentVertices.m_colors = new aiColor4D[numItems]; - copyColor4DArray(numItems, vaList, m_currentVertices.m_colors); - } else if (Normal == attribType) { - m_currentVertices.m_normals.resize(numItems); - copyVectorArray(numItems, vaList, m_currentVertices.m_normals.data()); - } else if (TexCoord == attribType) { - m_currentVertices.m_numUVComps[0] = numItems; - m_currentVertices.m_textureCoords[0] = new aiVector3D[numItems]; - copyVectorArray(numItems, vaList, m_currentVertices.m_textureCoords[0]); - } - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == node) { - throw DeadlyImportError("No parent node for name."); - return; - } - - if (nullptr == m_currentMesh) { - throw DeadlyImportError("No current mesh for index data found."); - return; - } - - DataArrayList *vaList = node->getDataArrayList(); - if (nullptr == vaList) { - return; - } - - const size_t numItems(countDataArrayListItems(vaList)); - m_currentMesh->mNumFaces = static_cast<unsigned int>(numItems); - m_currentMesh->mFaces = new aiFace[numItems]; - m_currentMesh->mNumVertices = static_cast<unsigned int>(numItems * 3); - m_currentMesh->mVertices = new aiVector3D[m_currentMesh->mNumVertices]; - bool hasColors(false); - if (m_currentVertices.m_numColors > 0) { - m_currentMesh->mColors[0] = new aiColor4D[m_currentVertices.m_numColors]; - hasColors = true; - } - bool hasNormalCoords(false); - if (!m_currentVertices.m_normals.empty()) { - 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++) { - aiFace ¤t(m_currentMesh->mFaces[i]); - current.mNumIndices = 3; - current.mIndices = new unsigned int[current.mNumIndices]; - Value *next(vaList->m_dataList); - for (size_t indices = 0; indices < current.mNumIndices; indices++) { - const int idx(next->getUnsignedInt32()); - ai_assert(static_cast<size_t>(idx) <= m_currentVertices.m_vertices.size()); - ai_assert(index < m_currentMesh->mNumVertices); - aiVector3D &pos = (m_currentVertices.m_vertices[idx]); - m_currentMesh->mVertices[index].Set(pos.x, pos.y, pos.z); - if (hasColors) { - aiColor4D &col = m_currentVertices.m_colors[idx]; - m_currentMesh->mColors[0][index] = col; - } - 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++; - - next = next->m_next; - } - vaList = vaList->m_next; - } -} - -//------------------------------------------------------------------------------------------------ -static void getColorRGB3(aiColor3D *pColor, DataArrayList *colList) { - if (nullptr == pColor || nullptr == colList) { - return; - } - - ai_assert(3 == colList->m_numItems); - Value *val(colList->m_dataList); - pColor->r = val->getFloat(); - val = val->getNext(); - pColor->g = val->getFloat(); - val = val->getNext(); - pColor->b = val->getFloat(); -} - -//------------------------------------------------------------------------------------------------ -static void getColorRGB4(aiColor4D *pColor, DataArrayList *colList) { - if (nullptr == pColor || nullptr == colList) { - return; - } - - ai_assert(4 == colList->m_numItems); - Value *val(colList->m_dataList); - pColor->r = val->getFloat(); - val = val->getNext(); - pColor->g = val->getFloat(); - val = val->getNext(); - pColor->b = val->getFloat(); - val = val->getNext(); - pColor->a = val->getFloat(); -} - -//------------------------------------------------------------------------------------------------ -enum ColorType { - NoneColor = 0, - DiffuseColor, - SpecularColor, - EmissionColor, - LightColor -}; - -//------------------------------------------------------------------------------------------------ -static ColorType getColorType(Text *id) { - if (nullptr == id) { - return NoneColor; - } - - if (*id == Grammar::DiffuseColorToken) { - return DiffuseColor; - } else if (*id == Grammar::SpecularColorToken) { - return SpecularColor; - } else if (*id == Grammar::EmissionColorToken) { - return EmissionColor; - } else if (*id == "light") { - return LightColor; - } - - return NoneColor; -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleMaterialNode(ODDLParser::DDLNode *node, aiScene *pScene) { - m_currentMaterial = new aiMaterial; - m_materialCache.push_back(m_currentMaterial); - m_tokenType = Grammar::MaterialToken; - handleNodes(node, pScene); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleColorNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == node) { - return; - } - - Property *prop = node->findPropertyByName("attrib"); - if (nullptr != prop) { - if (nullptr != prop->m_value) { - DataArrayList *colList(node->getDataArrayList()); - if (nullptr == colList) { - return; - } - aiColor3D col; - if (3 == colList->m_numItems) { - aiColor3D col3; - getColorRGB3(&col3, colList); - col = col3; - } else { - aiColor4D col4; - getColorRGB4(&col4, colList); - col.r = col4.r; - col.g = col4.g; - col.b = col4.b; - } -#ifdef ASSIMP_USE_HUNTER - const ColorType colType(getColorType(&prop->m_key->m_text)); -#else - const ColorType colType(getColorType(prop->m_key)); -#endif - if (DiffuseColor == colType) { - m_currentMaterial->AddProperty(&col, 1, AI_MATKEY_COLOR_DIFFUSE); - } else if (SpecularColor == colType) { - 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; - } - } - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleTextureNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { - if (nullptr == node) { - return; - } - - Property *prop = node->findPropertyByName("attrib"); - if (nullptr != prop) { - if (nullptr != prop->m_value) { - Value *val(node->getValue()); - if (nullptr != val) { - aiString tex; - tex.Set(val->getString()); - if (prop->m_value->getString() == Grammar::DiffuseTextureToken) { - m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_DIFFUSE(0)); - } else if (prop->m_value->getString() == Grammar::DiffuseSpecularTextureToken) { - m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_SPECULAR(0)); - } else if (prop->m_value->getString() == Grammar::SpecularPowerTextureToken) { - m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_SPECULAR(0)); - } 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 ) ); - } else if (prop->m_value->getString() == Grammar::NormalTextureToken) { - m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_NORMALS(0)); - } else { - ai_assert(false); - } - } - } - } -} - -//------------------------------------------------------------------------------------------------ -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 (0 == ASSIMP_strincmp("fov", prop->m_value->getString(), 3)) { - m_currentCamera->mHorizontalFOV = floatVal; - } else if (0 == ASSIMP_strincmp("near", prop->m_value->getString(), 4)) { - 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"))) { - m_currentLight->mAttenuationQuadratic = floatVal; - } - } - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::copyMeshes(aiScene *pScene) { - ai_assert(nullptr != pScene); - - if (m_meshCache.empty()) { - return; - } - - pScene->mNumMeshes = static_cast<unsigned int>(m_meshCache.size()); - pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; - for (unsigned int i = 0; i < pScene->mNumMeshes; i++) { - pScene->mMeshes[i] = m_meshCache[i].release(); - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::copyCameras(aiScene *pScene) { - ai_assert(nullptr != pScene); - - if (m_cameraCache.empty()) { - return; - } - - pScene->mNumCameras = static_cast<unsigned int>(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 = static_cast<unsigned int>(m_lightCache.size()); - pScene->mLights = new aiLight *[pScene->mNumLights]; - std::copy(m_lightCache.begin(), m_lightCache.end(), pScene->mLights); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::copyMaterials(aiScene *pScene) { - ai_assert(nullptr != pScene); - - if (m_materialCache.empty()) { - return; - } - - pScene->mNumMaterials = static_cast<unsigned int>(m_materialCache.size()); - pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; - std::copy(m_materialCache.begin(), m_materialCache.end(), pScene->mMaterials); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::resolveReferences() { - if (m_unresolvedRefStack.empty()) { - return; - } - - RefInfo *currentRefInfo(nullptr); - for (auto it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it) { - currentRefInfo = it->get(); - if (nullptr != currentRefInfo) { - 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]); - ReferenceMap::const_iterator curIt(m_mesh2refMap.find(name)); - if (m_mesh2refMap.end() != curIt) { - unsigned int meshIdx = static_cast<unsigned int>(m_mesh2refMap[name]); - node->mMeshes[i] = meshIdx; - } - } - } else if (RefInfo::MaterialRef == currentRefInfo->m_type) { - for (size_t i = 0; i < currentRefInfo->m_Names.size(); ++i) { - const std::string name(currentRefInfo->m_Names[i]); - ReferenceMap::const_iterator curIt(m_material2refMap.find(name)); - if (m_material2refMap.end() != curIt) { - if (nullptr != m_currentMesh) { - unsigned int matIdx = static_cast<unsigned int>(m_material2refMap[name]); - if (m_currentMesh->mMaterialIndex != 0) { - ASSIMP_LOG_WARN("Override of material reference in current mesh by material reference."); - } - m_currentMesh->mMaterialIndex = matIdx; - } else { - ASSIMP_LOG_WARN("Cannot resolve material reference, because no current mesh is there."); - } - } - } - } else { - throw DeadlyImportError("Unknown reference info to resolve."); - } - } - } -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::createNodeTree(aiScene *pScene) { - if (nullptr == m_root) { - return; - } - - if (m_root->m_children.empty()) { - return; - } - - pScene->mRootNode->mNumChildren = static_cast<unsigned int>(m_root->m_children.size()); - pScene->mRootNode->mChildren = new aiNode *[pScene->mRootNode->mNumChildren]; - std::copy(m_root->m_children.begin(), m_root->m_children.end(), pScene->mRootNode->mChildren); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::pushNode(aiNode *node, aiScene *pScene) { - ai_assert(nullptr != pScene); - - if (nullptr == 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] = std::unique_ptr<ChildInfo>(info); - } else { - info = it->second.get(); - } - 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] = std::unique_ptr<ChildInfo>(info); - } else { - info = it->second.get(); - } - info->m_children.push_back(node); - } - m_nodeStack.push_back(node); -} - -//------------------------------------------------------------------------------------------------ -aiNode *OpenGEXImporter::popNode() { - if (m_nodeStack.empty()) { - return nullptr; - } - - aiNode *node(top()); - m_nodeStack.pop_back(); - - return node; -} - -//------------------------------------------------------------------------------------------------ -aiNode *OpenGEXImporter::top() const { - if (m_nodeStack.empty()) { - return nullptr; - } - - return m_nodeStack.back(); -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXImporter::clearNodeStack() { - m_nodeStack.clear(); -} - -//------------------------------------------------------------------------------------------------ - -} // Namespace OpenGEX -} // Namespace Assimp - -#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER |