summaryrefslogtreecommitdiff
path: root/libs/assimp/code/AssetLib/3DS
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-02-12 23:53:22 -0600
committersanine <sanine.not@pm.me>2023-02-12 23:53:22 -0600
commitf1fe73d1909a2448a004a88362a1a532d0d4f7c3 (patch)
treeab37ae3837e2f858de2932bcee9f26e69fab3db1 /libs/assimp/code/AssetLib/3DS
parentf567ea1e2798fd3156a416e61f083ea3e6b95719 (diff)
switch to tinyobj and nanovg from assimp and cairo
Diffstat (limited to 'libs/assimp/code/AssetLib/3DS')
-rw-r--r--libs/assimp/code/AssetLib/3DS/3DSConverter.cpp807
-rw-r--r--libs/assimp/code/AssetLib/3DS/3DSExporter.cpp584
-rw-r--r--libs/assimp/code/AssetLib/3DS/3DSExporter.h98
-rw-r--r--libs/assimp/code/AssetLib/3DS/3DSHelper.h702
-rw-r--r--libs/assimp/code/AssetLib/3DS/3DSLoader.cpp1336
-rw-r--r--libs/assimp/code/AssetLib/3DS/3DSLoader.h289
6 files changed, 0 insertions, 3816 deletions
diff --git a/libs/assimp/code/AssetLib/3DS/3DSConverter.cpp b/libs/assimp/code/AssetLib/3DS/3DSConverter.cpp
deleted file mode 100644
index 5a01429..0000000
--- a/libs/assimp/code/AssetLib/3DS/3DSConverter.cpp
+++ /dev/null
@@ -1,807 +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 Implementation of the 3ds importer class */
-
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// internal headers
-#include "3DSLoader.h"
-#include "Common/TargetAnimation.h"
-#include <assimp/StringComparison.h>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <cctype>
-#include <memory>
-
-using namespace Assimp;
-
-static const unsigned int NotSet = 0xcdcdcdcd;
-
-// ------------------------------------------------------------------------------------------------
-// Setup final material indices, generae a default material if necessary
-void Discreet3DSImporter::ReplaceDefaultMaterial() {
- // Try to find an existing material that matches the
- // typical default material setting:
- // - no textures
- // - diffuse color (in grey!)
- // NOTE: This is here to workaround the fact that some
- // exporters are writing a default material, too.
- unsigned int idx(NotSet);
- for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
- std::string s = mScene->mMaterials[i].mName;
- for (char & it : s) {
- it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
- }
-
- if (std::string::npos == s.find("default")) continue;
-
- if (mScene->mMaterials[i].mDiffuse.r !=
- mScene->mMaterials[i].mDiffuse.g ||
- mScene->mMaterials[i].mDiffuse.r !=
- mScene->mMaterials[i].mDiffuse.b) continue;
-
- if (ContainsTextures(i)) {
- continue;
- }
- idx = i;
- }
- if (NotSet == idx) {
- idx = (unsigned int)mScene->mMaterials.size();
- }
-
- // now iterate through all meshes and through all faces and
- // find all faces that are using the default material
- unsigned int cnt = 0;
- for (std::vector<D3DS::Mesh>::iterator
- i = mScene->mMeshes.begin();
- i != mScene->mMeshes.end(); ++i) {
- for (std::vector<unsigned int>::iterator
- a = (*i).mFaceMaterials.begin();
- a != (*i).mFaceMaterials.end(); ++a) {
- // NOTE: The additional check seems to be necessary,
- // some exporters seem to generate invalid data here
- if (0xcdcdcdcd == (*a)) {
- (*a) = idx;
- ++cnt;
- } else if ((*a) >= mScene->mMaterials.size()) {
- (*a) = idx;
- ASSIMP_LOG_WARN("Material index overflow in 3DS file. Using default material");
- ++cnt;
- }
- }
- }
- if (cnt && idx == mScene->mMaterials.size()) {
- // We need to create our own default material
- D3DS::Material sMat("%%%DEFAULT");
- sMat.mDiffuse = aiColor3D(0.3f, 0.3f, 0.3f);
- mScene->mMaterials.push_back(sMat);
-
- ASSIMP_LOG_INFO("3DS: Generating default material");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether all indices are valid. Otherwise we'd crash before the validation step is reached
-void Discreet3DSImporter::CheckIndices(D3DS::Mesh &sMesh) {
- for (std::vector<D3DS::Face>::iterator i = sMesh.mFaces.begin(); i != sMesh.mFaces.end(); ++i) {
- // check whether all indices are in range
- for (unsigned int a = 0; a < 3; ++a) {
- if ((*i).mIndices[a] >= sMesh.mPositions.size()) {
- ASSIMP_LOG_WARN("3DS: Vertex index overflow)");
- (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size() - 1;
- }
- if (!sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size()) {
- ASSIMP_LOG_WARN("3DS: Texture coordinate index overflow)");
- (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size() - 1;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate out unique verbose format representation
-void Discreet3DSImporter::MakeUnique(D3DS::Mesh &sMesh) {
- // TODO: really necessary? I don't think. Just a waste of memory and time
- // to do it now in a separate buffer.
-
- // Allocate output storage
- std::vector<aiVector3D> vNew(sMesh.mFaces.size() * 3);
- std::vector<aiVector3D> vNew2;
- if (sMesh.mTexCoords.size())
- vNew2.resize(sMesh.mFaces.size() * 3);
-
- for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size(); ++i) {
- D3DS::Face &face = sMesh.mFaces[i];
-
- // Positions
- for (unsigned int a = 0; a < 3; ++a, ++base) {
- vNew[base] = sMesh.mPositions[face.mIndices[a]];
- if (sMesh.mTexCoords.size())
- vNew2[base] = sMesh.mTexCoords[face.mIndices[a]];
-
- face.mIndices[a] = base;
- }
- }
- sMesh.mPositions = vNew;
- sMesh.mTexCoords = vNew2;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a 3DS texture to texture keys in an aiMaterial
-void CopyTexture(aiMaterial &mat, D3DS::Texture &texture, aiTextureType type) {
- // Setup the texture name
- aiString tex;
- tex.Set(texture.mMapName);
- mat.AddProperty(&tex, AI_MATKEY_TEXTURE(type, 0));
-
- // Setup the texture blend factor
- if (is_not_qnan(texture.mTextureBlend))
- mat.AddProperty<ai_real>(&texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type, 0));
-
- // Setup the texture mapping mode
- int mapMode = static_cast<int>(texture.mMapMode);
- mat.AddProperty<int>(&mapMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0));
- mat.AddProperty<int>(&mapMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0));
-
- // Mirroring - double the scaling values
- // FIXME: this is not really correct ...
- if (texture.mMapMode == aiTextureMapMode_Mirror) {
- texture.mScaleU *= 2.0;
- texture.mScaleV *= 2.0;
- texture.mOffsetU /= 2.0;
- texture.mOffsetV /= 2.0;
- }
-
- // Setup texture UV transformations
- mat.AddProperty<ai_real>(&texture.mOffsetU, 5, AI_MATKEY_UVTRANSFORM(type, 0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a 3DS material to an aiMaterial
-void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
- aiMaterial &mat) {
- // NOTE: Pass the background image to the viewer by bypassing the
- // material system. This is an evil hack, never do it again!
- if (0 != mBackgroundImage.length() && bHasBG) {
- aiString tex;
- tex.Set(mBackgroundImage);
- mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
-
- // Be sure this is only done for the first material
- mBackgroundImage = std::string();
- }
-
- // At first add the base ambient color of the scene to the material
- oldMat.mAmbient.r += mClrAmbient.r;
- oldMat.mAmbient.g += mClrAmbient.g;
- oldMat.mAmbient.b += mClrAmbient.b;
-
- aiString name;
- name.Set(oldMat.mName);
- mat.AddProperty(&name, AI_MATKEY_NAME);
-
- // Material colors
- mat.AddProperty(&oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
- mat.AddProperty(&oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat.AddProperty(&oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- mat.AddProperty(&oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
-
- // Phong shininess and shininess strength
- if (D3DS::Discreet3DS::Phong == oldMat.mShading ||
- D3DS::Discreet3DS::Metal == oldMat.mShading) {
- if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength) {
- oldMat.mShading = D3DS::Discreet3DS::Gouraud;
- } else {
- mat.AddProperty(&oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
- mat.AddProperty(&oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
- }
- }
-
- // Opacity
- mat.AddProperty<ai_real>(&oldMat.mTransparency, 1, AI_MATKEY_OPACITY);
-
- // Bump height scaling
- mat.AddProperty<ai_real>(&oldMat.mBumpHeight, 1, AI_MATKEY_BUMPSCALING);
-
- // Two sided rendering?
- if (oldMat.mTwoSided) {
- int i = 1;
- mat.AddProperty<int>(&i, 1, AI_MATKEY_TWOSIDED);
- }
-
- // Shading mode
- aiShadingMode eShading = aiShadingMode_NoShading;
- switch (oldMat.mShading) {
- case D3DS::Discreet3DS::Flat:
- eShading = aiShadingMode_Flat;
- break;
-
- // I don't know what "Wire" shading should be,
- // assume it is simple lambertian diffuse shading
- case D3DS::Discreet3DS::Wire: {
- // Set the wireframe flag
- unsigned int iWire = 1;
- mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
- }
-
- case D3DS::Discreet3DS::Gouraud:
- eShading = aiShadingMode_Gouraud;
- break;
-
- // assume cook-torrance shading for metals.
- case D3DS::Discreet3DS::Phong:
- eShading = aiShadingMode_Phong;
- break;
-
- case D3DS::Discreet3DS::Metal:
- eShading = aiShadingMode_CookTorrance;
- break;
-
- // FIX to workaround a warning with GCC 4 who complained
- // about a missing case Blinn: here - Blinn isn't a valid
- // value in the 3DS Loader, it is just needed for ASE
- case D3DS::Discreet3DS::Blinn:
- eShading = aiShadingMode_Blinn;
- break;
- }
- int eShading_ = static_cast<int>(eShading);
- mat.AddProperty<int>(&eShading_, 1, AI_MATKEY_SHADING_MODEL);
-
- // DIFFUSE texture
- if (oldMat.sTexDiffuse.mMapName.length() > 0)
- CopyTexture(mat, oldMat.sTexDiffuse, aiTextureType_DIFFUSE);
-
- // SPECULAR texture
- if (oldMat.sTexSpecular.mMapName.length() > 0)
- CopyTexture(mat, oldMat.sTexSpecular, aiTextureType_SPECULAR);
-
- // OPACITY texture
- if (oldMat.sTexOpacity.mMapName.length() > 0)
- CopyTexture(mat, oldMat.sTexOpacity, aiTextureType_OPACITY);
-
- // EMISSIVE texture
- if (oldMat.sTexEmissive.mMapName.length() > 0)
- CopyTexture(mat, oldMat.sTexEmissive, aiTextureType_EMISSIVE);
-
- // BUMP texture
- if (oldMat.sTexBump.mMapName.length() > 0)
- CopyTexture(mat, oldMat.sTexBump, aiTextureType_HEIGHT);
-
- // SHININESS texture
- if (oldMat.sTexShininess.mMapName.length() > 0)
- CopyTexture(mat, oldMat.sTexShininess, aiTextureType_SHININESS);
-
- // REFLECTION texture
- if (oldMat.sTexReflective.mMapName.length() > 0)
- CopyTexture(mat, oldMat.sTexReflective, aiTextureType_REFLECTION);
-
- // Store the name of the material itself, too
- if (oldMat.mName.length()) {
- aiString tex;
- tex.Set(oldMat.mName);
- mat.AddProperty(&tex, AI_MATKEY_NAME);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Split meshes by their materials and generate output aiMesh'es
-void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
- std::vector<aiMesh *> avOutMeshes;
- avOutMeshes.reserve(mScene->mMeshes.size() * 2);
-
- unsigned int iFaceCnt = 0, num = 0;
- aiString name;
-
- // we need to split all meshes by their materials
- for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
- std::unique_ptr<std::vector<unsigned int>[]> aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
-
- name.length = ASSIMP_itoa10(name.data, num++);
-
- unsigned int iNum = 0;
- for (std::vector<unsigned int>::const_iterator a = (*i).mFaceMaterials.begin();
- a != (*i).mFaceMaterials.end(); ++a, ++iNum) {
- aiSplit[*a].push_back(iNum);
- }
- // now generate submeshes
- for (unsigned int p = 0; p < mScene->mMaterials.size(); ++p) {
- if (aiSplit[p].empty()) {
- continue;
- }
- aiMesh *meshOut = new aiMesh();
- meshOut->mName = name;
- meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // be sure to setup the correct material index
- meshOut->mMaterialIndex = p;
-
- // use the color data as temporary storage
- meshOut->mColors[0] = (aiColor4D *)(&*i);
- avOutMeshes.push_back(meshOut);
-
- // convert vertices
- meshOut->mNumFaces = (unsigned int)aiSplit[p].size();
- meshOut->mNumVertices = meshOut->mNumFaces * 3;
-
- // allocate enough storage for faces
- meshOut->mFaces = new aiFace[meshOut->mNumFaces];
- iFaceCnt += meshOut->mNumFaces;
-
- meshOut->mVertices = new aiVector3D[meshOut->mNumVertices];
- meshOut->mNormals = new aiVector3D[meshOut->mNumVertices];
- if ((*i).mTexCoords.size()) {
- meshOut->mTextureCoords[0] = new aiVector3D[meshOut->mNumVertices];
- }
- for (unsigned int q = 0, base = 0; q < aiSplit[p].size(); ++q) {
- unsigned int index = aiSplit[p][q];
- aiFace &face = meshOut->mFaces[q];
-
- face.mIndices = new unsigned int[3];
- face.mNumIndices = 3;
-
- for (unsigned int a = 0; a < 3; ++a, ++base) {
- unsigned int idx = (*i).mFaces[index].mIndices[a];
- meshOut->mVertices[base] = (*i).mPositions[idx];
- meshOut->mNormals[base] = (*i).mNormals[idx];
-
- if ((*i).mTexCoords.size())
- meshOut->mTextureCoords[0][base] = (*i).mTexCoords[idx];
-
- face.mIndices[a] = base;
- }
- }
- }
- }
-
- // Copy them to the output array
- pcOut->mNumMeshes = (unsigned int)avOutMeshes.size();
- pcOut->mMeshes = new aiMesh *[pcOut->mNumMeshes]();
- for (unsigned int a = 0; a < pcOut->mNumMeshes; ++a) {
- pcOut->mMeshes[a] = avOutMeshes[a];
- }
-
- // We should have at least one face here
- if (!iFaceCnt) {
- throw DeadlyImportError("No faces loaded. The mesh is empty");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a node to the scenegraph and setup its final transformation
-void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
- D3DS::Node *pcIn, aiMatrix4x4 & /*absTrafo*/) {
- std::vector<unsigned int> iArray;
- iArray.reserve(3);
-
- aiMatrix4x4 abs;
-
- // Find all meshes with the same name as the node
- for (unsigned int a = 0; a < pcSOut->mNumMeshes; ++a) {
- const D3DS::Mesh *pcMesh = (const D3DS::Mesh *)pcSOut->mMeshes[a]->mColors[0];
- ai_assert(nullptr != pcMesh);
-
- if (pcIn->mName == pcMesh->mName)
- iArray.push_back(a);
- }
- if (!iArray.empty()) {
- // The matrix should be identical for all meshes with the
- // same name. It HAS to be identical for all meshes .....
- D3DS::Mesh *imesh = ((D3DS::Mesh *)pcSOut->mMeshes[iArray[0]]->mColors[0]);
-
- // Compute the inverse of the transformation matrix to move the
- // vertices back to their relative and local space
- aiMatrix4x4 mInv = imesh->mMat, mInvTransposed = imesh->mMat;
- mInv.Inverse();
- mInvTransposed.Transpose();
- aiVector3D pivot = pcIn->vPivot;
-
- pcOut->mNumMeshes = (unsigned int)iArray.size();
- pcOut->mMeshes = new unsigned int[iArray.size()];
- for (unsigned int i = 0; i < iArray.size(); ++i) {
- const unsigned int iIndex = iArray[i];
- aiMesh *const mesh = pcSOut->mMeshes[iIndex];
-
- if (mesh->mColors[1] == nullptr) {
- // Transform the vertices back into their local space
- // fixme: consider computing normals after this, so we don't need to transform them
- const aiVector3D *const pvEnd = mesh->mVertices + mesh->mNumVertices;
- aiVector3D *pvCurrent = mesh->mVertices, *t2 = mesh->mNormals;
-
- for (; pvCurrent != pvEnd; ++pvCurrent, ++t2) {
- *pvCurrent = mInv * (*pvCurrent);
- *t2 = mInvTransposed * (*t2);
- }
-
- // Handle negative transformation matrix determinant -> invert vertex x
- if (imesh->mMat.Determinant() < 0.0f) {
- /* we *must* have normals */
- for (pvCurrent = mesh->mVertices, t2 = mesh->mNormals; pvCurrent != pvEnd; ++pvCurrent, ++t2) {
- pvCurrent->x *= -1.f;
- t2->x *= -1.f;
- }
- ASSIMP_LOG_INFO("3DS: Flipping mesh X-Axis");
- }
-
- // Handle pivot point
- if (pivot.x || pivot.y || pivot.z) {
- for (pvCurrent = mesh->mVertices; pvCurrent != pvEnd; ++pvCurrent) {
- *pvCurrent -= pivot;
- }
- }
-
- mesh->mColors[1] = (aiColor4D *)1;
- } else
- mesh->mColors[1] = (aiColor4D *)1;
-
- // Setup the mesh index
- pcOut->mMeshes[i] = iIndex;
- }
- }
-
- // Setup the name of the node
- // First instance keeps its name otherwise something might break, all others will be postfixed with their instance number
- if (pcIn->mInstanceNumber > 1) {
- char tmp[12];
- ASSIMP_itoa10(tmp, pcIn->mInstanceNumber);
- std::string tempStr = pcIn->mName + "_inst_";
- tempStr += tmp;
- pcOut->mName.Set(tempStr);
- } else
- pcOut->mName.Set(pcIn->mName);
-
- // Now build the transformation matrix of the node
- // ROTATION
- if (pcIn->aRotationKeys.size()) {
-
- // FIX to get to Assimp's quaternion conventions
- for (std::vector<aiQuatKey>::iterator it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) {
- (*it).mValue.w *= -1.f;
- }
-
- pcOut->mTransformation = aiMatrix4x4(pcIn->aRotationKeys[0].mValue.GetMatrix());
- } else if (pcIn->aCameraRollKeys.size()) {
- aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(-pcIn->aCameraRollKeys[0].mValue),
- pcOut->mTransformation);
- }
-
- // SCALING
- aiMatrix4x4 &m = pcOut->mTransformation;
- if (pcIn->aScalingKeys.size()) {
- const aiVector3D &v = pcIn->aScalingKeys[0].mValue;
- m.a1 *= v.x;
- m.b1 *= v.x;
- m.c1 *= v.x;
- m.a2 *= v.y;
- m.b2 *= v.y;
- m.c2 *= v.y;
- m.a3 *= v.z;
- m.b3 *= v.z;
- m.c3 *= v.z;
- }
-
- // TRANSLATION
- if (pcIn->aPositionKeys.size()) {
- const aiVector3D &v = pcIn->aPositionKeys[0].mValue;
- m.a4 += v.x;
- m.b4 += v.y;
- m.c4 += v.z;
- }
-
- // Generate animation channels for the node
- if (pcIn->aPositionKeys.size() > 1 || pcIn->aRotationKeys.size() > 1 ||
- pcIn->aScalingKeys.size() > 1 || pcIn->aCameraRollKeys.size() > 1 ||
- pcIn->aTargetPositionKeys.size() > 1) {
- aiAnimation *anim = pcSOut->mAnimations[0];
- ai_assert(nullptr != anim);
-
- if (pcIn->aCameraRollKeys.size() > 1) {
- ASSIMP_LOG_VERBOSE_DEBUG("3DS: Converting camera roll track ...");
-
- // Camera roll keys - in fact they're just rotations
- // around the camera's z axis. The angles are given
- // in degrees (and they're clockwise).
- pcIn->aRotationKeys.resize(pcIn->aCameraRollKeys.size());
- for (unsigned int i = 0; i < pcIn->aCameraRollKeys.size(); ++i) {
- aiQuatKey &q = pcIn->aRotationKeys[i];
- aiFloatKey &f = pcIn->aCameraRollKeys[i];
-
- q.mTime = f.mTime;
-
- // FIX to get to Assimp quaternion conventions
- q.mValue = aiQuaternion(0.f, 0.f, AI_DEG_TO_RAD(/*-*/ f.mValue));
- }
- }
-#if 0
- if (pcIn->aTargetPositionKeys.size() > 1)
- {
- ASSIMP_LOG_VERBOSE_DEBUG("3DS: Converting target track ...");
-
- // Camera or spot light - need to convert the separate
- // target position channel to our representation
- TargetAnimationHelper helper;
-
- if (pcIn->aPositionKeys.empty())
- {
- // We can just pass zero here ...
- helper.SetFixedMainAnimationChannel(aiVector3D());
- }
- else helper.SetMainAnimationChannel(&pcIn->aPositionKeys);
- helper.SetTargetAnimationChannel(&pcIn->aTargetPositionKeys);
-
- // Do the conversion
- std::vector<aiVectorKey> distanceTrack;
- helper.Process(&distanceTrack);
-
- // Now add a new node as child, name it <ourName>.Target
- // and assign the distance track to it. This is that the
- // information where the target is and how it moves is
- // not lost
- D3DS::Node* nd = new D3DS::Node();
- pcIn->push_back(nd);
-
- nd->mName = pcIn->mName + ".Target";
-
- aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
- nda->mNodeName.Set(nd->mName);
-
- nda->mNumPositionKeys = (unsigned int)distanceTrack.size();
- nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
- ::memcpy(nda->mPositionKeys,&distanceTrack[0],
- sizeof(aiVectorKey)*nda->mNumPositionKeys);
- }
-#endif
-
- // Cameras or lights define their transformation in their parent node and in the
- // corresponding light or camera chunks. However, we read and process the latter
- // to to be able to return valid cameras/lights even if no scenegraph is given.
- for (unsigned int n = 0; n < pcSOut->mNumCameras; ++n) {
- if (pcSOut->mCameras[n]->mName == pcOut->mName) {
- pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f, 0.f, 1.f);
- }
- }
- for (unsigned int n = 0; n < pcSOut->mNumLights; ++n) {
- if (pcSOut->mLights[n]->mName == pcOut->mName) {
- pcSOut->mLights[n]->mDirection = aiVector3D(0.f, 0.f, 1.f);
- }
- }
-
- // Allocate a new node anim and setup its name
- aiNodeAnim *nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
- nda->mNodeName.Set(pcIn->mName);
-
- // POSITION keys
- if (pcIn->aPositionKeys.size() > 0) {
- nda->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size();
- nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
- ::memcpy(nda->mPositionKeys, &pcIn->aPositionKeys[0],
- sizeof(aiVectorKey) * nda->mNumPositionKeys);
- }
-
- // ROTATION keys
- if (pcIn->aRotationKeys.size() > 0) {
- nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
- nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
-
- // Rotations are quaternion offsets
- aiQuaternion abs1;
- for (unsigned int n = 0; n < nda->mNumRotationKeys; ++n) {
- const aiQuatKey &q = pcIn->aRotationKeys[n];
-
- abs1 = (n ? abs1 * q.mValue : q.mValue);
- nda->mRotationKeys[n].mTime = q.mTime;
- nda->mRotationKeys[n].mValue = abs1.Normalize();
- }
- }
-
- // SCALING keys
- if (pcIn->aScalingKeys.size() > 0) {
- nda->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size();
- nda->mScalingKeys = new aiVectorKey[nda->mNumScalingKeys];
- ::memcpy(nda->mScalingKeys, &pcIn->aScalingKeys[0],
- sizeof(aiVectorKey) * nda->mNumScalingKeys);
- }
- }
-
- // Allocate storage for children
- pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
- pcOut->mChildren = new aiNode *[pcIn->mChildren.size()];
-
- // Recursively process all children
- const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
- for (unsigned int i = 0; i < size; ++i) {
- pcOut->mChildren[i] = new aiNode();
- pcOut->mChildren[i]->mParent = pcOut;
- AddNodeToGraph(pcSOut, pcOut->mChildren[i], pcIn->mChildren[i], abs);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find out how many node animation channels we'll have finally
-void CountTracks(D3DS::Node *node, unsigned int &cnt) {
- //////////////////////////////////////////////////////////////////////////////
- // We will never generate more than one channel for a node, so
- // this is rather easy here.
-
- if (node->aPositionKeys.size() > 1 || node->aRotationKeys.size() > 1 ||
- node->aScalingKeys.size() > 1 || node->aCameraRollKeys.size() > 1 ||
- node->aTargetPositionKeys.size() > 1) {
- ++cnt;
-
- // account for the additional channel for the camera/spotlight target position
- if (node->aTargetPositionKeys.size() > 1) ++cnt;
- }
-
- // Recursively process all children
- for (unsigned int i = 0; i < node->mChildren.size(); ++i)
- CountTracks(node->mChildren[i], cnt);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate the output node graph
-void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
- pcOut->mRootNode = new aiNode();
- if (0 == mRootNode->mChildren.size()) {
- //////////////////////////////////////////////////////////////////////////////
- // It seems the file is so messed up that it has not even a hierarchy.
- // generate a flat hiearachy which looks like this:
- //
- // ROOT_NODE
- // |
- // ----------------------------------------
- // | | | | |
- // MESH_0 MESH_1 MESH_2 ... MESH_N CAMERA_0 ....
- //
- ASSIMP_LOG_WARN("No hierarchy information has been found in the file. ");
-
- pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes +
- static_cast<unsigned int>(mScene->mCameras.size() + mScene->mLights.size());
-
- pcOut->mRootNode->mChildren = new aiNode *[pcOut->mRootNode->mNumChildren];
- pcOut->mRootNode->mName.Set("<3DSDummyRoot>");
-
- // Build dummy nodes for all meshes
- unsigned int a = 0;
- for (unsigned int i = 0; i < pcOut->mNumMeshes; ++i, ++a) {
- aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
- pcNode->mMeshes = new unsigned int[1];
- pcNode->mMeshes[0] = i;
- pcNode->mNumMeshes = 1;
-
- // Build a name for the node
- pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u", i);
- }
-
- // Build dummy nodes for all cameras
- for (unsigned int i = 0; i < (unsigned int)mScene->mCameras.size(); ++i, ++a) {
- aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
-
- // Build a name for the node
- pcNode->mName = mScene->mCameras[i]->mName;
- }
-
- // Build dummy nodes for all lights
- for (unsigned int i = 0; i < (unsigned int)mScene->mLights.size(); ++i, ++a) {
- aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
-
- // Build a name for the node
- pcNode->mName = mScene->mLights[i]->mName;
- }
- } else {
- // First of all: find out how many scaling, rotation and translation
- // animation tracks we'll have afterwards
- unsigned int numChannel = 0;
- CountTracks(mRootNode, numChannel);
-
- if (numChannel) {
- // Allocate a primary animation channel
- pcOut->mNumAnimations = 1;
- pcOut->mAnimations = new aiAnimation *[1];
- aiAnimation *anim = pcOut->mAnimations[0] = new aiAnimation();
-
- anim->mName.Set("3DSMasterAnim");
-
- // Allocate enough storage for all node animation channels,
- // but don't set the mNumChannels member - we'll use it to
- // index into the array
- anim->mChannels = new aiNodeAnim *[numChannel];
- }
-
- aiMatrix4x4 m;
- AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode, m);
- }
-
- // We used the first and second vertex color set to store some temporary values so we need to cleanup here
- for (unsigned int a = 0; a < pcOut->mNumMeshes; ++a) {
- pcOut->mMeshes[a]->mColors[0] = nullptr;
- pcOut->mMeshes[a]->mColors[1] = nullptr;
- }
-
- pcOut->mRootNode->mTransformation = aiMatrix4x4(
- 1.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 1.f, 0.f,
- 0.f, -1.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 1.f) *
- pcOut->mRootNode->mTransformation;
-
- // If the root node is unnamed name it "<3DSRoot>"
- if (::strstr(pcOut->mRootNode->mName.data, "UNNAMED") ||
- (pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$')) {
- pcOut->mRootNode->mName.Set("<3DSRoot>");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert all meshes in the scene and generate the final output scene.
-void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
- // Allocate enough storage for all output materials
- pcOut->mNumMaterials = (unsigned int)mScene->mMaterials.size();
- pcOut->mMaterials = new aiMaterial *[pcOut->mNumMaterials];
-
- // ... and convert the 3DS materials to aiMaterial's
- for (unsigned int i = 0; i < pcOut->mNumMaterials; ++i) {
- aiMaterial *pcNew = new aiMaterial();
- ConvertMaterial(mScene->mMaterials[i], *pcNew);
- pcOut->mMaterials[i] = pcNew;
- }
-
- // Generate the output mesh list
- ConvertMeshes(pcOut);
-
- // Now copy all light sources to the output scene
- pcOut->mNumLights = (unsigned int)mScene->mLights.size();
- if (pcOut->mNumLights) {
- pcOut->mLights = new aiLight *[pcOut->mNumLights];
- ::memcpy(pcOut->mLights, &mScene->mLights[0], sizeof(void *) * pcOut->mNumLights);
- }
-
- // Now copy all cameras to the output scene
- pcOut->mNumCameras = (unsigned int)mScene->mCameras.size();
- if (pcOut->mNumCameras) {
- pcOut->mCameras = new aiCamera *[pcOut->mNumCameras];
- ::memcpy(pcOut->mCameras, &mScene->mCameras[0], sizeof(void *) * pcOut->mNumCameras);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
diff --git a/libs/assimp/code/AssetLib/3DS/3DSExporter.cpp b/libs/assimp/code/AssetLib/3DS/3DSExporter.cpp
deleted file mode 100644
index 71588f9..0000000
--- a/libs/assimp/code/AssetLib/3DS/3DSExporter.cpp
+++ /dev/null
@@ -1,584 +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_EXPORT
-#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
-
-#include "AssetLib/3DS/3DSExporter.h"
-#include "AssetLib/3DS/3DSHelper.h"
-#include "AssetLib/3DS/3DSLoader.h"
-#include "PostProcessing/SplitLargeMeshes.h"
-
-#include <assimp/SceneCombiner.h>
-#include <assimp/StringComparison.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/Exporter.hpp>
-#include <assimp/IOSystem.hpp>
-
-#include <memory>
-
-namespace Assimp {
-
-using namespace D3DS;
-
-namespace {
-
-//////////////////////////////////////////////////////////////////////////////////////
-// Scope utility to write a 3DS file chunk.
-//
-// Upon construction, the chunk header is written with the chunk type (flags)
-// filled out, but the chunk size left empty. Upon destruction, the correct chunk
-// size based on the then-position of the output stream cursor is filled in.
-class ChunkWriter {
- enum {
- CHUNK_SIZE_NOT_SET = 0xdeadbeef,
- SIZE_OFFSET = 2
- };
-
-public:
- ChunkWriter(StreamWriterLE &writer, uint16_t chunk_type) :
- writer(writer) {
- chunk_start_pos = writer.GetCurrentPos();
- writer.PutU2(chunk_type);
- writer.PutU4((uint32_t)CHUNK_SIZE_NOT_SET);
- }
-
- ~ChunkWriter() {
- std::size_t head_pos = writer.GetCurrentPos();
-
- ai_assert(head_pos > chunk_start_pos);
- const std::size_t chunk_size = head_pos - chunk_start_pos;
-
- writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
- writer.PutU4(static_cast<uint32_t>(chunk_size));
- writer.SetCurrentPos(head_pos);
- }
-
-private:
- StreamWriterLE &writer;
- std::size_t chunk_start_pos;
-};
-
-// Return an unique name for a given |mesh| attached to |node| that
-// preserves the mesh's given name if it has one. |index| is the index
-// of the mesh in |aiScene::mMeshes|.
-std::string GetMeshName(const aiMesh &mesh, unsigned int index, const aiNode &node) {
- static const char underscore = '_';
- char postfix[10] = { 0 };
- ASSIMP_itoa10(postfix, index);
-
- std::string result = node.mName.C_Str();
- if (mesh.mName.length > 0) {
- result += underscore;
- result += mesh.mName.C_Str();
- }
- return result + underscore + postfix;
-}
-
-// Return an unique name for a given |mat| with original position |index|
-// in |aiScene::mMaterials|. The name preserves the original material
-// name if possible.
-std::string GetMaterialName(const aiMaterial &mat, unsigned int index) {
- static const std::string underscore = "_";
- char postfix[10] = { 0 };
- ASSIMP_itoa10(postfix, index);
-
- aiString mat_name;
- if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
- return mat_name.C_Str() + underscore + postfix;
- }
-
- return "Material" + underscore + postfix;
-}
-
-// Collect world transformations for each node
-void CollectTrafos(const aiNode *node, std::map<const aiNode *, aiMatrix4x4> &trafos) {
- const aiMatrix4x4 &parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4();
- trafos[node] = parent * node->mTransformation;
- for (unsigned int i = 0; i < node->mNumChildren; ++i) {
- CollectTrafos(node->mChildren[i], trafos);
- }
-}
-
-// Generate a flat list of the meshes (by index) assigned to each node
-void CollectMeshes(const aiNode *node, std::multimap<const aiNode *, unsigned int> &meshes) {
- for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
- meshes.insert(std::make_pair(node, node->mMeshes[i]));
- }
- for (unsigned int i = 0; i < node->mNumChildren; ++i) {
- CollectMeshes(node->mChildren[i], meshes);
- }
-}
-} // namespace
-
-// ------------------------------------------------------------------------------------------------
-// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
-void ExportScene3DS(const char *pFile, IOSystem *pIOSystem, const aiScene *pScene, const ExportProperties * /*pProperties*/) {
- std::shared_ptr<IOStream> outfile(pIOSystem->Open(pFile, "wb"));
- if (!outfile) {
- throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile));
- }
-
- // TODO: This extra copy should be avoided and all of this made a preprocess
- // requirement of the 3DS exporter.
- //
- // 3DS meshes can be max 0xffff (16 Bit) vertices and faces, respectively.
- // SplitLargeMeshes can do this, but it requires the correct limit to be set
- // which is not possible with the current way of specifying preprocess steps
- // in |Exporter::ExportFormatEntry|.
- aiScene *scenecopy_tmp;
- SceneCombiner::CopyScene(&scenecopy_tmp, pScene);
- std::unique_ptr<aiScene> scenecopy(scenecopy_tmp);
-
- SplitLargeMeshesProcess_Triangle tri_splitter;
- tri_splitter.SetLimit(0xffff);
- tri_splitter.Execute(scenecopy.get());
-
- SplitLargeMeshesProcess_Vertex vert_splitter;
- vert_splitter.SetLimit(0xffff);
- vert_splitter.Execute(scenecopy.get());
-
- // Invoke the actual exporter
- Discreet3DSExporter exporter(outfile, scenecopy.get());
-}
-
-} // end of namespace Assimp
-
-// ------------------------------------------------------------------------------------------------
-Discreet3DSExporter::Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, const aiScene *scene) :
- scene(scene), writer(outfile) {
- CollectTrafos(scene->mRootNode, trafos);
- CollectMeshes(scene->mRootNode, meshes);
-
- ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_MAIN);
-
- {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_OBJMESH);
- WriteMaterials();
- WriteMeshes();
-
- {
- ChunkWriter curChunk1(writer, Discreet3DS::CHUNK_MASTER_SCALE);
- writer.PutF4(1.0f);
- }
- }
-
- {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
- WriteHierarchy(*scene->mRootNode, -1, -1);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-Discreet3DSExporter::~Discreet3DSExporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-int Discreet3DSExporter::WriteHierarchy(const aiNode &node, int seq, int sibling_level) {
- // 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
- {
- ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_TRACKINFO);
- {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
-
- // Assimp node names are unique and distinct from all mesh-node
- // names we generate; thus we can use them as-is
- WriteString(node.mName);
-
- // Two unknown int16 values - it is even unclear if 0 is a safe value
- // but luckily importers do not know better either.
- writer.PutI4(0);
-
- int16_t hierarchy_pos = static_cast<int16_t>(seq);
- if (sibling_level != -1) {
- hierarchy_pos = (uint16_t)sibling_level;
- }
-
- // Write the hierarchy position
- writer.PutI2(hierarchy_pos);
- }
- }
-
- // TODO: write transformation chunks
-
- ++seq;
- sibling_level = seq;
-
- // Write all children
- for (unsigned int i = 0; i < node.mNumChildren; ++i) {
- seq = WriteHierarchy(*node.mChildren[i], seq, i == 0 ? -1 : sibling_level);
- }
-
- // Write all meshes as separate nodes to be able to reference the meshes by name
- for (unsigned int i = 0; i < node.mNumMeshes; ++i) {
- const bool first_child = node.mNumChildren == 0 && i == 0;
-
- const unsigned int mesh_idx = node.mMeshes[i];
- const aiMesh &mesh = *scene->mMeshes[mesh_idx];
-
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRACKINFO);
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
- WriteString(GetMeshName(mesh, mesh_idx, node));
-
- writer.PutI4(0);
- writer.PutI2(static_cast<int16_t>(first_child ? seq : sibling_level));
- ++seq;
- }
- }
- return seq;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteMaterials() {
- for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
- ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
- const aiMaterial &mat = *scene->mMaterials[i];
-
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME);
- const std::string &name = GetMaterialName(mat, i);
- WriteString(name);
- }
-
- aiColor3D color;
- if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
- WriteColor(color);
- }
-
- if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
- WriteColor(color);
- }
-
- if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
- WriteColor(color);
- }
-
- float f;
- if (mat.Get(AI_MATKEY_OPACITY, f) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TRANSPARENCY);
- WritePercentChunk(1.0f - f);
- }
-
- if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
- WriteColor(color);
- }
-
- aiShadingMode shading_mode = aiShadingMode_Flat;
- if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
-
- Discreet3DS::shadetype3ds shading_mode_out;
- switch (shading_mode) {
- case aiShadingMode_Flat:
- case aiShadingMode_NoShading:
- shading_mode_out = Discreet3DS::Flat;
- break;
-
- case aiShadingMode_Gouraud:
- case aiShadingMode_Toon:
- case aiShadingMode_OrenNayar:
- case aiShadingMode_Minnaert:
- shading_mode_out = Discreet3DS::Gouraud;
- break;
-
- case aiShadingMode_Phong:
- case aiShadingMode_Blinn:
- case aiShadingMode_CookTorrance:
- case aiShadingMode_Fresnel:
- case aiShadingMode_PBR_BRDF: // Possibly should be Discreet3DS::Metal in some cases but this is undocumented
- shading_mode_out = Discreet3DS::Phong;
- break;
-
- default:
- shading_mode_out = Discreet3DS::Flat;
- ai_assert(false);
- };
- writer.PutU2(static_cast<uint16_t>(shading_mode_out));
- }
-
- if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS);
- WritePercentChunk(f);
- }
-
- if (mat.Get(AI_MATKEY_SHININESS_STRENGTH, f) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS_PERCENT);
- WritePercentChunk(f);
- }
-
- int twosided;
- if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
- writer.PutI2(1);
- }
-
- // Fallback to BASE_COLOR if no DIFFUSE
- if (!WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE))
- WriteTexture(mat, aiTextureType_BASE_COLOR, Discreet3DS::CHUNK_MAT_TEXTURE);
-
- WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP);
- WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP);
- WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP);
- WriteTexture(mat, aiTextureType_SPECULAR, Discreet3DS::CHUNK_MAT_SPECMAP);
- WriteTexture(mat, aiTextureType_EMISSIVE, Discreet3DS::CHUNK_MAT_SELFIMAP);
- WriteTexture(mat, aiTextureType_REFLECTION, Discreet3DS::CHUNK_MAT_REFLMAP);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// returns true if the texture existed
-bool Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type, uint16_t chunk_flags) {
- aiString path;
- aiTextureMapMode map_mode[2] = {
- aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
- };
- ai_real blend = 1.0;
- if (mat.GetTexture(type, 0, &path, nullptr, nullptr, &blend, nullptr, map_mode) != AI_SUCCESS || !path.length) {
- return false;
- }
-
- // TODO: handle embedded textures properly
- if (path.data[0] == '*') {
- ASSIMP_LOG_ERROR("Ignoring embedded texture for export: ", path.C_Str());
- return false;
- }
-
- ChunkWriter chunk(writer, chunk_flags);
- {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAPFILE);
- WriteString(path);
- }
-
- WritePercentChunk(blend);
-
- {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
- uint16_t val = 0; // WRAP
- if (map_mode[0] == aiTextureMapMode_Mirror) {
- val = 0x2;
- } else if (map_mode[0] == aiTextureMapMode_Decal) {
- val = 0x10;
- }
- writer.PutU2(val);
- }
- // TODO: export texture transformation (i.e. UV offset, scale, rotation)
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteMeshes() {
- // NOTE: 3DS allows for instances. However:
- // i) not all importers support reading them
- // ii) instances are not as flexible as they are in assimp, in particular,
- // nodes can carry (and instance) only one mesh.
- //
- // This exporter currently deep clones all instanced meshes, i.e. for each mesh
- // attached to a node a full TRIMESH chunk is written to the file.
- //
- // Furthermore, the TRIMESH is transformed into world space so that it will
- // appear correctly if importers don't read the scene hierarchy at all.
- for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) {
- const aiNode &node = *(*it).first;
- const unsigned int mesh_idx = (*it).second;
-
- const aiMesh &mesh = *scene->mMeshes[mesh_idx];
-
- // This should not happen if the SLM step is correctly executed
- // before the scene is handed to the exporter
- ai_assert(mesh.mNumVertices <= 0xffff);
- ai_assert(mesh.mNumFaces <= 0xffff);
-
- const aiMatrix4x4 &trafo = trafos[&node];
-
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK);
-
- // Mesh name is tied to the node it is attached to so it can later be referenced
- const std::string &name = GetMeshName(mesh, mesh_idx, node);
- WriteString(name);
-
- // TRIMESH chunk
- ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH);
-
- // Vertices in world space
- {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_VERTLIST);
-
- const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
- writer.PutU2(count);
- for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
- const aiVector3D &v = mesh.mVertices[i];
- writer.PutF4(v.x);
- writer.PutF4(v.y);
- writer.PutF4(v.z);
- }
- }
-
- // UV coordinates
- if (mesh.HasTextureCoords(0)) {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAPLIST);
- const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
- writer.PutU2(count);
-
- for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
- const aiVector3D &v = mesh.mTextureCoords[0][i];
- writer.PutF4(v.x);
- writer.PutF4(v.y);
- }
- }
-
- // Faces (indices)
- {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_FACELIST);
-
- ai_assert(mesh.mNumFaces <= 0xffff);
-
- // Count triangles, discard lines and points
- uint16_t count = 0;
- for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
- const aiFace &f = mesh.mFaces[i];
- if (f.mNumIndices < 3) {
- continue;
- }
- // TRIANGULATE step is a pre-requisite so we should not see polys here
- ai_assert(f.mNumIndices == 3);
- ++count;
- }
-
- writer.PutU2(count);
- for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
- const aiFace &f = mesh.mFaces[i];
- if (f.mNumIndices < 3) {
- continue;
- }
-
- for (unsigned int j = 0; j < 3; ++j) {
- ai_assert(f.mIndices[j] <= 0xffff);
- writer.PutI2(static_cast<uint16_t>(f.mIndices[j]));
- }
-
- // Edge visibility flag
- writer.PutI2(0x0);
- }
-
- // TODO: write smoothing groups (CHUNK_SMOOLIST)
-
- WriteFaceMaterialChunk(mesh);
- }
-
- // Transformation matrix by which the mesh vertices have been pre-transformed with.
- {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRMATRIX);
- // Store rotation 3x3 matrix row wise
- for (unsigned int r = 0; r < 3; ++r) {
- for (unsigned int c = 0; c < 3; ++c) {
- writer.PutF4(trafo[r][c]);
- }
- }
- // Store translation sub vector column wise
- for (unsigned int r = 0; r < 3; ++r) {
- writer.PutF4(trafo[r][3]);
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh &mesh) {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_FACEMAT);
- const std::string &name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex);
- WriteString(name);
-
- // Because assimp splits meshes by material, only a single
- // FACEMAT chunk needs to be written
- ai_assert(mesh.mNumFaces <= 0xffff);
- const uint16_t count = static_cast<uint16_t>(mesh.mNumFaces);
- writer.PutU2(count);
-
- for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
- writer.PutU2(static_cast<uint16_t>(i));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteString(const std::string &s) {
- for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
- writer.PutI1(*it);
- }
- writer.PutI1('\0');
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteString(const aiString &s) {
- for (std::size_t i = 0; i < s.length; ++i) {
- writer.PutI1(s.data[i]);
- }
- writer.PutI1('\0');
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteColor(const aiColor3D &color) {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_RGBF);
- writer.PutF4(color.r);
- writer.PutF4(color.g);
- writer.PutF4(color.b);
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WritePercentChunk(float f) {
- ChunkWriter curChunk(writer, Discreet3DS::CHUNK_PERCENTF);
- writer.PutF4(f);
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WritePercentChunk(double f) {
- ChunkWriter ccurChunkhunk(writer, Discreet3DS::CHUNK_PERCENTD);
- writer.PutF8(f);
-}
-
-#endif // ASSIMP_BUILD_NO_3DS_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/libs/assimp/code/AssetLib/3DS/3DSExporter.h b/libs/assimp/code/AssetLib/3DS/3DSExporter.h
deleted file mode 100644
index 82ec351..0000000
--- a/libs/assimp/code/AssetLib/3DS/3DSExporter.h
+++ /dev/null
@@ -1,98 +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 3DSExporter.h
- * 3DS Exporter Main Header
- */
-#ifndef AI_3DSEXPORTER_H_INC
-#define AI_3DSEXPORTER_H_INC
-
-#include <map>
-#include <memory>
-
-#include <assimp/StreamWriter.h>
-#include <assimp/material.h>
-
-struct aiScene;
-struct aiNode;
-struct aiMaterial;
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ------------------------------------------------------------------------------------------------
-/**
- * @brief Helper class to export a given scene to a 3DS file.
- */
-// ------------------------------------------------------------------------------------------------
-class Discreet3DSExporter {
-public:
- Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, const aiScene* pScene);
- ~Discreet3DSExporter();
-
-private:
- void WriteMeshes();
- void WriteMaterials();
- bool WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
- void WriteFaceMaterialChunk(const aiMesh& mesh);
- int WriteHierarchy(const aiNode& node, int level, int sibling_level);
- void WriteString(const std::string& s);
- void WriteString(const aiString& s);
- void WriteColor(const aiColor3D& color);
- void WritePercentChunk(float f);
- void WritePercentChunk(double f);
-
-private:
- const aiScene* const scene;
- StreamWriterLE writer;
-
- std::map<const aiNode*, aiMatrix4x4> trafos;
-
- typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
- MeshesByNodeMap meshes;
-
-};
-
-} // Namespace Assimp
-
-#endif // AI_3DSEXPORTER_H_INC
diff --git a/libs/assimp/code/AssetLib/3DS/3DSHelper.h b/libs/assimp/code/AssetLib/3DS/3DSHelper.h
deleted file mode 100644
index dc10980..0000000
--- a/libs/assimp/code/AssetLib/3DS/3DSHelper.h
+++ /dev/null
@@ -1,702 +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 Defines helper data structures for the import of 3DS files */
-
-#ifndef AI_3DSFILEHELPER_H_INC
-#define AI_3DSFILEHELPER_H_INC
-
-#include <assimp/SmoothingGroups.h>
-#include <assimp/SpatialSort.h>
-#include <assimp/StringUtils.h>
-#include <assimp/anim.h>
-#include <assimp/camera.h>
-#include <assimp/light.h>
-#include <assimp/material.h>
-#include <assimp/qnan.h>
-#include <cstdio> //sprintf
-
-namespace Assimp {
-namespace D3DS {
-
-#include <assimp/Compiler/pushpack1.h>
-
-// ---------------------------------------------------------------------------
-/** Defines chunks and data structures.
-*/
-namespace Discreet3DS {
-
- //! data structure for a single chunk in a .3ds file
- struct Chunk {
- uint16_t Flag;
- uint32_t Size;
- } PACK_STRUCT;
-
- //! Used for shading field in material3ds structure
- //! From AutoDesk 3ds SDK
- typedef enum {
- // translated to gouraud shading with wireframe active
- Wire = 0x0,
-
- // if this material is set, no vertex normals will
- // be calculated for the model. Face normals + gouraud
- Flat = 0x1,
-
- // standard gouraud shading
- Gouraud = 0x2,
-
- // phong shading
- Phong = 0x3,
-
- // cooktorrance or anistropic phong shading ...
- // the exact meaning is unknown, if you know it
- // feel free to tell me ;-)
- Metal = 0x4,
-
- // required by the ASE loader
- Blinn = 0x5
- } shadetype3ds;
-
- // Flags for animated keys
- enum {
- KEY_USE_TENS = 0x1,
- KEY_USE_CONT = 0x2,
- KEY_USE_BIAS = 0x4,
- KEY_USE_EASE_TO = 0x8,
- KEY_USE_EASE_FROM = 0x10
- };
-
- enum {
-
- // ********************************************************************
- // Basic chunks which can be found everywhere in the file
- CHUNK_VERSION = 0x0002,
- CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B
- CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B
-
- // Linear color values (gamma = 2.2?)
- CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B
- CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B
-
- CHUNK_PERCENTW = 0x0030, // int2 percentage
- CHUNK_PERCENTF = 0x0031, // float4 percentage
- CHUNK_PERCENTD = 0x0032, // float8 percentage
- // ********************************************************************
-
- // Prj master chunk
- CHUNK_PRJ = 0xC23D,
-
- // MDLI master chunk
- CHUNK_MLI = 0x3DAA,
-
- // Primary main chunk of the .3ds file
- CHUNK_MAIN = 0x4D4D,
-
- // Mesh main chunk
- CHUNK_OBJMESH = 0x3D3D,
-
- // Specifies the background color of the .3ds file
- // This is passed through the material system for
- // viewing purposes.
- CHUNK_BKGCOLOR = 0x1200,
-
- // Specifies the ambient base color of the scene.
- // This is added to all materials in the file
- CHUNK_AMBCOLOR = 0x2100,
-
- // Specifies the background image for the whole scene
- // This value is passed through the material system
- // to the viewer
- CHUNK_BIT_MAP = 0x1100,
- CHUNK_BIT_MAP_EXISTS = 0x1101,
-
- // ********************************************************************
- // Viewport related stuff. Ignored
- CHUNK_DEFAULT_VIEW = 0x3000,
- CHUNK_VIEW_TOP = 0x3010,
- CHUNK_VIEW_BOTTOM = 0x3020,
- CHUNK_VIEW_LEFT = 0x3030,
- CHUNK_VIEW_RIGHT = 0x3040,
- CHUNK_VIEW_FRONT = 0x3050,
- CHUNK_VIEW_BACK = 0x3060,
- CHUNK_VIEW_USER = 0x3070,
- CHUNK_VIEW_CAMERA = 0x3080,
- // ********************************************************************
-
- // Mesh chunks
- CHUNK_OBJBLOCK = 0x4000,
- CHUNK_TRIMESH = 0x4100,
- CHUNK_VERTLIST = 0x4110,
- CHUNK_VERTFLAGS = 0x4111,
- CHUNK_FACELIST = 0x4120,
- CHUNK_FACEMAT = 0x4130,
- CHUNK_MAPLIST = 0x4140,
- CHUNK_SMOOLIST = 0x4150,
- CHUNK_TRMATRIX = 0x4160,
- CHUNK_MESHCOLOR = 0x4165,
- CHUNK_TXTINFO = 0x4170,
- CHUNK_LIGHT = 0x4600,
- CHUNK_CAMERA = 0x4700,
- CHUNK_HIERARCHY = 0x4F00,
-
- // Specifies the global scaling factor. This is applied
- // to the root node's transformation matrix
- CHUNK_MASTER_SCALE = 0x0100,
-
- // ********************************************************************
- // Material chunks
- CHUNK_MAT_MATERIAL = 0xAFFF,
-
- // asciiz containing the name of the material
- CHUNK_MAT_MATNAME = 0xA000,
- CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk
- CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk
- CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk
-
- // Specifies the shininess of the material
- // followed by percentage chunk
- CHUNK_MAT_SHININESS = 0xA040,
- CHUNK_MAT_SHININESS_PERCENT = 0xA041,
-
- // Specifies the shading mode to be used
- // followed by a short
- CHUNK_MAT_SHADING = 0xA100,
-
- // NOTE: Emissive color (self illumination) seems not
- // to be a color but a single value, type is unknown.
- // Make the parser accept both of them.
- // followed by percentage chunk (?)
- CHUNK_MAT_SELF_ILLUM = 0xA080,
-
- // Always followed by percentage chunk (?)
- CHUNK_MAT_SELF_ILPCT = 0xA084,
-
- // Always followed by percentage chunk
- CHUNK_MAT_TRANSPARENCY = 0xA050,
-
- // Diffuse texture channel 0
- CHUNK_MAT_TEXTURE = 0xA200,
-
- // Contains opacity information for each texel
- CHUNK_MAT_OPACMAP = 0xA210,
-
- // Contains a reflection map to be used to reflect
- // the environment. This is partially supported.
- CHUNK_MAT_REFLMAP = 0xA220,
-
- // Self Illumination map (emissive colors)
- CHUNK_MAT_SELFIMAP = 0xA33d,
-
- // Bumpmap. Not specified whether it is a heightmap
- // or a normal map. Assme it is a heightmap since
- // artist normally prefer this format.
- CHUNK_MAT_BUMPMAP = 0xA230,
-
- // Specular map. Seems to influence the specular color
- CHUNK_MAT_SPECMAP = 0xA204,
-
- // Holds shininess data.
- CHUNK_MAT_MAT_SHINMAP = 0xA33C,
-
- // Scaling in U/V direction.
- // (need to gen separate UV coordinate set
- // and do this by hand)
- CHUNK_MAT_MAP_USCALE = 0xA354,
- CHUNK_MAT_MAP_VSCALE = 0xA356,
-
- // Translation in U/V direction.
- // (need to gen separate UV coordinate set
- // and do this by hand)
- CHUNK_MAT_MAP_UOFFSET = 0xA358,
- CHUNK_MAT_MAP_VOFFSET = 0xA35a,
-
- // UV-coordinates rotation around the z-axis
- // Assumed to be in radians.
- CHUNK_MAT_MAP_ANG = 0xA35C,
-
- // Tiling flags for 3DS files
- CHUNK_MAT_MAP_TILING = 0xa351,
-
- // Specifies the file name of a texture
- CHUNK_MAPFILE = 0xA300,
-
- // Specifies whether a material requires two-sided rendering
- CHUNK_MAT_TWO_SIDE = 0xA081,
- // ********************************************************************
-
- // Main keyframer chunk. Contains translation/rotation/scaling data
- CHUNK_KEYFRAMER = 0xB000,
-
- // Supported sub chunks
- CHUNK_TRACKINFO = 0xB002,
- CHUNK_TRACKOBJNAME = 0xB010,
- CHUNK_TRACKDUMMYOBJNAME = 0xB011,
- CHUNK_TRACKPIVOT = 0xB013,
- CHUNK_TRACKPOS = 0xB020,
- CHUNK_TRACKROTATE = 0xB021,
- CHUNK_TRACKSCALE = 0xB022,
-
- // ********************************************************************
- // Keyframes for various other stuff in the file
- // Partially ignored
- CHUNK_AMBIENTKEY = 0xB001,
- CHUNK_TRACKMORPH = 0xB026,
- CHUNK_TRACKHIDE = 0xB029,
- CHUNK_OBJNUMBER = 0xB030,
- CHUNK_TRACKCAMERA = 0xB003,
- CHUNK_TRACKFOV = 0xB023,
- CHUNK_TRACKROLL = 0xB024,
- CHUNK_TRACKCAMTGT = 0xB004,
- CHUNK_TRACKLIGHT = 0xB005,
- CHUNK_TRACKLIGTGT = 0xB006,
- CHUNK_TRACKSPOTL = 0xB007,
- CHUNK_FRAMES = 0xB008,
- // ********************************************************************
-
- // light sub-chunks
- CHUNK_DL_OFF = 0x4620,
- CHUNK_DL_OUTER_RANGE = 0x465A,
- CHUNK_DL_INNER_RANGE = 0x4659,
- CHUNK_DL_MULTIPLIER = 0x465B,
- CHUNK_DL_EXCLUDE = 0x4654,
- CHUNK_DL_ATTENUATE = 0x4625,
- CHUNK_DL_SPOTLIGHT = 0x4610,
-
- // camera sub-chunks
- CHUNK_CAM_RANGES = 0x4720
- };
-}
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a 3ds mesh face */
-struct Face : public FaceWithSmoothingGroup {
-};
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4315)
-#endif // _MSC_VER
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a texture */
-struct Texture {
- //! Default constructor
- Texture() AI_NO_EXCEPT
- : mTextureBlend(0.0f),
- mMapName(),
- mOffsetU(0.0),
- mOffsetV(0.0),
- mScaleU(1.0),
- mScaleV(1.0),
- mRotation(0.0),
- mMapMode(aiTextureMapMode_Wrap),
- bPrivate(),
- iUVSrc(0) {
- mTextureBlend = get_qnan();
- }
-
- Texture(const Texture &other) :
- mTextureBlend(other.mTextureBlend),
- mMapName(other.mMapName),
- mOffsetU(other.mOffsetU),
- mOffsetV(other.mOffsetV),
- mScaleU(other.mScaleU),
- mScaleV(other.mScaleV),
- mRotation(other.mRotation),
- mMapMode(other.mMapMode),
- bPrivate(other.bPrivate),
- iUVSrc(other.iUVSrc) {
- // empty
- }
-
- Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(other.mTextureBlend),
- mMapName(std::move(other.mMapName)),
- mOffsetU(other.mOffsetU),
- mOffsetV(other.mOffsetV),
- mScaleU(other.mScaleU),
- mScaleV(other.mScaleV),
- mRotation(other.mRotation),
- mMapMode(other.mMapMode),
- bPrivate(other.bPrivate),
- iUVSrc(other.iUVSrc) {
- // empty
- }
-
- Texture &operator=(Texture &&other) AI_NO_EXCEPT {
- if (this == &other) {
- return *this;
- }
-
- mTextureBlend = other.mTextureBlend;
- mMapName = std::move(other.mMapName);
- mOffsetU = other.mOffsetU;
- mOffsetV = other.mOffsetV;
- mScaleU = other.mScaleU;
- mScaleV = other.mScaleV;
- mRotation = other.mRotation;
- mMapMode = other.mMapMode;
- bPrivate = other.bPrivate;
- iUVSrc = other.iUVSrc;
-
- return *this;
- }
-
- //! Specifies the blend factor for the texture
- ai_real mTextureBlend;
-
- //! Specifies the filename of the texture
- std::string mMapName;
-
- //! Specifies texture coordinate offsets/scaling/rotations
- ai_real mOffsetU;
- ai_real mOffsetV;
- ai_real mScaleU;
- ai_real mScaleV;
- ai_real mRotation;
-
- //! Specifies the mapping mode to be used for the texture
- aiTextureMapMode mMapMode;
-
- //! Used internally
- bool bPrivate;
- int iUVSrc;
-};
-
-#include <assimp/Compiler/poppack1.h>
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a 3ds material */
-struct Material {
- //! Default constructor has been deleted
- Material() :
- mName(),
- mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
- mSpecularExponent(ai_real(0.0)),
- mShininessStrength(ai_real(1.0)),
- mShading(Discreet3DS::Gouraud),
- mTransparency(ai_real(1.0)),
- mBumpHeight(ai_real(1.0)),
- mTwoSided(false) {
- // empty
- }
-
- //! Constructor with explicit name
- explicit Material(const std::string &name) :
- mName(name),
- mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
- mSpecularExponent(ai_real(0.0)),
- mShininessStrength(ai_real(1.0)),
- mShading(Discreet3DS::Gouraud),
- mTransparency(ai_real(1.0)),
- mBumpHeight(ai_real(1.0)),
- mTwoSided(false) {
- // empty
- }
-
- Material(const Material &other) :
- mName(other.mName),
- mDiffuse(other.mDiffuse),
- mSpecularExponent(other.mSpecularExponent),
- mShininessStrength(other.mShininessStrength),
- mSpecular(other.mSpecular),
- mAmbient(other.mAmbient),
- mShading(other.mShading),
- mTransparency(other.mTransparency),
- sTexDiffuse(other.sTexDiffuse),
- sTexOpacity(other.sTexOpacity),
- sTexSpecular(other.sTexSpecular),
- sTexReflective(other.sTexReflective),
- sTexBump(other.sTexBump),
- sTexEmissive(other.sTexEmissive),
- sTexShininess(other.sTexShininess),
- mBumpHeight(other.mBumpHeight),
- mEmissive(other.mEmissive),
- sTexAmbient(other.sTexAmbient),
- mTwoSided(other.mTwoSided) {
- // empty
- }
-
- //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
- Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
- mDiffuse(other.mDiffuse),
- mSpecularExponent(other.mSpecularExponent),
- mShininessStrength(other.mShininessStrength),
- mSpecular(other.mSpecular),
- mAmbient(other.mAmbient),
- mShading(other.mShading),
- mTransparency(other.mTransparency),
- sTexDiffuse(std::move(other.sTexDiffuse)),
- sTexOpacity(std::move(other.sTexOpacity)),
- sTexSpecular(std::move(other.sTexSpecular)),
- sTexReflective(std::move(other.sTexReflective)),
- sTexBump(std::move(other.sTexBump)),
- sTexEmissive(std::move(other.sTexEmissive)),
- sTexShininess(std::move(other.sTexShininess)),
- mBumpHeight(other.mBumpHeight),
- mEmissive(other.mEmissive),
- sTexAmbient(std::move(other.sTexAmbient)),
- mTwoSided(other.mTwoSided) {
- // empty
- }
-
- Material &operator=(Material &&other) AI_NO_EXCEPT {
- if (this == &other) {
- return *this;
- }
-
- mName = std::move(other.mName);
- mDiffuse = other.mDiffuse;
- mSpecularExponent = other.mSpecularExponent;
- mShininessStrength = other.mShininessStrength,
- mSpecular = other.mSpecular;
- mAmbient = other.mAmbient;
- mShading = other.mShading;
- mTransparency = other.mTransparency;
- sTexDiffuse = std::move(other.sTexDiffuse);
- sTexOpacity = std::move(other.sTexOpacity);
- sTexSpecular = std::move(other.sTexSpecular);
- sTexReflective = std::move(other.sTexReflective);
- sTexBump = std::move(other.sTexBump);
- sTexEmissive = std::move(other.sTexEmissive);
- sTexShininess = std::move(other.sTexShininess);
- mBumpHeight = other.mBumpHeight;
- mEmissive = other.mEmissive;
- sTexAmbient = std::move(other.sTexAmbient);
- mTwoSided = other.mTwoSided;
-
- return *this;
- }
-
- virtual ~Material() {
- // empty
- }
-
- //! Name of the material
- std::string mName;
- //! Diffuse color of the material
- aiColor3D mDiffuse;
- //! Specular exponent
- ai_real mSpecularExponent;
- //! Shininess strength, in percent
- ai_real mShininessStrength;
- //! Specular color of the material
- aiColor3D mSpecular;
- //! Ambient color of the material
- aiColor3D mAmbient;
- //! Shading type to be used
- Discreet3DS::shadetype3ds mShading;
- //! Opacity of the material
- ai_real mTransparency;
- //! Diffuse texture channel
- Texture sTexDiffuse;
- //! Opacity texture channel
- Texture sTexOpacity;
- //! Specular texture channel
- Texture sTexSpecular;
- //! Reflective texture channel
- Texture sTexReflective;
- //! Bump texture channel
- Texture sTexBump;
- //! Emissive texture channel
- Texture sTexEmissive;
- //! Shininess texture channel
- Texture sTexShininess;
- //! Scaling factor for the bump values
- ai_real mBumpHeight;
- //! Emissive color
- aiColor3D mEmissive;
- //! Ambient texture channel
- //! (used by the ASE format)
- Texture sTexAmbient;
- //! True if the material must be rendered from two sides
- bool mTwoSided;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent a 3ds file mesh */
-struct Mesh : public MeshWithSmoothingGroups<D3DS::Face> {
- //! Default constructor has been deleted
- Mesh() = delete;
-
- //! Constructor with explicit name
- explicit Mesh(const std::string &name) :
- mName(name) {
- }
-
- //! Name of the mesh
- std::string mName;
-
- //! Texture coordinates
- std::vector<aiVector3D> mTexCoords;
-
- //! Face materials
- std::vector<unsigned int> mFaceMaterials;
-
- //! Local transformation matrix
- aiMatrix4x4 mMat;
-};
-
-// ---------------------------------------------------------------------------
-/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the
- C-API, so it would be difficult to make them a template. */
-struct aiFloatKey {
- double mTime; ///< The time of this key
- ai_real mValue; ///< The value of this key
-
-#ifdef __cplusplus
-
- // time is not compared
- bool operator==(const aiFloatKey &o) const { return o.mValue == this->mValue; }
-
- bool operator!=(const aiFloatKey &o) const { return o.mValue != this->mValue; }
-
- // Only time is compared. This operator is defined
- // for use with std::sort
- bool operator<(const aiFloatKey &o) const { return mTime < o.mTime; }
-
- bool operator>(const aiFloatKey &o) const { return mTime > o.mTime; }
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent a 3ds file node */
-struct Node {
- Node() = delete;
-
- explicit Node(const std::string &name) :
- mParent(nullptr),
- mName(name),
- mInstanceNumber(0),
- mHierarchyPos(0),
- mHierarchyIndex(0),
- mInstanceCount(1) {
- aRotationKeys.reserve(20);
- aPositionKeys.reserve(20);
- aScalingKeys.reserve(20);
- }
-
- ~Node() {
- for (unsigned int i = 0; i < mChildren.size(); ++i)
- delete mChildren[i];
- }
-
- //! Pointer to the parent node
- Node *mParent;
-
- //! Holds all child nodes
- std::vector<Node *> mChildren;
-
- //! Name of the node
- std::string mName;
-
- //! InstanceNumber of the node
- int32_t mInstanceNumber;
-
- //! Dummy nodes: real name to be combined with the $$$DUMMY
- std::string mDummyName;
-
- //! Position of the node in the hierarchy (tree depth)
- int16_t mHierarchyPos;
-
- //! Index of the node
- int16_t mHierarchyIndex;
-
- //! Rotation keys loaded from the file
- std::vector<aiQuatKey> aRotationKeys;
-
- //! Position keys loaded from the file
- std::vector<aiVectorKey> aPositionKeys;
-
- //! Scaling keys loaded from the file
- std::vector<aiVectorKey> aScalingKeys;
-
- // For target lights (spot lights and directional lights):
- // The position of the target
- std::vector<aiVectorKey> aTargetPositionKeys;
-
- // For cameras: the camera roll angle
- std::vector<aiFloatKey> aCameraRollKeys;
-
- //! Pivot position loaded from the file
- aiVector3D vPivot;
-
- //instance count, will be kept only for the first node
- int32_t mInstanceCount;
-
- //! Add a child node, setup the right parent node for it
- //! \param pc Node to be 'adopted'
- inline Node &push_back(Node *pc) {
- mChildren.push_back(pc);
- pc->mParent = this;
- return *this;
- }
-};
-// ---------------------------------------------------------------------------
-/** Helper structure analogue to aiScene */
-struct Scene {
- //! List of all materials loaded
- //! NOTE: 3ds references materials globally
- std::vector<Material> mMaterials;
-
- //! List of all meshes loaded
- std::vector<Mesh> mMeshes;
-
- //! List of all cameras loaded
- std::vector<aiCamera *> mCameras;
-
- //! List of all lights loaded
- std::vector<aiLight *> mLights;
-
- //! Pointer to the root node of the scene
- // --- moved to main class
- // Node* pcRootNode;
-};
-
-} // end of namespace D3DS
-} // end of namespace Assimp
-
-#endif // AI_XFILEHELPER_H_INC
diff --git a/libs/assimp/code/AssetLib/3DS/3DSLoader.cpp b/libs/assimp/code/AssetLib/3DS/3DSLoader.cpp
deleted file mode 100644
index 0ec8b87..0000000
--- a/libs/assimp/code/AssetLib/3DS/3DSLoader.cpp
+++ /dev/null
@@ -1,1336 +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 3DSLoader.cpp
- * @brief Implementation of the 3ds importer class
- *
- * http://www.the-labs.com/Blender/3DS-details.html
- */
-
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-#include "3DSLoader.h"
-#include <assimp/StringComparison.h>
-#include <assimp/importerdesc.h>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/IOSystem.hpp>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Discreet 3DS Importer",
- "",
- "",
- "Limited animation support",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "3ds prj"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Begins a new parsing block
-// - Reads the current chunk and validates it
-// - computes its length
-#define ASSIMP_3DS_BEGIN_CHUNK() \
- while (true) { \
- if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)) { \
- return; \
- } \
- Discreet3DS::Chunk chunk; \
- ReadChunk(&chunk); \
- int chunkSize = chunk.Size - sizeof(Discreet3DS::Chunk); \
- if (chunkSize <= 0) \
- continue; \
- const unsigned int oldReadLimit = stream->SetReadLimit( \
- stream->GetCurrentPos() + chunkSize);
-
-// ------------------------------------------------------------------------------------------------
-// End a parsing block
-// Must follow at the end of each parsing block, reset chunk end marker to previous value
-#define ASSIMP_3DS_END_CHUNK() \
- stream->SkipToReadLimit(); \
- stream->SetReadLimit(oldReadLimit); \
- if (stream->GetRemainingSizeToLimit() == 0) \
- return; \
- }
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-Discreet3DSImporter::Discreet3DSImporter() :
- stream(), mLastNodeIndex(), mCurrentNode(), mRootNode(), mScene(), mMasterScale(), bHasBG(), bIsPrj() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-Discreet3DSImporter::~Discreet3DSImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
- static const uint16_t token[] = { 0x4d4d, 0x3dc2 /*, 0x3daa */ };
- return CheckMagicToken(pIOHandler, pFile, token, AI_COUNT_OF(token), 0, sizeof token[0]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Loader registry entry
-const aiImporterDesc *Discreet3DSImporter::GetInfo() const {
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) {
- // nothing to be done for the moment
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void Discreet3DSImporter::InternReadFile(const std::string &pFile,
- aiScene *pScene, IOSystem *pIOHandler) {
-
- auto theFile = pIOHandler->Open(pFile, "rb");
- if (!theFile) {
- throw DeadlyImportError("3DS: Could not open ", pFile);
- }
-
- StreamReaderLE theStream(theFile);
-
- // We should have at least one chunk
- if (theStream.GetRemainingSize() < 16) {
- throw DeadlyImportError("3DS file is either empty or corrupt: ", pFile);
- }
- this->stream = &theStream;
-
- // Allocate our temporary 3DS representation
- D3DS::Scene _scene;
- mScene = &_scene;
-
- // Initialize members
- D3DS::Node _rootNode("UNNAMED");
- mLastNodeIndex = -1;
- mCurrentNode = &_rootNode;
- mRootNode = mCurrentNode;
- mRootNode->mHierarchyPos = -1;
- mRootNode->mHierarchyIndex = -1;
- mRootNode->mParent = nullptr;
- mMasterScale = 1.0f;
- mBackgroundImage = std::string();
- bHasBG = false;
- bIsPrj = false;
-
- // Parse the file
- ParseMainChunk();
-
- // Process all meshes in the file. First check whether all
- // face indices have valid values. The generate our
- // internal verbose representation. Finally compute normal
- // vectors from the smoothing groups we read from the
- // file.
- for (auto &mesh : mScene->mMeshes) {
- if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
- throw DeadlyImportError("3DS file contains faces but no vertices: ", pFile);
- }
- CheckIndices(mesh);
- MakeUnique(mesh);
- ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
- }
-
- // Replace all occurrences of the default material with a
- // valid material. Generate it if no material containing
- // DEFAULT in its name has been found in the file
- ReplaceDefaultMaterial();
-
- // Convert the scene from our internal representation to an
- // aiScene object. This involves copying all meshes, lights
- // and cameras to the scene
- ConvertScene(pScene);
-
- // Generate the node graph for the scene. This is a little bit
- // tricky since we'll need to split some meshes into sub-meshes
- GenerateNodeGraph(pScene);
-
- // Now apply the master scaling factor to the scene
- ApplyMasterScale(pScene);
-
- // Our internal scene representation and the root
- // node will be automatically deleted, so the whole hierarchy will follow
-
- AI_DEBUG_INVALIDATE_PTR(mRootNode);
- AI_DEBUG_INVALIDATE_PTR(mScene);
- AI_DEBUG_INVALIDATE_PTR(this->stream);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Applies a master-scaling factor to the imported scene
-void Discreet3DSImporter::ApplyMasterScale(aiScene *pScene) {
- // There are some 3DS files with a zero scaling factor
- if (!mMasterScale)
- mMasterScale = 1.0f;
- else
- mMasterScale = 1.0f / mMasterScale;
-
- // Construct an uniform scaling matrix and multiply with it
- pScene->mRootNode->mTransformation *= aiMatrix4x4(
- mMasterScale, 0.0f, 0.0f, 0.0f,
- 0.0f, mMasterScale, 0.0f, 0.0f,
- 0.0f, 0.0f, mMasterScale, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
- // Check whether a scaling track is assigned to the root node.
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a new chunk from the file
-void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk *pcOut) {
- ai_assert(pcOut != nullptr);
-
- pcOut->Flag = stream->GetI2();
- pcOut->Size = stream->GetI4();
-
- if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize()) {
- throw DeadlyImportError("Chunk is too large");
- }
-
- if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit()) {
- ASSIMP_LOG_ERROR("3DS: Chunk overflow");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skip a chunk
-void Discreet3DSImporter::SkipChunk() {
- Discreet3DS::Chunk psChunk;
- ReadChunk(&psChunk);
-
- stream->IncPtr(psChunk.Size - sizeof(Discreet3DS::Chunk));
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Process the primary chunk of the file
-void Discreet3DSImporter::ParseMainChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag) {
-
- case Discreet3DS::CHUNK_PRJ:
- bIsPrj = true;
- break;
- case Discreet3DS::CHUNK_MAIN:
- ParseEditorChunk();
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
- // recursively continue processing this hierarchy level
- return ParseMainChunk();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseEditorChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_OBJMESH:
-
- ParseObjectChunk();
- break;
-
- // NOTE: In several documentations in the internet this
- // chunk appears at different locations
- case Discreet3DS::CHUNK_KEYFRAMER:
-
- ParseKeyframeChunk();
- break;
-
- case Discreet3DS::CHUNK_VERSION: {
- // print the version number
- char buff[10];
- ASSIMP_itoa10(buff, stream->GetI2());
- ASSIMP_LOG_INFO("3DS file format version: ", buff);
- } break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseObjectChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_OBJBLOCK: {
- unsigned int cnt = 0;
- const char *sz = (const char *)stream->GetPtr();
-
- // Get the name of the geometry object
- while (stream->GetI1())
- ++cnt;
- ParseChunk(sz, cnt);
- } break;
-
- case Discreet3DS::CHUNK_MAT_MATERIAL:
-
- // Add a new material to the list
- mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + ai_to_string(mScene->mMaterials.size()))));
- ParseMaterialChunk();
- break;
-
- case Discreet3DS::CHUNK_AMBCOLOR:
-
- // This is the ambient base color of the scene.
- // We add it to the ambient color of all materials
- ParseColorChunk(&mClrAmbient, true);
- if (is_qnan(mClrAmbient.r)) {
- // We failed to read the ambient base color.
- ASSIMP_LOG_ERROR("3DS: Failed to read ambient base color");
- mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f;
- }
- break;
-
- case Discreet3DS::CHUNK_BIT_MAP: {
- // Specifies the background image. The string should already be
- // properly 0 terminated but we need to be sure
- unsigned int cnt = 0;
- const char *sz = (const char *)stream->GetPtr();
- while (stream->GetI1())
- ++cnt;
- mBackgroundImage = std::string(sz, cnt);
- } break;
-
- case Discreet3DS::CHUNK_BIT_MAP_EXISTS:
- bHasBG = true;
- break;
-
- case Discreet3DS::CHUNK_MASTER_SCALE:
- // Scene master scaling factor
- mMasterScale = stream->GetF4();
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // IMPLEMENTATION NOTE;
- // Cameras or lights define their transformation in their parent node and in the
- // corresponding light or camera chunks. However, we read and process the latter
- // to to be able to return valid cameras/lights even if no scenegraph is given.
-
- // get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_TRIMESH: {
- // this starts a new triangle mesh
- mScene->mMeshes.push_back(D3DS::Mesh(std::string(name, num)));
-
- // Read mesh chunks
- ParseMeshChunk();
- } break;
-
- case Discreet3DS::CHUNK_LIGHT: {
- // This starts a new light
- aiLight *light = new aiLight();
- mScene->mLights.push_back(light);
-
- light->mName.Set(std::string(name, num));
-
- // First read the position of the light
- light->mPosition.x = stream->GetF4();
- light->mPosition.y = stream->GetF4();
- light->mPosition.z = stream->GetF4();
-
- light->mColorDiffuse = aiColor3D(1.f, 1.f, 1.f);
-
- // Now check for further subchunks
- if (!bIsPrj) /* fixme */
- ParseLightChunk();
-
- // The specular light color is identical the the diffuse light color. The ambient light color
- // is equal to the ambient base color of the whole scene.
- light->mColorSpecular = light->mColorDiffuse;
- light->mColorAmbient = mClrAmbient;
-
- if (light->mType == aiLightSource_UNDEFINED) {
- // It must be a point light
- light->mType = aiLightSource_POINT;
- }
- } break;
-
- case Discreet3DS::CHUNK_CAMERA: {
- // This starts a new camera
- aiCamera *camera = new aiCamera();
- mScene->mCameras.push_back(camera);
- camera->mName.Set(std::string(name, num));
-
- // First read the position of the camera
- camera->mPosition.x = stream->GetF4();
- camera->mPosition.y = stream->GetF4();
- camera->mPosition.z = stream->GetF4();
-
- // Then the camera target
- camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
- camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
- camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
- ai_real len = camera->mLookAt.Length();
- if (len < 1e-5) {
-
- // There are some files with lookat == position. Don't know why or whether it's ok or not.
- ASSIMP_LOG_ERROR("3DS: Unable to read proper camera look-at vector");
- camera->mLookAt = aiVector3D(0.0, 1.0, 0.0);
-
- } else
- camera->mLookAt /= len;
-
- // And finally - the camera rotation angle, in counter clockwise direction
- const ai_real angle = AI_DEG_TO_RAD(stream->GetF4());
- aiQuaternion quat(camera->mLookAt, angle);
- camera->mUp = quat.GetMatrix() * aiVector3D(0.0, 1.0, 0.0);
-
- // Read the lense angle
- camera->mHorizontalFOV = AI_DEG_TO_RAD(stream->GetF4());
- if (camera->mHorizontalFOV < 0.001f) {
- camera->mHorizontalFOV = float(AI_DEG_TO_RAD(45.f));
- }
-
- // Now check for further subchunks
- if (!bIsPrj) /* fixme */ {
- ParseCameraChunk();
- }
- } break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseLightChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
- aiLight *light = mScene->mLights.back();
-
- // get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_DL_SPOTLIGHT:
- // Now we can be sure that the light is a spot light
- light->mType = aiLightSource_SPOT;
-
- // We wouldn't need to normalize here, but we do it
- light->mDirection.x = stream->GetF4() - light->mPosition.x;
- light->mDirection.y = stream->GetF4() - light->mPosition.y;
- light->mDirection.z = stream->GetF4() - light->mPosition.z;
- light->mDirection.Normalize();
-
- // Now the hotspot and falloff angles - in degrees
- light->mAngleInnerCone = AI_DEG_TO_RAD(stream->GetF4());
-
- // FIX: the falloff angle is just an offset
- light->mAngleOuterCone = light->mAngleInnerCone + AI_DEG_TO_RAD(stream->GetF4());
- break;
-
- // intensity multiplier
- case Discreet3DS::CHUNK_DL_MULTIPLIER:
- light->mColorDiffuse = light->mColorDiffuse * stream->GetF4();
- break;
-
- // light color
- case Discreet3DS::CHUNK_RGBF:
- case Discreet3DS::CHUNK_LINRGBF:
- light->mColorDiffuse.r *= stream->GetF4();
- light->mColorDiffuse.g *= stream->GetF4();
- light->mColorDiffuse.b *= stream->GetF4();
- break;
-
- // light attenuation
- case Discreet3DS::CHUNK_DL_ATTENUATE:
- light->mAttenuationLinear = stream->GetF4();
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseCameraChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
- aiCamera *camera = mScene->mCameras.back();
-
- // get chunk type
- switch (chunk.Flag) {
- // near and far clip plane
- case Discreet3DS::CHUNK_CAM_RANGES:
- camera->mClipPlaneNear = stream->GetF4();
- camera->mClipPlaneFar = stream->GetF4();
- break;
- }
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseKeyframeChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_TRACKCAMTGT:
- case Discreet3DS::CHUNK_TRACKSPOTL:
- case Discreet3DS::CHUNK_TRACKCAMERA:
- case Discreet3DS::CHUNK_TRACKINFO:
- case Discreet3DS::CHUNK_TRACKLIGHT:
- case Discreet3DS::CHUNK_TRACKLIGTGT:
-
- // this starts a new mesh hierarchy chunk
- ParseHierarchyChunk(chunk.Flag);
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Little helper function for ParseHierarchyChunk
-void Discreet3DSImporter::InverseNodeSearch(D3DS::Node *pcNode, D3DS::Node *pcCurrent) {
- if (!pcCurrent) {
- mRootNode->push_back(pcNode);
- return;
- }
-
- if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos) {
- if (pcCurrent->mParent) {
- pcCurrent->mParent->push_back(pcNode);
- } else
- pcCurrent->push_back(pcNode);
- return;
- }
- return InverseNodeSearch(pcNode, pcCurrent->mParent);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find a node with a specific name in the import hierarchy
-D3DS::Node *FindNode(D3DS::Node *root, const std::string &name) {
- if (root->mName == name) {
- return root;
- }
-
- for (std::vector<D3DS::Node *>::iterator it = root->mChildren.begin(); it != root->mChildren.end(); ++it) {
- D3DS::Node *nd = FindNode(*it, name);
- if (nullptr != nd) {
- return nd;
- }
- }
-
- return nullptr;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Binary predicate for std::unique()
-template <class T>
-bool KeyUniqueCompare(const T &first, const T &second) {
- return first.mTime == second.mTime;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skip some additional import data.
-void Discreet3DSImporter::SkipTCBInfo() {
- unsigned int flags = stream->GetI2();
-
- if (!flags) {
- // Currently we can't do anything with these values. They occur
- // quite rare, so it wouldn't be worth the effort implementing
- // them. 3DS is not really suitable for complex animations,
- // so full support is not required.
- ASSIMP_LOG_WARN("3DS: Skipping TCB animation info");
- }
-
- if (flags & Discreet3DS::KEY_USE_TENS) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_BIAS) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_CONT) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_EASE_FROM) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_EASE_TO) {
- stream->IncPtr(4);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read hierarchy and keyframe info
-void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_TRACKOBJNAME:
-
- // This is the name of the object to which the track applies. The chunk also
- // defines the position of this object in the hierarchy.
- {
-
- // First of all: get the name of the object
- unsigned int cnt = 0;
- const char *sz = (const char *)stream->GetPtr();
-
- while (stream->GetI1())
- ++cnt;
- std::string name = std::string(sz, cnt);
-
- // Now find out whether we have this node already (target animation channels
- // are stored with a separate object ID)
- D3DS::Node *pcNode = FindNode(mRootNode, name);
- int instanceNumber = 1;
-
- if (pcNode) {
- // if the source is not a CHUNK_TRACKINFO block it won't be an object instance
- if (parent != Discreet3DS::CHUNK_TRACKINFO) {
- mCurrentNode = pcNode;
- break;
- }
- pcNode->mInstanceCount++;
- instanceNumber = pcNode->mInstanceCount;
- }
- pcNode = new D3DS::Node(name);
- pcNode->mInstanceNumber = instanceNumber;
-
- // There are two unknown values which we can safely ignore
- stream->IncPtr(4);
-
- // Now read the hierarchy position of the object
- uint16_t hierarchy = stream->GetI2() + 1;
- pcNode->mHierarchyPos = hierarchy;
- pcNode->mHierarchyIndex = mLastNodeIndex;
-
- // And find a proper position in the graph for it
- if (mCurrentNode && mCurrentNode->mHierarchyPos == hierarchy) {
-
- // add to the parent of the last touched node
- mCurrentNode->mParent->push_back(pcNode);
- mLastNodeIndex++;
- } else if (hierarchy >= mLastNodeIndex) {
-
- // place it at the current position in the hierarchy
- mCurrentNode->push_back(pcNode);
- mLastNodeIndex = hierarchy;
- } else {
- // need to go back to the specified position in the hierarchy.
- InverseNodeSearch(pcNode, mCurrentNode);
- mLastNodeIndex++;
- }
- // Make this node the current node
- mCurrentNode = pcNode;
- }
- break;
-
- case Discreet3DS::CHUNK_TRACKDUMMYOBJNAME:
-
- // This is the "real" name of a $$$DUMMY object
- {
- const char *sz = (const char *)stream->GetPtr();
- while (stream->GetI1())
- ;
-
- // If object name is DUMMY, take this one instead
- if (mCurrentNode->mName == "$$$DUMMY") {
- mCurrentNode->mName = std::string(sz);
- break;
- }
- }
- break;
-
- case Discreet3DS::CHUNK_TRACKPIVOT:
-
- if (Discreet3DS::CHUNK_TRACKINFO != parent) {
- ASSIMP_LOG_WARN("3DS: Skipping pivot subchunk for non usual object");
- break;
- }
-
- // Pivot = origin of rotation and scaling
- mCurrentNode->vPivot.x = stream->GetF4();
- mCurrentNode->vPivot.y = stream->GetF4();
- mCurrentNode->vPivot.z = stream->GetF4();
- break;
-
- // ////////////////////////////////////////////////////////////////////
- // POSITION KEYFRAME
- case Discreet3DS::CHUNK_TRACKPOS: {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
- bool sortKeys = false;
-
- // This could also be meant as the target position for
- // (targeted) lights and cameras
- std::vector<aiVectorKey> *l;
- if (Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent) {
- l = &mCurrentNode->aTargetPositionKeys;
- } else
- l = &mCurrentNode->aPositionKeys;
-
- l->reserve(numFrames);
- for (unsigned int i = 0; i < numFrames; ++i) {
- const unsigned int fidx = stream->GetI4();
-
- // Setup a new position key
- aiVectorKey v;
- v.mTime = (double)fidx;
-
- SkipTCBInfo();
- v.mValue.x = stream->GetF4();
- v.mValue.y = stream->GetF4();
- v.mValue.z = stream->GetF4();
-
- // check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Add the new keyframe to the list
- l->push_back(v);
- }
-
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(), l->end());
- l->erase(std::unique(l->begin(), l->end(), &KeyUniqueCompare<aiVectorKey>), l->end());
- }
- }
-
- break;
-
- // ////////////////////////////////////////////////////////////////////
- // CAMERA ROLL KEYFRAME
- case Discreet3DS::CHUNK_TRACKROLL: {
- // roll keys are accepted for cameras only
- if (parent != Discreet3DS::CHUNK_TRACKCAMERA) {
- ASSIMP_LOG_WARN("3DS: Ignoring roll track for non-camera object");
- break;
- }
- bool sortKeys = false;
- std::vector<aiFloatKey> *l = &mCurrentNode->aCameraRollKeys;
-
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
- l->reserve(numFrames);
- for (unsigned int i = 0; i < numFrames; ++i) {
- const unsigned int fidx = stream->GetI4();
-
- // Setup a new position key
- aiFloatKey v;
- v.mTime = (double)fidx;
-
- // This is just a single float
- SkipTCBInfo();
- v.mValue = stream->GetF4();
-
- // Check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Add the new keyframe to the list
- l->push_back(v);
- }
-
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(), l->end());
- l->erase(std::unique(l->begin(), l->end(), &KeyUniqueCompare<aiFloatKey>), l->end());
- }
- } break;
-
- // ////////////////////////////////////////////////////////////////////
- // CAMERA FOV KEYFRAME
- case Discreet3DS::CHUNK_TRACKFOV: {
- ASSIMP_LOG_ERROR("3DS: Skipping FOV animation track. "
- "This is not supported");
- } break;
-
- // ////////////////////////////////////////////////////////////////////
- // ROTATION KEYFRAME
- case Discreet3DS::CHUNK_TRACKROTATE: {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
-
- bool sortKeys = false;
- std::vector<aiQuatKey> *l = &mCurrentNode->aRotationKeys;
- l->reserve(numFrames);
-
- for (unsigned int i = 0; i < numFrames; ++i) {
- const unsigned int fidx = stream->GetI4();
- SkipTCBInfo();
-
- aiQuatKey v;
- v.mTime = (double)fidx;
-
- // The rotation keyframe is given as an axis-angle pair
- const float rad = stream->GetF4();
- aiVector3D axis;
- axis.x = stream->GetF4();
- axis.y = stream->GetF4();
- axis.z = stream->GetF4();
-
- if (!axis.x && !axis.y && !axis.z)
- axis.y = 1.f;
-
- // Construct a rotation quaternion from the axis-angle pair
- v.mValue = aiQuaternion(axis, rad);
-
- // Check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // add the new keyframe to the list
- l->push_back(v);
- }
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(), l->end());
- l->erase(std::unique(l->begin(), l->end(), &KeyUniqueCompare<aiQuatKey>), l->end());
- }
- } break;
-
- // ////////////////////////////////////////////////////////////////////
- // SCALING KEYFRAME
- case Discreet3DS::CHUNK_TRACKSCALE: {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI2();
- stream->IncPtr(2);
-
- bool sortKeys = false;
- std::vector<aiVectorKey> *l = &mCurrentNode->aScalingKeys;
- l->reserve(numFrames);
-
- for (unsigned int i = 0; i < numFrames; ++i) {
- const unsigned int fidx = stream->GetI4();
- SkipTCBInfo();
-
- // Setup a new key
- aiVectorKey v;
- v.mTime = (double)fidx;
-
- // ... and read its value
- v.mValue.x = stream->GetF4();
- v.mValue.y = stream->GetF4();
- v.mValue.z = stream->GetF4();
-
- // check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Remove zero-scalings on singular axes - they've been reported to be there erroneously in some strange files
- if (!v.mValue.x) v.mValue.x = 1.f;
- if (!v.mValue.y) v.mValue.y = 1.f;
- if (!v.mValue.z) v.mValue.z = 1.f;
-
- l->push_back(v);
- }
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(), l->end());
- l->erase(std::unique(l->begin(), l->end(), &KeyUniqueCompare<aiVectorKey>), l->end());
- }
- } break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a face chunk - it contains smoothing groups and material assignments
-void Discreet3DSImporter::ParseFaceChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // Get the mesh we're currently working on
- D3DS::Mesh &mMesh = mScene->mMeshes.back();
-
- // Get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_SMOOLIST: {
- // This is the list of smoothing groups - a bitfield for every face.
- // Up to 32 smoothing groups assigned to a single face.
- unsigned int num = chunkSize / 4, m = 0;
- if (num > mMesh.mFaces.size()) {
- throw DeadlyImportError("3DS: More smoothing groups than faces");
- }
- for (std::vector<D3DS::Face>::iterator i = mMesh.mFaces.begin(); m != num; ++i, ++m) {
- // nth bit is set for nth smoothing group
- (*i).iSmoothGroup = stream->GetI4();
- }
- } break;
-
- case Discreet3DS::CHUNK_FACEMAT: {
- // at fist an asciiz with the material name
- const char *sz = (const char *)stream->GetPtr();
- while (stream->GetI1())
- ;
-
- // find the index of the material
- unsigned int idx = 0xcdcdcdcd, cnt = 0;
- for (std::vector<D3DS::Material>::const_iterator i = mScene->mMaterials.begin(); i != mScene->mMaterials.end(); ++i, ++cnt) {
- // use case independent comparisons. hopefully it will work.
- if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str())) {
- idx = cnt;
- break;
- }
- }
- if (0xcdcdcdcd == idx) {
- ASSIMP_LOG_ERROR("3DS: Unknown material: ", sz);
- }
-
- // Now continue and read all material indices
- cnt = (uint16_t)stream->GetI2();
- for (unsigned int i = 0; i < cnt; ++i) {
- unsigned int fidx = (uint16_t)stream->GetI2();
-
- // check range
- if (fidx >= mMesh.mFaceMaterials.size()) {
- ASSIMP_LOG_ERROR("3DS: Invalid face index in face material list");
- } else
- mMesh.mFaceMaterials[fidx] = idx;
- }
- } break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a mesh chunk. Here's the actual mesh data
-void Discreet3DSImporter::ParseMeshChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // Get the mesh we're currently working on
- D3DS::Mesh &mMesh = mScene->mMeshes.back();
-
- // get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_VERTLIST: {
- // This is the list of all vertices in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mPositions.reserve(num);
- while (num-- > 0) {
- aiVector3D v;
- v.x = stream->GetF4();
- v.y = stream->GetF4();
- v.z = stream->GetF4();
- mMesh.mPositions.push_back(v);
- }
- } break;
- case Discreet3DS::CHUNK_TRMATRIX: {
- // This is the RLEATIVE transformation matrix of the current mesh. Vertices are
- // pretransformed by this matrix wonder.
- mMesh.mMat.a1 = stream->GetF4();
- mMesh.mMat.b1 = stream->GetF4();
- mMesh.mMat.c1 = stream->GetF4();
- mMesh.mMat.a2 = stream->GetF4();
- mMesh.mMat.b2 = stream->GetF4();
- mMesh.mMat.c2 = stream->GetF4();
- mMesh.mMat.a3 = stream->GetF4();
- mMesh.mMat.b3 = stream->GetF4();
- mMesh.mMat.c3 = stream->GetF4();
- mMesh.mMat.a4 = stream->GetF4();
- mMesh.mMat.b4 = stream->GetF4();
- mMesh.mMat.c4 = stream->GetF4();
- } break;
-
- case Discreet3DS::CHUNK_MAPLIST: {
- // This is the list of all UV coords in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mTexCoords.reserve(num);
- while (num-- > 0) {
- aiVector3D v;
- v.x = stream->GetF4();
- v.y = stream->GetF4();
- mMesh.mTexCoords.push_back(v);
- }
- } break;
-
- case Discreet3DS::CHUNK_FACELIST: {
- // This is the list of all faces in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mFaces.reserve(num);
- while (num-- > 0) {
- // 3DS faces are ALWAYS triangles
- mMesh.mFaces.push_back(D3DS::Face());
- D3DS::Face &sFace = mMesh.mFaces.back();
-
- sFace.mIndices[0] = (uint16_t)stream->GetI2();
- sFace.mIndices[1] = (uint16_t)stream->GetI2();
- sFace.mIndices[2] = (uint16_t)stream->GetI2();
-
- stream->IncPtr(2); // skip edge visibility flag
- }
-
- // Resize the material array (0xcdcdcdcd marks the default material; so if a face is
- // not referenced by a material, $$DEFAULT will be assigned to it)
- mMesh.mFaceMaterials.resize(mMesh.mFaces.size(), 0xcdcdcdcd);
-
- // Larger 3DS files could have multiple FACE chunks here
- chunkSize = (int)stream->GetRemainingSizeToLimit();
- if (chunkSize > (int)sizeof(Discreet3DS::Chunk))
- ParseFaceChunk();
- } break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a 3DS material chunk
-void Discreet3DSImporter::ParseMaterialChunk() {
- ASSIMP_3DS_BEGIN_CHUNK();
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_MAT_MATNAME:
-
- {
- // The material name string is already zero-terminated, but we need to be sure ...
- const char *sz = (const char *)stream->GetPtr();
- unsigned int cnt = 0;
- while (stream->GetI1())
- ++cnt;
-
- if (!cnt) {
- // This may not be, we use the default name instead
- ASSIMP_LOG_ERROR("3DS: Empty material name");
- } else
- mScene->mMaterials.back().mName = std::string(sz, cnt);
- } break;
-
- case Discreet3DS::CHUNK_MAT_DIFFUSE: {
- // This is the diffuse material color
- aiColor3D *pc = &mScene->mMaterials.back().mDiffuse;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- ASSIMP_LOG_ERROR("3DS: Unable to read DIFFUSE chunk");
- pc->r = pc->g = pc->b = 1.0f;
- }
- } break;
-
- case Discreet3DS::CHUNK_MAT_SPECULAR: {
- // This is the specular material color
- aiColor3D *pc = &mScene->mMaterials.back().mSpecular;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- ASSIMP_LOG_ERROR("3DS: Unable to read SPECULAR chunk");
- pc->r = pc->g = pc->b = 1.0f;
- }
- } break;
-
- case Discreet3DS::CHUNK_MAT_AMBIENT: {
- // This is the ambient material color
- aiColor3D *pc = &mScene->mMaterials.back().mAmbient;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- ASSIMP_LOG_ERROR("3DS: Unable to read AMBIENT chunk");
- pc->r = pc->g = pc->b = 0.0f;
- }
- } break;
-
- case Discreet3DS::CHUNK_MAT_SELF_ILLUM: {
- // This is the emissive material color
- aiColor3D *pc = &mScene->mMaterials.back().mEmissive;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- ASSIMP_LOG_ERROR("3DS: Unable to read EMISSIVE chunk");
- pc->r = pc->g = pc->b = 0.0f;
- }
- } break;
-
- case Discreet3DS::CHUNK_MAT_TRANSPARENCY: {
- // This is the material's transparency
- ai_real *pcf = &mScene->mMaterials.back().mTransparency;
- *pcf = ParsePercentageChunk();
-
- // NOTE: transparency, not opacity
- if (is_qnan(*pcf))
- *pcf = ai_real(1.0);
- else
- *pcf = ai_real(1.0) - *pcf * (ai_real)0xFFFF / ai_real(100.0);
- } break;
-
- case Discreet3DS::CHUNK_MAT_SHADING:
- // This is the material shading mode
- mScene->mMaterials.back().mShading = (D3DS::Discreet3DS::shadetype3ds)stream->GetI2();
- break;
-
- case Discreet3DS::CHUNK_MAT_TWO_SIDE:
- // This is the two-sided flag
- mScene->mMaterials.back().mTwoSided = true;
- break;
-
- case Discreet3DS::CHUNK_MAT_SHININESS: { // This is the shininess of the material
- ai_real *pcf = &mScene->mMaterials.back().mSpecularExponent;
- *pcf = ParsePercentageChunk();
- if (is_qnan(*pcf))
- *pcf = 0.0;
- else
- *pcf *= (ai_real)0xFFFF;
- } break;
-
- case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT: { // This is the shininess strength of the material
- ai_real *pcf = &mScene->mMaterials.back().mShininessStrength;
- *pcf = ParsePercentageChunk();
- if (is_qnan(*pcf))
- *pcf = ai_real(0.0);
- else
- *pcf *= (ai_real)0xffff / ai_real(100.0);
- } break;
-
- case Discreet3DS::CHUNK_MAT_SELF_ILPCT: { // This is the self illumination strength of the material
- ai_real f = ParsePercentageChunk();
- if (is_qnan(f))
- f = ai_real(0.0);
- else
- f *= (ai_real)0xFFFF / ai_real(100.0);
- mScene->mMaterials.back().mEmissive = aiColor3D(f, f, f);
- } break;
-
- // Parse texture chunks
- case Discreet3DS::CHUNK_MAT_TEXTURE:
- // Diffuse texture
- ParseTextureChunk(&mScene->mMaterials.back().sTexDiffuse);
- break;
- case Discreet3DS::CHUNK_MAT_BUMPMAP:
- // Height map
- ParseTextureChunk(&mScene->mMaterials.back().sTexBump);
- break;
- case Discreet3DS::CHUNK_MAT_OPACMAP:
- // Opacity texture
- ParseTextureChunk(&mScene->mMaterials.back().sTexOpacity);
- break;
- case Discreet3DS::CHUNK_MAT_MAT_SHINMAP:
- // Shininess map
- ParseTextureChunk(&mScene->mMaterials.back().sTexShininess);
- break;
- case Discreet3DS::CHUNK_MAT_SPECMAP:
- // Specular map
- ParseTextureChunk(&mScene->mMaterials.back().sTexSpecular);
- break;
- case Discreet3DS::CHUNK_MAT_SELFIMAP:
- // Self-illumination (emissive) map
- ParseTextureChunk(&mScene->mMaterials.back().sTexEmissive);
- break;
- case Discreet3DS::CHUNK_MAT_REFLMAP:
- // Reflection map
- ParseTextureChunk(&mScene->mMaterials.back().sTexReflective);
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture *pcOut) {
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_MAPFILE: {
- // The material name string is already zero-terminated, but we need to be sure ...
- const char *sz = (const char *)stream->GetPtr();
- unsigned int cnt = 0;
- while (stream->GetI1())
- ++cnt;
- pcOut->mMapName = std::string(sz, cnt);
- } break;
-
- case Discreet3DS::CHUNK_PERCENTD:
- // Manually parse the blend factor
- pcOut->mTextureBlend = ai_real(stream->GetF8());
- break;
-
- case Discreet3DS::CHUNK_PERCENTF:
- // Manually parse the blend factor
- pcOut->mTextureBlend = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_PERCENTW:
- // Manually parse the blend factor
- pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / ai_real(100.0);
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_USCALE:
- // Texture coordinate scaling in the U direction
- pcOut->mScaleU = stream->GetF4();
- if (0.0f == pcOut->mScaleU) {
- ASSIMP_LOG_WARN("Texture coordinate scaling in the x direction is zero. Assuming 1.");
- pcOut->mScaleU = 1.0f;
- }
- break;
- case Discreet3DS::CHUNK_MAT_MAP_VSCALE:
- // Texture coordinate scaling in the V direction
- pcOut->mScaleV = stream->GetF4();
- if (0.0f == pcOut->mScaleV) {
- ASSIMP_LOG_WARN("Texture coordinate scaling in the y direction is zero. Assuming 1.");
- pcOut->mScaleV = 1.0f;
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_UOFFSET:
- // Texture coordinate offset in the U direction
- pcOut->mOffsetU = -stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_VOFFSET:
- // Texture coordinate offset in the V direction
- pcOut->mOffsetV = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_ANG:
- // Texture coordinate rotation, CCW in DEGREES
- pcOut->mRotation = -AI_DEG_TO_RAD(stream->GetF4());
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_TILING: {
- const uint16_t iFlags = stream->GetI2();
-
- // Get the mapping mode (for both axes)
- if (iFlags & 0x2u)
- pcOut->mMapMode = aiTextureMapMode_Mirror;
-
- else if (iFlags & 0x10u)
- pcOut->mMapMode = aiTextureMapMode_Decal;
-
- // wrapping in all remaining cases
- else
- pcOut->mMapMode = aiTextureMapMode_Wrap;
- } break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a percentage chunk
-ai_real Discreet3DSImporter::ParsePercentageChunk() {
- Discreet3DS::Chunk chunk;
- ReadChunk(&chunk);
-
- if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag) {
- return stream->GetF4() * ai_real(100) / ai_real(0xFFFF);
- } else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag) {
- return (ai_real)((uint16_t)stream->GetI2()) / (ai_real)0xFFFF;
- }
-
- return get_qnan();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
-void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
- ai_assert(out != nullptr);
-
- // error return value
- const ai_real qnan = get_qnan();
- static const aiColor3D clrError = aiColor3D(qnan, qnan, qnan);
-
- Discreet3DS::Chunk chunk;
- ReadChunk(&chunk);
- const unsigned int diff = chunk.Size - sizeof(Discreet3DS::Chunk);
-
- bool bGamma = false;
-
- // Get the type of the chunk
- switch (chunk.Flag) {
- case Discreet3DS::CHUNK_LINRGBF:
- bGamma = true;
-
- case Discreet3DS::CHUNK_RGBF:
- if (sizeof(float) * 3 > diff) {
- *out = clrError;
- return;
- }
- out->r = stream->GetF4();
- out->g = stream->GetF4();
- out->b = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_LINRGBB:
- bGamma = true;
- case Discreet3DS::CHUNK_RGBB: {
- if (sizeof(char) * 3 > diff) {
- *out = clrError;
- return;
- }
- const ai_real invVal = ai_real(1.0) / ai_real(255.0);
- out->r = (ai_real)(uint8_t)stream->GetI1() * invVal;
- out->g = (ai_real)(uint8_t)stream->GetI1() * invVal;
- out->b = (ai_real)(uint8_t)stream->GetI1() * invVal;
- } break;
-
- // Percentage chunks are accepted, too.
- case Discreet3DS::CHUNK_PERCENTF:
- if (acceptPercent && 4 <= diff) {
- out->g = out->b = out->r = stream->GetF4();
- break;
- }
- *out = clrError;
- return;
-
- case Discreet3DS::CHUNK_PERCENTW:
- if (acceptPercent && 1 <= diff) {
- out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / ai_real(255.0);
- break;
- }
- *out = clrError;
- return;
-
- default:
- stream->IncPtr(diff);
- // Skip unknown chunks, hope this won't cause any problems.
- return ParseColorChunk(out, acceptPercent);
- };
- (void)bGamma;
-}
-
-#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
diff --git a/libs/assimp/code/AssetLib/3DS/3DSLoader.h b/libs/assimp/code/AssetLib/3DS/3DSLoader.h
deleted file mode 100644
index f47fcfe..0000000
--- a/libs/assimp/code/AssetLib/3DS/3DSLoader.h
+++ /dev/null
@@ -1,289 +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 3DSLoader.h
- * @brief 3DS File format loader
- */
-#ifndef AI_3DSIMPORTER_H_INC
-#define AI_3DSIMPORTER_H_INC
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-#include <assimp/BaseImporter.h>
-#include <assimp/types.h>
-
-
-#include "3DSHelper.h"
-#include <assimp/StreamReader.h>
-
-struct aiNode;
-
-namespace Assimp {
-
-
-using namespace D3DS;
-
-// ---------------------------------------------------------------------------------
-/** Importer class for 3D Studio r3 and r4 3DS files
- */
-class Discreet3DSImporter : public BaseImporter {
-public:
- Discreet3DSImporter();
- ~Discreet3DSImporter();
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const override;
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp) override;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const override;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler) override;
-
- // -------------------------------------------------------------------
- /** Converts a temporary material to the outer representation
- */
- void ConvertMaterial(D3DS::Material& p_cMat,
- aiMaterial& p_pcOut);
-
- // -------------------------------------------------------------------
- /** Read a chunk
- *
- * @param pcOut Receives the current chunk
- */
- void ReadChunk(Discreet3DS::Chunk* pcOut);
-
- // -------------------------------------------------------------------
- /** Parse a percentage chunk. mCurrent will point to the next
- * chunk behind afterwards. If no percentage chunk is found
- * QNAN is returned.
- */
- ai_real ParsePercentageChunk();
-
- // -------------------------------------------------------------------
- /** Parse a color chunk. mCurrent will point to the next
- * chunk behind afterwards. If no color chunk is found
- * QNAN is returned in all members.
- */
- void ParseColorChunk(aiColor3D* p_pcOut,
- bool p_bAcceptPercent = true);
-
-
- // -------------------------------------------------------------------
- /** Skip a chunk in the file
- */
- void SkipChunk();
-
- // -------------------------------------------------------------------
- /** Generate the nodegraph
- */
- void GenerateNodeGraph(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** Parse a main top-level chunk in the file
- */
- void ParseMainChunk();
-
- // -------------------------------------------------------------------
- /** Parse a top-level chunk in the file
- */
- void ParseChunk(const char* name, unsigned int num);
-
- // -------------------------------------------------------------------
- /** Parse a top-level editor chunk in the file
- */
- void ParseEditorChunk();
-
- // -------------------------------------------------------------------
- /** Parse a top-level object chunk in the file
- */
- void ParseObjectChunk();
-
- // -------------------------------------------------------------------
- /** Parse a material chunk in the file
- */
- void ParseMaterialChunk();
-
- // -------------------------------------------------------------------
- /** Parse a mesh chunk in the file
- */
- void ParseMeshChunk();
-
- // -------------------------------------------------------------------
- /** Parse a light chunk in the file
- */
- void ParseLightChunk();
-
- // -------------------------------------------------------------------
- /** Parse a camera chunk in the file
- */
- void ParseCameraChunk();
-
- // -------------------------------------------------------------------
- /** Parse a face list chunk in the file
- */
- void ParseFaceChunk();
-
- // -------------------------------------------------------------------
- /** Parse a keyframe chunk in the file
- */
- void ParseKeyframeChunk();
-
- // -------------------------------------------------------------------
- /** Parse a hierarchy chunk in the file
- */
- void ParseHierarchyChunk(uint16_t parent);
-
- // -------------------------------------------------------------------
- /** Parse a texture chunk in the file
- */
- void ParseTextureChunk(D3DS::Texture* pcOut);
-
- // -------------------------------------------------------------------
- /** Convert the meshes in the file
- */
- void ConvertMeshes(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** Replace the default material in the scene
- */
- void ReplaceDefaultMaterial();
-
- bool ContainsTextures(unsigned int i) const {
- return !mScene->mMaterials[i].sTexDiffuse.mMapName.empty() ||
- !mScene->mMaterials[i].sTexBump.mMapName.empty() ||
- !mScene->mMaterials[i].sTexOpacity.mMapName.empty() ||
- !mScene->mMaterials[i].sTexEmissive.mMapName.empty() ||
- !mScene->mMaterials[i].sTexSpecular.mMapName.empty() ||
- !mScene->mMaterials[i].sTexShininess.mMapName.empty() ;
- }
-
- // -------------------------------------------------------------------
- /** Convert the whole scene
- */
- void ConvertScene(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** generate unique vertices for a mesh
- */
- void MakeUnique(D3DS::Mesh& sMesh);
-
- // -------------------------------------------------------------------
- /** Add a node to the node graph
- */
- void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
- aiMatrix4x4& absTrafo);
-
- // -------------------------------------------------------------------
- /** Search for a node in the graph.
- * Called recursively
- */
- void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
-
- // -------------------------------------------------------------------
- /** Apply the master scaling factor to the mesh
- */
- void ApplyMasterScale(aiScene* pScene);
-
- // -------------------------------------------------------------------
- /** Clamp all indices in the file to a valid range
- */
- void CheckIndices(D3DS::Mesh& sMesh);
-
- // -------------------------------------------------------------------
- /** Skip the TCB info in a track key
- */
- void SkipTCBInfo();
-
-protected:
-
- /** Stream to read from */
- StreamReaderLE* stream;
-
- /** Last touched node index */
- short mLastNodeIndex;
-
- /** Current node, root node */
- D3DS::Node* mCurrentNode, *mRootNode;
-
- /** Scene under construction */
- D3DS::Scene* mScene;
-
- /** Ambient base color of the scene */
- aiColor3D mClrAmbient;
-
- /** Master scaling factor of the scene */
- ai_real mMasterScale;
-
- /** Path to the background image of the scene */
- std::string mBackgroundImage;
- bool bHasBG;
-
- /** true if PRJ file */
- bool bIsPrj;
-};
-
-} // end of namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
-
-#endif // AI_3DSIMPORTER_H_INC