diff options
Diffstat (limited to 'libs/assimp/code/AssetLib/Q3D/Q3DLoader.cpp')
-rw-r--r-- | libs/assimp/code/AssetLib/Q3D/Q3DLoader.cpp | 575 |
1 files changed, 0 insertions, 575 deletions
diff --git a/libs/assimp/code/AssetLib/Q3D/Q3DLoader.cpp b/libs/assimp/code/AssetLib/Q3D/Q3DLoader.cpp deleted file mode 100644 index c773bbf..0000000 --- a/libs/assimp/code/AssetLib/Q3D/Q3DLoader.cpp +++ /dev/null @@ -1,575 +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. ---------------------------------------------------------------------------- -*/ - -/** @file Q3DLoader.cpp - * @brief Implementation of the Q3D importer class - */ - -#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER - -// internal headers -#include "Q3DLoader.h" -#include <assimp/StringUtils.h> -#include <assimp/StreamReader.h> -#include <assimp/fast_atof.h> -#include <assimp/importerdesc.h> -#include <assimp/scene.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/IOSystem.hpp> - -using namespace Assimp; - -static const aiImporterDesc desc = { - "Quick3D Importer", - "", - "", - "http://www.quick3d.com/", - aiImporterFlags_SupportBinaryFlavour, - 0, - 0, - 0, - 0, - "q3o q3s" -}; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -Q3DImporter::Q3DImporter() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -Q3DImporter::~Q3DImporter() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. -bool Q3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { - static const char *tokens[] = { "quick3Do", "quick3Ds" }; - return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); -} - -// ------------------------------------------------------------------------------------------------ -const aiImporterDesc *Q3DImporter::GetInfo() const { - return &desc; -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. -void Q3DImporter::InternReadFile(const std::string &pFile, - aiScene *pScene, IOSystem *pIOHandler) { - - auto file = pIOHandler->Open(pFile, "rb"); - if (!file) - throw DeadlyImportError("Quick3D: Could not open ", pFile); - - StreamReaderLE stream(file); - - // The header is 22 bytes large - if (stream.GetRemainingSize() < 22) - throw DeadlyImportError("File is either empty or corrupt: ", pFile); - - // Check the file's signature - if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) && - ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) { - throw DeadlyImportError("Not a Quick3D file. Signature string is: ", ai_str_toprintable((const char *)stream.GetPtr(), 8)); - } - - // Print the file format version - ASSIMP_LOG_INFO("Quick3D File format version: ", - std::string(&((const char *)stream.GetPtr())[8], 2)); - - // ... an store it - char major = ((const char *)stream.GetPtr())[8]; - char minor = ((const char *)stream.GetPtr())[9]; - - stream.IncPtr(10); - unsigned int numMeshes = (unsigned int)stream.GetI4(); - unsigned int numMats = (unsigned int)stream.GetI4(); - unsigned int numTextures = (unsigned int)stream.GetI4(); - - std::vector<Material> materials; - materials.reserve(numMats); - - std::vector<Mesh> meshes; - meshes.reserve(numMeshes); - - // Allocate the scene root node - pScene->mRootNode = new aiNode(); - - aiColor3D fgColor(0.6f, 0.6f, 0.6f); - - // Now read all file chunks - while (true) { - if (stream.GetRemainingSize() < 1) break; - char c = stream.GetI1(); - switch (c) { - // Meshes chunk - case 'm': { - for (unsigned int quak = 0; quak < numMeshes; ++quak) { - meshes.push_back(Mesh()); - Mesh &mesh = meshes.back(); - - // read all vertices - unsigned int numVerts = (unsigned int)stream.GetI4(); - if (!numVerts) - throw DeadlyImportError("Quick3D: Found mesh with zero vertices"); - - std::vector<aiVector3D> &verts = mesh.verts; - verts.resize(numVerts); - - for (unsigned int i = 0; i < numVerts; ++i) { - verts[i].x = stream.GetF4(); - verts[i].y = stream.GetF4(); - verts[i].z = stream.GetF4(); - } - - // read all faces - numVerts = (unsigned int)stream.GetI4(); - if (!numVerts) - throw DeadlyImportError("Quick3D: Found mesh with zero faces"); - - std::vector<Face> &faces = mesh.faces; - faces.reserve(numVerts); - - // number of indices - for (unsigned int i = 0; i < numVerts; ++i) { - faces.push_back(Face(stream.GetI2())); - if (faces.back().indices.empty()) - throw DeadlyImportError("Quick3D: Found face with zero indices"); - } - - // indices - for (unsigned int i = 0; i < numVerts; ++i) { - Face &vec = faces[i]; - for (unsigned int a = 0; a < (unsigned int)vec.indices.size(); ++a) - vec.indices[a] = stream.GetI4(); - } - - // material indices - for (unsigned int i = 0; i < numVerts; ++i) { - faces[i].mat = (unsigned int)stream.GetI4(); - } - - // read all normals - numVerts = (unsigned int)stream.GetI4(); - std::vector<aiVector3D> &normals = mesh.normals; - normals.resize(numVerts); - - for (unsigned int i = 0; i < numVerts; ++i) { - normals[i].x = stream.GetF4(); - normals[i].y = stream.GetF4(); - normals[i].z = stream.GetF4(); - } - - numVerts = (unsigned int)stream.GetI4(); - if (numTextures && numVerts) { - // read all texture coordinates - std::vector<aiVector3D> &uv = mesh.uv; - uv.resize(numVerts); - - for (unsigned int i = 0; i < numVerts; ++i) { - uv[i].x = stream.GetF4(); - uv[i].y = stream.GetF4(); - } - - // UV indices - for (unsigned int i = 0; i < (unsigned int)faces.size(); ++i) { - Face &vec = faces[i]; - for (unsigned int a = 0; a < (unsigned int)vec.indices.size(); ++a) { - vec.uvindices[a] = stream.GetI4(); - if (!i && !a) - mesh.prevUVIdx = vec.uvindices[a]; - else if (vec.uvindices[a] != mesh.prevUVIdx) - mesh.prevUVIdx = UINT_MAX; - } - } - } - - // we don't need the rest, but we need to get to the next chunk - stream.IncPtr(36); - if (minor > '0' && major == '3') - stream.IncPtr(mesh.faces.size()); - } - // stream.IncPtr(4); // unknown value here - } break; - - // materials chunk - case 'c': - - for (unsigned int i = 0; i < numMats; ++i) { - materials.push_back(Material()); - Material &mat = materials.back(); - - // read the material name - c = stream.GetI1(); - while (c) { - mat.name.data[mat.name.length++] = c; - c = stream.GetI1(); - } - - // add the terminal character - mat.name.data[mat.name.length] = '\0'; - - // read the ambient color - mat.ambient.r = stream.GetF4(); - mat.ambient.g = stream.GetF4(); - mat.ambient.b = stream.GetF4(); - - // read the diffuse color - mat.diffuse.r = stream.GetF4(); - mat.diffuse.g = stream.GetF4(); - mat.diffuse.b = stream.GetF4(); - - // read the ambient color - mat.specular.r = stream.GetF4(); - mat.specular.g = stream.GetF4(); - mat.specular.b = stream.GetF4(); - - // read the transparency - mat.transparency = stream.GetF4(); - - // unknown value here - // stream.IncPtr(4); - // FIX: it could be the texture index ... - mat.texIdx = (unsigned int)stream.GetI4(); - } - - break; - - // texture chunk - case 't': - - pScene->mNumTextures = numTextures; - if (!numTextures) { - break; - } - pScene->mTextures = new aiTexture *[pScene->mNumTextures]; - // to make sure we won't crash if we leave through an exception - ::memset(pScene->mTextures, 0, sizeof(void *) * pScene->mNumTextures); - for (unsigned int i = 0; i < pScene->mNumTextures; ++i) { - aiTexture *tex = pScene->mTextures[i] = new aiTexture; - - // skip the texture name - while (stream.GetI1()) - ; - - // read texture width and height - tex->mWidth = (unsigned int)stream.GetI4(); - tex->mHeight = (unsigned int)stream.GetI4(); - - if (!tex->mWidth || !tex->mHeight) { - throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero"); - } - - unsigned int mul = tex->mWidth * tex->mHeight; - aiTexel *begin = tex->pcData = new aiTexel[mul]; - aiTexel *const end = &begin[mul - 1] + 1; - - for (; begin != end; ++begin) { - begin->r = stream.GetI1(); - begin->g = stream.GetI1(); - begin->b = stream.GetI1(); - begin->a = 0xff; - } - } - - break; - - // scene chunk - case 's': { - // skip position and rotation - stream.IncPtr(12); - - for (unsigned int i = 0; i < 4; ++i) - for (unsigned int a = 0; a < 4; ++a) - pScene->mRootNode->mTransformation[i][a] = stream.GetF4(); - - stream.IncPtr(16); - - // now setup a single camera - pScene->mNumCameras = 1; - pScene->mCameras = new aiCamera *[1]; - aiCamera *cam = pScene->mCameras[0] = new aiCamera(); - cam->mPosition.x = stream.GetF4(); - cam->mPosition.y = stream.GetF4(); - cam->mPosition.z = stream.GetF4(); - cam->mName.Set("Q3DCamera"); - - // skip eye rotation for the moment - stream.IncPtr(12); - - // read the default material color - fgColor.r = stream.GetF4(); - fgColor.g = stream.GetF4(); - fgColor.b = stream.GetF4(); - - // skip some unimportant properties - stream.IncPtr(29); - - // setup a single point light with no attenuation - pScene->mNumLights = 1; - pScene->mLights = new aiLight *[1]; - aiLight *light = pScene->mLights[0] = new aiLight(); - light->mName.Set("Q3DLight"); - light->mType = aiLightSource_POINT; - - light->mAttenuationConstant = 1; - light->mAttenuationLinear = 0; - light->mAttenuationQuadratic = 0; - - light->mColorDiffuse.r = stream.GetF4(); - light->mColorDiffuse.g = stream.GetF4(); - light->mColorDiffuse.b = stream.GetF4(); - - light->mColorSpecular = light->mColorDiffuse; - - // We don't need the rest, but we need to know where this chunk ends. - unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4()); - - // skip the background file name - while (stream.GetI1()) - ; - - // skip background texture data + the remaining fields - stream.IncPtr(temp * 3 + 20); // 4 bytes of unknown data here - - // TODO - goto outer; - } break; - - default: - throw DeadlyImportError("Quick3D: Unknown chunk"); - break; - }; - } -outer: - - // If we have no mesh loaded - break here - if (meshes.empty()) - throw DeadlyImportError("Quick3D: No meshes loaded"); - - // If we have no materials loaded - generate a default mat - if (materials.empty()) { - ASSIMP_LOG_INFO("Quick3D: No material found, generating one"); - materials.push_back(Material()); - materials.back().diffuse = fgColor; - } - - // find out which materials we'll need - typedef std::pair<unsigned int, unsigned int> FaceIdx; - typedef std::vector<FaceIdx> FaceIdxArray; - FaceIdxArray *fidx = new FaceIdxArray[materials.size()]; - - unsigned int p = 0; - for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end(); - it != end; ++it, ++p) { - unsigned int q = 0; - for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end(); - fit != fend; ++fit, ++q) { - if ((*fit).mat >= materials.size()) { - ASSIMP_LOG_WARN("Quick3D: Material index overflow"); - (*fit).mat = 0; - } - if (fidx[(*fit).mat].empty()) ++pScene->mNumMeshes; - fidx[(*fit).mat].push_back(FaceIdx(p, q)); - } - } - pScene->mNumMaterials = pScene->mNumMeshes; - pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; - pScene->mMeshes = new aiMesh *[pScene->mNumMaterials]; - - for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i) { - if (fidx[i].empty()) continue; - - // Allocate a mesh and a material - aiMesh *mesh = pScene->mMeshes[real] = new aiMesh(); - aiMaterial *mat = new aiMaterial(); - pScene->mMaterials[real] = mat; - - mesh->mMaterialIndex = real; - - // Build the output material - Material &srcMat = materials[i]; - mat->AddProperty(&srcMat.diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); - mat->AddProperty(&srcMat.specular, 1, AI_MATKEY_COLOR_SPECULAR); - mat->AddProperty(&srcMat.ambient, 1, AI_MATKEY_COLOR_AMBIENT); - - // NOTE: Ignore transparency for the moment - it seems - // unclear how to interpret the data -#if 0 - if (!(minor > '0' && major == '3')) - srcMat.transparency = 1.0f - srcMat.transparency; - mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_OPACITY); -#endif - - // add shininess - Quick3D seems to use it ins its viewer - srcMat.transparency = 16.f; - mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_SHININESS); - - int m = (int)aiShadingMode_Phong; - mat->AddProperty(&m, 1, AI_MATKEY_SHADING_MODEL); - - if (srcMat.name.length) - mat->AddProperty(&srcMat.name, AI_MATKEY_NAME); - - // Add a texture - if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures) { - srcMat.name.data[0] = '*'; - srcMat.name.length = ASSIMP_itoa10(&srcMat.name.data[1], 1000, - (srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real)); - mat->AddProperty(&srcMat.name, AI_MATKEY_TEXTURE_DIFFUSE(0)); - } - - mesh->mNumFaces = (unsigned int)fidx[i].size(); - aiFace *faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; - - // Now build the output mesh. First find out how many - // vertices we'll need - for (FaceIdxArray::const_iterator it = fidx[i].begin(), end = fidx[i].end(); - it != end; ++it) { - mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[(*it).second].indices.size(); - } - - aiVector3D *verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - aiVector3D *norms = mesh->mNormals = new aiVector3D[mesh->mNumVertices]; - aiVector3D *uv = nullptr; - if (real < pScene->mNumTextures) { - uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; - mesh->mNumUVComponents[0] = 2; - } - - // Build the final array - unsigned int cnt = 0; - for (FaceIdxArray::const_iterator it = fidx[i].begin(), end = fidx[i].end(); - it != end; ++it, ++faces) { - Mesh &curMesh = meshes[(*it).first]; - Face &face = curMesh.faces[(*it).second]; - faces->mNumIndices = (unsigned int)face.indices.size(); - faces->mIndices = new unsigned int[faces->mNumIndices]; - - aiVector3D faceNormal; - bool fnOK = false; - - for (unsigned int n = 0; n < faces->mNumIndices; ++n, ++cnt, ++norms, ++verts) { - if (face.indices[n] >= curMesh.verts.size()) { - ASSIMP_LOG_WARN("Quick3D: Vertex index overflow"); - face.indices[n] = 0; - } - - // copy vertices - *verts = curMesh.verts[face.indices[n]]; - - if (face.indices[n] >= curMesh.normals.size() && faces->mNumIndices >= 3) { - // we have no normal here - assign the face normal - if (!fnOK) { - const aiVector3D &pV1 = curMesh.verts[face.indices[0]]; - const aiVector3D &pV2 = curMesh.verts[face.indices[1]]; - const aiVector3D &pV3 = curMesh.verts[face.indices.size() - 1]; - faceNormal = (pV2 - pV1) ^ (pV3 - pV1).Normalize(); - fnOK = true; - } - *norms = faceNormal; - } else { - *norms = curMesh.normals[face.indices[n]]; - } - - // copy texture coordinates - if (uv && curMesh.uv.size()) { - if (curMesh.prevUVIdx != 0xffffffff && curMesh.uv.size() >= curMesh.verts.size()) // workaround - { - *uv = curMesh.uv[face.indices[n]]; - } else { - if (face.uvindices[n] >= curMesh.uv.size()) { - ASSIMP_LOG_WARN("Quick3D: Texture coordinate index overflow"); - face.uvindices[n] = 0; - } - *uv = curMesh.uv[face.uvindices[n]]; - } - uv->y = 1.f - uv->y; - ++uv; - } - - // setup the new vertex index - faces->mIndices[n] = cnt; - } - } - ++real; - } - - // Delete our nice helper array - delete[] fidx; - - // Now we need to attach the meshes to the root node of the scene - pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; - pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) - pScene->mRootNode->mMeshes[i] = i; - - /*pScene->mRootNode->mTransformation *= aiMatrix4x4( - 1.f, 0.f, 0.f, 0.f, - 0.f, -1.f,0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f);*/ - - // Add cameras and light sources to the scene root node - pScene->mRootNode->mNumChildren = pScene->mNumLights + pScene->mNumCameras; - if (pScene->mRootNode->mNumChildren) { - pScene->mRootNode->mChildren = new aiNode *[pScene->mRootNode->mNumChildren]; - - // the light source - aiNode *nd = pScene->mRootNode->mChildren[0] = new aiNode(); - nd->mParent = pScene->mRootNode; - nd->mName.Set("Q3DLight"); - nd->mTransformation = pScene->mRootNode->mTransformation; - nd->mTransformation.Inverse(); - - // camera - nd = pScene->mRootNode->mChildren[1] = new aiNode(); - nd->mParent = pScene->mRootNode; - nd->mName.Set("Q3DCamera"); - nd->mTransformation = pScene->mRootNode->mChildren[0]->mTransformation; - } -} - -#endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER |