diff --git a/apps/openmw_test_suite/nif/node.hpp b/apps/openmw_test_suite/nif/node.hpp index 7e413d03cd..2d82289592 100644 --- a/apps/openmw_test_suite/nif/node.hpp +++ b/apps/openmw_test_suite/nif/node.hpp @@ -13,7 +13,7 @@ namespace Nif::Testing inline void init(Extra& value) { - value.next = ExtraPtr(nullptr); + value.mNext = ExtraPtr(nullptr); } inline void init(Named& value) diff --git a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp index 25df366d23..49030a8902 100644 --- a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp +++ b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp @@ -996,7 +996,7 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_extra_data_string_equal_ncc_should_return_shape_with_cameraonly_collision) { - mNiStringExtraData.string = "NCC__"; + mNiStringExtraData.mData = "NCC__"; mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.parents.push_back(&mNiNode); @@ -1024,8 +1024,8 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_not_first_extra_data_string_equal_ncc_should_return_shape_with_cameraonly_collision) { - mNiStringExtraData.next = Nif::ExtraPtr(&mNiStringExtraData2); - mNiStringExtraData2.string = "NCC__"; + mNiStringExtraData.mNext = Nif::ExtraPtr(&mNiStringExtraData2); + mNiStringExtraData2.mData = "NCC__"; mNiStringExtraData2.recType = Nif::RC_NiStringExtraData; mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.parents.push_back(&mNiNode); @@ -1052,7 +1052,7 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_extra_data_string_starting_with_nc_should_return_shape_with_nocollision) { - mNiStringExtraData.string = "NC___"; + mNiStringExtraData.mData = "NC___"; mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.parents.push_back(&mNiNode); @@ -1079,8 +1079,8 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_not_first_extra_data_string_starting_with_nc_should_return_shape_with_nocollision) { - mNiStringExtraData.next = Nif::ExtraPtr(&mNiStringExtraData2); - mNiStringExtraData2.string = "NC___"; + mNiStringExtraData.mNext = Nif::ExtraPtr(&mNiStringExtraData2); + mNiStringExtraData2.mData = "NC___"; mNiStringExtraData2.recType = Nif::RC_NiStringExtraData; mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.parents.push_back(&mNiNode); @@ -1141,7 +1141,7 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_extra_data_string_mrk_should_return_shape_with_null_collision_shape) { - mNiStringExtraData.string = "MRK"; + mNiStringExtraData.mData = "MRK"; mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.parents.push_back(&mNiNode); @@ -1160,7 +1160,7 @@ namespace TEST_F(TestBulletNifLoader, bsx_editor_marker_flag_disables_collision_for_markers) { - mNiIntegerExtraData.data = 32; // BSX flag "editor marker" + mNiIntegerExtraData.mData = 32; // BSX flag "editor marker" mNiIntegerExtraData.recType = Nif::RC_BSXFlags; mNiTriShape.extralist.push_back(Nif::ExtraPtr(&mNiIntegerExtraData)); mNiTriShape.parents.push_back(&mNiNode); @@ -1181,7 +1181,7 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_extra_data_string_mrk_and_other_collision_node_should_return_shape_with_triangle_mesh_shape_with_all_meshes) { - mNiStringExtraData.string = "MRK"; + mNiStringExtraData.mData = "MRK"; mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.parents.push_back(&mNiNode2); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 71e508e882..6e79c2a060 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -111,7 +111,7 @@ add_component_dir (sceneutil ) add_component_dir (nif - controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream physics + base controller data effect extra niffile nifkey nifstream niftypes node particle physics property record record_ptr texture ) add_component_dir (nifosg diff --git a/components/nif/base.cpp b/components/nif/base.cpp index ed440cd96d..af98cfa16d 100644 --- a/components/nif/base.cpp +++ b/components/nif/base.cpp @@ -5,11 +5,11 @@ namespace Nif void Extra::read(NIFStream* nif) { if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0)) - name = nif->getString(); + nif->read(mName); else if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0)) { - next.read(nif); - recordSize = nif->getUInt(); + mNext.read(nif); + nif->read(mRecordSize); } } diff --git a/components/nif/base.hpp b/components/nif/base.hpp index 2cdbdec77f..69094ffc51 100644 --- a/components/nif/base.hpp +++ b/components/nif/base.hpp @@ -13,12 +13,12 @@ namespace Nif // An extra data record. All the extra data connected to an object form a linked list. struct Extra : public Record { - std::string name; - ExtraPtr next; // Next extra data record in the list - unsigned int recordSize{ 0u }; + std::string mName; + ExtraPtr mNext; // Next extra data record in the list + uint32_t mRecordSize{ 0u }; void read(NIFStream* nif) override; - void post(Reader& nif) override { next.post(nif); } + void post(Reader& nif) override { mNext.post(nif); } }; struct Controller : public Record diff --git a/components/nif/controlled.cpp b/components/nif/controlled.cpp deleted file mode 100644 index bacba07d5f..0000000000 --- a/components/nif/controlled.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "controlled.hpp" - -#include "data.hpp" - -namespace Nif -{ - - void NiSourceTexture::read(NIFStream* nif) - { - Named::read(nif); - - external = nif->getChar() != 0; - bool internal = false; - if (external) - filename = nif->getString(); - else - { - if (nif->getVersion() <= NIFStream::generateVersion(10, 0, 1, 3)) - internal = nif->getChar(); - if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) - filename = nif->getString(); // Original file path of the internal texture - } - if (nif->getVersion() <= NIFStream::generateVersion(10, 0, 1, 3)) - { - if (!external && internal) - data.read(nif); - } - else - { - data.read(nif); - } - - pixel = nif->getUInt(); - mipmap = nif->getUInt(); - alpha = nif->getUInt(); - - // Renderer hints, typically of no use for us - /* bool mIsStatic = */ nif->getChar(); - if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 103)) - /* bool mDirectRendering = */ nif->getBoolean(); - if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 4)) - /* bool mPersistRenderData = */ nif->getBoolean(); - } - - void NiSourceTexture::post(Reader& nif) - { - Named::post(nif); - data.post(nif); - } - - void BSShaderTextureSet::read(NIFStream* nif) - { - nif->getSizedStrings(textures, nif->getUInt()); - } - - void NiParticleModifier::read(NIFStream* nif) - { - next.read(nif); - controller.read(nif); - } - - void NiParticleModifier::post(Reader& nif) - { - next.post(nif); - controller.post(nif); - } - - void NiParticleGrowFade::read(NIFStream* nif) - { - NiParticleModifier::read(nif); - growTime = nif->getFloat(); - fadeTime = nif->getFloat(); - } - - void NiParticleColorModifier::read(NIFStream* nif) - { - NiParticleModifier::read(nif); - data.read(nif); - } - - void NiParticleColorModifier::post(Reader& nif) - { - NiParticleModifier::post(nif); - data.post(nif); - } - - void NiGravity::read(NIFStream* nif) - { - NiParticleModifier::read(nif); - - mDecay = nif->getFloat(); - mForce = nif->getFloat(); - mType = nif->getUInt(); - mPosition = nif->getVector3(); - mDirection = nif->getVector3(); - } - - void NiParticleCollider::read(NIFStream* nif) - { - NiParticleModifier::read(nif); - - mBounceFactor = nif->getFloat(); - if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 0, 2)) - { - // Unused in NifSkope. Need to figure out what these do. - /*bool mSpawnOnCollision = */ nif->getBoolean(); - /*bool mDieOnCollision = */ nif->getBoolean(); - } - } - - void NiPlanarCollider::read(NIFStream* nif) - { - NiParticleCollider::read(nif); - - mExtents = nif->getVector2(); - mPosition = nif->getVector3(); - mXVector = nif->getVector3(); - mYVector = nif->getVector3(); - mPlaneNormal = nif->getVector3(); - mPlaneDistance = nif->getFloat(); - } - - void NiParticleRotation::read(NIFStream* nif) - { - NiParticleModifier::read(nif); - - /* bool mRandomInitialAxis = */ nif->getChar(); - /* osg::Vec3f mInitialAxis = */ nif->getVector3(); - /* float mRotationSpeed = */ nif->getFloat(); - } - - void NiSphericalCollider::read(NIFStream* nif) - { - NiParticleCollider::read(nif); - - mRadius = nif->getFloat(); - mCenter = nif->getVector3(); - } - -} diff --git a/components/nif/controlled.hpp b/components/nif/controlled.hpp deleted file mode 100644 index 09bab3cbfd..0000000000 --- a/components/nif/controlled.hpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - OpenMW - The completely unofficial reimplementation of Morrowind - Copyright (C) 2008-2010 Nicolay Korslund - Email: < korslund@gmail.com > - WWW: https://openmw.org/ - - This file (controlled.h) is part of the OpenMW package. - - OpenMW is distributed as free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License - version 3, as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - version 3 along with this program. If not, see - https://www.gnu.org/licenses/ . - - */ - -#ifndef OPENMW_COMPONENTS_NIF_CONTROLLED_HPP -#define OPENMW_COMPONENTS_NIF_CONTROLLED_HPP - -#include "base.hpp" - -namespace Nif -{ - - struct NiSourceTexture : public Named - { - // Is this an external (references a separate texture file) or - // internal (data is inside the nif itself) texture? - bool external; - - std::string filename; // In case of external textures - NiPixelDataPtr data; // In case of internal textures - - /* Pixel layout - 0 - Palettised - 1 - High color 16 - 2 - True color 32 - 3 - Compressed - 4 - Bumpmap - 5 - Default */ - unsigned int pixel; - - /* Mipmap format - 0 - no - 1 - yes - 2 - default */ - unsigned int mipmap; - - /* Alpha - 0 - none - 1 - binary - 2 - smooth - 3 - default (use material alpha, or multiply material with texture if present) - */ - unsigned int alpha; - - void read(NIFStream* nif) override; - void post(Reader& nif) override; - }; - - struct BSShaderTextureSet : public Record - { - enum TextureType - { - TextureType_Base = 0, - TextureType_Normal = 1, - TextureType_Glow = 2, - TextureType_Parallax = 3, - TextureType_Env = 4, - TextureType_EnvMask = 5, - TextureType_Subsurface = 6, - TextureType_BackLighting = 7 - }; - std::vector textures; - - void read(NIFStream* nif) override; - }; - - struct NiParticleModifier : public Record - { - NiParticleModifierPtr next; - ControllerPtr controller; - - void read(NIFStream* nif) override; - void post(Reader& nif) override; - }; - - struct NiParticleGrowFade : public NiParticleModifier - { - float growTime; - float fadeTime; - - void read(NIFStream* nif) override; - }; - - struct NiParticleColorModifier : public NiParticleModifier - { - NiColorDataPtr data; - - void read(NIFStream* nif) override; - void post(Reader& nif) override; - }; - - struct NiGravity : public NiParticleModifier - { - float mForce; - /* 0 - Wind (fixed direction) - * 1 - Point (fixed origin) - */ - int mType; - float mDecay; - osg::Vec3f mPosition; - osg::Vec3f mDirection; - - void read(NIFStream* nif) override; - }; - - struct NiParticleCollider : public NiParticleModifier - { - float mBounceFactor; - void read(NIFStream* nif) override; - }; - - // NiPinaColada - struct NiPlanarCollider : public NiParticleCollider - { - osg::Vec2f mExtents; - osg::Vec3f mPosition; - osg::Vec3f mXVector, mYVector; - osg::Vec3f mPlaneNormal; - float mPlaneDistance; - - void read(NIFStream* nif) override; - }; - - struct NiSphericalCollider : public NiParticleCollider - { - float mRadius; - osg::Vec3f mCenter; - - void read(NIFStream* nif) override; - }; - - struct NiParticleRotation : public NiParticleModifier - { - void read(NIFStream* nif) override; - }; - -} // Namespace -#endif diff --git a/components/nif/controller.cpp b/components/nif/controller.cpp index 9e93b31162..1355ce21d3 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -1,9 +1,9 @@ #include "controller.hpp" -#include "controlled.hpp" #include "data.hpp" #include "node.hpp" -#include "recordptr.hpp" +#include "particle.hpp" +#include "texture.hpp" namespace Nif { diff --git a/components/nif/effect.cpp b/components/nif/effect.cpp index 3b90d50564..36407f8dc2 100644 --- a/components/nif/effect.cpp +++ b/components/nif/effect.cpp @@ -1,7 +1,7 @@ #include "effect.hpp" -#include "controlled.hpp" #include "node.hpp" +#include "texture.hpp" namespace Nif { @@ -9,55 +9,61 @@ namespace Nif void NiDynamicEffect::read(NIFStream* nif) { Node::read(nif); - if (nif->getVersion() >= nif->generateVersion(10, 1, 0, 106) - && nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO4) - nif->getBoolean(); // Switch state - if (nif->getVersion() <= NIFFile::VER_MW - || (nif->getVersion() >= nif->generateVersion(10, 1, 0, 0) - && nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO4)) - { - size_t numAffectedNodes = nif->get(); - nif->skip(numAffectedNodes * 4); - } + + if (nif->getVersion() > NIFFile::VER_MW && nif->getVersion() < nif->generateVersion(10, 1, 0, 0)) + return; + + if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO4) + return; + + if (nif->getVersion() >= nif->generateVersion(10, 1, 0, 106)) + nif->read(mSwitchState); + size_t numAffectedNodes = nif->get(); + nif->skip(numAffectedNodes * 4); } void NiLight::read(NIFStream* nif) { NiDynamicEffect::read(nif); - dimmer = nif->getFloat(); - ambient = nif->getVector3(); - diffuse = nif->getVector3(); - specular = nif->getVector3(); + mDimmer = nif->getFloat(); + mAmbient = nif->getVector3(); + mDiffuse = nif->getVector3(); + mSpecular = nif->getVector3(); + } + + void NiPointLight::read(NIFStream* nif) + { + NiLight::read(nif); + + mConstantAttenuation = nif->getFloat(); + mLinearAttenuation = nif->getFloat(); + mQuadraticAttenuation = nif->getFloat(); + } + + void NiSpotLight::read(NIFStream* nif) + { + NiPointLight::read(nif); + + mCutoff = nif->getFloat(); + mExponent = nif->getFloat(); } void NiTextureEffect::read(NIFStream* nif) { NiDynamicEffect::read(nif); - // Model Projection Matrix - nif->skip(3 * 3 * sizeof(float)); - - // Model Projection Transform - nif->skip(3 * sizeof(float)); - - // Texture Filtering - nif->skip(4); - - // Max anisotropy samples + nif->read(mProjectionRotation); + nif->read(mProjectionPosition); + nif->read(mFilterMode); if (nif->getVersion() >= NIFStream::generateVersion(20, 5, 0, 4)) - nif->skip(2); - - clamp = nif->getUInt(); - - textureType = (TextureType)nif->getUInt(); - - coordGenType = (CoordGenType)nif->getUInt(); - - texture.read(nif); - - nif->skip(1); // Use clipping plane - nif->skip(16); // Clipping plane dimensions vector + nif->read(mMaxAnisotropy); + nif->read(mClampMode); + mTextureType = static_cast(nif->get()); + mCoordGenType = static_cast(nif->get()); + mTexture.read(nif); + nif->read(mEnableClipPlane); + mClipPlane = osg::Plane(nif->get()); if (nif->getVersion() <= NIFStream::generateVersion(10, 2, 0, 0)) nif->skip(4); // PS2-specific shorts if (nif->getVersion() <= NIFStream::generateVersion(4, 1, 0, 12)) @@ -67,24 +73,8 @@ namespace Nif void NiTextureEffect::post(Reader& nif) { NiDynamicEffect::post(nif); - texture.post(nif); - } - void NiPointLight::read(NIFStream* nif) - { - NiLight::read(nif); - - constantAttenuation = nif->getFloat(); - linearAttenuation = nif->getFloat(); - quadraticAttenuation = nif->getFloat(); - } - - void NiSpotLight::read(NIFStream* nif) - { - NiPointLight::read(nif); - - cutoff = nif->getFloat(); - exponent = nif->getFloat(); + mTexture.post(nif); } } diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index ea9e21f003..06f85cd5d5 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -29,67 +29,75 @@ namespace Nif { + // Abstract struct NiDynamicEffect : public Node { + bool mSwitchState{ true }; void read(NIFStream* nif) override; }; - // Used as base for NiAmbientLight, NiDirectionalLight, NiPointLight and NiSpotLight. + // Abstract light source struct NiLight : NiDynamicEffect { - float dimmer; - osg::Vec3f ambient; - osg::Vec3f diffuse; - osg::Vec3f specular; + float mDimmer; + osg::Vec3f mAmbient; + osg::Vec3f mDiffuse; + osg::Vec3f mSpecular; void read(NIFStream* nif) override; }; struct NiPointLight : public NiLight { - float constantAttenuation; - float linearAttenuation; - float quadraticAttenuation; + float mConstantAttenuation; + float mLinearAttenuation; + float mQuadraticAttenuation; void read(NIFStream* nif) override; }; struct NiSpotLight : public NiPointLight { - float cutoff; - float exponent; + float mCutoff; + float mExponent; void read(NIFStream* nif) override; }; struct NiTextureEffect : NiDynamicEffect { - NiSourceTexturePtr texture; - unsigned int clamp; - - enum TextureType + enum class TextureType : uint32_t { - Projected_Light = 0, - Projected_Shadow = 1, - Environment_Map = 2, - Fog_Map = 3 + ProjectedLight = 0, + ProjectedShadow = 1, + EnvironmentMap = 2, + FogMap = 3, }; - TextureType textureType; - enum CoordGenType + enum class CoordGenType : uint32_t { - World_Parallel = 0, - World_Perspective, - Sphere_Map, - Specular_Cube_Map, - Diffuse_Cube_Map + WorldParallel = 0, + WorldPerspective = 1, + SphereMap = 2, + SpecularCubeMap = 3, + DiffuseCubeMap = 4, }; - CoordGenType coordGenType; + + Matrix3 mProjectionRotation; + osg::Vec3f mProjectionPosition; + uint32_t mFilterMode; + NiSourceTexturePtr mTexture; + uint16_t mMaxAnisotropy{ 0 }; + uint32_t mClampMode; + TextureType mTextureType; + CoordGenType mCoordGenType; + uint8_t mEnableClipPlane; + osg::Plane mClipPlane; void read(NIFStream* nif) override; void post(Reader& nif) override; - bool wrapT() const { return clamp & 1; } - bool wrapS() const { return (clamp >> 1) & 1; } + bool wrapT() const { return mClampMode & 1; } + bool wrapS() const { return mClampMode & 2; } }; } // Namespace diff --git a/components/nif/extra.cpp b/components/nif/extra.cpp index 4384289f9e..e289ae626e 100644 --- a/components/nif/extra.cpp +++ b/components/nif/extra.cpp @@ -6,25 +6,21 @@ namespace Nif void NiExtraData::read(NIFStream* nif) { Extra::read(nif); - nif->readVector(data, recordSize); - } - void NiStringExtraData::read(NIFStream* nif) - { - Extra::read(nif); - string = nif->getString(); + nif->readVector(mData, mRecordSize); } void NiTextKeyExtraData::read(NIFStream* nif) { Extra::read(nif); - int keynum = nif->getInt(); - list.resize(keynum); - for (int i = 0; i < keynum; i++) + uint32_t numKeys; + nif->read(numKeys); + mList.resize(numKeys); + for (TextKey& key : mList) { - list[i].time = nif->getFloat(); - list[i].text = nif->getString(); + nif->read(key.mTime); + nif->read(key.mText); } } @@ -32,81 +28,39 @@ namespace Nif { Extra::read(nif); - nif->skip(nif->getUShort() * sizeof(float)); // vertex weights I guess - } - - void NiIntegerExtraData::read(NIFStream* nif) - { - Extra::read(nif); - - data = nif->getUInt(); - } - - void NiIntegersExtraData::read(NIFStream* nif) - { - Extra::read(nif); - - nif->readVector(data, nif->getUInt()); - } - - void NiBinaryExtraData::read(NIFStream* nif) - { - Extra::read(nif); - nif->readVector(data, nif->getUInt()); - } - - void NiBooleanExtraData::read(NIFStream* nif) - { - Extra::read(nif); - data = nif->getBoolean(); - } - - void NiVectorExtraData::read(NIFStream* nif) - { - Extra::read(nif); - data = nif->getVector4(); - } - - void NiFloatExtraData::read(NIFStream* nif) - { - Extra::read(nif); - - data = nif->getFloat(); - } - - void NiFloatsExtraData::read(NIFStream* nif) - { - Extra::read(nif); - nif->readVector(data, nif->getUInt()); + nif->skip(nif->get() * sizeof(float)); // vertex weights I guess } void BSBound::read(NIFStream* nif) { Extra::read(nif); - center = nif->getVector3(); - halfExtents = nif->getVector3(); + + nif->read(mCenter); + nif->read(mExtents); } void BSFurnitureMarker::LegacyFurniturePosition::read(NIFStream* nif) { - mOffset = nif->getVector3(); - mOrientation = nif->getUShort(); - mPositionRef = nif->getChar(); + nif->read(mOffset); + nif->read(mOrientation); + nif->read(mPositionRef); nif->skip(1); // Position ref 2 } void BSFurnitureMarker::FurniturePosition::read(NIFStream* nif) { - mOffset = nif->getVector3(); - mHeading = nif->getFloat(); - mType = nif->getUShort(); - mEntryPoint = nif->getUShort(); + nif->read(mOffset); + nif->read(mHeading); + nif->read(mType); + nif->read(mEntryPoint); } void BSFurnitureMarker::read(NIFStream* nif) { Extra::read(nif); - unsigned int num = nif->getUInt(); + + uint32_t num; + nif->read(num); if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3) { mLegacyMarkers.resize(num); @@ -124,19 +78,20 @@ namespace Nif void BSInvMarker::read(NIFStream* nif) { Extra::read(nif); - float rotX = nif->getUShort() / 1000.0; - float rotY = nif->getUShort() / 1000.0; - float rotZ = nif->getUShort() / 1000.0; - mScale = nif->getFloat(); + float rotX = nif->get() / 1000.f; + float rotY = nif->get() / 1000.f; + float rotZ = nif->get() / 1000.f; mRotation = osg::Quat(rotX, osg::X_AXIS, rotY, osg::Y_AXIS, rotZ, osg::Z_AXIS); + nif->read(mScale); } void BSBehaviorGraphExtraData::read(NIFStream* nif) { Extra::read(nif); - mFile = nif->getString(); - mControlsBaseSkeleton = nif->getBoolean(); + + nif->read(mFile); + nif->read(mControlsBaseSkeleton); } } diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index b59fb2f76a..dfe4539138 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -1,26 +1,3 @@ -/* - OpenMW - The completely unofficial reimplementation of Morrowind - Copyright (C) 2008-2010 Nicolay Korslund - Email: < korslund@gmail.com > - WWW: https://openmw.org/ - - This file (extra.h) is part of the OpenMW package. - - OpenMW is distributed as free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License - version 3, as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - version 3 along with this program. If not, see - https://www.gnu.org/licenses/ . - - */ - #ifndef OPENMW_COMPONENTS_NIF_EXTRA_HPP #define OPENMW_COMPONENTS_NIF_EXTRA_HPP @@ -29,9 +6,46 @@ namespace Nif { + template + struct TypedExtra : public Extra + { + T mData; + + void read(NIFStream* nif) override + { + Extra::read(nif); + + nif->read(mData); + } + }; + + template + struct TypedVectorExtra : public Extra + { + std::vector mData; + + void read(NIFStream* nif) override + { + Extra::read(nif); + + nif->readVector(mData, nif->get()); + } + }; + + using NiBooleanExtraData = TypedExtra; + using NiFloatExtraData = TypedExtra; + using NiIntegerExtraData = TypedExtra; + using NiStringExtraData = TypedExtra; + using NiVectorExtraData = TypedExtra; + + using NiBinaryExtraData = TypedVectorExtra; + using NiFloatsExtraData = TypedVectorExtra; + using NiIntegersExtraData = TypedVectorExtra; + + // Distinct from NiBinaryExtraData, uses mRecordSize as its size struct NiExtraData : public Extra { - std::vector data; + std::vector mData; void read(NIFStream* nif) override; }; @@ -45,78 +59,17 @@ namespace Nif { struct TextKey { - float time; - std::string text; + float mTime; + std::string mText; }; - std::vector list; - - void read(NIFStream* nif) override; - }; - - struct NiStringExtraData : public Extra - { - /* Known meanings: - "MRK" - marker, only visible in the editor, not rendered in-game - "NCC" - no collision except with the camera - Anything else starting with "NC" - no collision - */ - std::string string; - - void read(NIFStream* nif) override; - }; - - struct NiIntegerExtraData : public Extra - { - unsigned int data; - - void read(NIFStream* nif) override; - }; - - struct NiIntegersExtraData : public Extra - { - std::vector data; - - void read(NIFStream* nif) override; - }; - - struct NiBinaryExtraData : public Extra - { - std::vector data; - - void read(NIFStream* nif) override; - }; - - struct NiBooleanExtraData : public Extra - { - bool data; - - void read(NIFStream* nif) override; - }; - - struct NiVectorExtraData : public Extra - { - osg::Vec4f data; - - void read(NIFStream* nif) override; - }; - - struct NiFloatExtraData : public Extra - { - float data; - - void read(NIFStream* nif) override; - }; - - struct NiFloatsExtraData : public Extra - { - std::vector data; + std::vector mList; void read(NIFStream* nif) override; }; struct BSBound : public Extra { - osg::Vec3f center, halfExtents; + osg::Vec3f mCenter, mExtents; void read(NIFStream* nif) override; }; @@ -149,7 +102,7 @@ namespace Nif struct BSInvMarker : public Extra { osg::Quat mRotation; - float mScale = 1.0f; + float mScale; void read(NIFStream* nif) override; }; @@ -162,5 +115,5 @@ namespace Nif void read(NIFStream* nif) override; }; -} // Namespace +} #endif diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index f806c61bc1..e147ee3528 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -10,15 +10,16 @@ #include #include -#include "controlled.hpp" #include "controller.hpp" #include "data.hpp" #include "effect.hpp" #include "exception.hpp" #include "extra.hpp" #include "node.hpp" +#include "particle.hpp" #include "physics.hpp" #include "property.hpp" +#include "texture.hpp" namespace Nif { diff --git a/components/nif/particle.cpp b/components/nif/particle.cpp new file mode 100644 index 0000000000..ae391c59e4 --- /dev/null +++ b/components/nif/particle.cpp @@ -0,0 +1,95 @@ +#include "particle.hpp" + +#include "data.hpp" + +namespace Nif +{ + + void NiParticleModifier::read(NIFStream* nif) + { + mNext.read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13)) + mController.read(nif); + } + + void NiParticleModifier::post(Reader& nif) + { + mNext.post(nif); + mController.post(nif); + } + + void NiParticleGrowFade::read(NIFStream* nif) + { + NiParticleModifier::read(nif); + nif->read(mGrowTime); + nif->read(mFadeTime); + } + + void NiParticleColorModifier::read(NIFStream* nif) + { + NiParticleModifier::read(nif); + + mData.read(nif); + } + + void NiParticleColorModifier::post(Reader& nif) + { + NiParticleModifier::post(nif); + + mData.post(nif); + } + + void NiGravity::read(NIFStream* nif) + { + NiParticleModifier::read(nif); + + if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13)) + nif->read(mDecay); + nif->read(mForce); + mType = static_cast(nif->get()); + nif->read(mPosition); + nif->read(mDirection); + } + + void NiParticleCollider::read(NIFStream* nif) + { + NiParticleModifier::read(nif); + + nif->read(mBounceFactor); + if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 0, 2)) + { + nif->read(mSpawnOnCollision); + nif->read(mDieOnCollision); + } + } + + void NiPlanarCollider::read(NIFStream* nif) + { + NiParticleCollider::read(nif); + + nif->read(mExtents); + nif->read(mPosition); + nif->read(mXVector); + nif->read(mYVector); + nif->read(mPlaneNormal); + nif->read(mPlaneDistance); + } + + void NiSphericalCollider::read(NIFStream* nif) + { + NiParticleCollider::read(nif); + + nif->read(mRadius); + nif->read(mCenter); + } + + void NiParticleRotation::read(NIFStream* nif) + { + NiParticleModifier::read(nif); + + nif->read(mRandomInitialAxis); + nif->read(mInitialAxis); + nif->read(mRotationSpeed); + } + +} diff --git a/components/nif/particle.hpp b/components/nif/particle.hpp new file mode 100644 index 0000000000..5590877294 --- /dev/null +++ b/components/nif/particle.hpp @@ -0,0 +1,90 @@ +#ifndef OPENMW_COMPONENTS_NIF_PARTICLE_HPP +#define OPENMW_COMPONENTS_NIF_PARTICLE_HPP + +#include "base.hpp" + +namespace Nif +{ + + struct NiParticleModifier : public Record + { + NiParticleModifierPtr mNext; + ControllerPtr mController; + + void read(NIFStream* nif) override; + void post(Reader& nif) override; + }; + + struct NiParticleGrowFade : public NiParticleModifier + { + float mGrowTime; + float mFadeTime; + + void read(NIFStream* nif) override; + }; + + struct NiParticleColorModifier : public NiParticleModifier + { + NiColorDataPtr mData; + + void read(NIFStream* nif) override; + void post(Reader& nif) override; + }; + + struct NiGravity : public NiParticleModifier + { + enum class ForceType : uint32_t + { + Wind = 0, // Fixed direction + Point = 1, // Fixed origin + }; + + float mDecay{ 0.f }; + float mForce; + ForceType mType; + osg::Vec3f mPosition; + osg::Vec3f mDirection; + + void read(NIFStream* nif) override; + }; + + struct NiParticleCollider : public NiParticleModifier + { + float mBounceFactor; + bool mSpawnOnCollision{ false }; + bool mDieOnCollision{ false }; + + void read(NIFStream* nif) override; + }; + + // NiPinaColada + struct NiPlanarCollider : public NiParticleCollider + { + osg::Vec2f mExtents; + osg::Vec3f mPosition; + osg::Vec3f mXVector, mYVector; + osg::Vec3f mPlaneNormal; + float mPlaneDistance; + + void read(NIFStream* nif) override; + }; + + struct NiSphericalCollider : public NiParticleCollider + { + float mRadius; + osg::Vec3f mCenter; + + void read(NIFStream* nif) override; + }; + + struct NiParticleRotation : public NiParticleModifier + { + uint8_t mRandomInitialAxis; + osg::Vec3f mInitialAxis; + float mRotationSpeed; + + void read(NIFStream* nif) override; + }; + +} +#endif diff --git a/components/nif/physics.cpp b/components/nif/physics.cpp index daa4f90c2a..95786cb247 100644 --- a/components/nif/physics.cpp +++ b/components/nif/physics.cpp @@ -12,15 +12,15 @@ namespace Nif void bhkWorldObjCInfoProperty::read(NIFStream* nif) { - mData = nif->getUInt(); - mSize = nif->getUInt(); - mCapacityAndFlags = nif->getUInt(); + nif->read(mData); + nif->read(mSize); + nif->read(mCapacityAndFlags); } void bhkWorldObjectCInfo::read(NIFStream* nif) { nif->skip(4); // Unused - mPhaseType = static_cast(nif->getChar()); + mPhaseType = static_cast(nif->get()); nif->skip(3); // Unused mProperty.read(nif); } @@ -29,47 +29,47 @@ namespace Nif { if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD) nif->skip(4); // Unknown - mMaterial = nif->getUInt(); + nif->read(mMaterial); } void HavokFilter::read(NIFStream* nif) { - mLayer = nif->getChar(); - mFlags = nif->getChar(); - mGroup = nif->getUShort(); + nif->read(mLayer); + nif->read(mFlags); + nif->read(mGroup); } void hkSubPartData::read(NIFStream* nif) { mHavokFilter.read(nif); - mNumVertices = nif->getUInt(); + nif->read(mNumVertices); mHavokMaterial.read(nif); } - void hkpMoppCode::read(NIFStream* nif) - { - unsigned int size = nif->getUInt(); - if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) - mOffset = nif->getVector4(); - if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3) - nif->getChar(); // MOPP data build type - nif->readVector(mData, size); - } - void bhkEntityCInfo::read(NIFStream* nif) { - mResponseType = static_cast(nif->getChar()); + mResponseType = static_cast(nif->get()); nif->skip(1); // Unused - mProcessContactDelay = nif->getUShort(); + nif->read(mProcessContactDelay); + } + + void hkpMoppCode::read(NIFStream* nif) + { + uint32_t dataSize; + nif->read(dataSize); + if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) + nif->read(mOffset); + if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3) + nif->read(mBuildType); + nif->readVector(mData, dataSize); } void TriangleData::read(NIFStream* nif) { - for (int i = 0; i < 3; i++) - mTriangle[i] = nif->getUShort(); - mWeldingInfo = nif->getUShort(); + nif->readArray(mTriangle); + nif->read(mWeldingInfo); if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB) - mNormal = nif->getVector3(); + nif->read(mNormal); } void bhkMeshMaterial::read(NIFStream* nif) @@ -80,28 +80,27 @@ namespace Nif void bhkQsTransform::read(NIFStream* nif) { - mTranslation = nif->getVector4(); - mRotation = nif->getQuaternion(); + nif->read(mTranslation); + nif->read(mRotation); } void bhkCMSBigTri::read(NIFStream* nif) { - for (int i = 0; i < 3; i++) - mTriangle[i] = nif->getUShort(); - mMaterial = nif->getUInt(); - mWeldingInfo = nif->getUShort(); + nif->readArray(mTriangle); + nif->read(mMaterial); + nif->read(mWeldingInfo); } void bhkCMSChunk::read(NIFStream* nif) { - mTranslation = nif->getVector4(); - mMaterialIndex = nif->getUInt(); - mReference = nif->getUShort(); - mTransformIndex = nif->getUShort(); - nif->readVector(mVertices, nif->getUInt()); - nif->readVector(mIndices, nif->getUInt()); - nif->readVector(mStrips, nif->getUInt()); - nif->readVector(mWeldingInfos, nif->getUInt()); + nif->read(mTranslation); + nif->read(mMaterialIndex); + nif->read(mReference); + nif->read(mTransformIndex); + nif->readVector(mVertices, nif->get()); + nif->readVector(mIndices, nif->get()); + nif->readVector(mStrips, nif->get()); + nif->readVector(mWeldingInfos, nif->get()); } void bhkRigidBodyCInfo::read(NIFStream* nif) @@ -115,64 +114,67 @@ namespace Nif { if (nif->getBethVersion() >= 83) nif->skip(4); // Unused - mResponseType = static_cast(nif->getChar()); + mResponseType = static_cast(nif->get()); nif->skip(1); // Unused - mProcessContactDelay = nif->getUShort(); + nif->read(mProcessContactDelay); } } if (nif->getBethVersion() < 83) nif->skip(4); // Unused - mTranslation = nif->getVector4(); - mRotation = nif->getQuaternion(); - mLinearVelocity = nif->getVector4(); - mAngularVelocity = nif->getVector4(); + nif->read(mTranslation); + nif->read(mRotation); + nif->read(mLinearVelocity); + nif->read(mAngularVelocity); + // A bit hacky, but this is the only instance where a 3x3 matrix has padding. for (int i = 0; i < 3; i++) - for (int j = 0; j < 4; j++) - mInertiaTensor[i][j] = nif->getFloat(); - mCenter = nif->getVector4(); - mMass = nif->getFloat(); - mLinearDamping = nif->getFloat(); - mAngularDamping = nif->getFloat(); + { + nif->read(mInertiaTensor.mValues[i], 3); + nif->skip(4); // Padding + } + nif->read(mCenter); + nif->read(mMass); + nif->read(mLinearDamping); + nif->read(mAngularDamping); if (nif->getBethVersion() >= 83) { if (nif->getBethVersion() != NIFFile::BethVersion::BETHVER_FO4) - mTimeFactor = nif->getFloat(); - mGravityFactor = nif->getFloat(); + nif->read(mTimeFactor); + nif->read(mGravityFactor); } - mFriction = nif->getFloat(); + nif->read(mFriction); if (nif->getBethVersion() >= 83) - mRollingFrictionMult = nif->getFloat(); - mRestitution = nif->getFloat(); + nif->read(mRollingFrictionMult); + nif->read(mRestitution); if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) { - mMaxLinearVelocity = nif->getFloat(); - mMaxAngularVelocity = nif->getFloat(); + nif->read(mMaxLinearVelocity); + nif->read(mMaxAngularVelocity); if (nif->getBethVersion() != NIFFile::BethVersion::BETHVER_FO4) - mPenetrationDepth = nif->getFloat(); + nif->read(mPenetrationDepth); } - mMotionType = static_cast(nif->getChar()); + mMotionType = static_cast(nif->get()); if (nif->getBethVersion() < 83) - mDeactivatorType = static_cast(nif->getChar()); + mDeactivatorType = static_cast(nif->get()); else - mEnableDeactivation = nif->getBoolean(); - mSolverDeactivation = static_cast(nif->getChar()); + nif->read(mEnableDeactivation); + mSolverDeactivation = static_cast(nif->get()); if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_FO4) { nif->skip(1); - mPenetrationDepth = nif->getFloat(); - mTimeFactor = nif->getFloat(); + nif->read(mPenetrationDepth); + nif->read(mTimeFactor); nif->skip(4); - mResponseType = static_cast(nif->getChar()); + mResponseType = static_cast(nif->get()); nif->skip(1); // Unused - mProcessContactDelay = nif->getUShort(); + nif->read(mProcessContactDelay); } - mQualityType = static_cast(nif->getChar()); + mQualityType = static_cast(nif->get()); if (nif->getBethVersion() >= 83) { - mAutoRemoveLevel = nif->getChar(); - mResponseModifierFlags = nif->getChar(); - mNumContactPointShapeKeys = nif->getChar(); - mForceCollidedOntoPPU = nif->getBoolean(); + nif->read(mAutoRemoveLevel); + nif->read(mResponseModifierFlags); + nif->read(mNumContactPointShapeKeys); + nif->read(mForceCollidedOntoPPU); } if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_FO4) nif->skip(3); // Unused @@ -182,7 +184,7 @@ namespace Nif void bhkConstraintCInfo::read(NIFStream* nif) { - nif->get(); // Number of entities, unused + nif->get(); // Number of entities, unused mEntityA.read(nif); mEntityB.read(nif); @@ -203,7 +205,7 @@ namespace Nif nif->read(mDamping); nif->read(mProportionalRecoveryVelocity); nif->read(mConstantRecoveryVelocity); - mEnabled = nif->getBoolean(); + nif->read(mEnabled); } void bhkVelocityConstraintMotor::read(NIFStream* nif) @@ -212,8 +214,8 @@ namespace Nif nif->read(mMaxForce); nif->read(mTau); nif->read(mTargetVelocity); - mUseVelocityTarget = nif->getBoolean(); - mEnabled = nif->getBoolean(); + nif->read(mUseVelocityTarget); + nif->read(mEnabled); } void bhkSpringDamperConstraintMotor::read(NIFStream* nif) @@ -222,7 +224,7 @@ namespace Nif nif->read(mMaxForce); nif->read(mSpringConstant); nif->read(mSpringDamping); - mEnabled = nif->getBoolean(); + nif->read(mEnabled); } void bhkConstraintMotorCInfo::read(NIFStream* nif) @@ -335,7 +337,8 @@ namespace Nif void bhkCollisionObject::read(NIFStream* nif) { NiCollisionObject::read(nif); - mFlags = nif->getUShort(); + + nif->read(mFlags); mBody.read(nif); } @@ -356,6 +359,7 @@ namespace Nif void bhkEntity::read(NIFStream* nif) { bhkWorldObject::read(nif); + mInfo.read(nif); } @@ -372,21 +376,26 @@ namespace Nif void bhkMoppBvTreeShape::read(NIFStream* nif) { bhkBvTreeShape::read(nif); + nif->skip(12); // Unused - mScale = nif->getFloat(); + nif->read(mScale); mMopp.read(nif); } void bhkNiTriStripsShape::read(NIFStream* nif) { mHavokMaterial.read(nif); - mRadius = nif->getFloat(); + nif->read(mRadius); nif->skip(20); // Unused - mGrowBy = nif->getUInt(); + nif->read(mGrowBy); if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) - mScale = nif->getVector4(); + nif->read(mScale); readRecordList(nif, mData); - nif->readVector(mFilters, nif->getUInt()); + uint32_t numFilters; + nif->read(numFilters); + mHavokFilters.resize(numFilters); + for (HavokFilter& filter : mHavokFilters) + filter.read(nif); } void bhkNiTriStripsShape::post(Reader& nif) @@ -398,15 +407,17 @@ namespace Nif { if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB) { - mSubshapes.resize(nif->getUShort()); + uint16_t numSubshapes; + nif->read(numSubshapes); + mSubshapes.resize(numSubshapes); for (hkSubPartData& subshape : mSubshapes) subshape.read(nif); } - mUserData = nif->getUInt(); + nif->read(mUserData); nif->skip(4); // Unused - mRadius = nif->getFloat(); + nif->read(mRadius); nif->skip(4); // Unused - mScale = nif->getVector4(); + nif->read(mScale); nif->skip(20); // Duplicates of the two previous fields mData.read(nif); } @@ -418,22 +429,26 @@ namespace Nif void hkPackedNiTriStripsData::read(NIFStream* nif) { - unsigned int numTriangles = nif->getUInt(); + uint32_t numTriangles; + nif->read(numTriangles); mTriangles.resize(numTriangles); - for (unsigned int i = 0; i < numTriangles; i++) + for (uint32_t i = 0; i < numTriangles; i++) mTriangles[i].read(nif); - unsigned int numVertices = nif->getUInt(); + uint32_t numVertices; + nif->read(numVertices); bool compressed = false; if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS) - compressed = nif->getBoolean(); + nif->read(compressed); if (!compressed) nif->readVector(mVertices, numVertices); else nif->skip(6 * numVertices); // Half-precision vectors are not currently supported if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS) { - mSubshapes.resize(nif->getUShort()); + uint16_t numSubshapes; + nif->read(numSubshapes); + mSubshapes.resize(numSubshapes); for (hkSubPartData& subshape : mSubshapes) subshape.read(nif); } @@ -447,23 +462,25 @@ namespace Nif void bhkConvexShape::read(NIFStream* nif) { bhkSphereRepShape::read(nif); - mRadius = nif->getFloat(); + + nif->read(mRadius); } void bhkConvexVerticesShape::read(NIFStream* nif) { bhkConvexShape::read(nif); + mVerticesProperty.read(nif); mNormalsProperty.read(nif); - nif->readVector(mVertices, nif->getUInt()); - nif->readVector(mNormals, nif->getUInt()); + nif->readVector(mVertices, nif->get()); + nif->readVector(mNormals, nif->get()); } void bhkConvexTransformShape::read(NIFStream* nif) { mShape.read(nif); mHavokMaterial.read(nif); - mRadius = nif->getFloat(); + nif->read(mRadius); nif->skip(8); // Unused std::array mat; nif->readArray(mat); @@ -478,19 +495,21 @@ namespace Nif void bhkBoxShape::read(NIFStream* nif) { bhkConvexShape::read(nif); + nif->skip(8); // Unused - mExtents = nif->getVector3(); + nif->read(mExtents); nif->skip(4); // Unused } void bhkCapsuleShape::read(NIFStream* nif) { bhkConvexShape::read(nif); + nif->skip(8); // Unused - mPoint1 = nif->getVector3(); - mRadius1 = nif->getFloat(); - mPoint2 = nif->getVector3(); - mRadius2 = nif->getFloat(); + nif->read(mPoint1); + nif->read(mRadius1); + nif->read(mPoint2); + nif->read(mRadius2); } void bhkListShape::read(NIFStream* nif) @@ -499,7 +518,8 @@ namespace Nif mHavokMaterial.read(nif); mChildShapeProperty.read(nif); mChildFilterProperty.read(nif); - unsigned int numFilters = nif->getUInt(); + uint32_t numFilters; + nif->read(numFilters); mHavokFilters.resize(numFilters); for (HavokFilter& filter : mHavokFilters) filter.read(nif); @@ -508,12 +528,12 @@ namespace Nif void bhkCompressedMeshShape::read(NIFStream* nif) { mTarget.read(nif); - mUserData = nif->getUInt(); - mRadius = nif->getFloat(); - nif->getFloat(); // Unknown - mScale = nif->getVector4(); - nif->getFloat(); // Radius - nif->getVector4(); // Scale + nif->read(mUserData); + nif->read(mRadius); + nif->skip(4); // Unknown + nif->read(mScale); + nif->skip(4); // Radius + nif->skip(16); // Scale mData.read(nif); } @@ -525,60 +545,66 @@ namespace Nif void bhkCompressedMeshShapeData::read(NIFStream* nif) { - mBitsPerIndex = nif->getUInt(); - mBitsPerWIndex = nif->getUInt(); - mMaskWIndex = nif->getUInt(); - mMaskIndex = nif->getUInt(); - mError = nif->getFloat(); - mAabbMin = nif->getVector4(); - mAabbMax = nif->getVector4(); - mWeldingType = nif->getChar(); - mMaterialType = nif->getChar(); - nif->skip(nif->getUInt() * 4); // Unused - nif->skip(nif->getUInt() * 4); // Unused - nif->skip(nif->getUInt() * 4); // Unused + nif->read(mBitsPerIndex); + nif->read(mBitsPerWIndex); + nif->read(mMaskWIndex); + nif->read(mMaskIndex); + nif->read(mError); + nif->read(mAabbMin); + nif->read(mAabbMax); + nif->read(mWeldingType); + nif->read(mMaterialType); + nif->skip(nif->get() * 4); // Unused + nif->skip(nif->get() * 4); // Unused + nif->skip(nif->get() * 4); // Unused - size_t numMaterials = nif->getUInt(); + uint32_t numMaterials; + nif->read(numMaterials); mMaterials.resize(numMaterials); for (bhkMeshMaterial& material : mMaterials) material.read(nif); - nif->getUInt(); // Unused - size_t numTransforms = nif->getUInt(); + nif->skip(4); // Unused + uint32_t numTransforms; + nif->read(numTransforms); mChunkTransforms.resize(numTransforms); for (bhkQsTransform& transform : mChunkTransforms) transform.read(nif); - nif->readVector(mBigVerts, nif->getUInt()); + nif->readVector(mBigVerts, nif->get()); - size_t numBigTriangles = nif->getUInt(); + uint32_t numBigTriangles; + nif->read(numBigTriangles); mBigTris.resize(numBigTriangles); for (bhkCMSBigTri& tri : mBigTris) tri.read(nif); - size_t numChunks = nif->getUInt(); + uint32_t numChunks; + nif->read(numChunks); mChunks.resize(numChunks); for (bhkCMSChunk& chunk : mChunks) chunk.read(nif); - nif->getUInt(); // Unused + nif->skip(4); // Unused } void bhkRigidBody::read(NIFStream* nif) { bhkEntity::read(nif); + mInfo.read(nif); readRecordList(nif, mConstraints); if (nif->getBethVersion() < 76) - mBodyFlags = nif->getUInt(); + nif->read(mBodyFlags); else - mBodyFlags = nif->getUShort(); + mBodyFlags = nif->get(); } void bhkSimpleShapePhantom::read(NIFStream* nif) { bhkWorldObject::read(nif); + nif->skip(8); // Unused std::array mat; nif->readArray(mat); @@ -598,18 +624,21 @@ namespace Nif void bhkRagdollConstraint::read(NIFStream* nif) { bhkConstraint::read(nif); + mConstraint.read(nif); } void bhkHingeConstraint::read(NIFStream* nif) { bhkConstraint::read(nif); + mConstraint.read(nif); } void bhkLimitedHingeConstraint::read(NIFStream* nif) { bhkConstraint::read(nif); + mConstraint.read(nif); } diff --git a/components/nif/physics.hpp b/components/nif/physics.hpp index cc1a3ba755..a7bfa1425d 100644 --- a/components/nif/physics.hpp +++ b/components/nif/physics.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_COMPONENTS_NIF_PHYSICS_HPP #define OPENMW_COMPONENTS_NIF_PHYSICS_HPP +#include "niftypes.hpp" #include "record.hpp" #include "recordptr.hpp" @@ -23,9 +24,10 @@ namespace Nif struct bhkWorldObjCInfoProperty { - unsigned int mData; - unsigned int mSize; - unsigned int mCapacityAndFlags; + uint32_t mData; + uint32_t mSize; + uint32_t mCapacityAndFlags; + void read(NIFStream* nif); }; @@ -41,28 +43,32 @@ namespace Nif { BroadPhaseType mPhaseType; bhkWorldObjCInfoProperty mProperty; + void read(NIFStream* nif); }; struct HavokMaterial { - unsigned int mMaterial; + uint32_t mMaterial; + void read(NIFStream* nif); }; struct HavokFilter { - unsigned char mLayer; - unsigned char mFlags; - unsigned short mGroup; + uint8_t mLayer; + uint8_t mFlags; + uint16_t mGroup; + void read(NIFStream* nif); }; struct hkSubPartData { HavokMaterial mHavokMaterial; - unsigned int mNumVertices; + uint32_t mNumVertices; HavokFilter mHavokFilter; + void read(NIFStream* nif); }; @@ -77,22 +83,26 @@ namespace Nif struct bhkEntityCInfo { hkResponseType mResponseType; - unsigned short mProcessContactDelay; + uint16_t mProcessContactDelay; + void read(NIFStream* nif); }; struct hkpMoppCode { osg::Vec4f mOffset; - std::vector mData; + uint8_t mBuildType; + std::vector mData; + void read(NIFStream* nif); }; struct TriangleData { - unsigned short mTriangle[3]; - unsigned short mWeldingInfo; + std::array mTriangle; + uint16_t mWeldingInfo; osg::Vec3f mNormal; + void read(NIFStream* nif); }; @@ -100,6 +110,7 @@ namespace Nif { HavokMaterial mHavokMaterial; HavokFilter mHavokFilter; + void read(NIFStream* nif); }; @@ -107,27 +118,30 @@ namespace Nif { osg::Vec4f mTranslation; osg::Quat mRotation; + void read(NIFStream* nif); }; struct bhkCMSBigTri { - unsigned short mTriangle[3]; - unsigned int mMaterial; - unsigned short mWeldingInfo; + std::array mTriangle; + uint32_t mMaterial; + uint16_t mWeldingInfo; + void read(NIFStream* nif); }; struct bhkCMSChunk { osg::Vec4f mTranslation; - unsigned int mMaterialIndex; - unsigned short mReference; - unsigned short mTransformIndex; - std::vector mVertices; - std::vector mIndices; - std::vector mStrips; - std::vector mWeldingInfos; + uint32_t mMaterialIndex; + uint16_t mReference; + uint16_t mTransformIndex; + std::vector mVertices; + std::vector mIndices; + std::vector mStrips; + std::vector mWeldingInfos; + void read(NIFStream* nif); }; @@ -180,12 +194,12 @@ namespace Nif { HavokFilter mHavokFilter; hkResponseType mResponseType; - unsigned short mProcessContactDelay; + uint16_t mProcessContactDelay; osg::Vec4f mTranslation; osg::Quat mRotation; osg::Vec4f mLinearVelocity; osg::Vec4f mAngularVelocity; - float mInertiaTensor[3][4]; + Matrix3 mInertiaTensor; osg::Vec4f mCenter; float mMass; float mLinearDamping; @@ -203,10 +217,11 @@ namespace Nif bool mEnableDeactivation{ true }; hkSolverDeactivation mSolverDeactivation; hkQualityType mQualityType; - unsigned char mAutoRemoveLevel; - unsigned char mResponseModifierFlags; - unsigned char mNumContactPointShapeKeys; + uint8_t mAutoRemoveLevel; + uint8_t mResponseModifierFlags; + uint8_t mNumContactPointShapeKeys; bool mForceCollidedOntoPPU; + void read(NIFStream* nif); }; @@ -222,6 +237,7 @@ namespace Nif bhkEntityPtr mEntityA; bhkEntityPtr mEntityB; ConstraintPriority mPriority; + void read(NIFStream* nif); void post(Reader& nif); }; @@ -242,6 +258,7 @@ namespace Nif float mProportionalRecoveryVelocity; float mConstantRecoveryVelocity; bool mEnabled; + void read(NIFStream* nif); }; @@ -252,6 +269,7 @@ namespace Nif float mTargetVelocity; bool mUseVelocityTarget; bool mEnabled; + void read(NIFStream* nif); }; @@ -261,6 +279,7 @@ namespace Nif float mSpringConstant; float mSpringDamping; bool mEnabled; + void read(NIFStream* nif); }; @@ -270,6 +289,7 @@ namespace Nif bhkPositionConstraintMotor mPositionMotor; bhkVelocityConstraintMotor mVelocityMotor; bhkSpringDamperConstraintMotor mSpringDamperMotor; + void read(NIFStream* nif); }; @@ -289,6 +309,7 @@ namespace Nif float mTwistMinAngle, mTwistMaxAngle; float mMaxFriction; bhkConstraintMotorCInfo mMotor; + void read(NIFStream* nif); }; @@ -301,8 +322,10 @@ namespace Nif osg::Vec4f mPerpAxis1; osg::Vec4f mPerpAxis2; }; + HingeData mDataA; HingeData mDataB; + void read(NIFStream* nif); }; @@ -315,11 +338,13 @@ namespace Nif osg::Vec4f mPerpAxis1; osg::Vec4f mPerpAxis2; }; + HingeData mDataA; HingeData mDataB; float mMinAngle, mMaxAngle; float mMaxFriction; bhkConstraintMotorCInfo mMotor; + void read(NIFStream* nif); }; @@ -358,7 +383,7 @@ namespace Nif // Bethesda Havok-specific collision object struct bhkCollisionObject : public NiCollisionObject { - unsigned short mFlags; + uint16_t mFlags; bhkWorldObjectPtr mBody; void read(NIFStream* nif) override; @@ -375,6 +400,7 @@ namespace Nif bhkShapePtr mShape; HavokFilter mHavokFilter; bhkWorldObjectCInfo mWorldObjectInfo; + void read(NIFStream* nif) override; void post(Reader& nif) override; }; @@ -383,6 +409,7 @@ namespace Nif struct bhkEntity : public bhkWorldObject { bhkEntityCInfo mInfo; + void read(NIFStream* nif) override; }; @@ -391,6 +418,7 @@ namespace Nif struct bhkBvTreeShape : public bhkShape { bhkShapePtr mShape; + void read(NIFStream* nif) override; void post(Reader& nif) override; }; @@ -400,6 +428,7 @@ namespace Nif { float mScale; hkpMoppCode mMopp; + void read(NIFStream* nif) override; }; @@ -408,10 +437,11 @@ namespace Nif { HavokMaterial mHavokMaterial; float mRadius; - unsigned int mGrowBy; + uint32_t mGrowBy; osg::Vec4f mScale{ 1.f, 1.f, 1.f, 0.f }; NiTriStripsDataList mData; - std::vector mFilters; + std::vector mHavokFilters; + void read(NIFStream* nif) override; void post(Reader& nif) override; }; @@ -420,7 +450,7 @@ namespace Nif struct bhkPackedNiTriStripsShape : public bhkShapeCollection { std::vector mSubshapes; - unsigned int mUserData; + uint32_t mUserData; float mRadius; osg::Vec4f mScale; hkPackedNiTriStripsDataPtr mData; @@ -435,6 +465,7 @@ namespace Nif std::vector mTriangles; std::vector mVertices; std::vector mSubshapes; + void read(NIFStream* nif) override; }; @@ -442,6 +473,7 @@ namespace Nif struct bhkSphereRepShape : public bhkShape { HavokMaterial mHavokMaterial; + void read(NIFStream* nif) override; }; @@ -449,6 +481,7 @@ namespace Nif struct bhkConvexShape : public bhkSphereRepShape { float mRadius; + void read(NIFStream* nif) override; }; @@ -459,6 +492,7 @@ namespace Nif bhkWorldObjCInfoProperty mNormalsProperty; std::vector mVertices; std::vector mNormals; + void read(NIFStream* nif) override; }; @@ -468,6 +502,7 @@ namespace Nif HavokMaterial mHavokMaterial; float mRadius; osg::Matrixf mTransform; + void read(NIFStream* nif) override; void post(Reader& nif) override; }; @@ -476,6 +511,7 @@ namespace Nif struct bhkBoxShape : public bhkConvexShape { osg::Vec3f mExtents; + void read(NIFStream* nif) override; }; @@ -499,28 +535,30 @@ namespace Nif bhkWorldObjCInfoProperty mChildShapeProperty; bhkWorldObjCInfoProperty mChildFilterProperty; std::vector mHavokFilters; + void read(NIFStream* nif) override; }; struct bhkCompressedMeshShape : public bhkShape { NodePtr mTarget; - unsigned int mUserData; + uint32_t mUserData; float mRadius; osg::Vec4f mScale; bhkCompressedMeshShapeDataPtr mData; + void read(NIFStream* nif) override; void post(Reader& nif) override; }; struct bhkCompressedMeshShapeData : public bhkRefObject { - unsigned int mBitsPerIndex, mBitsPerWIndex; - unsigned int mMaskWIndex, mMaskIndex; + uint32_t mBitsPerIndex, mBitsPerWIndex; + uint32_t mMaskWIndex, mMaskIndex; float mError; osg::Vec4f mAabbMin, mAabbMax; - char mWeldingType; - char mMaterialType; + uint8_t mWeldingType; + uint8_t mMaterialType; std::vector mMaterials; std::vector mChunkTransforms; std::vector mBigVerts; @@ -534,7 +572,7 @@ namespace Nif { bhkRigidBodyCInfo mInfo; bhkSerializableList mConstraints; - unsigned int mBodyFlags; + uint32_t mBodyFlags; void read(NIFStream* nif) override; }; @@ -542,6 +580,7 @@ namespace Nif struct bhkSimpleShapePhantom : public bhkWorldObject { osg::Matrixf mTransform; + void read(NIFStream* nif) override; }; @@ -549,6 +588,7 @@ namespace Nif struct bhkConstraint : public bhkSerializable { bhkConstraintCInfo mInfo; + void read(NIFStream* nif) override; void post(Reader& nif) override; }; @@ -556,18 +596,21 @@ namespace Nif struct bhkRagdollConstraint : public bhkConstraint { bhkRagdollConstraintCInfo mConstraint; + void read(NIFStream* nif) override; }; struct bhkHingeConstraint : public bhkConstraint { bhkHingeConstraintCInfo mConstraint; + void read(NIFStream* nif) override; }; struct bhkLimitedHingeConstraint : public bhkConstraint { bhkLimitedHingeConstraintCInfo mConstraint; + void read(NIFStream* nif) override; }; diff --git a/components/nif/property.cpp b/components/nif/property.cpp index 3c1c424de9..39a7cbff23 100644 --- a/components/nif/property.cpp +++ b/components/nif/property.cpp @@ -1,7 +1,7 @@ #include "property.hpp" -#include "controlled.hpp" #include "data.hpp" +#include "texture.hpp" namespace Nif { diff --git a/components/nif/texture.cpp b/components/nif/texture.cpp new file mode 100644 index 0000000000..116ded6f7e --- /dev/null +++ b/components/nif/texture.cpp @@ -0,0 +1,47 @@ +#include "texture.hpp" + +#include "data.hpp" + +namespace Nif +{ + + void NiSourceTexture::read(NIFStream* nif) + { + NiTexture::read(nif); + + nif->read(mExternal); + if (mExternal || nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) + nif->read(mFile); + + bool hasData = nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 4); + if (!hasData && !mExternal) + nif->read(hasData); + + if (hasData) + mData.read(nif); + + mPrefs.mPixelLayout = static_cast(nif->get()); + mPrefs.mUseMipMaps = static_cast(nif->get()); + mPrefs.mAlphaFormat = static_cast(nif->get()); + + nif->read(mIsStatic); + if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 103)) + { + nif->read(mDirectRendering); + if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 4)) + nif->read(mPersistRenderData); + } + } + + void NiSourceTexture::post(Reader& nif) + { + NiTexture::post(nif); + mData.post(nif); + } + + void BSShaderTextureSet::read(NIFStream* nif) + { + nif->getSizedStrings(mTextures, nif->get()); + } + +} diff --git a/components/nif/texture.hpp b/components/nif/texture.hpp new file mode 100644 index 0000000000..a326b47f14 --- /dev/null +++ b/components/nif/texture.hpp @@ -0,0 +1,81 @@ +#ifndef OPENMW_COMPONENTS_NIF_TEXTURE_HPP +#define OPENMW_COMPONENTS_NIF_TEXTURE_HPP + +#include "base.hpp" + +namespace Nif +{ + + struct NiTexture : public Named + { + }; + + struct NiSourceTexture : public NiTexture + { + enum class PixelLayout : uint32_t + { + Palette = 0, + HighColor = 1, + TrueColor = 2, + Compressed = 3, + BumpMap = 4, + Default = 5, + }; + + enum class MipMapFormat : uint32_t + { + No = 0, + Yes = 1, + Default = 2, + }; + + enum class AlphaFormat : uint32_t + { + None = 0, + Binary = 1, + Smooth = 2, + Default = 3, + }; + + struct FormatPrefs + { + PixelLayout mPixelLayout; + MipMapFormat mUseMipMaps; + AlphaFormat mAlphaFormat; + }; + + char mExternal; // References external file + + std::string mFile; + NiPixelDataPtr mData; + + FormatPrefs mPrefs; + + char mIsStatic{ 1 }; + bool mDirectRendering{ true }; + bool mPersistRenderData{ false }; + + void read(NIFStream* nif) override; + void post(Reader& nif) override; + }; + + struct BSShaderTextureSet : public Record + { + enum class TextureType : uint32_t + { + Base = 0, + Normal = 1, + Glow = 2, + Parallax = 3, + Environment = 4, + EnvironmentMask = 5, + Subsurface = 6, + BackLighting = 7, + }; + std::vector mTextures; + + void read(NIFStream* nif) override; + }; + +} +#endif diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 251795eb21..0c85949a53 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -305,7 +305,7 @@ namespace NifBullet // Check for extra data std::vector extraCollection; - for (Nif::ExtraPtr e = node.extra; !e.empty(); e = e->next) + for (Nif::ExtraPtr e = node.extra; !e.empty(); e = e->mNext) extraCollection.emplace_back(e); for (const auto& extraNode : node.extralist) if (!extraNode.empty()) @@ -316,29 +316,30 @@ namespace NifBullet { // String markers may contain important information // affecting the entire subtree of this node - Nif::NiStringExtraData* sd = (Nif::NiStringExtraData*)e.getPtr(); + auto sd = static_cast(e.getPtr()); - if (Misc::StringUtils::ciStartsWith(sd->string, "NC")) + if (Misc::StringUtils::ciStartsWith(sd->mData, "NC")) { // NCC flag in vanilla is partly case sensitive: prefix NC is case insensitive but second C needs be // uppercase - if (sd->string.length() > 2 && sd->string[2] == 'C') + if (sd->mData.length() > 2 && sd->mData[2] == 'C') // Collide only with camera. visualCollisionType = Resource::VisualCollisionType::Camera; else // No collision. visualCollisionType = Resource::VisualCollisionType::Default; } - else if (sd->string == "MRK" && args.mAutogenerated) + // Don't autogenerate collision if MRK is set. + // FIXME: verify if this covers the entire subtree + else if (sd->mData == "MRK" && args.mAutogenerated) { - // Marker can still have collision if the model explicitely specifies it via a RootCollisionNode. return; } } else if (e->recType == Nif::RC_BSXFlags) { auto bsxFlags = static_cast(e.getPtr()); - if (bsxFlags->data & 32) // Editor marker flag + if (bsxFlags->mData & 32) // Editor marker flag args.mHasMarkers = true; } } diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 2e2d0293e6..dde4f261e2 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -42,13 +42,14 @@ #include #include -#include #include #include #include #include #include +#include #include +#include #include #include #include @@ -174,16 +175,16 @@ namespace void extractTextKeys(const Nif::NiTextKeyExtraData* tk, SceneUtil::TextKeyMap& textkeys) { - for (size_t i = 0; i < tk->list.size(); i++) + for (const Nif::NiTextKeyExtraData::TextKey& key : tk->mList) { std::vector results; - Misc::StringUtils::split(tk->list[i].text, results, "\r\n"); + Misc::StringUtils::split(key.mText, results, "\r\n"); for (std::string& result : results) { Misc::StringUtils::trim(result); Misc::StringUtils::lowerCaseInPlace(result); if (!result.empty()) - textkeys.emplace(tk->list[i].time, std::move(result)); + textkeys.emplace(key.mTime, std::move(result)); } } } @@ -285,9 +286,9 @@ namespace NifOsg extractTextKeys(static_cast(extra.getPtr()), target.mTextKeys); - extra = extra->next; + extra = extra->mNext; Nif::ControllerPtr ctrl = seq->controller; - for (; !extra.empty() && !ctrl.empty(); (extra = extra->next), (ctrl = ctrl->next)) + for (; !extra.empty() && !ctrl.empty(); (extra = extra->mNext), (ctrl = ctrl->next)) { if (extra->recType != Nif::RC_NiStringExtraData || ctrl->recType != Nif::RC_NiKeyframeController) { @@ -315,8 +316,8 @@ namespace NifOsg osg::ref_ptr callback = new NifOsg::KeyframeController(key); setupController(key, callback, /*animflags*/ 0); - if (!target.mKeyframeControllers.emplace(strdata->string, callback).second) - Log(Debug::Verbose) << "Controller " << strdata->string << " present more than once in " + if (!target.mKeyframeControllers.emplace(strdata->mData, callback).second) + Log(Debug::Verbose) << "Controller " << strdata->mData << " present more than once in " << nif.getFilename() << ", ignoring later version"; } } @@ -509,15 +510,15 @@ namespace NifOsg return nullptr; osg::ref_ptr image; - if (!st->external && !st->data.empty()) + if (st->mExternal) { - image = handleInternalTexture(st->data.getPtr()); - } - else - { - std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, imageManager->getVFS()); + std::string filename = Misc::ResourceHelpers::correctTexturePath(st->mFile, imageManager->getVFS()); image = imageManager->getImage(filename); } + else if (!st->mData.empty()) + { + image = handleInternalTexture(st->mData.getPtr()); + } return image; } @@ -536,38 +537,41 @@ namespace NifOsg } const Nif::NiTextureEffect* textureEffect = static_cast(nifNode); - if (textureEffect->textureType != Nif::NiTextureEffect::Environment_Map) + if (!textureEffect->mSwitchState) + return false; + + if (textureEffect->mTextureType != Nif::NiTextureEffect::TextureType::EnvironmentMap) { - Log(Debug::Info) << "Unhandled NiTextureEffect type " << textureEffect->textureType << " in " - << mFilename; + Log(Debug::Info) << "Unhandled NiTextureEffect type " + << static_cast(textureEffect->mTextureType) << " in " << mFilename; return false; } - if (textureEffect->texture.empty()) + if (textureEffect->mTexture.empty()) { Log(Debug::Info) << "NiTextureEffect missing source texture in " << mFilename; return false; } osg::ref_ptr texGen(new osg::TexGen); - switch (textureEffect->coordGenType) + switch (textureEffect->mCoordGenType) { - case Nif::NiTextureEffect::World_Parallel: + case Nif::NiTextureEffect::CoordGenType::WorldParallel: texGen->setMode(osg::TexGen::OBJECT_LINEAR); break; - case Nif::NiTextureEffect::World_Perspective: + case Nif::NiTextureEffect::CoordGenType::WorldPerspective: texGen->setMode(osg::TexGen::EYE_LINEAR); break; - case Nif::NiTextureEffect::Sphere_Map: + case Nif::NiTextureEffect::CoordGenType::SphereMap: texGen->setMode(osg::TexGen::SPHERE_MAP); break; default: - Log(Debug::Info) << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType - << " in " << mFilename; + Log(Debug::Info) << "Unhandled NiTextureEffect CoordGenType " + << static_cast(textureEffect->mCoordGenType) << " in " << mFilename; return false; } - osg::ref_ptr image(handleSourceTexture(textureEffect->texture.getPtr(), imageManager)); + osg::ref_ptr image(handleSourceTexture(textureEffect->mTexture.getPtr(), imageManager)); osg::ref_ptr texture2d(new osg::Texture2D(image)); if (image) texture2d->setTextureSize(image->s(), image->t()); @@ -644,7 +648,7 @@ namespace NifOsg std::vector extraCollection; - for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next) + for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->mNext) extraCollection.emplace_back(e); for (const auto& extraNode : nifNode->extralist) @@ -666,25 +670,25 @@ namespace NifOsg // String markers may contain important information // affecting the entire subtree of this obj - if (sd->string == "MRK" && !Loader::getShowMarkers()) + if (sd->mData == "MRK" && !Loader::getShowMarkers()) { // Marker objects. These meshes are only visible in the editor. args.mHasMarkers = true; } - else if (sd->string == "BONE") + else if (sd->mData == "BONE") { node->getOrCreateUserDataContainer()->addDescription("CustomBone"); } - else if (sd->string.rfind(extraDataIdentifer, 0) == 0) + else if (sd->mData.rfind(extraDataIdentifer, 0) == 0) { node->setUserValue( - Misc::OsgUserValues::sExtraData, sd->string.substr(extraDataIdentifer.length())); + Misc::OsgUserValues::sExtraData, sd->mData.substr(extraDataIdentifer.length())); } } else if (e->recType == Nif::RC_BSXFlags) { auto bsxFlags = static_cast(e.getPtr()); - if (bsxFlags->data & 32) // Editor marker flag + if (bsxFlags->mData & 32) // Editor marker flag args.mHasMarkers = true; } } @@ -895,7 +899,7 @@ namespace NifOsg if (!key->mInterpolator.empty() && key->mInterpolator->recType != Nif::RC_NiTransformInterpolator) { Log(Debug::Error) << "Unsupported interpolator type for NiKeyframeController " << key->recIndex - << " in " << mFilename; + << " in " << mFilename << ": " << key->mInterpolator->recName; continue; } osg::ref_ptr callback = new KeyframeController(key); @@ -922,7 +926,7 @@ namespace NifOsg && visctrl->mInterpolator->recType != Nif::RC_NiBoolInterpolator) { Log(Debug::Error) << "Unsupported interpolator type for NiVisController " << visctrl->recIndex - << " in " << mFilename; + << " in " << mFilename << ": " << visctrl->mInterpolator->recName; continue; } osg::ref_ptr callback(new VisController(visctrl, Loader::getHiddenNodeMask())); @@ -938,7 +942,7 @@ namespace NifOsg && rollctrl->mInterpolator->recType != Nif::RC_NiFloatInterpolator) { Log(Debug::Error) << "Unsupported interpolator type for NiRollController " << rollctrl->recIndex - << " in " << mFilename; + << " in " << mFilename << ": " << rollctrl->mInterpolator->recName; continue; } osg::ref_ptr callback = new RollController(rollctrl); @@ -973,8 +977,9 @@ namespace NifOsg if (!alphactrl->mInterpolator.empty() && alphactrl->mInterpolator->recType != Nif::RC_NiFloatInterpolator) { - Log(Debug::Error) << "Unsupported interpolator type for NiAlphaController " - << alphactrl->recIndex << " in " << mFilename; + Log(Debug::Error) + << "Unsupported interpolator type for NiAlphaController " << alphactrl->recIndex << " in " + << mFilename << ": " << alphactrl->mInterpolator->recName; continue; } osg::ref_ptr osgctrl = new AlphaController(alphactrl, baseMaterial); @@ -994,8 +999,9 @@ namespace NifOsg if (!matctrl->mInterpolator.empty() && matctrl->mInterpolator->recType != Nif::RC_NiPoint3Interpolator) { - Log(Debug::Error) << "Unsupported interpolator type for NiMaterialColorController " - << matctrl->recIndex << " in " << mFilename; + Log(Debug::Error) + << "Unsupported interpolator type for NiMaterialColorController " << matctrl->recIndex + << " in " << mFilename << ": " << matctrl->mInterpolator->recName; continue; } osg::ref_ptr osgctrl = new MaterialColorController(matctrl, baseMaterial); @@ -1021,7 +1027,7 @@ namespace NifOsg && flipctrl->mInterpolator->recType != Nif::RC_NiFloatInterpolator) { Log(Debug::Error) << "Unsupported interpolator type for NiFlipController " << flipctrl->recIndex - << " in " << mFilename; + << " in " << mFilename << ": " << flipctrl->mInterpolator->recName; continue; } std::vector> textures; @@ -1067,12 +1073,12 @@ namespace NifOsg attachTo->addChild(program); program->setParticleSystem(partsys); program->setReferenceFrame(rf); - for (; !affectors.empty(); affectors = affectors->next) + for (; !affectors.empty(); affectors = affectors->mNext) { if (affectors->recType == Nif::RC_NiParticleGrowFade) { const Nif::NiParticleGrowFade* gf = static_cast(affectors.getPtr()); - program->addOperator(new GrowFadeAffector(gf->growTime, gf->fadeTime)); + program->addOperator(new GrowFadeAffector(gf->mGrowTime, gf->mFadeTime)); } else if (affectors->recType == Nif::RC_NiGravity) { @@ -1083,9 +1089,9 @@ namespace NifOsg { const Nif::NiParticleColorModifier* cl = static_cast(affectors.getPtr()); - if (cl->data.empty()) + if (cl->mData.empty()) continue; - const Nif::NiColorData* clrdata = cl->data.getPtr(); + const Nif::NiColorData* clrdata = cl->mData.getPtr(); program->addOperator(new ParticleColorAffector(clrdata)); } else if (affectors->recType == Nif::RC_NiParticleRotation) @@ -1095,7 +1101,7 @@ namespace NifOsg else Log(Debug::Info) << "Unhandled particle modifier " << affectors->recName << " in " << mFilename; } - for (; !colliders.empty(); colliders = colliders->next) + for (; !colliders.empty(); colliders = colliders->mNext) { if (colliders->recType == Nif::RC_NiPlanarCollider) { @@ -2008,15 +2014,15 @@ namespace NifOsg const unsigned int uvSet = 0; - for (size_t i = 0; i < textureSet->textures.size(); ++i) + for (size_t i = 0; i < textureSet->mTextures.size(); ++i) { - if (textureSet->textures[i].empty()) + if (textureSet->mTextures[i].empty()) continue; - switch (i) + switch (static_cast(i)) { - case Nif::BSShaderTextureSet::TextureType_Base: - case Nif::BSShaderTextureSet::TextureType_Normal: - case Nif::BSShaderTextureSet::TextureType_Glow: + case Nif::BSShaderTextureSet::TextureType::Base: + case Nif::BSShaderTextureSet::TextureType::Normal: + case Nif::BSShaderTextureSet::TextureType::Glow: break; default: { @@ -2026,7 +2032,7 @@ namespace NifOsg } } std::string filename - = Misc::ResourceHelpers::correctTexturePath(textureSet->textures[i], imageManager->getVFS()); + = Misc::ResourceHelpers::correctTexturePath(textureSet->mTextures[i], imageManager->getVFS()); osg::ref_ptr image = imageManager->getImage(filename); osg::ref_ptr texture2d = new osg::Texture2D(image); if (image) @@ -2035,17 +2041,19 @@ namespace NifOsg unsigned int texUnit = boundTextures.size(); stateset->setTextureAttributeAndModes(texUnit, texture2d, osg::StateAttribute::ON); // BSShaderTextureSet presence means there's no need for FFP support for the affected node - switch (i) + switch (static_cast(i)) { - case Nif::BSShaderTextureSet::TextureType_Base: + case Nif::BSShaderTextureSet::TextureType::Base: texture2d->setName("diffuseMap"); break; - case Nif::BSShaderTextureSet::TextureType_Normal: + case Nif::BSShaderTextureSet::TextureType::Normal: texture2d->setName("normalMap"); break; - case Nif::BSShaderTextureSet::TextureType_Glow: + case Nif::BSShaderTextureSet::TextureType::Glow: texture2d->setName("emissiveMap"); break; + default: + break; } boundTextures.emplace_back(uvSet); } diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 2700b7eb93..8be0d4ba4f 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -281,20 +280,13 @@ namespace NifOsg GravityAffector::GravityAffector(const Nif::NiGravity* gravity) : mForce(gravity->mForce) - , mType(static_cast(gravity->mType)) + , mType(gravity->mType) , mPosition(gravity->mPosition) , mDirection(gravity->mDirection) , mDecay(gravity->mDecay) { } - GravityAffector::GravityAffector() - : mForce(0) - , mType(Type_Wind) - , mDecay(0.f) - { - } - GravityAffector::GravityAffector(const GravityAffector& copy, const osg::CopyOp& copyop) : osgParticle::Operator(copy, copyop) { @@ -311,8 +303,8 @@ namespace NifOsg { bool absolute = (program->getReferenceFrame() == osgParticle::ParticleProcessor::ABSOLUTE_RF); - if (mType == Type_Point - || mDecay != 0.f) // we don't need the position for Wind gravity, except if decay is being applied + // We don't need the position for Wind gravity, except if decay is being applied + if (mType == Nif::NiGravity::ForceType::Point || mDecay != 0.f) mCachedWorldPosition = absolute ? program->transformLocalToWorld(mPosition) : mPosition; mCachedWorldDirection = absolute ? program->rotateLocalToWorld(mDirection) : mDirection; @@ -324,7 +316,7 @@ namespace NifOsg const float magic = 1.6f; switch (mType) { - case Type_Wind: + case Nif::NiGravity::ForceType::Wind: { float decayFactor = 1.f; if (mDecay != 0.f) @@ -338,7 +330,7 @@ namespace NifOsg break; } - case Type_Point: + case Nif::NiGravity::ForceType::Point: { osg::Vec3f diff = mCachedWorldPosition - particle->getPosition(); diff --git a/components/nifosg/particle.hpp b/components/nifosg/particle.hpp index 3424512208..a9b628f695 100644 --- a/components/nifosg/particle.hpp +++ b/components/nifosg/particle.hpp @@ -10,15 +10,14 @@ #include #include +#include // NiGravity::ForceType + #include #include "controller.hpp" // ValueInterpolator namespace Nif { - struct NiGravity; - struct NiPlanarCollider; - struct NiSphericalCollider; struct NiColorData; } @@ -180,7 +179,7 @@ namespace NifOsg { public: GravityAffector(const Nif::NiGravity* gravity); - GravityAffector(); + GravityAffector() = default; GravityAffector(const GravityAffector& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); GravityAffector& operator=(const GravityAffector&) = delete; @@ -191,16 +190,11 @@ namespace NifOsg void beginOperate(osgParticle::Program*) override; private: - float mForce; - enum ForceType - { - Type_Wind, - Type_Point - }; - ForceType mType; + float mForce{ 0.f }; + Nif::NiGravity::ForceType mType{ Nif::NiGravity::ForceType::Wind }; osg::Vec3f mPosition; osg::Vec3f mDirection; - float mDecay; + float mDecay{ 0.f }; osg::Vec3f mCachedWorldPosition; osg::Vec3f mCachedWorldDirection; };