summaryrefslogtreecommitdiff
path: root/libs/assimp/code/AssetLib/LWO
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/LWO
parentf567ea1e2798fd3156a416e61f083ea3e6b95719 (diff)
switch to tinyobj and nanovg from assimp and cairo
Diffstat (limited to 'libs/assimp/code/AssetLib/LWO')
-rw-r--r--libs/assimp/code/AssetLib/LWO/LWOAnimation.cpp609
-rw-r--r--libs/assimp/code/AssetLib/LWO/LWOAnimation.h346
-rw-r--r--libs/assimp/code/AssetLib/LWO/LWOBLoader.cpp428
-rw-r--r--libs/assimp/code/AssetLib/LWO/LWOFileData.h638
-rw-r--r--libs/assimp/code/AssetLib/LWO/LWOLoader.cpp1422
-rw-r--r--libs/assimp/code/AssetLib/LWO/LWOLoader.h468
-rw-r--r--libs/assimp/code/AssetLib/LWO/LWOMaterial.cpp844
7 files changed, 0 insertions, 4755 deletions
diff --git a/libs/assimp/code/AssetLib/LWO/LWOAnimation.cpp b/libs/assimp/code/AssetLib/LWO/LWOAnimation.cpp
deleted file mode 100644
index c2ee2d9..0000000
--- a/libs/assimp/code/AssetLib/LWO/LWOAnimation.cpp
+++ /dev/null
@@ -1,609 +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 LWOAnimation.cpp
- * @brief LWOAnimationResolver utility class
- *
- * It's a very generic implementation of LightWave's system of
- * component-wise-animated stuff. The one and only fully free
- * implementation of LightWave envelopes of which I know.
-*/
-
-#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER) && (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
-
-#include <functional>
-
-// internal headers
-#include "LWOFileData.h"
-#include <assimp/anim.h>
-
-using namespace Assimp;
-using namespace Assimp::LWO;
-
-// ------------------------------------------------------------------------------------------------
-// Construct an animation resolver from a given list of envelopes
-AnimResolver::AnimResolver(std::list<Envelope> &_envelopes, double tick) :
- envelopes(_envelopes),
- sample_rate(0.),
- envl_x(),
- envl_y(),
- envl_z(),
- end_x(),
- end_y(),
- end_z(),
- flags(),
- sample_delta() {
- trans_x = trans_y = trans_z = nullptr;
- rotat_x = rotat_y = rotat_z = nullptr;
- scale_x = scale_y = scale_z = nullptr;
-
- first = last = 150392.;
-
- // find transformation envelopes
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
-
- (*it).old_first = 0;
- (*it).old_last = (*it).keys.size() - 1;
-
- if ((*it).keys.empty()) {
- continue;
- }
- if ((int)(*it).type < 1 || (int)(*it).type>EnvelopeType_Unknown) {
- continue;
- }
- switch ((*it).type) {
- // translation
- case LWO::EnvelopeType_Position_X:
- trans_x = &*it;
- break;
- case LWO::EnvelopeType_Position_Y:
- trans_y = &*it;
- break;
- case LWO::EnvelopeType_Position_Z:
- trans_z = &*it;
- break;
-
- // rotation
- case LWO::EnvelopeType_Rotation_Heading:
- rotat_x = &*it;
- break;
- case LWO::EnvelopeType_Rotation_Pitch:
- rotat_y = &*it;
- break;
- case LWO::EnvelopeType_Rotation_Bank:
- rotat_z = &*it;
- break;
-
- // scaling
- case LWO::EnvelopeType_Scaling_X:
- scale_x = &*it;
- break;
- case LWO::EnvelopeType_Scaling_Y:
- scale_y = &*it;
- break;
- case LWO::EnvelopeType_Scaling_Z:
- scale_z = &*it;
- break;
- default:
- continue;
- };
-
- // convert from seconds to ticks
- for (std::vector<LWO::Key>::iterator d = (*it).keys.begin(); d != (*it).keys.end(); ++d)
- (*d).time *= tick;
-
- // set default animation range (minimum and maximum time value for which we have a keyframe)
- first = std::min(first, (*it).keys.front().time);
- last = std::max(last, (*it).keys.back().time);
- }
-
- // deferred setup of animation range to increase performance.
- // typically the application will want to specify its own.
- need_to_setup = true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reset all envelopes to their original contents
-void AnimResolver::ClearAnimRangeSetup() {
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
-
- (*it).keys.erase((*it).keys.begin(), (*it).keys.begin() + (*it).old_first);
- (*it).keys.erase((*it).keys.begin() + (*it).old_last + 1, (*it).keys.end());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Insert additional keys to match LWO's pre& post behaviors.
-void AnimResolver::UpdateAnimRangeSetup() {
- // XXX doesn't work yet (hangs if more than one envelope channels needs to be interpolated)
-
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
- if ((*it).keys.empty()) continue;
-
- const double my_first = (*it).keys.front().time;
- const double my_last = (*it).keys.back().time;
-
- const double delta = my_last - my_first;
- const size_t old_size = (*it).keys.size();
-
- const float value_delta = (*it).keys.back().value - (*it).keys.front().value;
-
- // NOTE: We won't handle reset, linear and constant here.
- // See DoInterpolation() for their implementation.
-
- // process pre behavior
- switch ((*it).pre) {
- case LWO::PrePostBehaviour_OffsetRepeat:
- case LWO::PrePostBehaviour_Repeat:
- case LWO::PrePostBehaviour_Oscillate: {
- const double start_time = delta - std::fmod(my_first - first, delta);
- std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(), (*it).keys.end(),
- [start_time](double t) { return start_time > t; }),
- m;
-
- size_t ofs = 0;
- if (n != (*it).keys.end()) {
- // copy from here - don't use iterators, insert() would invalidate them
- ofs = (*it).keys.end() - n;
- (*it).keys.insert((*it).keys.begin(), ofs, LWO::Key());
-
- std::copy((*it).keys.end() - ofs, (*it).keys.end(), (*it).keys.begin());
- }
-
- // do full copies. again, no iterators
- const unsigned int num = (unsigned int)((my_first - first) / delta);
- (*it).keys.resize((*it).keys.size() + num * old_size);
-
- n = (*it).keys.begin() + ofs;
- bool reverse = false;
- for (unsigned int i = 0; i < num; ++i) {
- m = n + old_size * (i + 1);
- std::copy(n, n + old_size, m);
- const bool res = ((*it).pre == LWO::PrePostBehaviour_Oscillate);
- reverse = !reverse;
- if (res && reverse) {
- std::reverse(m, m + old_size - 1);
- }
- }
-
- // update time values
- n = (*it).keys.end() - (old_size + 1);
- double cur_minus = delta;
- unsigned int tt = 1;
- for (const double tmp = delta * (num + 1); cur_minus <= tmp; cur_minus += delta, ++tt) {
- m = (delta == tmp ? (*it).keys.begin() : n - (old_size + 1));
- for (; m != n; --n) {
- (*n).time -= cur_minus;
-
- // offset repeat? add delta offset to key value
- if ((*it).pre == LWO::PrePostBehaviour_OffsetRepeat) {
- (*n).value += tt * value_delta;
- }
- }
- }
- break;
- }
- default:
- // silence compiler warning
- break;
- }
-
- // process post behavior
- switch ((*it).post) {
-
- case LWO::PrePostBehaviour_OffsetRepeat:
- case LWO::PrePostBehaviour_Repeat:
- case LWO::PrePostBehaviour_Oscillate:
-
- break;
-
- default:
- // silence compiler warning
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extract bind pose matrix
-void AnimResolver::ExtractBindPose(aiMatrix4x4 &out) {
- // If we have no envelopes, return identity
- if (envelopes.empty()) {
- out = aiMatrix4x4();
- return;
- }
- aiVector3D angles, scaling(1.f, 1.f, 1.f), translation;
-
- if (trans_x) translation.x = trans_x->keys[0].value;
- if (trans_y) translation.y = trans_y->keys[0].value;
- if (trans_z) translation.z = trans_z->keys[0].value;
-
- if (rotat_x) angles.x = rotat_x->keys[0].value;
- if (rotat_y) angles.y = rotat_y->keys[0].value;
- if (rotat_z) angles.z = rotat_z->keys[0].value;
-
- if (scale_x) scaling.x = scale_x->keys[0].value;
- if (scale_y) scaling.y = scale_y->keys[0].value;
- if (scale_z) scaling.z = scale_z->keys[0].value;
-
- // build the final matrix
- aiMatrix4x4 s, rx, ry, rz, t;
- aiMatrix4x4::RotationZ(angles.z, rz);
- aiMatrix4x4::RotationX(angles.y, rx);
- aiMatrix4x4::RotationY(angles.x, ry);
- aiMatrix4x4::Translation(translation, t);
- aiMatrix4x4::Scaling(scaling, s);
- out = t * ry * rx * rz * s;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Do a single interpolation on a channel
-void AnimResolver::DoInterpolation(std::vector<LWO::Key>::const_iterator cur,
- LWO::Envelope *envl, double time, float &fill) {
- if (envl->keys.size() == 1) {
- fill = envl->keys[0].value;
- return;
- }
-
- // check whether we're at the beginning of the animation track
- if (cur == envl->keys.begin()) {
-
- // ok ... this depends on pre behaviour now
- // we don't need to handle repeat&offset repeat&oszillate here, see UpdateAnimRangeSetup()
- switch (envl->pre) {
- case LWO::PrePostBehaviour_Linear:
- DoInterpolation2(cur, cur + 1, time, fill);
- return;
-
- case LWO::PrePostBehaviour_Reset:
- fill = 0.f;
- return;
-
- default: //case LWO::PrePostBehaviour_Constant:
- fill = (*cur).value;
- return;
- }
- }
- // check whether we're at the end of the animation track
- else if (cur == envl->keys.end() - 1 && time > envl->keys.rbegin()->time) {
- // ok ... this depends on post behaviour now
- switch (envl->post) {
- case LWO::PrePostBehaviour_Linear:
- DoInterpolation2(cur, cur - 1, time, fill);
- return;
-
- case LWO::PrePostBehaviour_Reset:
- fill = 0.f;
- return;
-
- default: //case LWO::PrePostBehaviour_Constant:
- fill = (*cur).value;
- return;
- }
- }
-
- // Otherwise do a simple interpolation
- DoInterpolation2(cur - 1, cur, time, fill);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Almost the same, except we won't handle pre/post conditions here
-void AnimResolver::DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
- std::vector<LWO::Key>::const_iterator end, double time, float &fill) {
- switch ((*end).inter) {
-
- case LWO::IT_STEP:
- // no interpolation at all - take the value of the last key
- fill = (*beg).value;
- return;
- default:
-
- // silence compiler warning
- break;
- }
- // linear interpolation - default
- double duration = (*end).time - (*beg).time;
- if (duration > 0.0) {
- fill = (*beg).value + ((*end).value - (*beg).value) * (float)(((time - (*beg).time) / duration));
- } else {
- fill = (*beg).value;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Subsample animation track by given key values
-void AnimResolver::SubsampleAnimTrack(std::vector<aiVectorKey> & /*out*/,
- double /*time*/, double /*sample_delta*/) {
- //ai_assert(out.empty() && sample_delta);
-
- //const double time_start = out.back().mTime;
- // for ()
-}
-
-// ------------------------------------------------------------------------------------------------
-// Track interpolation
-void AnimResolver::InterpolateTrack(std::vector<aiVectorKey> &out, aiVectorKey &fill, double time) {
- // subsample animation track?
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- SubsampleAnimTrack(out, time, sample_delta);
- }
-
- fill.mTime = time;
-
- // get x
- if ((*cur_x).time == time) {
- fill.mValue.x = (*cur_x).value;
-
- if (cur_x != envl_x->keys.end() - 1) /* increment x */
- ++cur_x;
- else
- end_x = true;
- } else
- DoInterpolation(cur_x, envl_x, time, (float &)fill.mValue.x);
-
- // get y
- if ((*cur_y).time == time) {
- fill.mValue.y = (*cur_y).value;
-
- if (cur_y != envl_y->keys.end() - 1) /* increment y */
- ++cur_y;
- else
- end_y = true;
- } else
- DoInterpolation(cur_y, envl_y, time, (float &)fill.mValue.y);
-
- // get z
- if ((*cur_z).time == time) {
- fill.mValue.z = (*cur_z).value;
-
- if (cur_z != envl_z->keys.end() - 1) /* increment z */
- ++cur_z;
- else
- end_x = true;
- } else
- DoInterpolation(cur_z, envl_z, time, (float &)fill.mValue.z);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build linearly subsampled keys from three single envelopes, one for each component (x,y,z)
-void AnimResolver::GetKeys(std::vector<aiVectorKey> &out,
- LWO::Envelope *_envl_x,
- LWO::Envelope *_envl_y,
- LWO::Envelope *_envl_z,
- unsigned int _flags) {
- envl_x = _envl_x;
- envl_y = _envl_y;
- envl_z = _envl_z;
- flags = _flags;
-
- // generate default channels if none are given
- LWO::Envelope def_x, def_y, def_z;
- LWO::Key key_dummy;
- key_dummy.time = 0.f;
- if ((envl_x && envl_x->type == LWO::EnvelopeType_Scaling_X) ||
- (envl_y && envl_y->type == LWO::EnvelopeType_Scaling_Y) ||
- (envl_z && envl_z->type == LWO::EnvelopeType_Scaling_Z)) {
- key_dummy.value = 1.f;
- } else
- key_dummy.value = 0.f;
-
- if (!envl_x) {
- envl_x = &def_x;
- envl_x->keys.push_back(key_dummy);
- }
- if (!envl_y) {
- envl_y = &def_y;
- envl_y->keys.push_back(key_dummy);
- }
- if (!envl_z) {
- envl_z = &def_z;
- envl_z->keys.push_back(key_dummy);
- }
-
- // guess how many keys we'll get
- size_t reserve;
- double sr = 1.;
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- if (!sample_rate)
- sr = 100.f;
- else
- sr = sample_rate;
- sample_delta = 1.f / sr;
-
- reserve = (size_t)(
- std::max(envl_x->keys.rbegin()->time,
- std::max(envl_y->keys.rbegin()->time, envl_z->keys.rbegin()->time)) *
- sr);
- } else
- reserve = std::max(envl_x->keys.size(), std::max(envl_x->keys.size(), envl_z->keys.size()));
- out.reserve(reserve + (reserve >> 1));
-
- // Iterate through all three arrays at once - it's tricky, but
- // rather interesting to implement.
- cur_x = envl_x->keys.begin();
- cur_y = envl_y->keys.begin();
- cur_z = envl_z->keys.begin();
-
- end_x = end_y = end_z = false;
- while (1) {
-
- aiVectorKey fill;
-
- if ((*cur_x).time == (*cur_y).time && (*cur_x).time == (*cur_z).time) {
-
- // we have a keyframe for all of them defined .. this means
- // we don't need to interpolate here.
- fill.mTime = (*cur_x).time;
-
- fill.mValue.x = (*cur_x).value;
- fill.mValue.y = (*cur_y).value;
- fill.mValue.z = (*cur_z).value;
-
- // subsample animation track
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- //SubsampleAnimTrack(out,cur_x, cur_y, cur_z, d, sample_delta);
- }
- }
-
- // Find key with lowest time value
- else if ((*cur_x).time <= (*cur_y).time && !end_x) {
-
- if ((*cur_z).time <= (*cur_x).time && !end_z) {
- InterpolateTrack(out, fill, (*cur_z).time);
- } else {
- InterpolateTrack(out, fill, (*cur_x).time);
- }
- } else if ((*cur_z).time <= (*cur_y).time && !end_y) {
- InterpolateTrack(out, fill, (*cur_y).time);
- } else if (!end_y) {
- // welcome on the server, y
- InterpolateTrack(out, fill, (*cur_y).time);
- } else {
- // we have reached the end of at least 2 channels,
- // only one is remaining. Extrapolate the 2.
- if (end_y) {
- InterpolateTrack(out, fill, (end_x ? (*cur_z) : (*cur_x)).time);
- } else if (end_x) {
- InterpolateTrack(out, fill, (end_z ? (*cur_y) : (*cur_z)).time);
- } else { // if (end_z)
- InterpolateTrack(out, fill, (end_y ? (*cur_x) : (*cur_y)).time);
- }
- }
- double lasttime = fill.mTime;
- out.push_back(fill);
-
- if (lasttime >= (*cur_x).time) {
- if (cur_x != envl_x->keys.end() - 1)
- ++cur_x;
- else
- end_x = true;
- }
- if (lasttime >= (*cur_y).time) {
- if (cur_y != envl_y->keys.end() - 1)
- ++cur_y;
- else
- end_y = true;
- }
- if (lasttime >= (*cur_z).time) {
- if (cur_z != envl_z->keys.end() - 1)
- ++cur_z;
- else
- end_z = true;
- }
-
- if (end_x && end_y && end_z) /* finished? */
- break;
- }
-
- if (flags & AI_LWO_ANIM_FLAG_START_AT_ZERO) {
- for (std::vector<aiVectorKey>::iterator it = out.begin(); it != out.end(); ++it)
- (*it).mTime -= first;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extract animation channel
-void AnimResolver::ExtractAnimChannel(aiNodeAnim **out, unsigned int /*= 0*/) {
- *out = nullptr;
-
- //FIXME: crashes if more than one component is animated at different timings, to be resolved.
-
- // If we have no envelopes, return nullptr
- if (envelopes.empty()) {
- return;
- }
-
- // We won't spawn an animation channel if we don't have at least one envelope with more than one keyframe defined.
- const bool trans = ((trans_x && trans_x->keys.size() > 1) || (trans_y && trans_y->keys.size() > 1) || (trans_z && trans_z->keys.size() > 1));
- const bool rotat = ((rotat_x && rotat_x->keys.size() > 1) || (rotat_y && rotat_y->keys.size() > 1) || (rotat_z && rotat_z->keys.size() > 1));
- const bool scale = ((scale_x && scale_x->keys.size() > 1) || (scale_y && scale_y->keys.size() > 1) || (scale_z && scale_z->keys.size() > 1));
- if (!trans && !rotat && !scale)
- return;
-
- // Allocate the output animation
- aiNodeAnim *anim = *out = new aiNodeAnim();
-
- // Setup default animation setup if necessary
- if (need_to_setup) {
- UpdateAnimRangeSetup();
- need_to_setup = false;
- }
-
- // copy translation keys
- if (trans) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys, trans_x, trans_y, trans_z, flags);
-
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys = static_cast<unsigned int>(keys.size())];
- std::copy(keys.begin(), keys.end(), anim->mPositionKeys);
- }
-
- // copy rotation keys
- if (rotat) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys, rotat_x, rotat_y, rotat_z, flags);
-
- anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys = static_cast<unsigned int>(keys.size())];
-
- // convert heading, pitch, bank to quaternion
- // mValue.x=Heading=Rot(Y), mValue.y=Pitch=Rot(X), mValue.z=Bank=Rot(Z)
- // Lightwave's rotation order is ZXY
- aiVector3D X(1.0, 0.0, 0.0);
- aiVector3D Y(0.0, 1.0, 0.0);
- aiVector3D Z(0.0, 0.0, 1.0);
- for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) {
- aiQuatKey &qk = anim->mRotationKeys[i];
- qk.mTime = keys[i].mTime;
- qk.mValue = aiQuaternion(Y, keys[i].mValue.x) * aiQuaternion(X, keys[i].mValue.y) * aiQuaternion(Z, keys[i].mValue.z);
- }
- }
-
- // copy scaling keys
- if (scale) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys, scale_x, scale_y, scale_z, flags);
-
- anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys = static_cast<unsigned int>(keys.size())];
- std::copy(keys.begin(), keys.end(), anim->mScalingKeys);
- }
-}
-
-#endif // no lwo or no lws
diff --git a/libs/assimp/code/AssetLib/LWO/LWOAnimation.h b/libs/assimp/code/AssetLib/LWO/LWOAnimation.h
deleted file mode 100644
index 1e419d4..0000000
--- a/libs/assimp/code/AssetLib/LWO/LWOAnimation.h
+++ /dev/null
@@ -1,346 +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 LWOAnimation.h
- * @brief LWOAnimationResolver utility class
- *
- * This is for all lightwave-related file format, not only LWO.
- * LWS isthe main purpose.
-*/
-#ifndef AI_LWO_ANIMATION_INCLUDED
-#define AI_LWO_ANIMATION_INCLUDED
-
-//
-#include <vector>
-#include <list>
-
-struct aiNodeAnim;
-struct aiVectorKey;
-
-namespace Assimp {
-namespace LWO {
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO envelopes
- */
-enum EnvelopeType
-{
- EnvelopeType_Position_X = 0x1,
- EnvelopeType_Position_Y = 0x2,
- EnvelopeType_Position_Z = 0x3,
-
- EnvelopeType_Rotation_Heading = 0x4,
- EnvelopeType_Rotation_Pitch = 0x5,
- EnvelopeType_Rotation_Bank = 0x6,
-
- EnvelopeType_Scaling_X = 0x7,
- EnvelopeType_Scaling_Y = 0x8,
- EnvelopeType_Scaling_Z = 0x9,
-
- // -- currently not yet handled
- EnvelopeType_Color_R = 0xa,
- EnvelopeType_Color_G = 0xb,
- EnvelopeType_Color_B = 0xc,
-
- EnvelopeType_Falloff_X = 0xd,
- EnvelopeType_Falloff_Y = 0xe,
- EnvelopeType_Falloff_Z = 0xf,
-
- EnvelopeType_Unknown
-};
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO interpolation modes
- */
-enum InterpolationType
-{
- IT_STEP, IT_LINE, IT_TCB, IT_HERM, IT_BEZI, IT_BEZ2
-};
-
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO pre or post range behaviours
- */
-enum PrePostBehaviour
-{
- PrePostBehaviour_Reset = 0x0,
- PrePostBehaviour_Constant = 0x1,
- PrePostBehaviour_Repeat = 0x2,
- PrePostBehaviour_Oscillate = 0x3,
- PrePostBehaviour_OffsetRepeat = 0x4,
- PrePostBehaviour_Linear = 0x5
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO animation keyframe
- */
-struct Key {
- Key() AI_NO_EXCEPT
- : time()
- , value()
- , inter(IT_LINE)
- , params() {
- // empty
- }
-
- //! Current time
- double time;
-
- //! Current value
- float value;
-
- //! How to interpolate this key with previous key?
- InterpolationType inter;
-
- //! Interpolation parameters
- float params[5];
-
-
- // for std::find()
- operator double () {
- return time;
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO animation envelope
- */
-struct Envelope {
- Envelope() AI_NO_EXCEPT
- : index()
- , type(EnvelopeType_Unknown)
- , pre(PrePostBehaviour_Constant)
- , post(PrePostBehaviour_Constant)
- , old_first(0)
- , old_last(0) {
- // empty
- }
-
- //! Index of this envelope
- unsigned int index;
-
- //! Type of envelope
- EnvelopeType type;
-
- //! Pre- and post-behavior
- PrePostBehaviour pre,post;
-
- //! Keyframes for this envelope
- std::vector<Key> keys;
-
- // temporary data for AnimResolver
- size_t old_first,old_last;
-};
-
-// ---------------------------------------------------------------------------
-//! @def AI_LWO_ANIM_FLAG_SAMPLE_ANIMS
-//! Flag for AnimResolver, subsamples the input data with the rate specified
-//! by AnimResolver::SetSampleRate().
-#define AI_LWO_ANIM_FLAG_SAMPLE_ANIMS 0x1
-
-
-// ---------------------------------------------------------------------------
-//! @def AI_LWO_ANIM_FLAG_START_AT_ZERO
-//! Flag for AnimResolver, ensures that the animations starts at zero.
-#define AI_LWO_ANIM_FLAG_START_AT_ZERO 0x2
-
-// ---------------------------------------------------------------------------
-/** @brief Utility class to build Assimp animations from LWO envelopes.
- *
- * Used for both LWO and LWS (MOT also).
- */
-class AnimResolver
-{
-public:
-
- // ------------------------------------------------------------------
- /** @brief Construct an AnimResolver from a given list of envelopes
- * @param envelopes Input envelopes. May be empty.
- * @param Output tick rate, per second
- * @note The input envelopes are possibly modified.
- */
- AnimResolver(std::list<Envelope>& envelopes, double tick);
-
-public:
-
- // ------------------------------------------------------------------
- /** @brief Extract the bind-pose transformation matrix.
- * @param out Receives bind-pose transformation matrix
- */
- void ExtractBindPose(aiMatrix4x4& out);
-
- // ------------------------------------------------------------------
- /** @brief Extract a node animation channel
- * @param out Receives a pointer to a newly allocated node anim.
- * If there's just one keyframe defined, *out is set to nullptr and
- * no animation channel is computed.
- * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
- */
- void ExtractAnimChannel(aiNodeAnim** out, unsigned int flags = 0);
-
-
- // ------------------------------------------------------------------
- /** @brief Set the sampling rate for ExtractAnimChannel().
- *
- * Non-linear interpolations are subsampled with this rate (keys
- * per second). Closer sampling positions, if existent, are kept.
- * The sampling rate defaults to 0, if this value is not changed and
- * AI_LWO_ANIM_FLAG_SAMPLE_ANIMS is specified for ExtractAnimChannel(),
- * the class finds a suitable sample rate by itself.
- */
- void SetSampleRate(double sr) {
- sample_rate = sr;
- }
-
- // ------------------------------------------------------------------
- /** @brief Getter for SetSampleRate()
- */
- double GetSampleRate() const {
- return sample_rate;
- }
-
- // ------------------------------------------------------------------
- /** @brief Set the animation time range
- *
- * @param first Time where the animation starts, in ticks
- * @param last Time where the animation ends, in ticks
- */
- void SetAnimationRange(double _first, double _last) {
- first = _first;
- last = _last;
-
- ClearAnimRangeSetup();
- UpdateAnimRangeSetup();
- }
-
-protected:
-
- // ------------------------------------------------------------------
- /** @brief Build linearly subsampled keys from 3 single envelopes
- * @param out Receives output keys
- * @param envl_x X-component envelope
- * @param envl_y Y-component envelope
- * @param envl_z Z-component envelope
- * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
- * @note Up to two input envelopes may be nullptr
- */
- void GetKeys(std::vector<aiVectorKey>& out,
- LWO::Envelope* envl_x,
- LWO::Envelope* envl_y,
- LWO::Envelope* envl_z,
- unsigned int flags);
-
- // ------------------------------------------------------------------
- /** @brief Resolve a single animation key by applying the right
- * interpolation to it.
- * @param cur Current key
- * @param envl Envelope working on
- * @param time time to be interpolated
- * @param fill Receives the interpolated output value.
- */
- void DoInterpolation(std::vector<LWO::Key>::const_iterator cur,
- LWO::Envelope* envl,double time, float& fill);
-
- // ------------------------------------------------------------------
- /** @brief Almost the same, except we won't handle pre/post
- * conditions here.
- * @see DoInterpolation
- */
- void DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
- std::vector<LWO::Key>::const_iterator end,double time, float& fill);
-
- // ------------------------------------------------------------------
- /** @brief Interpolate 2 tracks if one is given
- *
- * @param out Receives extra output keys
- * @param key_out Primary output key
- * @param time Time to interpolate for
- */
- void InterpolateTrack(std::vector<aiVectorKey>& out,
- aiVectorKey& key_out,double time);
-
- // ------------------------------------------------------------------
- /** @brief Subsample an animation track by a given sampling rate
- *
- * @param out Receives output keys. Last key at input defines the
- * time where subsampling starts.
- * @param time Time to end subsampling at
- * @param sample_delta Time delta between two samples
- */
- void SubsampleAnimTrack(std::vector<aiVectorKey>& out,
- double time,double sample_delta);
-
- // ------------------------------------------------------------------
- /** @brief Delete all keys which we inserted to match anim setup
- */
- void ClearAnimRangeSetup();
-
- // ------------------------------------------------------------------
- /** @brief Insert extra keys to match LWO's pre and post behaviours
- * in a given time range [first...last]
- */
- void UpdateAnimRangeSetup();
-
-private:
- std::list<Envelope>& envelopes;
- double sample_rate;
-
- LWO::Envelope* trans_x, *trans_y, *trans_z;
- LWO::Envelope* rotat_x, *rotat_y, *rotat_z;
- LWO::Envelope* scale_x, *scale_y, *scale_z;
-
- double first, last;
- bool need_to_setup;
-
- // temporary storage
- LWO::Envelope* envl_x, * envl_y, * envl_z;
- std::vector<LWO::Key>::const_iterator cur_x,cur_y,cur_z;
- bool end_x, end_y, end_z;
-
- unsigned int flags;
- double sample_delta;
-};
-
-} // end namespace LWO
-} // end namespace Assimp
-
-#endif // !! AI_LWO_ANIMATION_INCLUDED
diff --git a/libs/assimp/code/AssetLib/LWO/LWOBLoader.cpp b/libs/assimp/code/AssetLib/LWO/LWOBLoader.cpp
deleted file mode 100644
index 1fbd9b9..0000000
--- a/libs/assimp/code/AssetLib/LWO/LWOBLoader.cpp
+++ /dev/null
@@ -1,428 +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 LWO importer class for the older LWOB
- file formats, including materials */
-
-
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// Internal headers
-#include "LWOLoader.h"
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBFile()
-{
- LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
- bool running = true;
- while (running)
- {
- if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
- const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- {
- throw DeadlyImportError("LWOB: Invalid chunk length");
- break;
- }
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- // vertex list
- case AI_LWO_PNTS:
- {
- if (!mCurLayer->mTempPoints.empty())
- ASSIMP_LOG_WARN("LWO: PNTS chunk encountered twice");
- else LoadLWOPoints(head.length);
- break;
- }
- // face list
- case AI_LWO_POLS:
- {
-
- if (!mCurLayer->mFaces.empty())
- ASSIMP_LOG_WARN("LWO: POLS chunk encountered twice");
- else LoadLWOBPolygons(head.length);
- break;
- }
- // list of tags
- case AI_LWO_SRFS:
- {
- if (!mTags->empty())
- ASSIMP_LOG_WARN("LWO: SRFS chunk encountered twice");
- else LoadLWOTags(head.length);
- break;
- }
-
- // surface chunk
- case AI_LWO_SURF:
- {
- LoadLWOBSurface(head.length);
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBPolygons(unsigned int length)
-{
- // first find out how many faces and vertices we'll finally need
- LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
- LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer;
-
- // perform endianness conversions
-#ifndef AI_BUILD_BIG_ENDIAN
- while (cursor < end)ByteSwap::Swap2(cursor++);
- cursor = (LE_NCONST uint16_t*)mFileBuffer;
-#endif
-
- unsigned int iNumFaces = 0,iNumVertices = 0;
- CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end);
-
- // allocate the output array and copy face indices
- if (iNumFaces)
- {
- cursor = (LE_NCONST uint16_t*)mFileBuffer;
-
- mCurLayer->mFaces.resize(iNumFaces);
- FaceList::iterator it = mCurLayer->mFaces.begin();
- CopyFaceIndicesLWOB(it,cursor,end);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces,
- LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max)
-{
- while (cursor < end && max--)
- {
- uint16_t numIndices;
- // must have 2 shorts left for numIndices and surface
- if (end - cursor < 2) {
- throw DeadlyImportError("LWOB: Unexpected end of file");
- }
- ::memcpy(&numIndices, cursor++, 2);
- // must have enough left for indices and surface
- if (end - cursor < (1 + numIndices)) {
- throw DeadlyImportError("LWOB: Unexpected end of file");
- }
- verts += numIndices;
- faces++;
- cursor += numIndices;
- int16_t surface;
- ::memcpy(&surface, cursor++, 2);
- if (surface < 0)
- {
- // there are detail polygons
- ::memcpy(&numIndices, cursor++, 2);
- CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
- LE_NCONST uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max)
-{
- while (cursor < end && max--)
- {
- LWO::Face& face = *it;++it;
- uint16_t numIndices;
- ::memcpy(&numIndices, cursor++, 2);
- face.mNumIndices = numIndices;
- if(face.mNumIndices)
- {
- if (cursor + face.mNumIndices >= end)
- {
- break;
- }
- face.mIndices = new unsigned int[face.mNumIndices];
- for (unsigned int i = 0; i < face.mNumIndices;++i) {
- unsigned int & mi = face.mIndices[i];
- uint16_t index;
- ::memcpy(&index, cursor++, 2);
- mi = index;
- if (mi > mCurLayer->mTempPoints.size())
- {
- ASSIMP_LOG_WARN("LWOB: face index is out of range");
- mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
- }
- }
- } else {
- ASSIMP_LOG_WARN("LWOB: Face has 0 indices");
- }
- int16_t surface;
- ::memcpy(&surface, cursor++, 2);
- if (surface < 0)
- {
- surface = -surface;
-
- // there are detail polygons.
- uint16_t numPolygons;
- ::memcpy(&numPolygons, cursor++, 2);
- if (cursor < end)
- {
- CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
- }
- }
- face.surfaceIndex = surface-1;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
-{
- list.push_back(LWO::Texture());
- LWO::Texture* tex = &list.back();
-
- std::string type;
- GetS0(type,size);
- const char* s = type.c_str();
-
- if(strstr(s, "Image Map"))
- {
- // Determine mapping type
- if(strstr(s, "Planar"))
- tex->mapMode = LWO::Texture::Planar;
- else if(strstr(s, "Cylindrical"))
- tex->mapMode = LWO::Texture::Cylindrical;
- else if(strstr(s, "Spherical"))
- tex->mapMode = LWO::Texture::Spherical;
- else if(strstr(s, "Cubic"))
- tex->mapMode = LWO::Texture::Cubic;
- else if(strstr(s, "Front"))
- tex->mapMode = LWO::Texture::FrontProjection;
- }
- else
- {
- // procedural or gradient, not supported
- ASSIMP_LOG_ERROR("LWOB: Unsupported legacy texture: ", type);
- }
-
- return tex;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBSurface(unsigned int size)
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- mSurfaces->push_back( LWO::Surface () );
- LWO::Surface& surf = mSurfaces->back();
- LWO::Texture *pTex = nullptr;
-
- GetS0(surf.mName,size);
- bool running = true;
- while (running) {
- if (mFileBuffer + 6 >= end)
- break;
-
- IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- /* A single test file (sonycam.lwo) seems to have invalid surface chunks.
- * I'm assuming it's the fault of a single, unknown exporter so there are
- * probably THOUSANDS of them. Here's a dirty workaround:
- *
- * We don't break if the chunk limit is exceeded. Instead, we're computing
- * how much storage is actually left and work with this value from now on.
- */
- if (mFileBuffer + head.length > end) {
- ASSIMP_LOG_ERROR("LWOB: Invalid surface chunk length. Trying to continue.");
- head.length = (uint16_t) (end - mFileBuffer);
- }
-
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- // diffuse color
- case AI_LWO_COLR:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,COLR,3);
- surf.mColor.r = GetU1() / 255.0f;
- surf.mColor.g = GetU1() / 255.0f;
- surf.mColor.b = GetU1() / 255.0f;
- break;
- }
- // diffuse strength ...
- case AI_LWO_DIFF:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,DIFF,2);
- surf.mDiffuseValue = GetU2() / 255.0f;
- break;
- }
- // specular strength ...
- case AI_LWO_SPEC:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPEC,2);
- surf.mSpecularValue = GetU2() / 255.0f;
- break;
- }
- // luminosity ...
- case AI_LWO_LUMI:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LUMI,2);
- surf.mLuminosity = GetU2() / 255.0f;
- break;
- }
- // transparency
- case AI_LWO_TRAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TRAN,2);
- surf.mTransparency = GetU2() / 255.0f;
- break;
- }
- // surface flags
- case AI_LWO_FLAG:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,FLAG,2);
- uint16_t flag = GetU2();
- if (flag & 0x4 ) surf.mMaximumSmoothAngle = 1.56207f;
- if (flag & 0x8 ) surf.mColorHighlights = 1.f;
- if (flag & 0x100) surf.bDoubleSided = true;
- break;
- }
- // maximum smoothing angle
- case AI_LWO_SMAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
- surf.mMaximumSmoothAngle = std::fabs( GetF4() );
- break;
- }
- // glossiness
- case AI_LWO_GLOS:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,GLOS,2);
- surf.mGlossiness = (float)GetU2();
- break;
- }
- // color texture
- case AI_LWO_CTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mColorTextures,
- head.length);
- break;
- }
- // diffuse texture
- case AI_LWO_DTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
- head.length);
- break;
- }
- // specular texture
- case AI_LWO_STEX:
- {
- pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
- head.length);
- break;
- }
- // bump texture
- case AI_LWO_BTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mBumpTextures,
- head.length);
- break;
- }
- // transparency texture
- case AI_LWO_TTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
- head.length);
- break;
- }
- // texture path
- case AI_LWO_TIMG:
- {
- if (pTex) {
- GetS0(pTex->mFileName,head.length);
- } else {
- ASSIMP_LOG_WARN("LWOB: Unexpected TIMG chunk");
- }
- break;
- }
- // texture strength
- case AI_LWO_TVAL:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TVAL,1);
- if (pTex) {
- pTex->mStrength = (float)GetU1()/ 255.f;
- } else {
- ASSIMP_LOG_ERROR("LWOB: Unexpected TVAL chunk");
- }
- break;
- }
- // texture flags
- case AI_LWO_TFLG:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TFLG,2);
-
- if (nullptr != pTex) {
- const uint16_t s = GetU2();
- if (s & 1)
- pTex->majorAxis = LWO::Texture::AXIS_X;
- else if (s & 2)
- pTex->majorAxis = LWO::Texture::AXIS_Y;
- else if (s & 4)
- pTex->majorAxis = LWO::Texture::AXIS_Z;
-
- if (s & 16) {
- ASSIMP_LOG_WARN("LWOB: Ignoring \'negate\' flag on texture");
- }
- }
- else {
- ASSIMP_LOG_WARN("LWOB: Unexpected TFLG chunk");
- }
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
diff --git a/libs/assimp/code/AssetLib/LWO/LWOFileData.h b/libs/assimp/code/AssetLib/LWO/LWOFileData.h
deleted file mode 100644
index f477f58..0000000
--- a/libs/assimp/code/AssetLib/LWO/LWOFileData.h
+++ /dev/null
@@ -1,638 +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 LWOFileData.h
- * @brief Defines chunk constants used by the LWO file format
-
-The chunks are taken from the official LightWave SDK headers.
-
-*/
-#ifndef AI_LWO_FILEDATA_INCLUDED
-#define AI_LWO_FILEDATA_INCLUDED
-
-// STL headers
-#include <list>
-#include <vector>
-
-// public ASSIMP headers
-#include <assimp/mesh.h>
-
-// internal headers
-#include "AssetLib/LWO/LWOAnimation.h"
-#include "Common/IFF.h"
-
-namespace Assimp {
-namespace LWO {
-
-#define AI_LWO_FOURCC_LWOB AI_IFF_FOURCC('L', 'W', 'O', 'B')
-#define AI_LWO_FOURCC_LWO2 AI_IFF_FOURCC('L', 'W', 'O', '2')
-#define AI_LWO_FOURCC_LXOB AI_IFF_FOURCC('L', 'X', 'O', 'B')
-
-// chunks specific to the LWOB format
-#define AI_LWO_SRFS AI_IFF_FOURCC('S', 'R', 'F', 'S')
-#define AI_LWO_FLAG AI_IFF_FOURCC('F', 'L', 'A', 'G')
-#define AI_LWO_VLUM AI_IFF_FOURCC('V', 'L', 'U', 'M')
-#define AI_LWO_VDIF AI_IFF_FOURCC('V', 'D', 'I', 'F')
-#define AI_LWO_VSPC AI_IFF_FOURCC('V', 'S', 'P', 'C')
-#define AI_LWO_RFLT AI_IFF_FOURCC('R', 'F', 'L', 'T')
-#define AI_LWO_BTEX AI_IFF_FOURCC('B', 'T', 'E', 'X')
-#define AI_LWO_CTEX AI_IFF_FOURCC('C', 'T', 'E', 'X')
-#define AI_LWO_DTEX AI_IFF_FOURCC('D', 'T', 'E', 'X')
-#define AI_LWO_LTEX AI_IFF_FOURCC('L', 'T', 'E', 'X')
-#define AI_LWO_RTEX AI_IFF_FOURCC('R', 'T', 'E', 'X')
-#define AI_LWO_STEX AI_IFF_FOURCC('S', 'T', 'E', 'X')
-#define AI_LWO_TTEX AI_IFF_FOURCC('T', 'T', 'E', 'X')
-#define AI_LWO_TFLG AI_IFF_FOURCC('T', 'F', 'L', 'G')
-#define AI_LWO_TSIZ AI_IFF_FOURCC('T', 'S', 'I', 'Z')
-#define AI_LWO_TCTR AI_IFF_FOURCC('T', 'C', 'T', 'R')
-#define AI_LWO_TFAL AI_IFF_FOURCC('T', 'F', 'A', 'L')
-#define AI_LWO_TVEL AI_IFF_FOURCC('T', 'V', 'E', 'L')
-#define AI_LWO_TCLR AI_IFF_FOURCC('T', 'C', 'L', 'R')
-#define AI_LWO_TVAL AI_IFF_FOURCC('T', 'V', 'A', 'L')
-#define AI_LWO_TAMP AI_IFF_FOURCC('T', 'A', 'M', 'P')
-#define AI_LWO_TIMG AI_IFF_FOURCC('T', 'I', 'M', 'G')
-#define AI_LWO_TAAS AI_IFF_FOURCC('T', 'A', 'A', 'S')
-#define AI_LWO_TREF AI_IFF_FOURCC('T', 'R', 'E', 'F')
-#define AI_LWO_TOPC AI_IFF_FOURCC('T', 'O', 'P', 'C')
-#define AI_LWO_SDAT AI_IFF_FOURCC('S', 'D', 'A', 'T')
-#define AI_LWO_TFP0 AI_IFF_FOURCC('T', 'F', 'P', '0')
-#define AI_LWO_TFP1 AI_IFF_FOURCC('T', 'F', 'P', '1')
-
-/* top-level chunks */
-#define AI_LWO_LAYR AI_IFF_FOURCC('L', 'A', 'Y', 'R')
-#define AI_LWO_TAGS AI_IFF_FOURCC('T', 'A', 'G', 'S')
-#define AI_LWO_PNTS AI_IFF_FOURCC('P', 'N', 'T', 'S')
-#define AI_LWO_BBOX AI_IFF_FOURCC('B', 'B', 'O', 'X')
-#define AI_LWO_VMAP AI_IFF_FOURCC('V', 'M', 'A', 'P')
-#define AI_LWO_VMAD AI_IFF_FOURCC('V', 'M', 'A', 'D')
-#define AI_LWO_POLS AI_IFF_FOURCC('P', 'O', 'L', 'S')
-#define AI_LWO_PTAG AI_IFF_FOURCC('P', 'T', 'A', 'G')
-#define AI_LWO_ENVL AI_IFF_FOURCC('E', 'N', 'V', 'L')
-#define AI_LWO_CLIP AI_IFF_FOURCC('C', 'L', 'I', 'P')
-#define AI_LWO_SURF AI_IFF_FOURCC('S', 'U', 'R', 'F')
-#define AI_LWO_DESC AI_IFF_FOURCC('D', 'E', 'S', 'C')
-#define AI_LWO_TEXT AI_IFF_FOURCC('T', 'E', 'X', 'T')
-#define AI_LWO_ICON AI_IFF_FOURCC('I', 'C', 'O', 'N')
-
-/* polygon types */
-#define AI_LWO_FACE AI_IFF_FOURCC('F', 'A', 'C', 'E')
-#define AI_LWO_CURV AI_IFF_FOURCC('C', 'U', 'R', 'V')
-#define AI_LWO_PTCH AI_IFF_FOURCC('P', 'T', 'C', 'H')
-#define AI_LWO_MBAL AI_IFF_FOURCC('M', 'B', 'A', 'L')
-#define AI_LWO_BONE AI_IFF_FOURCC('B', 'O', 'N', 'E')
-#define AI_LWO_SUBD AI_IFF_FOURCC('S', 'U', 'B', 'D')
-
-/* polygon tags */
-#define AI_LWO_SURF AI_IFF_FOURCC('S', 'U', 'R', 'F')
-#define AI_LWO_PART AI_IFF_FOURCC('P', 'A', 'R', 'T')
-#define AI_LWO_SMGP AI_IFF_FOURCC('S', 'M', 'G', 'P')
-
-/* envelopes */
-#define AI_LWO_PRE AI_IFF_FOURCC('P', 'R', 'E', ' ')
-#define AI_LWO_POST AI_IFF_FOURCC('P', 'O', 'S', 'T')
-#define AI_LWO_KEY AI_IFF_FOURCC('K', 'E', 'Y', ' ')
-#define AI_LWO_SPAN AI_IFF_FOURCC('S', 'P', 'A', 'N')
-#define AI_LWO_TCB AI_IFF_FOURCC('T', 'C', 'B', ' ')
-#define AI_LWO_HERM AI_IFF_FOURCC('H', 'E', 'R', 'M')
-#define AI_LWO_BEZI AI_IFF_FOURCC('B', 'E', 'Z', 'I')
-#define AI_LWO_BEZ2 AI_IFF_FOURCC('B', 'E', 'Z', '2')
-#define AI_LWO_LINE AI_IFF_FOURCC('L', 'I', 'N', 'E')
-#define AI_LWO_STEP AI_IFF_FOURCC('S', 'T', 'E', 'P')
-
-/* clips */
-#define AI_LWO_STIL AI_IFF_FOURCC('S', 'T', 'I', 'L')
-#define AI_LWO_ISEQ AI_IFF_FOURCC('I', 'S', 'E', 'Q')
-#define AI_LWO_ANIM AI_IFF_FOURCC('A', 'N', 'I', 'M')
-#define AI_LWO_XREF AI_IFF_FOURCC('X', 'R', 'E', 'F')
-#define AI_LWO_STCC AI_IFF_FOURCC('S', 'T', 'C', 'C')
-#define AI_LWO_TIME AI_IFF_FOURCC('T', 'I', 'M', 'E')
-#define AI_LWO_CONT AI_IFF_FOURCC('C', 'O', 'N', 'T')
-#define AI_LWO_BRIT AI_IFF_FOURCC('B', 'R', 'I', 'T')
-#define AI_LWO_SATR AI_IFF_FOURCC('S', 'A', 'T', 'R')
-#define AI_LWO_HUE AI_IFF_FOURCC('H', 'U', 'E', ' ')
-#define AI_LWO_GAMM AI_IFF_FOURCC('G', 'A', 'M', 'M')
-#define AI_LWO_NEGA AI_IFF_FOURCC('N', 'E', 'G', 'A')
-#define AI_LWO_IFLT AI_IFF_FOURCC('I', 'F', 'L', 'T')
-#define AI_LWO_PFLT AI_IFF_FOURCC('P', 'F', 'L', 'T')
-
-/* surfaces */
-#define AI_LWO_COLR AI_IFF_FOURCC('C', 'O', 'L', 'R')
-#define AI_LWO_LUMI AI_IFF_FOURCC('L', 'U', 'M', 'I')
-#define AI_LWO_DIFF AI_IFF_FOURCC('D', 'I', 'F', 'F')
-#define AI_LWO_SPEC AI_IFF_FOURCC('S', 'P', 'E', 'C')
-#define AI_LWO_GLOS AI_IFF_FOURCC('G', 'L', 'O', 'S')
-#define AI_LWO_REFL AI_IFF_FOURCC('R', 'E', 'F', 'L')
-#define AI_LWO_RFOP AI_IFF_FOURCC('R', 'F', 'O', 'P')
-#define AI_LWO_RIMG AI_IFF_FOURCC('R', 'I', 'M', 'G')
-#define AI_LWO_RSAN AI_IFF_FOURCC('R', 'S', 'A', 'N')
-#define AI_LWO_TRAN AI_IFF_FOURCC('T', 'R', 'A', 'N')
-#define AI_LWO_TROP AI_IFF_FOURCC('T', 'R', 'O', 'P')
-#define AI_LWO_TIMG AI_IFF_FOURCC('T', 'I', 'M', 'G')
-#define AI_LWO_RIND AI_IFF_FOURCC('R', 'I', 'N', 'D')
-#define AI_LWO_TRNL AI_IFF_FOURCC('T', 'R', 'N', 'L')
-#define AI_LWO_BUMP AI_IFF_FOURCC('B', 'U', 'M', 'P')
-#define AI_LWO_SMAN AI_IFF_FOURCC('S', 'M', 'A', 'N')
-#define AI_LWO_SIDE AI_IFF_FOURCC('S', 'I', 'D', 'E')
-#define AI_LWO_CLRH AI_IFF_FOURCC('C', 'L', 'R', 'H')
-#define AI_LWO_CLRF AI_IFF_FOURCC('C', 'L', 'R', 'F')
-#define AI_LWO_ADTR AI_IFF_FOURCC('A', 'D', 'T', 'R')
-#define AI_LWO_SHRP AI_IFF_FOURCC('S', 'H', 'R', 'P')
-#define AI_LWO_LINE AI_IFF_FOURCC('L', 'I', 'N', 'E')
-#define AI_LWO_LSIZ AI_IFF_FOURCC('L', 'S', 'I', 'Z')
-#define AI_LWO_ALPH AI_IFF_FOURCC('A', 'L', 'P', 'H')
-#define AI_LWO_AVAL AI_IFF_FOURCC('A', 'V', 'A', 'L')
-#define AI_LWO_GVAL AI_IFF_FOURCC('G', 'V', 'A', 'L')
-#define AI_LWO_BLOK AI_IFF_FOURCC('B', 'L', 'O', 'K')
-#define AI_LWO_VCOL AI_IFF_FOURCC('V', 'C', 'O', 'L')
-
-/* texture layer */
-#define AI_LWO_TYPE AI_IFF_FOURCC('T', 'Y', 'P', 'E')
-#define AI_LWO_CHAN AI_IFF_FOURCC('C', 'H', 'A', 'N')
-#define AI_LWO_NAME AI_IFF_FOURCC('N', 'A', 'M', 'E')
-#define AI_LWO_ENAB AI_IFF_FOURCC('E', 'N', 'A', 'B')
-#define AI_LWO_OPAC AI_IFF_FOURCC('O', 'P', 'A', 'C')
-#define AI_LWO_FLAG AI_IFF_FOURCC('F', 'L', 'A', 'G')
-#define AI_LWO_PROJ AI_IFF_FOURCC('P', 'R', 'O', 'J')
-#define AI_LWO_STCK AI_IFF_FOURCC('S', 'T', 'C', 'K')
-#define AI_LWO_TAMP AI_IFF_FOURCC('T', 'A', 'M', 'P')
-
-/* texture coordinates */
-#define AI_LWO_TMAP AI_IFF_FOURCC('T', 'M', 'A', 'P')
-#define AI_LWO_AXIS AI_IFF_FOURCC('A', 'X', 'I', 'S')
-#define AI_LWO_CNTR AI_IFF_FOURCC('C', 'N', 'T', 'R')
-#define AI_LWO_SIZE AI_IFF_FOURCC('S', 'I', 'Z', 'E')
-#define AI_LWO_ROTA AI_IFF_FOURCC('R', 'O', 'T', 'A')
-#define AI_LWO_OREF AI_IFF_FOURCC('O', 'R', 'E', 'F')
-#define AI_LWO_FALL AI_IFF_FOURCC('F', 'A', 'L', 'L')
-#define AI_LWO_CSYS AI_IFF_FOURCC('C', 'S', 'Y', 'S')
-
-/* image map */
-#define AI_LWO_IMAP AI_IFF_FOURCC('I', 'M', 'A', 'P')
-#define AI_LWO_IMAG AI_IFF_FOURCC('I', 'M', 'A', 'G')
-#define AI_LWO_WRAP AI_IFF_FOURCC('W', 'R', 'A', 'P')
-#define AI_LWO_WRPW AI_IFF_FOURCC('W', 'R', 'P', 'W')
-#define AI_LWO_WRPH AI_IFF_FOURCC('W', 'R', 'P', 'H')
-#define AI_LWO_VMAP AI_IFF_FOURCC('V', 'M', 'A', 'P')
-#define AI_LWO_AAST AI_IFF_FOURCC('A', 'A', 'S', 'T')
-#define AI_LWO_PIXB AI_IFF_FOURCC('P', 'I', 'X', 'B')
-
-/* procedural */
-#define AI_LWO_PROC AI_IFF_FOURCC('P', 'R', 'O', 'C')
-#define AI_LWO_COLR AI_IFF_FOURCC('C', 'O', 'L', 'R')
-#define AI_LWO_VALU AI_IFF_FOURCC('V', 'A', 'L', 'U')
-#define AI_LWO_FUNC AI_IFF_FOURCC('F', 'U', 'N', 'C')
-#define AI_LWO_FTPS AI_IFF_FOURCC('F', 'T', 'P', 'S')
-#define AI_LWO_ITPS AI_IFF_FOURCC('I', 'T', 'P', 'S')
-#define AI_LWO_ETPS AI_IFF_FOURCC('E', 'T', 'P', 'S')
-
-/* gradient */
-#define AI_LWO_GRAD AI_IFF_FOURCC('G', 'R', 'A', 'D')
-#define AI_LWO_GRST AI_IFF_FOURCC('G', 'R', 'S', 'T')
-#define AI_LWO_GREN AI_IFF_FOURCC('G', 'R', 'E', 'N')
-#define AI_LWO_PNAM AI_IFF_FOURCC('P', 'N', 'A', 'M')
-#define AI_LWO_INAM AI_IFF_FOURCC('I', 'N', 'A', 'M')
-#define AI_LWO_GRPT AI_IFF_FOURCC('G', 'R', 'P', 'T')
-#define AI_LWO_FKEY AI_IFF_FOURCC('F', 'K', 'E', 'Y')
-#define AI_LWO_IKEY AI_IFF_FOURCC('I', 'K', 'E', 'Y')
-
-/* shader */
-#define AI_LWO_SHDR AI_IFF_FOURCC('S', 'H', 'D', 'R')
-#define AI_LWO_DATA AI_IFF_FOURCC('D', 'A', 'T', 'A')
-
-/* VMAP types */
-#define AI_LWO_TXUV AI_IFF_FOURCC('T', 'X', 'U', 'V')
-#define AI_LWO_RGB AI_IFF_FOURCC('R', 'G', 'B', ' ')
-#define AI_LWO_RGBA AI_IFF_FOURCC('R', 'G', 'B', 'A')
-#define AI_LWO_WGHT AI_IFF_FOURCC('W', 'G', 'H', 'T')
-
-#define AI_LWO_MNVW AI_IFF_FOURCC('M', 'N', 'V', 'W')
-#define AI_LWO_MORF AI_IFF_FOURCC('M', 'O', 'R', 'F')
-#define AI_LWO_SPOT AI_IFF_FOURCC('S', 'P', 'O', 'T')
-#define AI_LWO_PICK AI_IFF_FOURCC('P', 'I', 'C', 'K')
-
-// MODO extension - per-vertex normal vectors
-#define AI_LWO_MODO_NORM AI_IFF_FOURCC('N', 'O', 'R', 'M')
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a face in a LWO file
- *
- * \note We can't use the code in SmoothingGroups.inl here - the mesh
- * structures of 3DS/ASE and LWO are too different.
- */
-struct Face : public aiFace {
- //! Default construction
- Face() AI_NO_EXCEPT
- : surfaceIndex(0),
- smoothGroup(0),
- type(AI_LWO_FACE) {
- // empty
- }
-
- //! Construction from given type
- explicit Face(uint32_t _type) :
- surfaceIndex(0), smoothGroup(0), type(_type) {}
-
- //! Copy construction
- Face(const Face &f) :
- aiFace() {
- *this = f;
- }
-
- //! Zero-based index into tags chunk
- unsigned int surfaceIndex;
-
- //! Smooth group this face is assigned to
- unsigned int smoothGroup;
-
- //! Type of face
- uint32_t type;
-
- //! Assignment operator
- Face &operator=(const LWO::Face &f) {
- aiFace::operator=(f);
- surfaceIndex = f.surfaceIndex;
- smoothGroup = f.smoothGroup;
- type = f.type;
- return *this;
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Base structure for all vertex map representations
- */
-struct VMapEntry {
- explicit VMapEntry(unsigned int _dims) :
- dims(_dims) {}
-
- virtual ~VMapEntry() {}
-
- //! allocates memory for the vertex map
- virtual void Allocate(unsigned int num) {
- if (!rawData.empty())
- return; // return if already allocated
-
- const unsigned int m = num * dims;
- rawData.reserve(m + (m >> 2u)); // 25% as extra storage for VMADs
- rawData.resize(m, 0.f);
- abAssigned.resize(num, false);
- }
-
- std::string name;
- unsigned int dims;
-
- std::vector<float> rawData;
- std::vector<bool> abAssigned;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents an extra vertex color channel
- */
-struct VColorChannel : public VMapEntry {
- VColorChannel() :
- VMapEntry(4) {}
-
- //! need to overwrite this function - the alpha channel must
- //! be initialized to 1.0 by default
- virtual void Allocate(unsigned int num) {
- if (!rawData.empty())
- return; // return if already allocated
-
- unsigned int m = num * dims;
- rawData.reserve(m + (m >> 2u)); // 25% as extra storage for VMADs
- rawData.resize(m);
-
- for (aiColor4D *p = (aiColor4D *)&rawData[0]; p < (aiColor4D *)&rawData[m - 1]; ++p)
- p->a = 1.f;
-
- abAssigned.resize(num, false);
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents an extra vertex UV channel
- */
-struct UVChannel : public VMapEntry {
- UVChannel() :
- VMapEntry(2) {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a weight map
- */
-struct WeightChannel : public VMapEntry {
- WeightChannel() :
- VMapEntry(1) {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a vertex-normals channel (MODO extension)
- */
-struct NormalChannel : public VMapEntry {
- NormalChannel() :
- VMapEntry(3) {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file texture
- */
-struct Texture {
- // we write the enum values out here to make debugging easier ...
- enum BlendType {
- Normal = 0,
- Subtractive = 1,
- Difference = 2,
- Multiply = 3,
- Divide = 4,
- Alpha = 5,
- TextureDispl = 6,
- Additive = 7
- };
-
- enum MappingMode {
- Planar = 0,
- Cylindrical = 1,
- Spherical = 2,
- Cubic = 3,
- FrontProjection = 4,
- UV = 5
- };
-
- enum Axes {
- AXIS_X = 0,
- AXIS_Y = 1,
- AXIS_Z = 2
- };
-
- enum Wrap {
- RESET = 0,
- REPEAT = 1,
- MIRROR = 2,
- EDGE = 3
- };
-
- Texture() :
- mClipIdx(UINT_MAX), mStrength(1.0f), type(), mUVChannelIndex("unknown"), mRealUVIndex(UINT_MAX), enabled(true), blendType(Additive), bCanUse(true), mapMode(UV), majorAxis(AXIS_X), wrapAmountH(1.0f), wrapAmountW(1.0f), wrapModeWidth(REPEAT), wrapModeHeight(REPEAT), ordinal("\x00") {}
-
- //! File name of the texture
- std::string mFileName;
-
- //! Clip index
- unsigned int mClipIdx;
-
- //! Strength of the texture - blend factor
- float mStrength;
-
- uint32_t type; // type of the texture
-
- //! Name of the corresponding UV channel
- std::string mUVChannelIndex;
- unsigned int mRealUVIndex;
-
- //! is the texture enabled?
- bool enabled;
-
- //! blend type
- BlendType blendType;
-
- //! are we able to use the texture?
- bool bCanUse;
-
- //! mapping mode
- MappingMode mapMode;
-
- //! major axis for planar, cylindrical, spherical projections
- Axes majorAxis;
-
- //! wrap amount for cylindrical and spherical projections
- float wrapAmountH, wrapAmountW;
-
- //! wrapping mode for the texture
- Wrap wrapModeWidth, wrapModeHeight;
-
- //! ordinal string of the texture
- std::string ordinal;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file clip
- */
-struct Clip {
- enum Type {
- STILL,
- SEQ,
- REF,
- UNSUPPORTED
- } type;
-
- Clip() :
- type(UNSUPPORTED), clipRef(), idx(0), negate(false) {}
-
- //! path to the base texture -
- std::string path;
-
- //! reference to another CLIP
- unsigned int clipRef;
-
- //! index of the clip
- unsigned int idx;
-
- //! Negate the clip?
- bool negate;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file shader
- *
- * Later
- */
-struct Shader {
- Shader() :
- ordinal("\x00"), functionName("unknown"), enabled(true) {}
-
- std::string ordinal;
- std::string functionName;
- bool enabled;
-};
-
-typedef std::list<Texture> TextureList;
-typedef std::list<Shader> ShaderList;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file surface (= material)
- */
-struct Surface {
- Surface() :
- mColor(0.78431f, 0.78431f, 0.78431f), bDoubleSided(false), mDiffuseValue(1.f), mSpecularValue(0.f), mTransparency(0.f), mGlossiness(0.4f), mLuminosity(0.f), mColorHighlights(0.f), mMaximumSmoothAngle(0.f) // 0 == not specified, no smoothing
- ,
- mVCMap(),
- mVCMapType(AI_LWO_RGBA),
- mIOR(1.f) // vakuum
- ,
- mBumpIntensity(1.f),
- mWireframe(false),
- mAdditiveTransparency(0.f) {}
-
- //! Name of the surface
- std::string mName;
-
- //! Color of the surface
- aiColor3D mColor;
-
- //! true for two-sided materials
- bool bDoubleSided;
-
- //! Various material parameters
- float mDiffuseValue, mSpecularValue, mTransparency, mGlossiness, mLuminosity, mColorHighlights;
-
- //! Maximum angle between two adjacent triangles
- //! that they can be smoothed - in degrees
- float mMaximumSmoothAngle;
-
- //! Vertex color map to be used to color the surface
- std::string mVCMap;
- uint32_t mVCMapType;
-
- //! Names of the special shaders to be applied to the surface
- ShaderList mShaders;
-
- //! Textures - the first entry in the list is evaluated first
- TextureList mColorTextures, // color textures are added to both diffuse and specular texture stacks
- mDiffuseTextures,
- mSpecularTextures,
- mOpacityTextures,
- mBumpTextures,
- mGlossinessTextures,
- mReflectionTextures;
-
- //! Index of refraction
- float mIOR;
-
- //! Bump intensity scaling
- float mBumpIntensity;
-
- //! Wireframe flag
- bool mWireframe;
-
- //! Intensity of additive blending
- float mAdditiveTransparency;
-};
-
-// ---------------------------------------------------------------------------
-#define AI_LWO_VALIDATE_CHUNK_LENGTH(length, name, size) \
- if (length < size) { \
- throw DeadlyImportError("LWO: " #name " chunk is too small"); \
- }
-
-// some typedefs ... to make life with loader monsters like this easier
-typedef std::vector<aiVector3D> PointList;
-typedef std::vector<LWO::Face> FaceList;
-typedef std::vector<LWO::Surface> SurfaceList;
-typedef std::vector<std::string> TagList;
-typedef std::vector<unsigned int> TagMappingTable;
-typedef std::vector<unsigned int> ReferrerList;
-typedef std::vector<WeightChannel> WeightChannelList;
-typedef std::vector<VColorChannel> VColorChannelList;
-typedef std::vector<UVChannel> UVChannelList;
-typedef std::vector<Clip> ClipList;
-typedef std::vector<Envelope> EnvelopeList;
-typedef std::vector<unsigned int> SortedRep;
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a layer in the file
- */
-struct Layer {
- Layer() :
- mFaceIDXOfs(0), mPointIDXOfs(0), mParent(0x0), mIndex(0xffff), skip(false) {}
-
- /** Temporary point list from the file */
- PointList mTempPoints;
-
- /** Lists for every point the index of another point
- that has been copied from *this* point or UINT_MAX if
- no copy of the point has been made */
- ReferrerList mPointReferrers;
-
- /** Weight channel list from the file */
- WeightChannelList mWeightChannels;
-
- /** Subdivision weight channel list from the file */
- WeightChannelList mSWeightChannels;
-
- /** Vertex color list from the file */
- VColorChannelList mVColorChannels;
-
- /** UV channel list from the file */
- UVChannelList mUVChannels;
-
- /** Normal vector channel from the file */
- NormalChannel mNormals;
-
- /** Temporary face list from the file*/
- FaceList mFaces;
-
- /** Current face indexing offset from the beginning of the buffers*/
- unsigned int mFaceIDXOfs;
-
- /** Current point indexing offset from the beginning of the buffers*/
- unsigned int mPointIDXOfs;
-
- /** Parent index */
- uint16_t mParent;
-
- /** Index of the layer */
- uint16_t mIndex;
-
- /** Name of the layer */
- std::string mName;
-
- /** Pivot point of the layer */
- aiVector3D mPivot;
-
- /** Skip this layer? */
- bool skip;
-};
-
-typedef std::list<LWO::Layer> LayerList;
-
-} // namespace LWO
-} // namespace Assimp
-
-#endif // !! AI_LWO_FILEDATA_INCLUDED
diff --git a/libs/assimp/code/AssetLib/LWO/LWOLoader.cpp b/libs/assimp/code/AssetLib/LWO/LWOLoader.cpp
deleted file mode 100644
index 7410fb6..0000000
--- a/libs/assimp/code/AssetLib/LWO/LWOLoader.cpp
+++ /dev/null
@@ -1,1422 +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 LWOLoader.cpp
- * @brief Implementation of the LWO importer class
- */
-
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// internal headers
-#include "AssetLib/LWO/LWOLoader.h"
-#include "PostProcessing/ConvertToLHProcess.h"
-#include "PostProcessing/ProcessHelper.h"
-
-#include <assimp/ByteSwapper.h>
-#include <assimp/SGSpatialSort.h>
-#include <assimp/StringComparison.h>
-#include <assimp/importerdesc.h>
-#include <assimp/IOSystem.hpp>
-
-#include <iomanip>
-#include <map>
-#include <memory>
-#include <sstream>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "LightWave/Modo Object Importer",
- "",
- "",
- "https://www.lightwave3d.com/lightwave_sdk/",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "lwo lxo"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-LWOImporter::LWOImporter() :
- mIsLWO2(),
- mIsLXOB(),
- mLayers(),
- mCurLayer(),
- mTags(),
- mMapping(),
- mSurfaces(),
- mFileBuffer(),
- fileSize(),
- mScene(nullptr),
- configSpeedFlag(),
- configLayerIndex(),
- hasNamedLayer() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-LWOImporter::~LWOImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool LWOImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool /*checkSig*/) const {
- static const uint32_t tokens[] = {
- AI_LWO_FOURCC_LWOB,
- AI_LWO_FOURCC_LWO2,
- AI_LWO_FOURCC_LXOB
- };
- return CheckMagicToken(pIOHandler, file, tokens, AI_COUNT_OF(tokens), 8);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void LWOImporter::SetupProperties(const Importer *pImp) {
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0) ? true : false);
- configLayerIndex = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, UINT_MAX);
- configLayerName = pImp->GetPropertyString(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, "");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of file extensions
-const aiImporterDesc *LWOImporter::GetInfo() const {
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void LWOImporter::InternReadFile(const std::string &pFile,
- aiScene *pScene,
- IOSystem *pIOHandler) {
- std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
-
- // Check whether we can read from the file
- if (file.get() == nullptr) {
- throw DeadlyImportError("Failed to open LWO file ", pFile, ".");
- }
-
- if ((this->fileSize = (unsigned int)file->FileSize()) < 12) {
- throw DeadlyImportError("LWO: The file is too small to contain the IFF header");
- }
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector<uint8_t> mBuffer(fileSize);
- file->Read(&mBuffer[0], 1, fileSize);
- mScene = pScene;
-
- // Determine the type of the file
- uint32_t fileType;
- const char *sz = IFF::ReadHeader(&mBuffer[0], fileType);
- if (sz) {
- throw DeadlyImportError(sz);
- }
-
- mFileBuffer = &mBuffer[0] + 12;
- fileSize -= 12;
-
- // Initialize some members with their default values
- hasNamedLayer = false;
-
- // Create temporary storage on the stack but store pointers to it in the class
- // instance. Therefore everything will be destructed properly if an exception
- // is thrown and we needn't take care of that.
- LayerList _mLayers;
- SurfaceList _mSurfaces;
- TagList _mTags;
- TagMappingTable _mMapping;
-
- mLayers = &_mLayers;
- mTags = &_mTags;
- mMapping = &_mMapping;
- mSurfaces = &_mSurfaces;
-
- // Allocate a default layer (layer indices are 1-based from now)
- mLayers->push_back(Layer());
- mCurLayer = &mLayers->back();
- mCurLayer->mName = "<LWODefault>";
- mCurLayer->mIndex = (uint16_t) -1;
-
- // old lightwave file format (prior to v6)
- if (AI_LWO_FOURCC_LWOB == fileType) {
- ASSIMP_LOG_INFO("LWO file format: LWOB (<= LightWave 5.5)");
-
- mIsLWO2 = false;
- mIsLXOB = false;
- LoadLWOBFile();
- } else if (AI_LWO_FOURCC_LWO2 == fileType) {
- // New lightwave format
- mIsLXOB = false;
- ASSIMP_LOG_INFO("LWO file format: LWO2 (>= LightWave 6)");
- } else if (AI_LWO_FOURCC_LXOB == fileType) {
- // MODO file format
- mIsLXOB = true;
- ASSIMP_LOG_INFO("LWO file format: LXOB (Modo)");
- }
- else {
- char szBuff[5];
- szBuff[0] = (char)(fileType >> 24u);
- szBuff[1] = (char)(fileType >> 16u);
- szBuff[2] = (char)(fileType >> 8u);
- szBuff[3] = (char)(fileType);
- szBuff[4] = '\0';
- throw DeadlyImportError("Unknown LWO sub format: ", szBuff);
- }
-
- if (AI_LWO_FOURCC_LWOB != fileType) {
- mIsLWO2 = true;
- LoadLWO2File();
-
- // The newer lightwave format allows the user to configure the
- // loader that just one layer is used. If this is the case
- // we need to check now whether the requested layer has been found.
- if (UINT_MAX != configLayerIndex) {
- unsigned int layerCount = 0;
- for (std::list<LWO::Layer>::iterator itLayers = mLayers->begin(); itLayers != mLayers->end(); ++itLayers)
- if (!itLayers->skip)
- layerCount++;
- if (layerCount != 2)
- throw DeadlyImportError("LWO2: The requested layer was not found");
- }
-
- if (configLayerName.length() && !hasNamedLayer) {
- throw DeadlyImportError("LWO2: Unable to find the requested layer: ", configLayerName);
- }
- }
-
- // now, as we have loaded all data, we can resolve cross-referenced tags and clips
- ResolveTags();
- ResolveClips();
-
- // now process all layers and build meshes and nodes
- std::vector<aiMesh *> apcMeshes;
- std::map<uint16_t, aiNode *> apcNodes;
-
- apcMeshes.reserve(mLayers->size() * std::min(((unsigned int)mSurfaces->size() / 2u), 1u));
-
- unsigned int iDefaultSurface = UINT_MAX; // index of the default surface
- for (LWO::Layer &layer : *mLayers) {
- if (layer.skip)
- continue;
-
- // I don't know whether there could be dummy layers, but it would be possible
- const unsigned int meshStart = (unsigned int)apcMeshes.size();
- if (!layer.mFaces.empty() && !layer.mTempPoints.empty()) {
-
- // now sort all faces by the surfaces assigned to them
- std::vector<SortedRep> pSorted(mSurfaces->size() + 1);
-
- unsigned int i = 0;
- for (FaceList::iterator it = layer.mFaces.begin(), end = layer.mFaces.end(); it != end; ++it, ++i) {
- // Check whether we support this face's type
- if ((*it).type != AI_LWO_FACE && (*it).type != AI_LWO_PTCH &&
- (*it).type != AI_LWO_BONE && (*it).type != AI_LWO_SUBD) {
- continue;
- }
-
- unsigned int idx = (*it).surfaceIndex;
- if (idx >= mTags->size()) {
- ASSIMP_LOG_WARN("LWO: Invalid face surface index");
- idx = UINT_MAX;
- }
- if (UINT_MAX == idx || UINT_MAX == (idx = _mMapping[idx])) {
- if (UINT_MAX == iDefaultSurface) {
- iDefaultSurface = (unsigned int)mSurfaces->size();
- mSurfaces->push_back(LWO::Surface());
- LWO::Surface &surf = mSurfaces->back();
- surf.mColor.r = surf.mColor.g = surf.mColor.b = 0.6f;
- surf.mName = "LWODefaultSurface";
- }
- idx = iDefaultSurface;
- }
- pSorted[idx].push_back(i);
- }
- if (UINT_MAX == iDefaultSurface) {
- pSorted.erase(pSorted.end() - 1);
- }
- for (unsigned int p = 0, j = 0; j < mSurfaces->size(); ++j) {
- SortedRep &sorted = pSorted[j];
- if (sorted.empty())
- continue;
-
- // generate the mesh
- aiMesh *mesh = new aiMesh();
- apcMeshes.push_back(mesh);
- mesh->mNumFaces = (unsigned int)sorted.size();
-
- // count the number of vertices
- SortedRep::const_iterator it = sorted.begin(), end = sorted.end();
- for (; it != end; ++it) {
- mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
- }
-
- aiVector3D *nrm = nullptr, *pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- aiFace *pf = mesh->mFaces = new aiFace[mesh->mNumFaces];
- mesh->mMaterialIndex = j;
-
- // find out which vertex color channels and which texture coordinate
- // channels are really required by the material attached to this mesh
- unsigned int vUVChannelIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- unsigned int vVColorIndices[AI_MAX_NUMBER_OF_COLOR_SETS];
-
-#ifdef ASSIMP_BUILD_DEBUG
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++mui) {
- vUVChannelIndices[mui] = UINT_MAX;
- }
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS; ++mui) {
- vVColorIndices[mui] = UINT_MAX;
- }
-#endif
-
- FindUVChannels(_mSurfaces[j], sorted, layer, vUVChannelIndices);
- FindVCChannels(_mSurfaces[j], sorted, layer, vVColorIndices);
-
- // allocate storage for UV and CV channels
- aiVector3D *pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++mui) {
- if (UINT_MAX == vUVChannelIndices[mui]) {
- break;
- }
-
- pvUV[mui] = mesh->mTextureCoords[mui] = new aiVector3D[mesh->mNumVertices];
-
- // LightWave doesn't support more than 2 UV components (?)
- mesh->mNumUVComponents[0] = 2;
- }
-
- if (layer.mNormals.name.length()) {
- nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- }
-
- aiColor4D *pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS; ++mui) {
- if (UINT_MAX == vVColorIndices[mui]) {
- break;
- }
- pvVC[mui] = mesh->mColors[mui] = new aiColor4D[mesh->mNumVertices];
- }
-
- // we would not need this extra array, but the code is much cleaner if we use it
- std::vector<unsigned int> &smoothingGroups = layer.mPointReferrers;
- smoothingGroups.erase(smoothingGroups.begin(), smoothingGroups.end());
- smoothingGroups.resize(mesh->mNumFaces, 0);
-
- // now convert all faces
- unsigned int vert = 0;
- std::vector<unsigned int>::iterator outIt = smoothingGroups.begin();
- for (it = sorted.begin(); it != end; ++it, ++outIt) {
- const LWO::Face &face = layer.mFaces[*it];
- *outIt = face.smoothGroup;
-
- // copy all vertices
- for (unsigned int q = 0; q < face.mNumIndices; ++q, ++vert) {
- unsigned int idx = face.mIndices[q];
- *pv++ = layer.mTempPoints[idx] /*- layer.mPivot*/;
-
- // process UV coordinates
- for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++w) {
- if (UINT_MAX == vUVChannelIndices[w]) {
- break;
- }
- aiVector3D *&pp = pvUV[w];
- const aiVector2D &src = ((aiVector2D *)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
- pp->x = src.x;
- pp->y = src.y;
- pp++;
- }
-
- // process normals (MODO extension)
- if (nrm) {
- *nrm = ((aiVector3D *)&layer.mNormals.rawData[0])[idx];
- nrm->z *= -1.f;
- ++nrm;
- }
-
- // process vertex colors
- for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_COLOR_SETS; ++w) {
- if (UINT_MAX == vVColorIndices[w]) {
- break;
- }
- *pvVC[w] = ((aiColor4D *)&layer.mVColorChannels[vVColorIndices[w]].rawData[0])[idx];
-
- // If a RGB color map is explicitly requested delete the
- // alpha channel - it could theoretically be != 1.
- if (_mSurfaces[j].mVCMapType == AI_LWO_RGB)
- pvVC[w]->a = 1.f;
-
- pvVC[w]++;
- }
-
-#if 0
- // process vertex weights. We can't properly reconstruct the whole skeleton for now,
- // but we can create dummy bones for all weight channels which we have.
- for (unsigned int w = 0; w < layer.mWeightChannels.size();++w)
- {
- }
-#endif
-
- face.mIndices[q] = vert;
- }
- pf->mIndices = face.mIndices;
- pf->mNumIndices = face.mNumIndices;
- unsigned int **facePtr = (unsigned int **)&face.mIndices;
- *facePtr = nullptr; // HACK: make sure it won't be deleted
- pf++;
- }
-
- if (!mesh->mNormals) {
- // Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
- // Step here since it wouldn't handle smoothing groups correctly for LWO.
- // So we use a separate implementation.
- ComputeNormals(mesh, smoothingGroups, _mSurfaces[j]);
- } else {
- ASSIMP_LOG_VERBOSE_DEBUG("LWO2: No need to compute normals, they're already there");
- }
- ++p;
- }
- }
-
- // Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
- unsigned int num = static_cast<unsigned int>(apcMeshes.size() - meshStart);
- if (layer.mName != "<LWODefault>" || num > 0) {
- aiNode *pcNode = new aiNode();
- pcNode->mName.Set(layer.mName);
- pcNode->mParent = (aiNode *)&layer;
- pcNode->mNumMeshes = num;
-
- if (pcNode->mNumMeshes) {
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
- for (unsigned int p = 0; p < pcNode->mNumMeshes; ++p)
- pcNode->mMeshes[p] = p + meshStart;
- }
- apcNodes[layer.mIndex] = pcNode;
- }
- }
-
- if (apcNodes.empty() || apcMeshes.empty())
- throw DeadlyImportError("LWO: No meshes loaded");
-
- // The RemoveRedundantMaterials step will clean this up later
- pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials = (unsigned int)mSurfaces->size()];
- for (unsigned int mat = 0; mat < pScene->mNumMaterials; ++mat) {
- aiMaterial *pcMat = new aiMaterial();
- pScene->mMaterials[mat] = pcMat;
- ConvertMaterial((*mSurfaces)[mat], pcMat);
- }
-
- // copy the meshes to the output structure
- pScene->mMeshes = new aiMesh *[pScene->mNumMeshes = (unsigned int)apcMeshes.size()];
- ::memcpy(pScene->mMeshes, &apcMeshes[0], pScene->mNumMeshes * sizeof(void *));
-
- // generate the final node graph
- GenerateNodeGraph(apcNodes);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &smoothingGroups,
- const LWO::Surface &surface) {
- // Allocate output storage
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
-
- // First generate per-face normals
- aiVector3D *out;
- std::vector<aiVector3D> faceNormals;
-
- // ... in some cases that's already enough
- if (!surface.mMaximumSmoothAngle)
- out = mesh->mNormals;
- else {
- faceNormals.resize(mesh->mNumVertices);
- out = &faceNormals[0];
- }
-
- aiFace *begin = mesh->mFaces, *const end = mesh->mFaces + mesh->mNumFaces;
- for (; begin != end; ++begin) {
- aiFace &face = *begin;
-
- if (face.mNumIndices < 3) {
- continue;
- }
-
- // LWO doc: "the normal is defined as the cross product of the first and last edges"
- aiVector3D *pV1 = mesh->mVertices + face.mIndices[0];
- aiVector3D *pV2 = mesh->mVertices + face.mIndices[1];
- aiVector3D *pV3 = mesh->mVertices + face.mIndices[face.mNumIndices - 1];
-
- aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
- for (unsigned int i = 0; i < face.mNumIndices; ++i)
- out[face.mIndices[i]] = vNor;
- }
- if (!surface.mMaximumSmoothAngle) return;
- const float posEpsilon = ComputePositionEpsilon(mesh);
-
- // Now generate the spatial sort tree
- SGSpatialSort sSort;
- std::vector<unsigned int>::const_iterator it = smoothingGroups.begin();
- for (begin = mesh->mFaces; begin != end; ++begin, ++it) {
- aiFace &face = *begin;
- for (unsigned int i = 0; i < face.mNumIndices; ++i) {
- unsigned int tt = face.mIndices[i];
- sSort.Add(mesh->mVertices[tt], tt, *it);
- }
- }
- // Sort everything - this takes O(nlogn) time
- sSort.Prepare();
- std::vector<unsigned int> poResult;
- poResult.reserve(20);
-
- // Generate vertex normals. We have O(logn) for the binary lookup, which we need
- // for n elements, thus the EXPECTED complexity is O(nlogn)
- if (surface.mMaximumSmoothAngle < 3.f && !configSpeedFlag) {
- const float fLimit = std::cos(surface.mMaximumSmoothAngle);
-
- for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
- const aiFace &face = *begin;
- unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices;
- for (; beginIdx != endIdx; ++beginIdx) {
- unsigned int idx = *beginIdx;
- sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true);
-
- aiVector3D vNormals;
- for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
- const aiVector3D &v = faceNormals[*a];
- if (v * faceNormals[idx] < fLimit)
- continue;
- vNormals += v;
- }
- mesh->mNormals[idx] = vNormals.Normalize();
- }
- }
- }
- // faster code path in case there is no smooth angle
- else {
- std::vector<bool> vertexDone(mesh->mNumVertices, false);
- for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
- const aiFace &face = *begin;
- unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices;
- for (; beginIdx != endIdx; ++beginIdx) {
- unsigned int idx = *beginIdx;
- if (vertexDone[idx])
- continue;
- sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true);
-
- aiVector3D vNormals;
- for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
- const aiVector3D &v = faceNormals[*a];
- vNormals += v;
- }
- vNormals.Normalize();
- for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
- mesh->mNormals[*a] = vNormals;
- vertexDone[*a] = true;
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
- // now generate the final nodegraph - generate a root node and attach children
- aiNode *root = mScene->mRootNode = new aiNode();
- root->mName.Set("<LWORoot>");
-
- //Set parent of all children, inserting pivots
- std::map<uint16_t, aiNode *> mapPivot;
- for (auto itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
-
- //Get the parent index
- LWO::Layer *nodeLayer = (LWO::Layer *)(itapcNodes->second->mParent);
- uint16_t parentIndex = nodeLayer->mParent;
-
- //Create pivot node, store it into the pivot map, and set the parent as the pivot
- aiNode *pivotNode = new aiNode();
- pivotNode->mName.Set("Pivot-" + std::string(itapcNodes->second->mName.data));
- itapcNodes->second->mParent = pivotNode;
-
- //Look for the parent node to attach the pivot to
- if (apcNodes.find(parentIndex) != apcNodes.end()) {
- pivotNode->mParent = apcNodes[parentIndex];
- } else {
- //If not, attach to the root node
- pivotNode->mParent = root;
- }
-
- //Set the node and the pivot node transformation
- itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
- itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
- itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
- pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
- pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
- pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
- mapPivot[-(itapcNodes->first + 2)] = pivotNode;
- }
-
- //Merge pivot map into node map
- for (auto itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end(); ++itMapPivot) {
- apcNodes[itMapPivot->first] = itMapPivot->second;
- }
-
- //Set children of all parents
- apcNodes[(uint16_t)-1] = root;
- for (auto itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) {
- for (auto itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
- if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
- ++(itMapParentNodes->second->mNumChildren);
- }
- }
- if (itMapParentNodes->second->mNumChildren) {
- itMapParentNodes->second->mChildren = new aiNode *[itMapParentNodes->second->mNumChildren];
- uint16_t p = 0;
- for (auto itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
- if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
- itMapParentNodes->second->mChildren[p++] = itMapChildNodes->second;
- }
- }
- }
- }
-
- if (!mScene->mRootNode->mNumChildren)
- throw DeadlyImportError("LWO: Unable to build a valid node graph");
-
- // Remove a single root node with no meshes assigned to it ...
- if (1 == mScene->mRootNode->mNumChildren) {
- aiNode *pc = mScene->mRootNode->mChildren[0];
- pc->mParent = mScene->mRootNode->mChildren[0] = nullptr;
- delete mScene->mRootNode;
- mScene->mRootNode = pc;
- }
-
- // convert the whole stuff to RH with CCW winding
- MakeLeftHandedProcess maker;
- maker.Execute(mScene);
-
- FlipWindingOrderProcess flipper;
- flipper.Execute(mScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ResolveTags() {
- // --- this function is used for both LWO2 and LWOB
- mMapping->resize(mTags->size(), UINT_MAX);
- for (unsigned int a = 0; a < mTags->size(); ++a) {
-
- const std::string &c = (*mTags)[a];
- for (unsigned int i = 0; i < mSurfaces->size(); ++i) {
-
- const std::string &d = (*mSurfaces)[i].mName;
- if (!ASSIMP_stricmp(c, d)) {
-
- (*mMapping)[a] = i;
- break;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ResolveClips() {
- for (unsigned int i = 0; i < mClips.size(); ++i) {
-
- Clip &clip = mClips[i];
- if (Clip::REF == clip.type) {
-
- if (clip.clipRef >= mClips.size()) {
- ASSIMP_LOG_ERROR("LWO2: Clip referrer index is out of range");
- clip.clipRef = 0;
- }
-
- Clip &dest = mClips[clip.clipRef];
- if (Clip::REF == dest.type) {
- ASSIMP_LOG_ERROR("LWO2: Clip references another clip reference");
- clip.type = Clip::UNSUPPORTED;
- }
-
- else {
- clip.path = dest.path;
- clip.type = dest.type;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::AdjustTexturePath(std::string &out) {
- // --- this function is used for both LWO2 and LWOB
- if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) {
-
- // remove the (sequence) and append 000
- ASSIMP_LOG_INFO("LWOB: Sequence of animated texture found. It will be ignored");
- out = out.substr(0, out.length() - 10) + "000";
- }
-
- // format: drive:path/file - we just need to insert a slash after the drive
- std::string::size_type n = out.find_first_of(':');
- if (std::string::npos != n) {
- out.insert(n + 1, "/");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOTags(unsigned int size) {
- // --- this function is used for both LWO2 and LWOB
-
- const char *szCur = (const char *)mFileBuffer, *szLast = szCur;
- const char *const szEnd = szLast + size;
- while (szCur < szEnd) {
- if (!(*szCur)) {
- const size_t len = (size_t)(szCur - szLast);
- // FIX: skip empty-sized tags
- if (len)
- mTags->push_back(std::string(szLast, len));
- szCur += (len & 0x1 ? 1 : 2);
- szLast = szCur;
- }
- szCur++;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOPoints(unsigned int length) {
- // --- this function is used for both LWO2 and LWOB but for
- // LWO2 we need to allocate 25% more storage - it could be we'll
- // need to duplicate some points later.
- const size_t vertexLen = 12;
- if ((length % vertexLen) != 0) {
- throw DeadlyImportError("LWO2: Points chunk length is not multiple of vertexLen (12)");
- }
- unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12;
- if (mIsLWO2) {
- mCurLayer->mTempPoints.reserve(regularSize + (regularSize >> 2u));
- mCurLayer->mTempPoints.resize(regularSize);
-
- // initialize all point referrers with the default values
- mCurLayer->mPointReferrers.reserve(regularSize + (regularSize >> 2u));
- mCurLayer->mPointReferrers.resize(regularSize, UINT_MAX);
- } else
- mCurLayer->mTempPoints.resize(regularSize);
-
- // perform endianness conversions
-#ifndef AI_BUILD_BIG_ENDIAN
- for (unsigned int i = 0; i<length >> 2; ++i)
- ByteSwap::Swap4(mFileBuffer + (i << 2));
-#endif
- ::memcpy(&mCurLayer->mTempPoints[0], mFileBuffer, length);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Polygons(unsigned int length) {
- LE_NCONST uint16_t *const end = (LE_NCONST uint16_t *)(mFileBuffer + length);
- const uint32_t type = GetU4();
-
- // Determine the type of the polygons
- switch (type) {
- // read unsupported stuff too (although we won't process it)
- case AI_LWO_MBAL:
- ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (METABALL)");
- break;
- case AI_LWO_CURV:
- ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (SPLINE)");
- ;
- break;
-
- // These are ok with no restrictions
- case AI_LWO_PTCH:
- case AI_LWO_FACE:
- case AI_LWO_BONE:
- case AI_LWO_SUBD:
- break;
- default:
-
- // hm!? wtf is this? ok ...
- ASSIMP_LOG_ERROR("LWO2: Ignoring unknown polygon type.");
- break;
- }
-
- // first find out how many faces and vertices we'll finally need
- uint16_t *cursor = (uint16_t *)mFileBuffer;
-
- unsigned int iNumFaces = 0, iNumVertices = 0;
- CountVertsAndFacesLWO2(iNumVertices, iNumFaces, cursor, end);
-
- // allocate the output array and copy face indices
- if (iNumFaces) {
- cursor = (uint16_t *)mFileBuffer;
-
- mCurLayer->mFaces.resize(iNumFaces, LWO::Face(type));
- FaceList::iterator it = mCurLayer->mFaces.begin();
- CopyFaceIndicesLWO2(it, cursor, end);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CountVertsAndFacesLWO2(unsigned int &verts, unsigned int &faces,
- uint16_t *&cursor, const uint16_t *const end, unsigned int max) {
- while (cursor < end && max--) {
- uint16_t numIndices;
- ::memcpy(&numIndices, cursor++, 2);
- AI_LSWAP2(numIndices);
- numIndices &= 0x03FF;
-
- verts += numIndices;
- ++faces;
-
- for (uint16_t i = 0; i < numIndices; i++) {
- ReadVSizedIntLWO2((uint8_t *&)cursor);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator &it,
- uint16_t *&cursor,
- const uint16_t *const end) {
- while (cursor < end) {
- LWO::Face &face = *it++;
- uint16_t numIndices;
- ::memcpy(&numIndices, cursor++, 2);
- AI_LSWAP2(numIndices);
- face.mNumIndices = numIndices & 0x03FF;
-
- if (face.mNumIndices) /* byte swapping has already been done */
- {
- face.mIndices = new unsigned int[face.mNumIndices];
- for (unsigned int i = 0; i < face.mNumIndices; i++) {
- face.mIndices[i] = ReadVSizedIntLWO2((uint8_t *&)cursor) + mCurLayer->mPointIDXOfs;
- if (face.mIndices[i] > mCurLayer->mTempPoints.size()) {
- ASSIMP_LOG_WARN("LWO2: Failure evaluating face record, index is out of range");
- face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size() - 1;
- }
- }
- } else
- throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2PolygonTags(unsigned int length) {
- LE_NCONST uint8_t *const end = mFileBuffer + length;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(length, PTAG, 4);
- uint32_t type = GetU4();
-
- if (type != AI_LWO_SURF && type != AI_LWO_SMGP)
- return;
-
- while (mFileBuffer < end) {
- unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
- unsigned int j = GetU2();
-
- if (i >= mCurLayer->mFaces.size()) {
- ASSIMP_LOG_WARN("LWO2: face index in PTAG is out of range");
- continue;
- }
-
- switch (type) {
-
- case AI_LWO_SURF:
- mCurLayer->mFaces[i].surfaceIndex = j;
- break;
- case AI_LWO_SMGP: /* is that really used? */
- mCurLayer->mFaces[i].smoothGroup = j;
- break;
- };
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-VMapEntry *FindEntry(std::vector<T> &list, const std::string &name, bool perPoly) {
- for (auto &elem : list) {
- if (elem.name == name) {
- if (!perPoly) {
- ASSIMP_LOG_WARN("LWO2: Found two VMAP sections with equal names");
- }
- return &elem;
- }
- }
- list.push_back(T());
- VMapEntry *p = &list.back();
- p->name = name;
- return p;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline void CreateNewEntry(T &chan, unsigned int srcIdx) {
- if (!chan.name.length())
- return;
-
- chan.abAssigned[srcIdx] = true;
- chan.abAssigned.resize(chan.abAssigned.size() + 1, false);
-
- for (unsigned int a = 0; a < chan.dims; ++a)
- chan.rawData.push_back(chan.rawData[srcIdx * chan.dims + a]);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline void CreateNewEntry(std::vector<T> &list, unsigned int srcIdx) {
- for (auto &elem : list) {
- CreateNewEntry(elem, srcIdx);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead,
- unsigned int idx, float *data) {
- ai_assert(nullptr != data);
- LWO::ReferrerList &refList = mCurLayer->mPointReferrers;
- unsigned int i;
-
- if (idx >= base->abAssigned.size()) {
- throw DeadlyImportError("Bad index");
- }
- base->abAssigned[idx] = true;
- for (i = 0; i < numRead; ++i) {
- base->rawData[idx * base->dims + i] = data[i];
- }
-
- if (UINT_MAX != (i = refList[idx])) {
- DoRecursiveVMAPAssignment(base, numRead, i, data);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void AddToSingleLinkedList(ReferrerList &refList, unsigned int srcIdx, unsigned int destIdx) {
- if (UINT_MAX == refList[srcIdx]) {
- refList[srcIdx] = destIdx;
- return;
- }
- AddToSingleLinkedList(refList, refList[srcIdx], destIdx);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load LWO2 vertex map
-void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
- LE_NCONST uint8_t *const end = mFileBuffer + length;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(length, VMAP, 6);
- unsigned int type = GetU4();
- unsigned int dims = GetU2();
-
- VMapEntry *base;
-
- // read the name of the vertex map
- std::string name;
- GetS0(name, length);
-
- switch (type) {
- case AI_LWO_TXUV:
- if (dims != 2) {
- ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'", name, "\' with !2 components");
- return;
- }
- base = FindEntry(mCurLayer->mUVChannels, name, perPoly);
- break;
- case AI_LWO_WGHT:
- case AI_LWO_MNVW:
- if (dims != 1) {
- ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'", name, "\' with !1 components");
- return;
- }
- base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels : mCurLayer->mSWeightChannels), name, perPoly);
- break;
- case AI_LWO_RGB:
- case AI_LWO_RGBA:
- if (dims != 3 && dims != 4) {
- ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'", name, "\' with a dimension > 4 or < 3");
- return;
- }
- base = FindEntry(mCurLayer->mVColorChannels, name, perPoly);
- break;
-
- case AI_LWO_MODO_NORM:
- /* This is a non-standard extension chunk used by Luxology's MODO.
- * It stores per-vertex normals. This VMAP exists just once, has
- * 3 dimensions and is btw extremely beautiful.
- */
- if (name != "vert_normals" || dims != 3 || mCurLayer->mNormals.name.length())
- return;
-
- ASSIMP_LOG_INFO("Processing non-standard extension: MODO VMAP.NORM.vert_normals");
-
- mCurLayer->mNormals.name = name;
- base = &mCurLayer->mNormals;
- break;
-
- case AI_LWO_PICK: /* these VMAPs are just silently dropped */
- case AI_LWO_MORF:
- case AI_LWO_SPOT:
- return;
-
- default:
- if (name == "APS.Level") {
- // XXX handle this (seems to be subdivision-related).
- }
- ASSIMP_LOG_WARN("LWO2: Skipping unknown VMAP/VMAD channel \'", name, "\'");
- return;
- };
- base->Allocate((unsigned int)mCurLayer->mTempPoints.size());
-
- // now read all entries in the map
- type = std::min(dims, base->dims);
- const unsigned int diff = (dims - type) << 2u;
-
- LWO::FaceList &list = mCurLayer->mFaces;
- LWO::PointList &pointList = mCurLayer->mTempPoints;
- LWO::ReferrerList &refList = mCurLayer->mPointReferrers;
-
- const unsigned int numPoints = (unsigned int)pointList.size();
- const unsigned int numFaces = (unsigned int)list.size();
-
- while (mFileBuffer < end) {
-
- unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
- if (idx >= numPoints) {
- ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAP/VMAD entry \'", name, "\', vertex index is out of range");
- mFileBuffer += base->dims << 2u;
- continue;
- }
- if (perPoly) {
- unsigned int polyIdx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
- if (base->abAssigned[idx]) {
- // we have already a VMAP entry for this vertex - thus
- // we need to duplicate the corresponding polygon.
- if (polyIdx >= numFaces) {
- ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAD entry \'", name, "\', polygon index is out of range");
- mFileBuffer += base->dims << 2u;
- continue;
- }
-
- LWO::Face &src = list[polyIdx];
-
- // generate a new unique vertex for the corresponding index - but only
- // if we can find the index in the face
- bool had = false;
- for (unsigned int i = 0; i < src.mNumIndices; ++i) {
-
- unsigned int srcIdx = src.mIndices[i], tmp = idx;
- do {
- if (tmp == srcIdx)
- break;
- } while ((tmp = refList[tmp]) != UINT_MAX);
- if (tmp == UINT_MAX) {
- continue;
- }
-
- had = true;
- refList.resize(refList.size() + 1, UINT_MAX);
-
- idx = (unsigned int)pointList.size();
- src.mIndices[i] = (unsigned int)pointList.size();
-
- // store the index of the new vertex in the old vertex
- // so we get a single linked list we can traverse in
- // only one direction
- AddToSingleLinkedList(refList, srcIdx, src.mIndices[i]);
- pointList.push_back(pointList[srcIdx]);
-
- CreateNewEntry(mCurLayer->mVColorChannels, srcIdx);
- CreateNewEntry(mCurLayer->mUVChannels, srcIdx);
- CreateNewEntry(mCurLayer->mWeightChannels, srcIdx);
- CreateNewEntry(mCurLayer->mSWeightChannels, srcIdx);
- CreateNewEntry(mCurLayer->mNormals, srcIdx);
- }
- if (!had) {
- ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAD entry \'", name, "\', vertex index wasn't found in that polygon");
- ai_assert(had);
- }
- }
- }
-
- std::unique_ptr<float[]> temp(new float[type]);
- for (unsigned int l = 0; l < type; ++l)
- temp[l] = GetF4();
-
- DoRecursiveVMAPAssignment(base, type, idx, temp.get());
- mFileBuffer += diff;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load LWO2 clip
-void LWOImporter::LoadLWO2Clip(unsigned int length) {
- AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 10);
-
- mClips.push_back(LWO::Clip());
- LWO::Clip &clip = mClips.back();
-
- // first - get the index of the clip
- clip.idx = GetU4();
-
- IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
- switch (head.type) {
- case AI_LWO_STIL:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, STIL, 1);
-
- // "Normal" texture
- GetS0(clip.path, head.length);
- clip.type = Clip::STILL;
- break;
-
- case AI_LWO_ISEQ:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ISEQ, 16);
- // Image sequence. We'll later take the first.
- {
- uint8_t digits = GetU1();
- mFileBuffer++;
- int16_t offset = GetU2();
- mFileBuffer += 4;
- int16_t start = GetU2();
- mFileBuffer += 4;
-
- std::string s;
- std::ostringstream ss;
- GetS0(s, head.length);
-
- head.length -= (uint16_t)s.length() + 1;
- ss << s;
- ss << std::setw(digits) << offset + start;
- GetS0(s, head.length);
- ss << s;
- clip.path = ss.str();
- clip.type = Clip::SEQ;
- }
- break;
-
- case AI_LWO_STCC:
- ASSIMP_LOG_WARN("LWO2: Color shifted images are not supported");
- break;
-
- case AI_LWO_ANIM:
- ASSIMP_LOG_WARN("LWO2: Animated textures are not supported");
- break;
-
- case AI_LWO_XREF:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, XREF, 4);
-
- // Just a cross-reference to another CLIp
- clip.type = Clip::REF;
- clip.clipRef = GetU4();
- break;
-
- case AI_LWO_NEGA:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, NEGA, 2);
- clip.negate = (0 != GetU2());
- break;
-
- default:
- ASSIMP_LOG_WARN("LWO2: Encountered unknown CLIP sub-chunk");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load envelope description
-void LWOImporter::LoadLWO2Envelope(unsigned int length) {
- LE_NCONST uint8_t *const end = mFileBuffer + length;
- AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
-
- mEnvelopes.push_back(LWO::Envelope());
- LWO::Envelope &envelope = mEnvelopes.back();
-
- // Get the index of the envelope
- envelope.index = ReadVSizedIntLWO2(mFileBuffer);
-
- // It looks like there might be an extra U4 right after the index,
- // at least in modo (LXOB) files: we'll ignore it if it's zero,
- // otherwise it represents the start of a subchunk, so we backtrack.
- if (mIsLXOB) {
- uint32_t extra = GetU4();
- if (extra) {
- mFileBuffer -= 4;
- }
- }
-
- // ... and read all subchunks
- while (true) {
- if (mFileBuffer + 6 >= end) break;
- LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid envelope chunk length");
-
- uint8_t *const next = mFileBuffer + head.length;
- switch (head.type) {
- // Type & representation of the envelope
- case AI_LWO_TYPE:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, TYPE, 2);
- mFileBuffer++; // skip user format
-
- // Determine type of envelope
- envelope.type = (LWO::EnvelopeType)*mFileBuffer;
- ++mFileBuffer;
- break;
-
- // precondition
- case AI_LWO_PRE:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, PRE, 2);
- envelope.pre = (LWO::PrePostBehaviour)GetU2();
- break;
-
- // postcondition
- case AI_LWO_POST:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, POST, 2);
- envelope.post = (LWO::PrePostBehaviour)GetU2();
- break;
-
- // keyframe
- case AI_LWO_KEY: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 8);
-
- envelope.keys.push_back(LWO::Key());
- LWO::Key &key = envelope.keys.back();
-
- key.time = GetF4();
- key.value = GetF4();
- break;
- }
-
- // interval interpolation
- case AI_LWO_SPAN: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPAN, 4);
- if (envelope.keys.size() < 2)
- ASSIMP_LOG_WARN("LWO2: Unexpected SPAN chunk");
- else {
- LWO::Key &key = envelope.keys.back();
- switch (GetU4()) {
- case AI_LWO_STEP:
- key.inter = LWO::IT_STEP;
- break;
- case AI_LWO_LINE:
- key.inter = LWO::IT_LINE;
- break;
- case AI_LWO_TCB:
- key.inter = LWO::IT_TCB;
- break;
- case AI_LWO_HERM:
- key.inter = LWO::IT_HERM;
- break;
- case AI_LWO_BEZI:
- key.inter = LWO::IT_BEZI;
- break;
- case AI_LWO_BEZ2:
- key.inter = LWO::IT_BEZ2;
- break;
- default:
- ASSIMP_LOG_WARN("LWO2: Unknown interval interpolation mode");
- };
-
- // todo ... read params
- }
- break;
- }
-
- default:
- ASSIMP_LOG_WARN("LWO2: Encountered unknown ENVL subchunk");
- break;
- }
- // regardless how much we did actually read, go to the next chunk
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load file - master function
-void LWOImporter::LoadLWO2File() {
- bool skip = false;
-
- LE_NCONST uint8_t *const end = mFileBuffer + fileSize;
- unsigned int iUnnamed = 0;
- while (true) {
- if (mFileBuffer + sizeof(IFF::ChunkHeader) > end) break;
- const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end) {
- throw DeadlyImportError("LWO2: Chunk length points behind the file");
- break;
- }
- uint8_t *const next = mFileBuffer + head.length;
-
- if (!head.length) {
- mFileBuffer = next;
- continue;
- }
-
- switch (head.type) {
- // new layer
- case AI_LWO_LAYR: {
- // add a new layer to the list ....
- mLayers->push_back(LWO::Layer());
- LWO::Layer &layer = mLayers->back();
- mCurLayer = &layer;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, LAYR, 16);
-
- // layer index.
- layer.mIndex = GetU2();
-
- // Continue loading this layer or ignore it? Check the layer index property
- if (UINT_MAX != configLayerIndex && (configLayerIndex - 1) != layer.mIndex) {
- skip = true;
- } else
- skip = false;
-
- // pivot point
- mFileBuffer += 2; /* unknown */
- mCurLayer->mPivot.x = GetF4();
- mCurLayer->mPivot.y = GetF4();
- mCurLayer->mPivot.z = GetF4();
- GetS0(layer.mName, head.length - 16);
-
- // if the name is empty, generate a default name
- if (layer.mName.empty()) {
- char buffer[128]; // should be sufficiently large
- ::ai_snprintf(buffer, 128, "Layer_%i", iUnnamed++);
- layer.mName = buffer;
- }
-
- // load this layer or ignore it? Check the layer name property
- if (configLayerName.length() && configLayerName != layer.mName) {
- skip = true;
- } else
- hasNamedLayer = true;
-
- // optional: parent of this layer
- if (mFileBuffer + 2 <= next)
- layer.mParent = GetU2();
- else
- layer.mParent = (uint16_t) -1;
-
- // Set layer skip parameter
- layer.skip = skip;
-
- break;
- }
-
- // vertex list
- case AI_LWO_PNTS: {
- if (skip)
- break;
-
- unsigned int old = (unsigned int)mCurLayer->mTempPoints.size();
- LoadLWOPoints(head.length);
- mCurLayer->mPointIDXOfs = old;
- break;
- }
- // vertex tags
- case AI_LWO_VMAD:
- if (mCurLayer->mFaces.empty()) {
- ASSIMP_LOG_WARN("LWO2: Unexpected VMAD chunk");
- break;
- }
- // --- intentionally no break here
- case AI_LWO_VMAP: {
- if (skip)
- break;
-
- if (mCurLayer->mTempPoints.empty())
- ASSIMP_LOG_WARN("LWO2: Unexpected VMAP chunk");
- else
- LoadLWO2VertexMap(head.length, head.type == AI_LWO_VMAD);
- break;
- }
- // face list
- case AI_LWO_POLS: {
- if (skip)
- break;
-
- unsigned int old = (unsigned int)mCurLayer->mFaces.size();
- LoadLWO2Polygons(head.length);
- mCurLayer->mFaceIDXOfs = old;
- break;
- }
- // polygon tags
- case AI_LWO_PTAG: {
- if (skip)
- break;
-
- if (mCurLayer->mFaces.empty()) {
- ASSIMP_LOG_WARN("LWO2: Unexpected PTAG");
- } else {
- LoadLWO2PolygonTags(head.length);
- }
- break;
- }
- // list of tags
- case AI_LWO_TAGS: {
- if (!mTags->empty()) {
- ASSIMP_LOG_WARN("LWO2: SRFS chunk encountered twice");
- } else {
- LoadLWOTags(head.length);
- }
- break;
- }
-
- // surface chunk
- case AI_LWO_SURF: {
- LoadLWO2Surface(head.length);
- break;
- }
-
- // clip chunk
- case AI_LWO_CLIP: {
- LoadLWO2Clip(head.length);
- break;
- }
-
- // envelope chunk
- case AI_LWO_ENVL: {
- LoadLWO2Envelope(head.length);
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
diff --git a/libs/assimp/code/AssetLib/LWO/LWOLoader.h b/libs/assimp/code/AssetLib/LWO/LWOLoader.h
deleted file mode 100644
index f3add53..0000000
--- a/libs/assimp/code/AssetLib/LWO/LWOLoader.h
+++ /dev/null
@@ -1,468 +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 Declaration of the LWO importer class. */
-#pragma once
-#ifndef AI_LWOLOADER_H_INCLUDED
-#define AI_LWOLOADER_H_INCLUDED
-
-#include "LWOFileData.h"
-#include <assimp/BaseImporter.h>
-#include <assimp/material.h>
-#include <assimp/DefaultLogger.hpp>
-
-#include <map>
-
-struct aiTexture;
-struct aiNode;
-struct aiMaterial;
-
-namespace Assimp {
-using namespace LWO;
-
-// ---------------------------------------------------------------------------
-/** Class to load LWO files.
- *
- * @note Methods named "xxxLWO2[xxx]" are used with the newer LWO2 format.
- * Methods named "xxxLWOB[xxx]" are used with the older LWOB format.
- * Methods named "xxxLWO[xxx]" are used with both formats.
- * Methods named "xxx" are used to preprocess the loaded data -
- * they aren't specific to one format version
-*/
-// ---------------------------------------------------------------------------
-class LWOImporter : public BaseImporter {
-public:
- LWOImporter();
- ~LWOImporter() override;
-
- // -------------------------------------------------------------------
- /** 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:
- // -------------------------------------------------------------------
- // Get list of supported extensions
- 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;
-
-private:
- // -------------------------------------------------------------------
- /** Loads a LWO file in the older LWOB format (LW < 6)
- */
- void LoadLWOBFile();
-
- // -------------------------------------------------------------------
- /** Loads a LWO file in the newer LWO2 format (LW >= 6)
- */
- void LoadLWO2File();
-
- // -------------------------------------------------------------------
- /** Parsing functions used for all file format versions
- */
- inline void GetS0(std::string &out, unsigned int max);
- inline float GetF4();
- inline uint32_t GetU4();
- inline uint16_t GetU2();
- inline uint8_t GetU1();
-
- // -------------------------------------------------------------------
- /** Loads a surface chunk from an LWOB file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWOBSurface(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Loads a surface chunk from an LWO2 file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWO2Surface(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Loads a texture block from a LWO2 file.
- * @param size Maximum size to be read, in bytes.
- * @param head Header of the SUF.BLOK header
- */
- void LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader *head,
- unsigned int size);
-
- // -------------------------------------------------------------------
- /** Loads a shader block from a LWO2 file.
- * @param size Maximum size to be read, in bytes.
- * @param head Header of the SUF.BLOK header
- */
- void LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader *head,
- unsigned int size);
-
- // -------------------------------------------------------------------
- /** Loads an image map from a LWO2 file
- * @param size Maximum size to be read, in bytes.
- * @param tex Texture object to be filled
- */
- void LoadLWO2ImageMap(unsigned int size, LWO::Texture &tex);
- void LoadLWO2Gradient(unsigned int size, LWO::Texture &tex);
- void LoadLWO2Procedural(unsigned int size, LWO::Texture &tex);
-
- // loads the header - used by thethree functions above
- void LoadLWO2TextureHeader(unsigned int size, LWO::Texture &tex);
-
- // -------------------------------------------------------------------
- /** Loads the LWO tag list from the file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWOTags(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Load polygons from a POLS chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Polygons(unsigned int length);
- void LoadLWOBPolygons(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load polygon tags from a PTAG chunk
- * @param length Size of the chunk
- */
- void LoadLWO2PolygonTags(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load a vertex map from a VMAP/VMAD chunk
- * @param length Size of the chunk
- * @param perPoly Operate on per-polygon base?
- */
- void LoadLWO2VertexMap(unsigned int length, bool perPoly);
-
- // -------------------------------------------------------------------
- /** Load polygons from a PNTS chunk
- * @param length Size of the chunk
- */
- void LoadLWOPoints(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load a clip from a CLIP chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Clip(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load an envelope from an EVL chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Envelope(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Count vertices and faces in a LWOB/LWO2 file
- */
- void CountVertsAndFacesLWO2(unsigned int &verts,
- unsigned int &faces,
- uint16_t *&cursor,
- const uint16_t *const end,
- unsigned int max = UINT_MAX);
-
- void CountVertsAndFacesLWOB(unsigned int &verts,
- unsigned int &faces,
- LE_NCONST uint16_t *&cursor,
- const uint16_t *const end,
- unsigned int max = UINT_MAX);
-
- // -------------------------------------------------------------------
- /** Read vertices and faces in a LWOB/LWO2 file
- */
- void CopyFaceIndicesLWO2(LWO::FaceList::iterator &it,
- uint16_t *&cursor,
- const uint16_t *const end);
-
- // -------------------------------------------------------------------
- void CopyFaceIndicesLWOB(LWO::FaceList::iterator &it,
- LE_NCONST uint16_t *&cursor,
- const uint16_t *const end,
- unsigned int max = UINT_MAX);
-
- // -------------------------------------------------------------------
- /** Resolve the tag and surface lists that have been loaded.
- * Generates the mMapping table.
- */
- void ResolveTags();
-
- // -------------------------------------------------------------------
- /** Resolve the clip list that has been loaded.
- * Replaces clip references with real clips.
- */
- void ResolveClips();
-
- // -------------------------------------------------------------------
- /** Add a texture list to an output material description.
- *
- * @param pcMat Output material
- * @param in Input texture list
- * @param type Type identifier of the texture list
- */
- bool HandleTextures(aiMaterial *pcMat, const TextureList &in,
- aiTextureType type);
-
- // -------------------------------------------------------------------
- /** Adjust a texture path
- */
- void AdjustTexturePath(std::string &out);
-
- // -------------------------------------------------------------------
- /** Convert a LWO surface description to an ASSIMP material
- */
- void ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat);
-
- // -------------------------------------------------------------------
- /** Get a list of all UV/VC channels required by a specific surface.
- *
- * @param surf Working surface
- * @param layer Working layer
- * @param out Output list. The members are indices into the
- * UV/VC channel lists of the layer
- */
- void FindUVChannels(/*const*/ LWO::Surface &surf,
- LWO::SortedRep &sorted,
- /*const*/ LWO::Layer &layer,
- unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]);
-
- // -------------------------------------------------------------------
- char FindUVChannels(LWO::TextureList &list,
- LWO::Layer &layer, LWO::UVChannel &uv, unsigned int next);
-
- // -------------------------------------------------------------------
- void FindVCChannels(const LWO::Surface &surf,
- LWO::SortedRep &sorted,
- const LWO::Layer &layer,
- unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]);
-
- // -------------------------------------------------------------------
- /** Generate the final node graph
- * Unused nodes are deleted.
- * @param apcNodes Flat list of nodes
- */
- void GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes);
-
- // -------------------------------------------------------------------
- /** Add children to a node
- * @param node Node to become a father
- * @param parent Index of the node
- * @param apcNodes Flat list of nodes - used nodes are set to nullptr.
- */
- void AddChildren(aiNode *node, uint16_t parent,
- std::vector<aiNode *> &apcNodes);
-
- // -------------------------------------------------------------------
- /** Read a variable sized integer
- * @param inout Input and output buffer
- */
- int ReadVSizedIntLWO2(uint8_t *&inout);
-
- // -------------------------------------------------------------------
- /** Assign a value from a VMAP to a vertex and all vertices
- * attached to it.
- * @param base VMAP destination data
- * @param numRead Number of float's to be read
- * @param idx Absolute index of the first vertex
- * @param data Value of the VMAP to be assigned - read numRead
- * floats from this array.
- */
- void DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead,
- unsigned int idx, float *data);
-
- // -------------------------------------------------------------------
- /** Compute normal vectors for a mesh
- * @param mesh Input mesh
- * @param smoothingGroups Smoothing-groups-per-face array
- * @param surface Surface for the mesh
- */
- void ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &smoothingGroups,
- const LWO::Surface &surface);
-
- // -------------------------------------------------------------------
- /** Setup a new texture after the corresponding chunk was
- * encountered in the file.
- * @param list Texture list
- * @param size Maximum number of bytes to be read
- * @return Pointer to new texture
- */
- LWO::Texture *SetupNewTextureLWOB(LWO::TextureList &list,
- unsigned int size);
-
-protected:
- /** true if the file is a LWO2 file*/
- bool mIsLWO2;
-
- /** true if the file is a LXOB file*/
- bool mIsLXOB;
-
- /** Temporary list of layers from the file */
- LayerList *mLayers;
-
- /** Pointer to the current layer */
- LWO::Layer *mCurLayer;
-
- /** Temporary tag list from the file */
- TagList *mTags;
-
- /** Mapping table to convert from tag to surface indices.
- UINT_MAX indicates that a no corresponding surface is available */
- TagMappingTable *mMapping;
-
- /** Temporary surface list from the file */
- SurfaceList *mSurfaces;
-
- /** Temporary clip list from the file */
- ClipList mClips;
-
- /** Temporary envelope list from the file */
- EnvelopeList mEnvelopes;
-
- /** file buffer */
- uint8_t *mFileBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-
- /** Output scene */
- aiScene *mScene;
-
- /** Configuration option: speed flag set? */
- bool configSpeedFlag;
-
- /** Configuration option: index of layer to be loaded */
- unsigned int configLayerIndex;
-
- /** Configuration option: name of layer to be loaded */
- std::string configLayerName;
-
- /** True if we have a named layer */
- bool hasNamedLayer;
-};
-
-// ------------------------------------------------------------------------------------------------
-inline float LWOImporter::GetF4() {
- float f;
- ::memcpy(&f, mFileBuffer, 4);
- mFileBuffer += 4;
- AI_LSWAP4(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint32_t LWOImporter::GetU4() {
- uint32_t f;
- ::memcpy(&f, mFileBuffer, 4);
- mFileBuffer += 4;
- AI_LSWAP4(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint16_t LWOImporter::GetU2() {
- uint16_t f;
- ::memcpy(&f, mFileBuffer, 2);
- mFileBuffer += 2;
- AI_LSWAP2(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint8_t LWOImporter::GetU1() {
- return *mFileBuffer++;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline int LWOImporter::ReadVSizedIntLWO2(uint8_t *&inout) {
- int i;
- int c = *inout;
- inout++;
- if (c != 0xFF) {
- i = c << 8;
- c = *inout;
- inout++;
- i |= c;
- } else {
- c = *inout;
- inout++;
- i = c << 16;
- c = *inout;
- inout++;
- i |= c << 8;
- c = *inout;
- inout++;
- i |= c;
- }
- return i;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void LWOImporter::GetS0(std::string &out, unsigned int max) {
- unsigned int iCursor = 0;
- const char *sz = (const char *)mFileBuffer;
- while (*mFileBuffer) {
- if (++iCursor > max) {
- ASSIMP_LOG_WARN("LWO: Invalid file, string is is too long");
- break;
- }
- ++mFileBuffer;
- }
- size_t len = (size_t)((const char *)mFileBuffer - sz);
- out = std::string(sz, len);
- mFileBuffer += (len & 0x1 ? 1 : 2);
-}
-
-} // end of namespace Assimp
-
-#endif // AI_LWOIMPORTER_H_INCLUDED
diff --git a/libs/assimp/code/AssetLib/LWO/LWOMaterial.cpp b/libs/assimp/code/AssetLib/LWO/LWOMaterial.cpp
deleted file mode 100644
index b6f0bcc..0000000
--- a/libs/assimp/code/AssetLib/LWO/LWOMaterial.cpp
+++ /dev/null
@@ -1,844 +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 material oart of the LWO importer class */
-
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// internal headers
-#include "LWOLoader.h"
-#include <assimp/ByteSwapper.h>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-T lerp(const T &one, const T &two, float val) {
- return one + (two - one) * val;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a lightwave mapping mode to our's
-inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in) {
- switch (in) {
- case LWO::Texture::REPEAT:
- return aiTextureMapMode_Wrap;
-
- case LWO::Texture::MIRROR:
- return aiTextureMapMode_Mirror;
-
- case LWO::Texture::RESET:
- ASSIMP_LOG_WARN("LWO2: Unsupported texture map mode: RESET");
-
- // fall though here
- case LWO::Texture::EDGE:
- return aiTextureMapMode_Clamp;
- }
- return (aiTextureMapMode)0;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTextureType type) {
- ai_assert(nullptr != pcMat);
-
- unsigned int cur = 0, temp = 0;
- aiString s;
- bool ret = false;
-
- for (const auto &texture : in) {
- if (!texture.enabled || !texture.bCanUse)
- continue;
- ret = true;
-
- // Convert lightwave's mapping modes to ours. We let them
- // as they are, the GenUVcoords step will compute UV
- // channels if they're not there.
-
- aiTextureMapping mapping = aiTextureMapping_OTHER;
- switch (texture.mapMode) {
- case LWO::Texture::Planar:
- mapping = aiTextureMapping_PLANE;
- break;
- case LWO::Texture::Cylindrical:
- mapping = aiTextureMapping_CYLINDER;
- break;
- case LWO::Texture::Spherical:
- mapping = aiTextureMapping_SPHERE;
- break;
- case LWO::Texture::Cubic:
- mapping = aiTextureMapping_BOX;
- break;
- case LWO::Texture::FrontProjection:
- ASSIMP_LOG_ERROR("LWO2: Unsupported texture mapping: FrontProjection");
- mapping = aiTextureMapping_OTHER;
- break;
- case LWO::Texture::UV: {
- if (UINT_MAX == texture.mRealUVIndex) {
- // We have no UV index for this texture, so we can't display it
- continue;
- }
-
- // add the UV source index
- temp = texture.mRealUVIndex;
- pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_UVWSRC(type, cur));
-
- mapping = aiTextureMapping_UV;
- } break;
- default:
- ai_assert(false);
- };
-
- if (mapping != aiTextureMapping_UV) {
- // Setup the main axis
- aiVector3D v;
- switch (texture.majorAxis) {
- case Texture::AXIS_X:
- v = aiVector3D(1.0, 0.0, 0.0);
- break;
- case Texture::AXIS_Y:
- v = aiVector3D(0.0, 1.0, 0.0);
- break;
- default: // case Texture::AXIS_Z:
- v = aiVector3D(0.0, 0.0, 1.0);
- break;
- }
-
- pcMat->AddProperty(&v, 1, AI_MATKEY_TEXMAP_AXIS(type, cur));
-
- // Setup UV scalings for cylindric and spherical projections
- if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE) {
- aiUVTransform trafo;
- trafo.mScaling.x = texture.wrapAmountW;
- trafo.mScaling.y = texture.wrapAmountH;
-
- static_assert(sizeof(aiUVTransform) / sizeof(ai_real) == 5, "sizeof(aiUVTransform)/sizeof(ai_real) == 5");
- pcMat->AddProperty(&trafo, 1, AI_MATKEY_UVTRANSFORM(type, cur));
- }
- ASSIMP_LOG_VERBOSE_DEBUG("LWO2: Setting up non-UV mapping");
- }
-
- // The older LWOB format does not use indirect references to clips.
- // The file name of a texture is directly specified in the tex chunk.
- if (mIsLWO2) {
- // find the corresponding clip (take the last one if multiple
- // share the same index)
- ClipList::iterator end = mClips.end(), candidate = end;
- temp = texture.mClipIdx;
- for (ClipList::iterator clip = mClips.begin(); clip != end; ++clip) {
- if ((*clip).idx == temp) {
- candidate = clip;
- }
- }
- if (candidate == end) {
- ASSIMP_LOG_ERROR("LWO2: Clip index is out of bounds");
- temp = 0;
-
- // fixme: apparently some LWO files shipping with Doom3 don't
- // have clips at all ... check whether that's true or whether
- // it's a bug in the loader.
-
- s.Set("$texture.png");
-
- //continue;
- } else {
- if (Clip::UNSUPPORTED == (*candidate).type) {
- ASSIMP_LOG_ERROR("LWO2: Clip type is not supported");
- continue;
- }
- AdjustTexturePath((*candidate).path);
- s.Set((*candidate).path);
-
- // Additional image settings
- int flags = 0;
- if ((*candidate).negate) {
- flags |= aiTextureFlags_Invert;
- }
- pcMat->AddProperty(&flags, 1, AI_MATKEY_TEXFLAGS(type, cur));
- }
- } else {
- std::string ss = texture.mFileName;
- if (!ss.length()) {
- ASSIMP_LOG_WARN("LWOB: Empty file name");
- continue;
- }
- AdjustTexturePath(ss);
- s.Set(ss);
- }
- pcMat->AddProperty(&s, AI_MATKEY_TEXTURE(type, cur));
-
- // add the blend factor
- pcMat->AddProperty<float>(&texture.mStrength, 1, AI_MATKEY_TEXBLEND(type, cur));
-
- // add the blend operation
- switch (texture.blendType) {
- case LWO::Texture::Normal:
- case LWO::Texture::Multiply:
- temp = (unsigned int)aiTextureOp_Multiply;
- break;
-
- case LWO::Texture::Subtractive:
- case LWO::Texture::Difference:
- temp = (unsigned int)aiTextureOp_Subtract;
- break;
-
- case LWO::Texture::Divide:
- temp = (unsigned int)aiTextureOp_Divide;
- break;
-
- case LWO::Texture::Additive:
- temp = (unsigned int)aiTextureOp_Add;
- break;
-
- default:
- temp = (unsigned int)aiTextureOp_Multiply;
- ASSIMP_LOG_WARN("LWO2: Unsupported texture blend mode: alpha or displacement");
- }
- // Setup texture operation
- pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_TEXOP(type, cur));
-
- // setup the mapping mode
- int mapping_ = static_cast<int>(mapping);
- pcMat->AddProperty<int>(&mapping_, 1, AI_MATKEY_MAPPING(type, cur));
-
- // add the u-wrapping
- temp = (unsigned int)GetMapMode(texture.wrapModeWidth);
- pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_MAPPINGMODE_U(type, cur));
-
- // add the v-wrapping
- temp = (unsigned int)GetMapMode(texture.wrapModeHeight);
- pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_MAPPINGMODE_V(type, cur));
-
- ++cur;
- }
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
- // copy the name of the surface
- aiString st;
- st.Set(surf.mName);
- pcMat->AddProperty(&st, AI_MATKEY_NAME);
-
- const int i = surf.bDoubleSided ? 1 : 0;
- pcMat->AddProperty(&i, 1, AI_MATKEY_TWOSIDED);
-
- // add the refraction index and the bump intensity
- pcMat->AddProperty(&surf.mIOR, 1, AI_MATKEY_REFRACTI);
- pcMat->AddProperty(&surf.mBumpIntensity, 1, AI_MATKEY_BUMPSCALING);
-
- aiShadingMode m;
- if (surf.mSpecularValue && surf.mGlossiness) {
- float fGloss;
- if (mIsLWO2) {
- fGloss = std::pow(surf.mGlossiness * ai_real(10.0) + ai_real(2.0), ai_real(2.0));
- } else {
- if (16.0 >= surf.mGlossiness)
- fGloss = 6.0;
- else if (64.0 >= surf.mGlossiness)
- fGloss = 20.0;
- else if (256.0 >= surf.mGlossiness)
- fGloss = 50.0;
- else
- fGloss = 80.0;
- }
-
- pcMat->AddProperty(&surf.mSpecularValue, 1, AI_MATKEY_SHININESS_STRENGTH);
- pcMat->AddProperty(&fGloss, 1, AI_MATKEY_SHININESS);
- m = aiShadingMode_Phong;
- } else
- m = aiShadingMode_Gouraud;
-
- // specular color
- aiColor3D clr = lerp(aiColor3D(1.0, 1.0, 1.0), surf.mColor, surf.mColorHighlights);
- pcMat->AddProperty(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
- pcMat->AddProperty(&surf.mSpecularValue, 1, AI_MATKEY_SHININESS_STRENGTH);
-
- // emissive color
- // luminosity is not really the same but it affects the surface in a similar way. Some scaling looks good.
- clr.g = clr.b = clr.r = surf.mLuminosity * ai_real(0.8);
- pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_EMISSIVE);
-
- // opacity ... either additive or default-blended, please
- if (0.0 != surf.mAdditiveTransparency) {
- const int add = aiBlendMode_Additive;
- pcMat->AddProperty(&surf.mAdditiveTransparency, 1, AI_MATKEY_OPACITY);
- pcMat->AddProperty(&add, 1, AI_MATKEY_BLEND_FUNC);
- } else if (10e10f != surf.mTransparency) {
- const int def = aiBlendMode_Default;
- const float f = 1.0f - surf.mTransparency;
- pcMat->AddProperty(&f, 1, AI_MATKEY_OPACITY);
- pcMat->AddProperty(&def, 1, AI_MATKEY_BLEND_FUNC);
- }
-
- // ADD TEXTURES to the material
- // TODO: find out how we can handle COLOR textures correctly...
- bool b = HandleTextures(pcMat, surf.mColorTextures, aiTextureType_DIFFUSE);
- b = (b || HandleTextures(pcMat, surf.mDiffuseTextures, aiTextureType_DIFFUSE));
- HandleTextures(pcMat, surf.mSpecularTextures, aiTextureType_SPECULAR);
- HandleTextures(pcMat, surf.mGlossinessTextures, aiTextureType_SHININESS);
- HandleTextures(pcMat, surf.mBumpTextures, aiTextureType_HEIGHT);
- HandleTextures(pcMat, surf.mOpacityTextures, aiTextureType_OPACITY);
- HandleTextures(pcMat, surf.mReflectionTextures, aiTextureType_REFLECTION);
-
- // Now we need to know which shader to use .. iterate through the shader list of
- // the surface and search for a name which we know ...
- for (const auto &shader : surf.mShaders) {
- if (shader.functionName == "LW_SuperCelShader" || shader.functionName == "AH_CelShader") {
- ASSIMP_LOG_INFO("LWO2: Mapping LW_SuperCelShader/AH_CelShader to aiShadingMode_Toon");
-
- m = aiShadingMode_Toon;
- break;
- } else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
- ASSIMP_LOG_INFO("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
-
- m = aiShadingMode_Fresnel;
- break;
- } else {
- ASSIMP_LOG_WARN("LWO2: Unknown surface shader: ", shader.functionName);
- }
- }
- if (surf.mMaximumSmoothAngle <= 0.0)
- m = aiShadingMode_Flat;
- int m_ = static_cast<int>(m);
- pcMat->AddProperty(&m_, 1, AI_MATKEY_SHADING_MODEL);
-
- // (the diffuse value is just a scaling factor)
- // If a diffuse texture is set, we set this value to 1.0
- clr = (b && false ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
- clr.r *= surf.mDiffuseValue;
- clr.g *= surf.mDiffuseValue;
- clr.b *= surf.mDiffuseValue;
- pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
-}
-
-// ------------------------------------------------------------------------------------------------
-char LWOImporter::FindUVChannels(LWO::TextureList &list,
- LWO::Layer & /*layer*/, LWO::UVChannel &uv, unsigned int next) {
- char ret = 0;
- for (auto &texture : list) {
-
- // Ignore textures with non-UV mappings for the moment.
- if (!texture.enabled || !texture.bCanUse || texture.mapMode != LWO::Texture::UV) {
- continue;
- }
-
- if (texture.mUVChannelIndex == uv.name) {
- ret = 1;
-
- // got it.
- if (texture.mRealUVIndex == UINT_MAX || texture.mRealUVIndex == next) {
- texture.mRealUVIndex = next;
- } else {
- // channel mismatch. need to duplicate the material.
- ASSIMP_LOG_WARN("LWO: Channel mismatch, would need to duplicate surface [design bug]");
-
- // TODO
- }
- }
- }
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::FindUVChannels(LWO::Surface &surf,
- LWO::SortedRep &sorted, LWO::Layer &layer,
- unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]) {
- unsigned int next = 0, extra = 0, num_extra = 0;
-
- // Check whether we have an UV entry != 0 for one of the faces in 'sorted'
- for (unsigned int i = 0; i < layer.mUVChannels.size(); ++i) {
- LWO::UVChannel &uv = layer.mUVChannels[i];
-
- for (LWO::SortedRep::const_iterator it = sorted.begin(); it != sorted.end(); ++it) {
-
- LWO::Face &face = layer.mFaces[*it];
-
- for (unsigned int n = 0; n < face.mNumIndices; ++n) {
- unsigned int idx = face.mIndices[n];
-
- if (uv.abAssigned[idx] && ((aiVector2D *)&uv.rawData[0])[idx] != aiVector2D()) {
-
- if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
-
- ASSIMP_LOG_ERROR("LWO: Maximum number of UV channels for "
- "this mesh reached. Skipping channel \'" +
- uv.name + "\'");
-
- } else {
- // Search through all textures assigned to 'surf' and look for this UV channel
- char had = 0;
- had |= FindUVChannels(surf.mColorTextures, layer, uv, next);
- had |= FindUVChannels(surf.mDiffuseTextures, layer, uv, next);
- had |= FindUVChannels(surf.mSpecularTextures, layer, uv, next);
- had |= FindUVChannels(surf.mGlossinessTextures, layer, uv, next);
- had |= FindUVChannels(surf.mOpacityTextures, layer, uv, next);
- had |= FindUVChannels(surf.mBumpTextures, layer, uv, next);
- had |= FindUVChannels(surf.mReflectionTextures, layer, uv, next);
-
- // We have a texture referencing this UV channel so we have to take special care
- // and are willing to drop unreferenced channels in favour of it.
- if (had != 0) {
- if (num_extra) {
-
- for (unsigned int a = next; a < std::min(extra, AI_MAX_NUMBER_OF_TEXTURECOORDS - 1u); ++a) {
- out[a + 1] = out[a];
- }
- }
- ++extra;
- out[next++] = i;
- }
- // Bah ... seems not to be used at all. Push to end if enough space is available.
- else {
- out[extra++] = i;
- ++num_extra;
- }
- }
- it = sorted.end() - 1;
- break;
- }
- }
- }
- }
- if (extra < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
- out[extra] = UINT_MAX;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::FindVCChannels(const LWO::Surface &surf, LWO::SortedRep &sorted, const LWO::Layer &layer,
- unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]) {
- unsigned int next = 0;
-
- // Check whether we have an vc entry != 0 for one of the faces in 'sorted'
- for (unsigned int i = 0; i < layer.mVColorChannels.size(); ++i) {
- const LWO::VColorChannel &vc = layer.mVColorChannels[i];
-
- if (surf.mVCMap == vc.name) {
- // The vertex color map is explicitly requested by the surface so we need to take special care of it
- for (unsigned int a = 0; a < std::min(next, AI_MAX_NUMBER_OF_COLOR_SETS - 1u); ++a) {
- out[a + 1] = out[a];
- }
- out[0] = i;
- ++next;
- } else {
-
- for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it) {
- const LWO::Face &face = layer.mFaces[*it];
-
- for (unsigned int n = 0; n < face.mNumIndices; ++n) {
- unsigned int idx = face.mIndices[n];
-
- if (vc.abAssigned[idx] && ((aiColor4D *)&vc.rawData[0])[idx] != aiColor4D(0.0, 0.0, 0.0, 1.0)) {
- if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
-
- ASSIMP_LOG_ERROR("LWO: Maximum number of vertex color channels for "
- "this mesh reached. Skipping channel \'" +
- vc.name + "\'");
-
- } else {
- out[next++] = i;
- }
- it = sorted.end() - 1;
- break;
- }
- }
- }
- }
- }
- if (next != AI_MAX_NUMBER_OF_COLOR_SETS) {
- out[next] = UINT_MAX;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture &tex) {
- LE_NCONST uint8_t *const end = mFileBuffer + size;
- while (true) {
- if (mFileBuffer + 6 >= end) break;
- LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
-
- uint8_t *const next = mFileBuffer + head.length;
- switch (head.type) {
- case AI_LWO_PROJ:
- tex.mapMode = (Texture::MappingMode)GetU2();
- break;
- case AI_LWO_WRAP:
- tex.wrapModeWidth = (Texture::Wrap)GetU2();
- tex.wrapModeHeight = (Texture::Wrap)GetU2();
- break;
- case AI_LWO_AXIS:
- tex.majorAxis = (Texture::Axes)GetU2();
- break;
- case AI_LWO_IMAG:
- tex.mClipIdx = GetU2();
- break;
- case AI_LWO_VMAP:
- GetS0(tex.mUVChannelIndex, head.length);
- break;
- case AI_LWO_WRPH:
- tex.wrapAmountH = GetF4();
- break;
- case AI_LWO_WRPW:
- tex.wrapAmountW = GetF4();
- break;
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture &tex) {
- // --- not supported at the moment
- ASSIMP_LOG_ERROR("LWO2: Found procedural texture, this is not supported");
- tex.bCanUse = false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture &tex) {
- // --- not supported at the moment
- ASSIMP_LOG_ERROR("LWO2: Found gradient texture, this is not supported");
- tex.bCanUse = false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture &tex) {
- LE_NCONST uint8_t *const end = mFileBuffer + size;
-
- // get the ordinal string
- GetS0(tex.ordinal, size);
-
- // we could crash later if this is an empty string ...
- if (!tex.ordinal.length()) {
- ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
- tex.ordinal = "\x00";
- }
- while (true) {
- if (mFileBuffer + 6 >= end) break;
- const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid texture header chunk length");
-
- uint8_t *const next = mFileBuffer + head.length;
- switch (head.type) {
- case AI_LWO_CHAN:
- tex.type = GetU4();
- break;
- case AI_LWO_ENAB:
- tex.enabled = GetU2() ? true : false;
- break;
- case AI_LWO_OPAC:
- tex.blendType = (Texture::BlendType)GetU2();
- tex.mStrength = GetF4();
- break;
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader *head, unsigned int size) {
- ai_assert(!mSurfaces->empty());
- LWO::Surface &surf = mSurfaces->back();
- LWO::Texture tex;
-
- // load the texture header
- LoadLWO2TextureHeader(head->length, tex);
- size -= head->length + 6;
-
- // now get the exact type of the texture
- switch (head->type) {
- case AI_LWO_PROC:
- LoadLWO2Procedural(size, tex);
- break;
- case AI_LWO_GRAD:
- LoadLWO2Gradient(size, tex);
- break;
- case AI_LWO_IMAP:
- LoadLWO2ImageMap(size, tex);
- }
-
- // get the destination channel
- TextureList *listRef = nullptr;
- switch (tex.type) {
- case AI_LWO_COLR:
- listRef = &surf.mColorTextures;
- break;
- case AI_LWO_DIFF:
- listRef = &surf.mDiffuseTextures;
- break;
- case AI_LWO_SPEC:
- listRef = &surf.mSpecularTextures;
- break;
- case AI_LWO_GLOS:
- listRef = &surf.mGlossinessTextures;
- break;
- case AI_LWO_BUMP:
- listRef = &surf.mBumpTextures;
- break;
- case AI_LWO_TRAN:
- listRef = &surf.mOpacityTextures;
- break;
- case AI_LWO_REFL:
- listRef = &surf.mReflectionTextures;
- break;
- default:
- ASSIMP_LOG_WARN("LWO2: Encountered unknown texture type");
- return;
- }
-
- // now attach the texture to the parent surface - sort by ordinal string
- for (TextureList::iterator it = listRef->begin(); it != listRef->end(); ++it) {
- if (::strcmp(tex.ordinal.c_str(), (*it).ordinal.c_str()) < 0) {
- listRef->insert(it, tex);
- return;
- }
- }
- listRef->push_back(tex);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader * /*head*/, unsigned int size) {
- LE_NCONST uint8_t *const end = mFileBuffer + size;
-
- ai_assert(!mSurfaces->empty());
- LWO::Surface &surf = mSurfaces->back();
- LWO::Shader shader;
-
- // get the ordinal string
- GetS0(shader.ordinal, size);
-
- // we could crash later if this is an empty string ...
- if (!shader.ordinal.length()) {
- ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
- shader.ordinal = "\x00";
- }
-
- // read the header
- while (true) {
- if (mFileBuffer + 6 >= end) break;
- const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid shader header chunk length");
-
- uint8_t *const next = mFileBuffer + head.length;
- switch (head.type) {
- case AI_LWO_ENAB:
- shader.enabled = GetU2() ? true : false;
- break;
-
- case AI_LWO_FUNC:
- GetS0(shader.functionName, head.length);
- }
- mFileBuffer = next;
- }
-
- // now attach the shader to the parent surface - sort by ordinal string
- for (ShaderList::iterator it = surf.mShaders.begin(); it != surf.mShaders.end(); ++it) {
- if (::strcmp(shader.ordinal.c_str(), (*it).ordinal.c_str()) < 0) {
- surf.mShaders.insert(it, shader);
- return;
- }
- }
- surf.mShaders.push_back(shader);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Surface(unsigned int size) {
- LE_NCONST uint8_t *const end = mFileBuffer + size;
-
- mSurfaces->push_back(LWO::Surface());
- LWO::Surface &surf = mSurfaces->back();
-
- GetS0(surf.mName, size);
-
- // check whether this surface was derived from any other surface
- std::string derived;
- GetS0(derived, (unsigned int)(end - mFileBuffer));
- if (derived.length()) {
- // yes, find this surface
- for (SurfaceList::iterator it = mSurfaces->begin(), itEnd = mSurfaces->end() - 1; it != itEnd; ++it) {
- if ((*it).mName == derived) {
- // we have it ...
- surf = *it;
- derived.clear();
- break;
- }
- }
- if (derived.size()) {
- ASSIMP_LOG_WARN("LWO2: Unable to find source surface: ", derived);
- }
- }
-
- while (true) {
- if (mFileBuffer + 6 >= end)
- break;
- const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid surface chunk length");
-
- uint8_t *const next = mFileBuffer + head.length;
- switch (head.type) {
- // diffuse color
- case AI_LWO_COLR: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, COLR, 12);
- surf.mColor.r = GetF4();
- surf.mColor.g = GetF4();
- surf.mColor.b = GetF4();
- break;
- }
- // diffuse strength ... hopefully
- case AI_LWO_DIFF: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, DIFF, 4);
- surf.mDiffuseValue = GetF4();
- break;
- }
- // specular strength ... hopefully
- case AI_LWO_SPEC: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPEC, 4);
- surf.mSpecularValue = GetF4();
- break;
- }
- // transparency
- case AI_LWO_TRAN: {
- // transparency explicitly disabled?
- if (surf.mTransparency == 10e10f)
- break;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, TRAN, 4);
- surf.mTransparency = GetF4();
- break;
- }
- // additive transparency
- case AI_LWO_ADTR: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ADTR, 4);
- surf.mAdditiveTransparency = GetF4();
- break;
- }
- // wireframe mode
- case AI_LWO_LINE: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, LINE, 2);
- if (GetU2() & 0x1)
- surf.mWireframe = true;
- break;
- }
- // glossiness
- case AI_LWO_GLOS: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, GLOS, 4);
- surf.mGlossiness = GetF4();
- break;
- }
- // bump intensity
- case AI_LWO_BUMP: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BUMP, 4);
- surf.mBumpIntensity = GetF4();
- break;
- }
- // color highlights
- case AI_LWO_CLRH: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, CLRH, 4);
- surf.mColorHighlights = GetF4();
- break;
- }
- // index of refraction
- case AI_LWO_RIND: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, RIND, 4);
- surf.mIOR = GetF4();
- break;
- }
- // polygon sidedness
- case AI_LWO_SIDE: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SIDE, 2);
- surf.bDoubleSided = (3 == GetU2());
- break;
- }
- // maximum smoothing angle
- case AI_LWO_SMAN: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SMAN, 4);
- surf.mMaximumSmoothAngle = std::fabs(GetF4());
- break;
- }
- // vertex color channel to be applied to the surface
- case AI_LWO_VCOL: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, VCOL, 12);
- surf.mDiffuseValue *= GetF4(); // strength
- ReadVSizedIntLWO2(mFileBuffer); // skip envelope
- surf.mVCMapType = GetU4(); // type of the channel
-
- // name of the channel
- GetS0(surf.mVCMap, (unsigned int)(next - mFileBuffer));
- break;
- }
- // surface bock entry
- case AI_LWO_BLOK: {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BLOK, 4);
- IFF::SubChunkHeader head2 = IFF::LoadSubChunk(mFileBuffer);
-
- switch (head2.type) {
- case AI_LWO_PROC:
- case AI_LWO_GRAD:
- case AI_LWO_IMAP:
- LoadLWO2TextureBlock(&head2, head.length);
- break;
- case AI_LWO_SHDR:
- LoadLWO2ShaderBlock(&head2, head.length);
- break;
-
- default:
- ASSIMP_LOG_WARN("LWO2: Found an unsupported surface BLOK");
- };
-
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_X_IMPORTER