mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-19 16:21:08 +00:00
Merge branch 'nif' into 'master'
Modernize NIF loader, part 1 See merge request OpenMW/openmw!3394
This commit is contained in:
commit
ccc465db27
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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<std::string> 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
|
@ -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
|
||||
{
|
||||
|
@ -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<uint32_t>();
|
||||
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<uint32_t>();
|
||||
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<TextureType>(nif->get<uint32_t>());
|
||||
mCoordGenType = static_cast<CoordGenType>(nif->get<uint32_t>());
|
||||
mTexture.read(nif);
|
||||
nif->read(mEnableClipPlane);
|
||||
mClipPlane = osg::Plane(nif->get<osg::Vec4f>());
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<uint16_t>() * 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<uint16_t>() / 1000.f;
|
||||
float rotY = nif->get<uint16_t>() / 1000.f;
|
||||
float rotZ = nif->get<uint16_t>() / 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 <typename T>
|
||||
struct TypedExtra : public Extra
|
||||
{
|
||||
T mData;
|
||||
|
||||
void read(NIFStream* nif) override
|
||||
{
|
||||
Extra::read(nif);
|
||||
|
||||
nif->read(mData);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TypedVectorExtra : public Extra
|
||||
{
|
||||
std::vector<T> mData;
|
||||
|
||||
void read(NIFStream* nif) override
|
||||
{
|
||||
Extra::read(nif);
|
||||
|
||||
nif->readVector(mData, nif->get<uint32_t>());
|
||||
}
|
||||
};
|
||||
|
||||
using NiBooleanExtraData = TypedExtra<bool>;
|
||||
using NiFloatExtraData = TypedExtra<float>;
|
||||
using NiIntegerExtraData = TypedExtra<uint32_t>;
|
||||
using NiStringExtraData = TypedExtra<std::string>;
|
||||
using NiVectorExtraData = TypedExtra<osg::Vec4f>;
|
||||
|
||||
using NiBinaryExtraData = TypedVectorExtra<uint8_t>;
|
||||
using NiFloatsExtraData = TypedVectorExtra<float>;
|
||||
using NiIntegersExtraData = TypedVectorExtra<uint32_t>;
|
||||
|
||||
// Distinct from NiBinaryExtraData, uses mRecordSize as its size
|
||||
struct NiExtraData : public Extra
|
||||
{
|
||||
std::vector<char> data;
|
||||
std::vector<uint8_t> 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<TextKey> 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<unsigned int> data;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiBinaryExtraData : public Extra
|
||||
{
|
||||
std::vector<char> 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<float> data;
|
||||
std::vector<TextKey> 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
|
||||
|
@ -10,15 +10,16 @@
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#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
|
||||
{
|
||||
|
95
components/nif/particle.cpp
Normal file
95
components/nif/particle.cpp
Normal file
@ -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<ForceType>(nif->get<uint32_t>());
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
90
components/nif/particle.hpp
Normal file
90
components/nif/particle.hpp
Normal file
@ -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
|
@ -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<BroadPhaseType>(nif->getChar());
|
||||
mPhaseType = static_cast<BroadPhaseType>(nif->get<uint8_t>());
|
||||
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<hkResponseType>(nif->getChar());
|
||||
mResponseType = static_cast<hkResponseType>(nif->get<uint8_t>());
|
||||
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<uint32_t>());
|
||||
nif->readVector(mIndices, nif->get<uint32_t>());
|
||||
nif->readVector(mStrips, nif->get<uint32_t>());
|
||||
nif->readVector(mWeldingInfos, nif->get<uint32_t>());
|
||||
}
|
||||
|
||||
void bhkRigidBodyCInfo::read(NIFStream* nif)
|
||||
@ -115,64 +114,67 @@ namespace Nif
|
||||
{
|
||||
if (nif->getBethVersion() >= 83)
|
||||
nif->skip(4); // Unused
|
||||
mResponseType = static_cast<hkResponseType>(nif->getChar());
|
||||
mResponseType = static_cast<hkResponseType>(nif->get<uint8_t>());
|
||||
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<hkMotionType>(nif->getChar());
|
||||
mMotionType = static_cast<hkMotionType>(nif->get<uint8_t>());
|
||||
if (nif->getBethVersion() < 83)
|
||||
mDeactivatorType = static_cast<hkDeactivatorType>(nif->getChar());
|
||||
mDeactivatorType = static_cast<hkDeactivatorType>(nif->get<uint8_t>());
|
||||
else
|
||||
mEnableDeactivation = nif->getBoolean();
|
||||
mSolverDeactivation = static_cast<hkSolverDeactivation>(nif->getChar());
|
||||
nif->read(mEnableDeactivation);
|
||||
mSolverDeactivation = static_cast<hkSolverDeactivation>(nif->get<uint8_t>());
|
||||
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<hkResponseType>(nif->getChar());
|
||||
mResponseType = static_cast<hkResponseType>(nif->get<uint8_t>());
|
||||
nif->skip(1); // Unused
|
||||
mProcessContactDelay = nif->getUShort();
|
||||
nif->read(mProcessContactDelay);
|
||||
}
|
||||
mQualityType = static_cast<hkQualityType>(nif->getChar());
|
||||
mQualityType = static_cast<hkQualityType>(nif->get<uint8_t>());
|
||||
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<unsigned int>(); // Number of entities, unused
|
||||
nif->get<uint32_t>(); // 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<uint32_t>());
|
||||
nif->readVector(mNormals, nif->get<uint32_t>());
|
||||
}
|
||||
|
||||
void bhkConvexTransformShape::read(NIFStream* nif)
|
||||
{
|
||||
mShape.read(nif);
|
||||
mHavokMaterial.read(nif);
|
||||
mRadius = nif->getFloat();
|
||||
nif->read(mRadius);
|
||||
nif->skip(8); // Unused
|
||||
std::array<float, 16> 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<uint32_t>() * 4); // Unused
|
||||
nif->skip(nif->get<uint32_t>() * 4); // Unused
|
||||
nif->skip(nif->get<uint32_t>() * 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<uint32_t>());
|
||||
|
||||
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<uint16_t>();
|
||||
}
|
||||
|
||||
void bhkSimpleShapePhantom::read(NIFStream* nif)
|
||||
{
|
||||
bhkWorldObject::read(nif);
|
||||
|
||||
nif->skip(8); // Unused
|
||||
std::array<float, 16> 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);
|
||||
}
|
||||
|
||||
|
@ -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<char> mData;
|
||||
uint8_t mBuildType;
|
||||
std::vector<uint8_t> mData;
|
||||
|
||||
void read(NIFStream* nif);
|
||||
};
|
||||
|
||||
struct TriangleData
|
||||
{
|
||||
unsigned short mTriangle[3];
|
||||
unsigned short mWeldingInfo;
|
||||
std::array<uint16_t, 3> 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<uint16_t, 3> 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<unsigned short> mVertices;
|
||||
std::vector<unsigned short> mIndices;
|
||||
std::vector<unsigned short> mStrips;
|
||||
std::vector<unsigned short> mWeldingInfos;
|
||||
uint32_t mMaterialIndex;
|
||||
uint16_t mReference;
|
||||
uint16_t mTransformIndex;
|
||||
std::vector<uint16_t> mVertices;
|
||||
std::vector<uint16_t> mIndices;
|
||||
std::vector<uint16_t> mStrips;
|
||||
std::vector<uint16_t> 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<unsigned int> mFilters;
|
||||
std::vector<HavokFilter> mHavokFilters;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
@ -420,7 +450,7 @@ namespace Nif
|
||||
struct bhkPackedNiTriStripsShape : public bhkShapeCollection
|
||||
{
|
||||
std::vector<hkSubPartData> mSubshapes;
|
||||
unsigned int mUserData;
|
||||
uint32_t mUserData;
|
||||
float mRadius;
|
||||
osg::Vec4f mScale;
|
||||
hkPackedNiTriStripsDataPtr mData;
|
||||
@ -435,6 +465,7 @@ namespace Nif
|
||||
std::vector<TriangleData> mTriangles;
|
||||
std::vector<osg::Vec3f> mVertices;
|
||||
std::vector<hkSubPartData> 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<osg::Vec4f> mVertices;
|
||||
std::vector<osg::Vec4f> 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<HavokFilter> 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<bhkMeshMaterial> mMaterials;
|
||||
std::vector<bhkQsTransform> mChunkTransforms;
|
||||
std::vector<osg::Vec4f> 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;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "property.hpp"
|
||||
|
||||
#include "controlled.hpp"
|
||||
#include "data.hpp"
|
||||
#include "texture.hpp"
|
||||
|
||||
namespace Nif
|
||||
{
|
||||
|
47
components/nif/texture.cpp
Normal file
47
components/nif/texture.cpp
Normal file
@ -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<PixelLayout>(nif->get<uint32_t>());
|
||||
mPrefs.mUseMipMaps = static_cast<MipMapFormat>(nif->get<uint32_t>());
|
||||
mPrefs.mAlphaFormat = static_cast<AlphaFormat>(nif->get<uint32_t>());
|
||||
|
||||
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<uint32_t>());
|
||||
}
|
||||
|
||||
}
|
81
components/nif/texture.hpp
Normal file
81
components/nif/texture.hpp
Normal file
@ -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<std::string> mTextures;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -305,7 +305,7 @@ namespace NifBullet
|
||||
|
||||
// Check for extra data
|
||||
std::vector<Nif::ExtraPtr> 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<const Nif::NiStringExtraData*>(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<const Nif::NiIntegerExtraData*>(e.getPtr());
|
||||
if (bsxFlags->data & 32) // Editor marker flag
|
||||
if (bsxFlags->mData & 32) // Editor marker flag
|
||||
args.mHasMarkers = true;
|
||||
}
|
||||
}
|
||||
|
@ -42,13 +42,14 @@
|
||||
#include <osg/TexEnvCombine>
|
||||
#include <osg/Texture2D>
|
||||
|
||||
#include <components/nif/controlled.hpp>
|
||||
#include <components/nif/effect.hpp>
|
||||
#include <components/nif/exception.hpp>
|
||||
#include <components/nif/extra.hpp>
|
||||
#include <components/nif/niffile.hpp>
|
||||
#include <components/nif/node.hpp>
|
||||
#include <components/nif/particle.hpp>
|
||||
#include <components/nif/property.hpp>
|
||||
#include <components/nif/texture.hpp>
|
||||
#include <components/sceneutil/depth.hpp>
|
||||
#include <components/sceneutil/morphgeometry.hpp>
|
||||
#include <components/sceneutil/riggeometry.hpp>
|
||||
@ -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<std::string> 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<const Nif::NiTextKeyExtraData*>(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<SceneUtil::KeyframeController> 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<osg::Image> 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<const Nif::NiTextureEffect*>(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<uint32_t>(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<osg::TexGen> 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<uint32_t>(textureEffect->mCoordGenType) << " in " << mFilename;
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Image> image(handleSourceTexture(textureEffect->texture.getPtr(), imageManager));
|
||||
osg::ref_ptr<osg::Image> image(handleSourceTexture(textureEffect->mTexture.getPtr(), imageManager));
|
||||
osg::ref_ptr<osg::Texture2D> texture2d(new osg::Texture2D(image));
|
||||
if (image)
|
||||
texture2d->setTextureSize(image->s(), image->t());
|
||||
@ -644,7 +648,7 @@ namespace NifOsg
|
||||
|
||||
std::vector<Nif::ExtraPtr> 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<const Nif::NiIntegerExtraData*>(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<KeyframeController> 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<VisController> 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<RollController> 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<AlphaController> 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<MaterialColorController> 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<osg::ref_ptr<osg::Texture2D>> 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<const Nif::NiParticleGrowFade*>(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<const Nif::NiParticleColorModifier*>(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<Nif::BSShaderTextureSet::TextureType>(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<osg::Image> image = imageManager->getImage(filename);
|
||||
osg::ref_ptr<osg::Texture2D> 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<Nif::BSShaderTextureSet::TextureType>(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);
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/misc/rng.hpp>
|
||||
#include <components/nif/controlled.hpp>
|
||||
#include <components/nif/data.hpp>
|
||||
#include <components/sceneutil/morphgeometry.hpp>
|
||||
#include <components/sceneutil/riggeometry.hpp>
|
||||
@ -281,20 +280,13 @@ namespace NifOsg
|
||||
|
||||
GravityAffector::GravityAffector(const Nif::NiGravity* gravity)
|
||||
: mForce(gravity->mForce)
|
||||
, mType(static_cast<ForceType>(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();
|
||||
|
||||
|
@ -10,15 +10,14 @@
|
||||
#include <osgParticle/Placer>
|
||||
#include <osgParticle/Shooter>
|
||||
|
||||
#include <components/nif/particle.hpp> // NiGravity::ForceType
|
||||
|
||||
#include <components/sceneutil/nodecallback.hpp>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user