mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-28 23:36:42 +00:00
Merge branch 'this_is_nife' into 'master'
More NIF stuff See merge request OpenMW/openmw!461
This commit is contained in:
commit
78e85fe011
14 changed files with 269 additions and 199 deletions
|
@ -259,14 +259,19 @@ namespace
|
||||||
value.isBone = false;
|
value.isBone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(Nif::NiTriShape& value)
|
void init(Nif::NiGeometry& value)
|
||||||
{
|
{
|
||||||
init(static_cast<Nif::Node&>(value));
|
init(static_cast<Nif::Node&>(value));
|
||||||
value.recType = Nif::RC_NiTriShape;
|
value.data = Nif::NiGeometryDataPtr(nullptr);
|
||||||
value.data = Nif::NiTriShapeDataPtr(nullptr);
|
|
||||||
value.skin = Nif::NiSkinInstancePtr(nullptr);
|
value.skin = Nif::NiSkinInstancePtr(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(Nif::NiTriShape& value)
|
||||||
|
{
|
||||||
|
init(static_cast<Nif::NiGeometry&>(value));
|
||||||
|
value.recType = Nif::RC_NiTriShape;
|
||||||
|
}
|
||||||
|
|
||||||
void init(Nif::NiSkinInstance& value)
|
void init(Nif::NiSkinInstance& value)
|
||||||
{
|
{
|
||||||
value.data = Nif::NiSkinDataPtr(nullptr);
|
value.data = Nif::NiSkinDataPtr(nullptr);
|
||||||
|
@ -361,13 +366,15 @@ namespace
|
||||||
init(mNiStringExtraData2);
|
init(mNiStringExtraData2);
|
||||||
init(mController);
|
init(mController);
|
||||||
|
|
||||||
|
mNiTriShapeData.recType = Nif::RC_NiTriShapeData;
|
||||||
mNiTriShapeData.vertices = {osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0)};
|
mNiTriShapeData.vertices = {osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0)};
|
||||||
mNiTriShapeData.triangles = {0, 1, 2};
|
mNiTriShapeData.triangles = {0, 1, 2};
|
||||||
mNiTriShape.data = Nif::NiTriShapeDataPtr(&mNiTriShapeData);
|
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||||
|
|
||||||
|
mNiTriShapeData2.recType = Nif::RC_NiTriShapeData;
|
||||||
mNiTriShapeData2.vertices = {osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1)};
|
mNiTriShapeData2.vertices = {osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1)};
|
||||||
mNiTriShapeData2.triangles = {0, 1, 2};
|
mNiTriShapeData2.triangles = {0, 1, 2};
|
||||||
mNiTriShape2.data = Nif::NiTriShapeDataPtr(&mNiTriShapeData2);
|
mNiTriShape2.data = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -873,7 +880,7 @@ namespace
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_empty_data_should_return_shape_with_null_collision_shape)
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_empty_data_should_return_shape_with_null_collision_shape)
|
||||||
{
|
{
|
||||||
mNiTriShape.data = Nif::NiTriShapeDataPtr(nullptr);
|
mNiTriShape.data = Nif::NiGeometryDataPtr(nullptr);
|
||||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
@ -888,7 +895,8 @@ namespace
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_empty_data_triangles_should_return_shape_with_null_collision_shape)
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_empty_data_triangles_should_return_shape_with_null_collision_shape)
|
||||||
{
|
{
|
||||||
mNiTriShape.data->triangles.clear();
|
auto data = static_cast<Nif::NiTriShapeData*>(mNiTriShape.data.getPtr());
|
||||||
|
data->triangles.clear();
|
||||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
|
|
@ -47,6 +47,11 @@ namespace Nif
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BSShaderTextureSet::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
nif->getSizedStrings(textures, nif->getUInt());
|
||||||
|
}
|
||||||
|
|
||||||
void NiParticleModifier::read(NIFStream *nif)
|
void NiParticleModifier::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
next.read(nif);
|
next.read(nif);
|
||||||
|
|
|
@ -66,6 +66,24 @@ public:
|
||||||
void post(NIFFile *nif) override;
|
void post(NIFFile *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
|
struct NiParticleModifier : public Record
|
||||||
{
|
{
|
||||||
NiParticleModifierPtr next;
|
NiParticleModifierPtr next;
|
||||||
|
|
|
@ -325,4 +325,15 @@ namespace Nif
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NiColorInterpolator::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
defaultVal = nif->getVector4();
|
||||||
|
data.read(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiColorInterpolator::post(NIFFile *nif)
|
||||||
|
{
|
||||||
|
data.post(nif);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
float lifetime;
|
float lifetime;
|
||||||
float lifespan;
|
float lifespan;
|
||||||
float timestamp;
|
float timestamp;
|
||||||
int vertex;
|
unsigned short vertex;
|
||||||
};
|
};
|
||||||
|
|
||||||
float velocity;
|
float velocity;
|
||||||
|
@ -230,5 +230,13 @@ struct NiTransformInterpolator : public Interpolator
|
||||||
void post(NIFFile *nif) override;
|
void post(NIFFile *nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NiColorInterpolator : public Interpolator
|
||||||
|
{
|
||||||
|
osg::Vec4f defaultVal;
|
||||||
|
NiColorDataPtr data;
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
void post(NIFFile *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -129,6 +129,10 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
|
||||||
factory["NiPoint3Interpolator"] = {&construct <NiPoint3Interpolator> , RC_NiPoint3Interpolator };
|
factory["NiPoint3Interpolator"] = {&construct <NiPoint3Interpolator> , RC_NiPoint3Interpolator };
|
||||||
factory["NiTransformController"] = {&construct <NiKeyframeController> , RC_NiKeyframeController };
|
factory["NiTransformController"] = {&construct <NiKeyframeController> , RC_NiKeyframeController };
|
||||||
factory["NiTransformInterpolator"] = {&construct <NiTransformInterpolator> , RC_NiTransformInterpolator };
|
factory["NiTransformInterpolator"] = {&construct <NiTransformInterpolator> , RC_NiTransformInterpolator };
|
||||||
|
factory["NiColorInterpolator"] = {&construct <NiColorInterpolator> , RC_NiColorInterpolator };
|
||||||
|
factory["BSShaderTextureSet"] = {&construct <BSShaderTextureSet> , RC_BSShaderTextureSet };
|
||||||
|
factory["BSLODTriShape"] = {&construct <BSLODTriShape> , RC_BSLODTriShape };
|
||||||
|
factory["BSShaderProperty"] = {&construct <BSShaderProperty> , RC_BSShaderProperty };
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -240,43 +240,6 @@ struct NiNode : Node
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiGeometry : Node
|
struct NiGeometry : Node
|
||||||
{
|
|
||||||
struct MaterialData
|
|
||||||
{
|
|
||||||
std::vector<std::string> materialNames;
|
|
||||||
std::vector<int> materialExtraData;
|
|
||||||
unsigned int activeMaterial{0};
|
|
||||||
bool materialNeedsUpdate{false};
|
|
||||||
void read(NIFStream *nif)
|
|
||||||
{
|
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(10,0,1,0))
|
|
||||||
return;
|
|
||||||
unsigned int numMaterials = 0;
|
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(20,1,0,3))
|
|
||||||
numMaterials = nif->getBoolean(); // Has Shader
|
|
||||||
else if (nif->getVersion() >= NIFStream::generateVersion(20,2,0,5))
|
|
||||||
numMaterials = nif->getUInt();
|
|
||||||
if (numMaterials)
|
|
||||||
{
|
|
||||||
nif->getStrings(materialNames, numMaterials);
|
|
||||||
nif->getInts(materialExtraData, numMaterials);
|
|
||||||
}
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(20,2,0,5))
|
|
||||||
activeMaterial = nif->getUInt();
|
|
||||||
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
|
|
||||||
{
|
|
||||||
materialNeedsUpdate = nif->getBoolean();
|
|
||||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
|
||||||
nif->skip(8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NiSkinInstancePtr skin;
|
|
||||||
MaterialData materialData;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NiTriShape : NiGeometry
|
|
||||||
{
|
{
|
||||||
/* Possible flags:
|
/* Possible flags:
|
||||||
0x40 - mesh has no vertex normals ?
|
0x40 - mesh has no vertex normals ?
|
||||||
|
@ -285,14 +248,50 @@ struct NiTriShape : NiGeometry
|
||||||
been observed so far.
|
been observed so far.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NiTriShapeDataPtr data;
|
struct MaterialData
|
||||||
|
{
|
||||||
|
std::vector<std::string> names;
|
||||||
|
std::vector<int> extra;
|
||||||
|
unsigned int active{0};
|
||||||
|
bool needsUpdate{false};
|
||||||
|
void read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
if (nif->getVersion() <= NIFStream::generateVersion(10,0,1,0))
|
||||||
|
return;
|
||||||
|
unsigned int num = 0;
|
||||||
|
if (nif->getVersion() <= NIFStream::generateVersion(20,1,0,3))
|
||||||
|
num = nif->getBoolean(); // Has Shader
|
||||||
|
else if (nif->getVersion() >= NIFStream::generateVersion(20,2,0,5))
|
||||||
|
num = nif->getUInt();
|
||||||
|
if (num)
|
||||||
|
{
|
||||||
|
nif->getStrings(names, num);
|
||||||
|
nif->getInts(extra, num);
|
||||||
|
}
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(20,2,0,5))
|
||||||
|
active = nif->getUInt();
|
||||||
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
|
||||||
|
needsUpdate = nif->getBoolean();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NiGeometryDataPtr data;
|
||||||
|
NiSkinInstancePtr skin;
|
||||||
|
MaterialData material;
|
||||||
|
BSShaderPropertyPtr shaderprop;
|
||||||
|
NiAlphaPropertyPtr alphaprop;
|
||||||
|
|
||||||
void read(NIFStream *nif) override
|
void read(NIFStream *nif) override
|
||||||
{
|
{
|
||||||
Node::read(nif);
|
Node::read(nif);
|
||||||
data.read(nif);
|
data.read(nif);
|
||||||
skin.read(nif);
|
skin.read(nif);
|
||||||
materialData.read(nif);
|
material.read(nif);
|
||||||
|
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
||||||
|
{
|
||||||
|
shaderprop.read(nif);
|
||||||
|
alphaprop.read(nif);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void post(NIFFile *nif) override
|
void post(NIFFile *nif) override
|
||||||
|
@ -300,53 +299,28 @@ struct NiTriShape : NiGeometry
|
||||||
Node::post(nif);
|
Node::post(nif);
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
skin.post(nif);
|
skin.post(nif);
|
||||||
if (!skin.empty())
|
shaderprop.post(nif);
|
||||||
|
alphaprop.post(nif);
|
||||||
|
if (recType != RC_NiParticles && !skin.empty())
|
||||||
nif->setUseSkinning(true);
|
nif->setUseSkinning(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiTriStrips : NiGeometry
|
struct NiTriShape : NiGeometry {};
|
||||||
|
struct BSLODTriShape : NiTriShape
|
||||||
{
|
{
|
||||||
NiTriStripsDataPtr data;
|
unsigned int lod0, lod1, lod2;
|
||||||
|
|
||||||
void read(NIFStream *nif) override
|
void read(NIFStream *nif) override
|
||||||
{
|
{
|
||||||
Node::read(nif);
|
NiTriShape::read(nif);
|
||||||
data.read(nif);
|
lod0 = nif->getUInt();
|
||||||
skin.read(nif);
|
lod1 = nif->getUInt();
|
||||||
materialData.read(nif);
|
lod2 = nif->getUInt();
|
||||||
}
|
|
||||||
|
|
||||||
void post(NIFFile *nif) override
|
|
||||||
{
|
|
||||||
Node::post(nif);
|
|
||||||
data.post(nif);
|
|
||||||
skin.post(nif);
|
|
||||||
if (!skin.empty())
|
|
||||||
nif->setUseSkinning(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NiLines : NiGeometry
|
|
||||||
{
|
|
||||||
NiLinesDataPtr data;
|
|
||||||
|
|
||||||
void read(NIFStream *nif) override
|
|
||||||
{
|
|
||||||
Node::read(nif);
|
|
||||||
data.read(nif);
|
|
||||||
skin.read(nif);
|
|
||||||
}
|
|
||||||
|
|
||||||
void post(NIFFile *nif) override
|
|
||||||
{
|
|
||||||
Node::post(nif);
|
|
||||||
data.post(nif);
|
|
||||||
skin.post(nif);
|
|
||||||
if (!skin.empty())
|
|
||||||
nif->setUseSkinning(true);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
struct NiTriStrips : NiGeometry {};
|
||||||
|
struct NiLines : NiGeometry {};
|
||||||
|
struct NiParticles : NiGeometry { };
|
||||||
|
|
||||||
struct NiCamera : Node
|
struct NiCamera : Node
|
||||||
{
|
{
|
||||||
|
@ -401,25 +375,6 @@ struct NiCamera : Node
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiParticles : NiGeometry
|
|
||||||
{
|
|
||||||
NiParticlesDataPtr data;
|
|
||||||
void read(NIFStream *nif) override
|
|
||||||
{
|
|
||||||
Node::read(nif);
|
|
||||||
data.read(nif);
|
|
||||||
skin.read(nif);
|
|
||||||
materialData.read(nif);
|
|
||||||
}
|
|
||||||
|
|
||||||
void post(NIFFile *nif) override
|
|
||||||
{
|
|
||||||
Node::post(nif);
|
|
||||||
data.post(nif);
|
|
||||||
skin.post(nif);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A node used as the base to switch between child nodes, such as for LOD levels.
|
// A node used as the base to switch between child nodes, such as for LOD levels.
|
||||||
struct NiSwitchNode : public NiNode
|
struct NiSwitchNode : public NiNode
|
||||||
{
|
{
|
||||||
|
|
|
@ -99,6 +99,25 @@ void NiTexturingProperty::post(NIFFile *nif)
|
||||||
shaderTextures[i].post(nif);
|
shaderTextures[i].post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BSShaderProperty::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
NiShadeProperty::read(nif);
|
||||||
|
if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3)
|
||||||
|
{
|
||||||
|
type = nif->getUInt();
|
||||||
|
flags1 = nif->getUInt();
|
||||||
|
flags2 = nif->getUInt();
|
||||||
|
envMapIntensity = nif->getFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSShaderLightingProperty::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
BSShaderProperty::read(nif);
|
||||||
|
if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3)
|
||||||
|
clamp = nif->getUInt();
|
||||||
|
}
|
||||||
|
|
||||||
void NiFogProperty::read(NIFStream *nif)
|
void NiFogProperty::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
Property::read(nif);
|
Property::read(nif);
|
||||||
|
|
|
@ -118,6 +118,19 @@ struct NiShadeProperty : public Property
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BSShaderProperty : public NiShadeProperty
|
||||||
|
{
|
||||||
|
unsigned int type{0u}, flags1{0u}, flags2{0u};
|
||||||
|
float envMapIntensity{0.f};
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BSShaderLightingProperty : public BSShaderProperty
|
||||||
|
{
|
||||||
|
unsigned int clamp{0u};
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
struct NiDitherProperty : public Property
|
struct NiDitherProperty : public Property
|
||||||
{
|
{
|
||||||
unsigned short flags;
|
unsigned short flags;
|
||||||
|
|
|
@ -118,7 +118,11 @@ enum RecordType
|
||||||
RC_NiFloatInterpolator,
|
RC_NiFloatInterpolator,
|
||||||
RC_NiPoint3Interpolator,
|
RC_NiPoint3Interpolator,
|
||||||
RC_NiBoolInterpolator,
|
RC_NiBoolInterpolator,
|
||||||
RC_NiTransformInterpolator
|
RC_NiTransformInterpolator,
|
||||||
|
RC_NiColorInterpolator,
|
||||||
|
RC_BSShaderTextureSet,
|
||||||
|
RC_BSLODTriShape,
|
||||||
|
RC_BSShaderProperty
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for all records
|
/// Base class for all records
|
||||||
|
|
|
@ -134,19 +134,20 @@ struct NiMorphData;
|
||||||
class NiPixelData;
|
class NiPixelData;
|
||||||
class NiColorData;
|
class NiColorData;
|
||||||
struct NiKeyframeData;
|
struct NiKeyframeData;
|
||||||
class NiTriShapeData;
|
|
||||||
class NiTriStripsData;
|
class NiTriStripsData;
|
||||||
class NiSkinInstance;
|
class NiSkinInstance;
|
||||||
class NiSourceTexture;
|
class NiSourceTexture;
|
||||||
class NiParticlesData;
|
|
||||||
class NiPalette;
|
class NiPalette;
|
||||||
struct NiParticleModifier;
|
struct NiParticleModifier;
|
||||||
struct NiLinesData;
|
|
||||||
struct NiBoolData;
|
struct NiBoolData;
|
||||||
struct NiSkinPartition;
|
struct NiSkinPartition;
|
||||||
struct NiFloatInterpolator;
|
struct NiFloatInterpolator;
|
||||||
struct NiPoint3Interpolator;
|
struct NiPoint3Interpolator;
|
||||||
struct NiTransformInterpolator;
|
struct NiTransformInterpolator;
|
||||||
|
struct BSShaderTextureSet;
|
||||||
|
struct NiGeometryData;
|
||||||
|
struct BSShaderProperty;
|
||||||
|
class NiAlphaProperty;
|
||||||
|
|
||||||
using NodePtr = RecordPtrT<Node>;
|
using NodePtr = RecordPtrT<Node>;
|
||||||
using ExtraPtr = RecordPtrT<Extra>;
|
using ExtraPtr = RecordPtrT<Extra>;
|
||||||
|
@ -161,12 +162,8 @@ using NiPixelDataPtr = RecordPtrT<NiPixelData>;
|
||||||
using NiFloatDataPtr = RecordPtrT<NiFloatData>;
|
using NiFloatDataPtr = RecordPtrT<NiFloatData>;
|
||||||
using NiColorDataPtr = RecordPtrT<NiColorData>;
|
using NiColorDataPtr = RecordPtrT<NiColorData>;
|
||||||
using NiKeyframeDataPtr = RecordPtrT<NiKeyframeData>;
|
using NiKeyframeDataPtr = RecordPtrT<NiKeyframeData>;
|
||||||
using NiTriShapeDataPtr = RecordPtrT<NiTriShapeData>;
|
|
||||||
using NiTriStripsDataPtr = RecordPtrT<NiTriStripsData>;
|
|
||||||
using NiLinesDataPtr = RecordPtrT<NiLinesData>;
|
|
||||||
using NiSkinInstancePtr = RecordPtrT<NiSkinInstance>;
|
using NiSkinInstancePtr = RecordPtrT<NiSkinInstance>;
|
||||||
using NiSourceTexturePtr = RecordPtrT<NiSourceTexture>;
|
using NiSourceTexturePtr = RecordPtrT<NiSourceTexture>;
|
||||||
using NiParticlesDataPtr = RecordPtrT<NiParticlesData>;
|
|
||||||
using NiPalettePtr = RecordPtrT<NiPalette>;
|
using NiPalettePtr = RecordPtrT<NiPalette>;
|
||||||
using NiParticleModifierPtr = RecordPtrT<NiParticleModifier>;
|
using NiParticleModifierPtr = RecordPtrT<NiParticleModifier>;
|
||||||
using NiBoolDataPtr = RecordPtrT<NiBoolData>;
|
using NiBoolDataPtr = RecordPtrT<NiBoolData>;
|
||||||
|
@ -174,12 +171,17 @@ using NiSkinPartitionPtr = RecordPtrT<NiSkinPartition>;
|
||||||
using NiFloatInterpolatorPtr = RecordPtrT<NiFloatInterpolator>;
|
using NiFloatInterpolatorPtr = RecordPtrT<NiFloatInterpolator>;
|
||||||
using NiPoint3InterpolatorPtr = RecordPtrT<NiPoint3Interpolator>;
|
using NiPoint3InterpolatorPtr = RecordPtrT<NiPoint3Interpolator>;
|
||||||
using NiTransformInterpolatorPtr = RecordPtrT<NiTransformInterpolator>;
|
using NiTransformInterpolatorPtr = RecordPtrT<NiTransformInterpolator>;
|
||||||
|
using BSShaderTextureSetPtr = RecordPtrT<BSShaderTextureSet>;
|
||||||
|
using NiGeometryDataPtr = RecordPtrT<NiGeometryData>;
|
||||||
|
using BSShaderPropertyPtr = RecordPtrT<BSShaderProperty>;
|
||||||
|
using NiAlphaPropertyPtr = RecordPtrT<NiAlphaProperty>;
|
||||||
|
|
||||||
using NodeList = RecordListT<Node>;
|
using NodeList = RecordListT<Node>;
|
||||||
using PropertyList = RecordListT<Property>;
|
using PropertyList = RecordListT<Property>;
|
||||||
using ExtraList = RecordListT<Extra>;
|
using ExtraList = RecordListT<Extra>;
|
||||||
using NiSourceTextureList = RecordListT<NiSourceTexture>;
|
using NiSourceTextureList = RecordListT<NiSourceTexture>;
|
||||||
using NiFloatInterpolatorList = RecordListT<NiFloatInterpolator>;
|
using NiFloatInterpolatorList = RecordListT<NiFloatInterpolator>;
|
||||||
|
using NiTriStripsDataList = RecordListT<NiTriStripsData>;
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,11 +34,10 @@ bool pathFileNameStartsWithX(const std::string& path)
|
||||||
|
|
||||||
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriShapeData& data, const osg::Matrixf &transform)
|
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriShapeData& data, const osg::Matrixf &transform)
|
||||||
{
|
{
|
||||||
mesh.preallocateVertices(static_cast<int>(data.vertices.size()));
|
|
||||||
mesh.preallocateIndices(static_cast<int>(data.triangles.size()));
|
|
||||||
|
|
||||||
const std::vector<osg::Vec3f> &vertices = data.vertices;
|
const std::vector<osg::Vec3f> &vertices = data.vertices;
|
||||||
const std::vector<unsigned short> &triangles = data.triangles;
|
const std::vector<unsigned short> &triangles = data.triangles;
|
||||||
|
mesh.preallocateVertices(static_cast<int>(vertices.size()));
|
||||||
|
mesh.preallocateIndices(static_cast<int>(triangles.size()));
|
||||||
|
|
||||||
for (std::size_t i = 0; i < triangles.size(); i += 3)
|
for (std::size_t i = 0; i < triangles.size(); i += 3)
|
||||||
{
|
{
|
||||||
|
@ -54,8 +53,6 @@ void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, co
|
||||||
{
|
{
|
||||||
const std::vector<osg::Vec3f> &vertices = data.vertices;
|
const std::vector<osg::Vec3f> &vertices = data.vertices;
|
||||||
const std::vector<std::vector<unsigned short>> &strips = data.strips;
|
const std::vector<std::vector<unsigned short>> &strips = data.strips;
|
||||||
if (vertices.empty() || strips.empty())
|
|
||||||
return;
|
|
||||||
mesh.preallocateVertices(static_cast<int>(vertices.size()));
|
mesh.preallocateVertices(static_cast<int>(vertices.size()));
|
||||||
int numTriangles = 0;
|
int numTriangles = 0;
|
||||||
for (const std::vector<unsigned short>& strip : strips)
|
for (const std::vector<unsigned short>& strip : strips)
|
||||||
|
@ -102,12 +99,12 @@ void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::Node* nifNode, const osg::Matrixf &transform = osg::Matrixf())
|
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiGeometry* geometry, const osg::Matrixf &transform = osg::Matrixf())
|
||||||
{
|
{
|
||||||
if (nifNode->recType == Nif::RC_NiTriShape)
|
if (geometry->recType == Nif::RC_NiTriShape || geometry->recType == Nif::RC_BSLODTriShape)
|
||||||
fillTriangleMesh(mesh, static_cast<const Nif::NiTriShape*>(nifNode)->data.get(), transform);
|
fillTriangleMesh(mesh, static_cast<const Nif::NiTriShapeData&>(geometry->data.get()), transform);
|
||||||
else if (nifNode->recType == Nif::RC_NiTriStrips)
|
else if (geometry->recType == Nif::RC_NiTriStrips)
|
||||||
fillTriangleMesh(mesh, static_cast<const Nif::NiTriStrips*>(nifNode)->data.get(), transform);
|
fillTriangleMesh(mesh, static_cast<const Nif::NiTriStripsData&>(geometry->data.get()), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -312,7 +309,9 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *n
|
||||||
// NOTE: a trishape with hasBounds=true, but no BBoxCollision flag should NOT go through handleNiTriShape!
|
// NOTE: a trishape with hasBounds=true, but no BBoxCollision flag should NOT go through handleNiTriShape!
|
||||||
// It must be ignored completely.
|
// It must be ignored completely.
|
||||||
// (occurs in tr_ex_imp_wall_arch_04.nif)
|
// (occurs in tr_ex_imp_wall_arch_04.nif)
|
||||||
if(!node->hasBounds && (node->recType == Nif::RC_NiTriShape || node->recType == Nif::RC_NiTriStrips))
|
if(!node->hasBounds && (node->recType == Nif::RC_NiTriShape
|
||||||
|
|| node->recType == Nif::RC_NiTriStrips
|
||||||
|
|| node->recType == Nif::RC_BSLODTriShape))
|
||||||
{
|
{
|
||||||
handleNiTriShape(node, flags, getWorldTransform(node), isAnimated, avoid);
|
handleNiTriShape(node, flags, getWorldTransform(node), isAnimated, avoid);
|
||||||
}
|
}
|
||||||
|
@ -341,23 +340,31 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
||||||
if ((flags & 0x800))
|
if ((flags & 0x800))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (nifNode->recType == Nif::RC_NiTriShape)
|
auto niGeometry = static_cast<const Nif::NiGeometry*>(nifNode);
|
||||||
|
if (niGeometry->data.empty() || niGeometry->data->vertices.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (niGeometry->recType == Nif::RC_NiTriShape || niGeometry->recType == Nif::RC_BSLODTriShape)
|
||||||
{
|
{
|
||||||
const Nif::NiTriShape* shape = static_cast<const Nif::NiTriShape*>(nifNode);
|
if (niGeometry->data->recType != Nif::RC_NiTriShapeData)
|
||||||
if (!shape->skin.empty())
|
return;
|
||||||
isAnimated = false;
|
|
||||||
if (shape->data.empty() || shape->data->triangles.empty())
|
auto data = static_cast<const Nif::NiTriShapeData*>(niGeometry->data.getPtr());
|
||||||
|
if (data->triangles.empty())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else if (niGeometry->recType == Nif::RC_NiTriStrips)
|
||||||
{
|
{
|
||||||
const Nif::NiTriStrips* shape = static_cast<const Nif::NiTriStrips*>(nifNode);
|
if (niGeometry->data->recType != Nif::RC_NiTriStripsData)
|
||||||
if (!shape->skin.empty())
|
return;
|
||||||
isAnimated = false;
|
|
||||||
if (shape->data.empty() || shape->data->strips.empty())
|
auto data = static_cast<const Nif::NiTriStripsData*>(niGeometry->data.getPtr());
|
||||||
|
if (data->strips.empty())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!niGeometry->skin.empty())
|
||||||
|
isAnimated = false;
|
||||||
|
|
||||||
if (isAnimated)
|
if (isAnimated)
|
||||||
{
|
{
|
||||||
|
@ -366,7 +373,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
||||||
|
|
||||||
std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh);
|
std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh);
|
||||||
|
|
||||||
fillTriangleMesh(*childMesh, nifNode);
|
fillTriangleMesh(*childMesh, niGeometry);
|
||||||
|
|
||||||
std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true));
|
std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true));
|
||||||
childMesh.release();
|
childMesh.release();
|
||||||
|
@ -394,7 +401,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
||||||
if (!mAvoidStaticMesh)
|
if (!mAvoidStaticMesh)
|
||||||
mAvoidStaticMesh.reset(new btTriangleMesh(false));
|
mAvoidStaticMesh.reset(new btTriangleMesh(false));
|
||||||
|
|
||||||
fillTriangleMesh(*mAvoidStaticMesh, nifNode, transform);
|
fillTriangleMesh(*mAvoidStaticMesh, niGeometry, transform);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -402,7 +409,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
||||||
mStaticMesh.reset(new btTriangleMesh(false));
|
mStaticMesh.reset(new btTriangleMesh(false));
|
||||||
|
|
||||||
// Static shape, just transform all vertices into position
|
// Static shape, just transform all vertices into position
|
||||||
fillTriangleMesh(*mStaticMesh, nifNode, transform);
|
fillTriangleMesh(*mStaticMesh, niGeometry, transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,9 @@ namespace NifOsg
|
||||||
std::conjunction_v<
|
std::conjunction_v<
|
||||||
std::disjunction<
|
std::disjunction<
|
||||||
std::is_same<ValueT, float>,
|
std::is_same<ValueT, float>,
|
||||||
std::is_same<ValueT, osg::Vec3f>
|
std::is_same<ValueT, osg::Vec3f>,
|
||||||
|
std::is_same<ValueT, bool>,
|
||||||
|
std::is_same<ValueT, osg::Vec4f>
|
||||||
>,
|
>,
|
||||||
std::is_same<decltype(T::defaultVal), ValueT>
|
std::is_same<decltype(T::defaultVal), ValueT>
|
||||||
>,
|
>,
|
||||||
|
|
|
@ -67,6 +67,7 @@ namespace
|
||||||
case Nif::RC_NiTriShape:
|
case Nif::RC_NiTriShape:
|
||||||
case Nif::RC_NiTriStrips:
|
case Nif::RC_NiTriStrips:
|
||||||
case Nif::RC_NiLines:
|
case Nif::RC_NiLines:
|
||||||
|
case Nif::RC_BSLODTriShape:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -95,6 +96,15 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
||||||
|
if (geometry)
|
||||||
|
{
|
||||||
|
if (!geometry->shaderprop.empty())
|
||||||
|
out.emplace_back(geometry->shaderprop.getPtr());
|
||||||
|
if (!geometry->alphaprop.empty())
|
||||||
|
out.emplace_back(geometry->alphaprop.getPtr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeCallback used to have a node always oriented towards the camera. The node can have translation and scale
|
// NodeCallback used to have a node always oriented towards the camera. The node can have translation and scale
|
||||||
|
@ -365,6 +375,11 @@ namespace NifOsg
|
||||||
handleProperty(props[i].getPtr(), applyTo, composite, imageManager, boundTextures, animflags);
|
handleProperty(props[i].getPtr(), applyTo, composite, imageManager, boundTextures, animflags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
||||||
|
// NiGeometry's NiAlphaProperty doesn't get handled here because it's a drawable property
|
||||||
|
if (geometry && !geometry->shaderprop.empty())
|
||||||
|
handleProperty(geometry->shaderprop.getPtr(), applyTo, composite, imageManager, boundTextures, animflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupController(const Nif::Controller* ctrl, SceneUtil::Controller* toSetup, int animflags)
|
void setupController(const Nif::Controller* ctrl, SceneUtil::Controller* toSetup, int animflags)
|
||||||
|
@ -466,19 +481,12 @@ namespace NifOsg
|
||||||
texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE);
|
texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE);
|
||||||
texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE);
|
texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE);
|
||||||
|
|
||||||
osg::ref_ptr<osg::TexEnvCombine> texEnv = new osg::TexEnvCombine;
|
|
||||||
texEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE);
|
|
||||||
texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS);
|
|
||||||
texEnv->setCombine_RGB(osg::TexEnvCombine::ADD);
|
|
||||||
texEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
|
|
||||||
texEnv->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
|
|
||||||
|
|
||||||
int texUnit = 3; // FIXME
|
int texUnit = 3; // FIXME
|
||||||
|
|
||||||
osg::StateSet* stateset = node->getOrCreateStateSet();
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
||||||
stateset->setTextureAttributeAndModes(texUnit, texture2d, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(texUnit, texture2d, osg::StateAttribute::ON);
|
||||||
stateset->setTextureAttributeAndModes(texUnit, texGen, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(texUnit, texGen, osg::StateAttribute::ON);
|
||||||
stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(texUnit, createEmissiveTexEnv(), osg::StateAttribute::ON);
|
||||||
|
|
||||||
stateset->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1)));
|
stateset->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1)));
|
||||||
}
|
}
|
||||||
|
@ -946,11 +954,11 @@ namespace NifOsg
|
||||||
// Load the initial state of the particle system, i.e. the initial particles and their positions, velocity and colors.
|
// Load the initial state of the particle system, i.e. the initial particles and their positions, velocity and colors.
|
||||||
void handleParticleInitialState(const Nif::Node* nifNode, osgParticle::ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl)
|
void handleParticleInitialState(const Nif::Node* nifNode, osgParticle::ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl)
|
||||||
{
|
{
|
||||||
const auto particleNode = static_cast<const Nif::NiParticles*>(nifNode);
|
auto particleNode = static_cast<const Nif::NiParticles*>(nifNode);
|
||||||
if (particleNode->data.empty())
|
if (particleNode->data.empty() || particleNode->data->recType != Nif::RC_NiParticlesData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Nif::NiParticlesData* particledata = particleNode->data.getPtr();
|
auto particledata = static_cast<const Nif::NiParticlesData*>(particleNode->data.getPtr());
|
||||||
|
|
||||||
osg::BoundingBox box;
|
osg::BoundingBox box;
|
||||||
|
|
||||||
|
@ -963,6 +971,9 @@ namespace NifOsg
|
||||||
if (particle.lifespan <= 0)
|
if (particle.lifespan <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (particle.vertex >= particledata->vertices.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
ParticleAgeSetter particletemplate(std::max(0.f, particle.lifetime));
|
ParticleAgeSetter particletemplate(std::max(0.f, particle.lifetime));
|
||||||
|
|
||||||
osgParticle::Particle* created = partsys->createParticle(&particletemplate);
|
osgParticle::Particle* created = partsys->createParticle(&particletemplate);
|
||||||
|
@ -971,16 +982,16 @@ namespace NifOsg
|
||||||
// Note this position and velocity is not correct for a particle system with absolute reference frame,
|
// Note this position and velocity is not correct for a particle system with absolute reference frame,
|
||||||
// which can not be done in this loader since we are not attached to the scene yet. Will be fixed up post-load in the SceneManager.
|
// which can not be done in this loader since we are not attached to the scene yet. Will be fixed up post-load in the SceneManager.
|
||||||
created->setVelocity(particle.velocity);
|
created->setVelocity(particle.velocity);
|
||||||
const osg::Vec3f& position = particledata->vertices.at(particle.vertex);
|
const osg::Vec3f& position = particledata->vertices[particle.vertex];
|
||||||
created->setPosition(position);
|
created->setPosition(position);
|
||||||
|
|
||||||
osg::Vec4f partcolor (1.f,1.f,1.f,1.f);
|
osg::Vec4f partcolor (1.f,1.f,1.f,1.f);
|
||||||
if (particle.vertex < int(particledata->colors.size()))
|
if (particle.vertex < particledata->colors.size())
|
||||||
partcolor = particledata->colors.at(particle.vertex);
|
partcolor = particledata->colors[particle.vertex];
|
||||||
|
|
||||||
float size = partctrl->size;
|
float size = partctrl->size;
|
||||||
if (particle.vertex < int(particledata->sizes.size()))
|
if (particle.vertex < particledata->sizes.size())
|
||||||
size *= particledata->sizes.at(particle.vertex);
|
size *= particledata->sizes[particle.vertex];
|
||||||
|
|
||||||
created->setSizeRange(osgParticle::rangef(size, size));
|
created->setSizeRange(osgParticle::rangef(size, size));
|
||||||
box.expandBy(osg::BoundingSphere(position, size));
|
box.expandBy(osg::BoundingSphere(position, size));
|
||||||
|
@ -1177,51 +1188,50 @@ namespace NifOsg
|
||||||
|
|
||||||
void handleNiGeometry(const Nif::Node *nifNode, osg::Geometry *geometry, osg::Node* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, int animflags)
|
void handleNiGeometry(const Nif::Node *nifNode, osg::Geometry *geometry, osg::Node* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
const Nif::NiGeometryData* niGeometryData = nullptr;
|
const Nif::NiGeometry* niGeometry = static_cast<const Nif::NiGeometry*>(nifNode);
|
||||||
if (nifNode->recType == Nif::RC_NiTriShape)
|
if (niGeometry->data.empty())
|
||||||
|
return;
|
||||||
|
const Nif::NiGeometryData* niGeometryData = niGeometry->data.getPtr();
|
||||||
|
|
||||||
|
if (niGeometry->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_BSLODTriShape)
|
||||||
{
|
{
|
||||||
const Nif::NiTriShape* triShape = static_cast<const Nif::NiTriShape*>(nifNode);
|
if (niGeometryData->recType != Nif::RC_NiTriShapeData)
|
||||||
if (!triShape->data.empty())
|
return;
|
||||||
{
|
auto triangles = static_cast<const Nif::NiTriShapeData*>(niGeometryData)->triangles;
|
||||||
const Nif::NiTriShapeData* data = triShape->data.getPtr();
|
if (triangles.empty())
|
||||||
niGeometryData = static_cast<const Nif::NiGeometryData*>(data);
|
return;
|
||||||
if (!data->triangles.empty())
|
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, triangles.size(),
|
||||||
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, data->triangles.size(),
|
(unsigned short*)triangles.data()));
|
||||||
(unsigned short*)data->triangles.data()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (nifNode->recType == Nif::RC_NiTriStrips)
|
else if (niGeometry->recType == Nif::RC_NiTriStrips)
|
||||||
{
|
{
|
||||||
const Nif::NiTriStrips* triStrips = static_cast<const Nif::NiTriStrips*>(nifNode);
|
if (niGeometryData->recType != Nif::RC_NiTriStripsData)
|
||||||
if (!triStrips->data.empty())
|
return;
|
||||||
|
auto data = static_cast<const Nif::NiTriStripsData*>(niGeometryData);
|
||||||
|
bool hasGeometry = false;
|
||||||
|
for (const auto& strip : data->strips)
|
||||||
{
|
{
|
||||||
const Nif::NiTriStripsData* data = triStrips->data.getPtr();
|
if (strip.size() < 3)
|
||||||
niGeometryData = static_cast<const Nif::NiGeometryData*>(data);
|
continue;
|
||||||
if (!data->strips.empty())
|
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(),
|
||||||
{
|
(unsigned short*)strip.data()));
|
||||||
for (const auto& strip : data->strips)
|
hasGeometry = true;
|
||||||
{
|
|
||||||
if (strip.size() >= 3)
|
|
||||||
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(),
|
|
||||||
(unsigned short*)strip.data()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!hasGeometry)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (nifNode->recType == Nif::RC_NiLines)
|
else if (niGeometry->recType == Nif::RC_NiLines)
|
||||||
{
|
{
|
||||||
const Nif::NiLines* lines = static_cast<const Nif::NiLines*>(nifNode);
|
if (niGeometryData->recType != Nif::RC_NiLinesData)
|
||||||
if (!lines->data.empty())
|
return;
|
||||||
{
|
auto data = static_cast<const Nif::NiLinesData*>(niGeometryData);
|
||||||
const Nif::NiLinesData* data = lines->data.getPtr();
|
const auto& line = data->lines;
|
||||||
niGeometryData = static_cast<const Nif::NiGeometryData*>(data);
|
if (line.empty())
|
||||||
const auto& line = data->lines;
|
return;
|
||||||
if (!line.empty())
|
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, line.size(),
|
||||||
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, line.size(), (unsigned short*)line.data()));
|
(unsigned short*)line.data()));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (niGeometryData)
|
handleNiGeometryData(geometry, niGeometryData, boundTextures, nifNode->name);
|
||||||
handleNiGeometryData(geometry, niGeometryData, boundTextures, nifNode->name);
|
|
||||||
|
|
||||||
// osg::Material properties are handled here for two reasons:
|
// osg::Material properties are handled here for two reasons:
|
||||||
// - if there are no vertex colors, we need to disable colorMode.
|
// - if there are no vertex colors, we need to disable colorMode.
|
||||||
|
@ -1229,7 +1239,7 @@ namespace NifOsg
|
||||||
// above the actual renderable would be tedious.
|
// above the actual renderable would be tedious.
|
||||||
std::vector<const Nif::Property*> drawableProps;
|
std::vector<const Nif::Property*> drawableProps;
|
||||||
collectDrawableProperties(nifNode, drawableProps);
|
collectDrawableProperties(nifNode, drawableProps);
|
||||||
applyDrawableProperties(parentNode, drawableProps, composite, niGeometryData && !niGeometryData->colors.empty(), animflags);
|
applyDrawableProperties(parentNode, drawableProps, composite, !niGeometryData->colors.empty(), animflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleGeometry(const Nif::Node* nifNode, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, int animflags)
|
void handleGeometry(const Nif::Node* nifNode, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, int animflags)
|
||||||
|
@ -1481,6 +1491,17 @@ namespace NifOsg
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::TexEnvCombine> createEmissiveTexEnv()
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::TexEnvCombine> texEnv(new osg::TexEnvCombine);
|
||||||
|
texEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE);
|
||||||
|
texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS);
|
||||||
|
texEnv->setCombine_RGB(osg::TexEnvCombine::ADD);
|
||||||
|
texEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
|
||||||
|
texEnv->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
|
||||||
|
return texEnv;
|
||||||
|
}
|
||||||
|
|
||||||
void handleTextureProperty(const Nif::NiTexturingProperty* texprop, const std::string& nodeName, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures, int animflags)
|
void handleTextureProperty(const Nif::NiTexturingProperty* texprop, const std::string& nodeName, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
if (!boundTextures.empty())
|
if (!boundTextures.empty())
|
||||||
|
@ -1567,14 +1588,7 @@ namespace NifOsg
|
||||||
|
|
||||||
if (i == Nif::NiTexturingProperty::GlowTexture)
|
if (i == Nif::NiTexturingProperty::GlowTexture)
|
||||||
{
|
{
|
||||||
osg::TexEnvCombine* texEnv = new osg::TexEnvCombine;
|
stateset->setTextureAttributeAndModes(texUnit, createEmissiveTexEnv(), osg::StateAttribute::ON);
|
||||||
texEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE);
|
|
||||||
texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS);
|
|
||||||
texEnv->setCombine_RGB(osg::TexEnvCombine::ADD);
|
|
||||||
texEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
|
|
||||||
texEnv->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
|
|
||||||
|
|
||||||
stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON);
|
|
||||||
}
|
}
|
||||||
else if (i == Nif::NiTexturingProperty::DarkTexture)
|
else if (i == Nif::NiTexturingProperty::DarkTexture)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue