From 55710991476930c79c6cc37cc88aa625ea31c58b Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Wed, 10 Nov 2021 19:31:28 +0300 Subject: [PATCH] Load NiCollisionObject and bhkCollisionObject --- components/CMakeLists.txt | 2 +- components/nif/niffile.cpp | 2 ++ components/nif/node.hpp | 7 +++- components/nif/physics.cpp | 32 +++++++++++++++++++ components/nif/physics.hpp | 62 ++++++++++++++++++++++++++++++++++++ components/nif/record.hpp | 4 ++- components/nif/recordptr.hpp | 6 ++++ 7 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 components/nif/physics.cpp create mode 100644 components/nif/physics.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 0b3c95ff45..5c0ead4ad0 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -61,7 +61,7 @@ add_component_dir (sceneutil ) add_component_dir (nif - controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream + controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream physics ) add_component_dir (nifosg diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 7f330450a0..1f6cc256fc 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -137,6 +137,8 @@ static std::map makeFactory() factory["BSShaderPPLightingProperty"] = {&construct , RC_BSShaderPPLightingProperty }; factory["BSShaderNoLightingProperty"] = {&construct , RC_BSShaderNoLightingProperty }; factory["BSFurnitureMarker"] = {&construct , RC_BSFurnitureMarker }; + factory["NiCollisionObject"] = {&construct , RC_NiCollisionObject }; + factory["bhkCollisionObject"] = {&construct , RC_bhkCollisionObject }; return factory; } diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 406a4d4549..c01ba9b663 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -8,6 +8,7 @@ #include "niftypes.hpp" #include "controller.hpp" #include "base.hpp" +#include "physics.hpp" #include @@ -143,6 +144,9 @@ struct Node : public Named bool hasBounds{false}; NiBoundingVolume bounds; + // Collision object info + NiCollisionObjectPtr collision; + void read(NIFStream *nif) override { Named::read(nif); @@ -160,7 +164,7 @@ struct Node : public Named bounds.read(nif); // Reference to the collision object in Gamebryo files. if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) - nif->skip(4); + collision.read(nif); parent = nullptr; @@ -171,6 +175,7 @@ struct Node : public Named { Named::post(nif); props.post(nif); + collision.post(nif); } // Parent node, or nullptr for the root node. As far as I'm aware, only diff --git a/components/nif/physics.cpp b/components/nif/physics.cpp new file mode 100644 index 0000000000..fbbc459ab2 --- /dev/null +++ b/components/nif/physics.cpp @@ -0,0 +1,32 @@ +#include "physics.hpp" +#include "node.hpp" + +namespace Nif +{ + void bhkCollisionObject::read(NIFStream *nif) + { + NiCollisionObject::read(nif); + flags = nif->getUShort(); + body.read(nif); + } + + void bhkWorldObject::read(NIFStream *nif) + { + shape.read(nif); + if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD) + nif->skip(4); // Unknown + flags = nif->getUInt(); + nif->skip(4); // Unused + worldObjectInfo.phaseType = nif->getChar(); + nif->skip(3); // Unused + worldObjectInfo.data = nif->getUInt(); + worldObjectInfo.size = nif->getUInt(); + worldObjectInfo.capacityAndFlags = nif->getUInt(); + } + + void bhkWorldObject::post(NIFFile *nif) + { + shape.post(nif); + } + +} // Namespace \ No newline at end of file diff --git a/components/nif/physics.hpp b/components/nif/physics.hpp new file mode 100644 index 0000000000..e64eb349eb --- /dev/null +++ b/components/nif/physics.hpp @@ -0,0 +1,62 @@ +#ifndef OPENMW_COMPONENTS_NIF_PHYSICS_HPP +#define OPENMW_COMPONENTS_NIF_PHYSICS_HPP + +#include "base.hpp" + +// This header contains certain record definitions +// specific to Bethesda implementation of Havok physics +namespace Nif +{ + +// Generic collision object +struct NiCollisionObject : public Record +{ + // The node that references this object + NodePtr target; + + void read(NIFStream *nif) override + { + target.read(nif); + } + void post(NIFFile *nif) override + { + target.post(nif); + } +}; + +// Bethesda Havok-specific collision object +struct bhkCollisionObject : public NiCollisionObject +{ + unsigned short flags; + CollisionBodyPtr body; + + void read(NIFStream *nif) override; + void post(NIFFile *nif) override + { + NiCollisionObject::post(nif); + body.post(nif); + } +}; + + +// Abstract Havok shape info record +struct bhkWorldObject : public Record +{ + bhkShapePtr shape; + unsigned int flags; // Havok layer type, collision filter flags and group + struct WorldObjectInfo + { + unsigned char phaseType; + unsigned int data; + unsigned int size; + unsigned int capacityAndFlags; + }; + WorldObjectInfo worldObjectInfo; + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; +}; + +struct bhkShape : public Record {}; + +} // Namespace +#endif \ No newline at end of file diff --git a/components/nif/record.hpp b/components/nif/record.hpp index dc7314cc95..88ffbe4141 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -126,7 +126,9 @@ enum RecordType RC_BSShaderProperty, RC_BSShaderPPLightingProperty, RC_BSShaderNoLightingProperty, - RC_BSFurnitureMarker + RC_BSFurnitureMarker, + RC_NiCollisionObject, + RC_bhkCollisionObject }; /// Base class for all records diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index b30d99fbe4..a25480fe43 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -148,6 +148,9 @@ struct BSShaderTextureSet; struct NiGeometryData; struct BSShaderProperty; struct NiAlphaProperty; +struct NiCollisionObject; +struct bhkWorldObject; +struct bhkShape; using NodePtr = RecordPtrT; using ExtraPtr = RecordPtrT; @@ -175,6 +178,9 @@ using BSShaderTextureSetPtr = RecordPtrT; using NiGeometryDataPtr = RecordPtrT; using BSShaderPropertyPtr = RecordPtrT; using NiAlphaPropertyPtr = RecordPtrT; +using NiCollisionObjectPtr = RecordPtrT; +using CollisionBodyPtr = RecordPtrT; +using bhkShapePtr = RecordPtrT; using NodeList = RecordListT; using PropertyList = RecordListT;