diff --git a/lib/hkStubs/CMakeLists.txt b/lib/hkStubs/CMakeLists.txt index b76110f4..24837775 100644 --- a/lib/hkStubs/CMakeLists.txt +++ b/lib/hkStubs/CMakeLists.txt @@ -1,6 +1,16 @@ project(hkStubs CXX ASM) add_library(hkStubs OBJECT + Havok/Animation/Animation/Animation/hkaAnimation.h + Havok/Animation/Animation/Animation/hkaAnimationBinding.h + Havok/Animation/Animation/Animation/hkaAnnotationTrack.h + Havok/Animation/Animation/Mapper/hkaSkeletonMapper.h + Havok/Animation/Animation/Mapper/hkaSkeletonMapperData.h + Havok/Animation/Animation/Motion/hkaAnimatedReferenceFrame.h + Havok/Animation/Animation/Rig/hkaBone.h + Havok/Animation/Animation/Rig/hkaSkeleton.h + Havok/Animation/Physics2012Bridge/Instance/hkaRagdollInstance.h + Havok/Common/Base/hkBase.h Havok/Common/Base/Container/hkContainerAllocators.h @@ -66,6 +76,7 @@ add_library(hkStubs OBJECT Havok/Common/Base/Types/hkRefVariant.h Havok/Common/Base/Types/Geometry/Aabb/hkAabb.h Havok/Common/Base/Types/Geometry/Aabb/hkAabbUtil.h + Havok/Common/Base/Types/Geometry/LocalFrame/hkLocalFrame.h Havok/Common/Base/Types/Geometry/Sphere/hkSphere.h Havok/Common/Base/Types/Physics/hkStepInfo.h Havok/Common/Base/Types/Physics/ContactPoint/hkContactPointMaterial.h diff --git a/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnimation.h b/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnimation.h new file mode 100644 index 00000000..24643675 --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnimation.h @@ -0,0 +1,171 @@ +#pragma once + +#include +#include +#include + +class hkaSkeleton; + +extern const class hkClass hkaAnimationClass; + +class hkaAnimation : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkaAnimation) + HK_DECLARE_REFLECTION() + + inline hkaAnimation(); + + explicit hkaAnimation(hkFinishLoadedObjectFlag flag) + : hkReferencedObject(flag), m_extractedMotion(flag), m_annotationTracks(flag) {} + + enum AnimationType { + HK_UNKNOWN_ANIMATION = 0, + HK_INTERLEAVED_ANIMATION, + HK_MIRRORED_ANIMATION, + HK_SPLINE_COMPRESSED_ANIMATION, + HK_QUANTIZED_COMPRESSED_ANIMATION, + HK_PREDICTIVE_COMPRESSED_ANIMATION, + HK_REFERENCE_POSE_ANIMATION, + }; + + HK_FORCE_INLINE hkaAnimation::AnimationType getType() const; + + virtual void sampleTracks(hkReal time, hkQsTransform* transformTracksOut, + hkReal* floatTracksOut) const = 0; + + virtual void samplePartialTracks(hkReal time, hkUint32 maxNumTransformTracks, + hkQsTransform* transformTracksOut, hkUint32 maxNumFloatTracks, + hkReal* floatTracksOut) const; + + inline void sampleSingleTransformTrack(hkReal time, hkInt16 track, + hkQsTransform* transformOut) const; + + inline void sampleSingleFloatTrack(hkReal time, hkInt16 track, hkReal* out) const; + + virtual void sampleIndividualTransformTracks(hkReal time, const hkInt16* tracks, + hkUint32 numTracks, + hkQsTransform* transformOut) const = 0; + + virtual void sampleIndividualFloatTracks(hkReal time, const hkInt16* tracks, hkUint32 numTracks, + hkReal* out) const = 0; + + virtual int getSizeInBytes() const = 0; + + virtual int getNumOriginalFrames() const = 0; + + // INTERNAL + struct DataChunk { + HK_DECLARE_CLASS_ALLOCATOR(DataChunk) + + const hkUint8* m_data; + hkUint32 m_size; + }; + + virtual int getNumDataChunks(hkUint32 frame, hkReal delta) const; + + virtual void getDataChunks(hkUint32 frame, hkReal delta, DataChunk* dataChunks, + int m_numDataChunks) const; + + virtual int getMaxSizeOfCombinedDataChunks() const; + + virtual int getMaxDecompressionTempBytes() const; + + virtual void getExtractedMotionReferenceFrame(hkReal time, hkQsTransform& motionOut) const; + + virtual void getExtractedMotionDeltaReferenceFrame(hkReal time, hkReal nextTime, int loops, + hkQsTransform& deltaMotionOut, + hkReal cropStartAmount, + hkReal cropEndAmount) const; + + hkBool hasExtractedMotion() const; + + void setExtractedMotion(const hkaAnimatedReferenceFrame* extractedMotion); + + const hkaAnimatedReferenceFrame* getExtractedMotion() const; + + // TODO + inline void getFrameAndDelta(hkReal time, hkUint32& frameOut, hkReal& deltaOut) const; + + struct TrackAnnotation { + HK_DECLARE_CLASS_ALLOCATOR(TrackAnnotation) + + hkUint16 m_trackID; + hkaAnnotationTrack::Annotation m_annotation; + }; + + virtual hkUint32 getNumAnnotations(hkReal startTime, hkReal deltaTime) const; + + virtual hkUint32 getAnnotations(hkReal startTime, hkReal deltaTime, + TrackAnnotation* annotationsOut, hkUint32 maxAnnotations) const; + + hkUint32 getAnnotations(hkReal startTime, hkReal deltaTime, + TrackAnnotation* annotationsOut) const { + return getAnnotations(startTime, deltaTime, annotationsOut, HK_INT32_MAX); + } + + virtual bool requiresSkeleton() const; + virtual const hkaSkeleton* getSkeleton() const; + virtual void setSkeleton(const hkaSkeleton* skeleton); + +protected: + hkaAnimation(const hkaAnimation&); + + hkEnum m_type; + +public: + hkReal m_duration; + int m_numberOfTransformTracks; + int m_numberOfFloatTracks; + +protected: + hkRefPtr m_extractedMotion; + +public: + hkArray m_annotationTracks; +}; + +inline hkaAnimation::hkaAnimation() : m_type(HK_UNKNOWN_ANIMATION) { + m_duration = 0; + m_numberOfTransformTracks = 0; + m_numberOfFloatTracks = 0; + m_extractedMotion = nullptr; +} + +inline hkaAnimation::AnimationType hkaAnimation::getType() const { + return m_type; +} + +inline void hkaAnimation::sampleSingleTransformTrack(hkReal time, hkInt16 track, + hkQsTransform* transformOut) const { + sampleIndividualTransformTracks(time, &track, 1, transformOut); +} + +inline void hkaAnimation::sampleSingleFloatTrack(hkReal time, hkInt16 track, hkReal* out) const { + sampleIndividualFloatTracks(time, &track, 1, out); +} + +inline hkBool hkaAnimation::hasExtractedMotion() const { + return m_extractedMotion != nullptr; +} + +inline void hkaAnimation::setExtractedMotion(const hkaAnimatedReferenceFrame* extractedMotion) { + m_extractedMotion = extractedMotion; +} + +inline const hkaAnimatedReferenceFrame* hkaAnimation::getExtractedMotion() const { + return m_extractedMotion; +} + +inline void hkaAnimation::getExtractedMotionReferenceFrame(hkReal time, + hkQsTransform& motionOut) const { + m_extractedMotion->getReferenceFrame(time, motionOut); +} + +inline void hkaAnimation::getExtractedMotionDeltaReferenceFrame(hkReal time, hkReal nextTime, + int loops, + hkQsTransform& deltaMotionOut, + hkReal cropStartAmount, + hkReal cropEndAmount) const { + m_extractedMotion->getDeltaReferenceFrame(time, nextTime, loops, deltaMotionOut, + cropStartAmount, cropEndAmount); +} diff --git a/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnimationBinding.h b/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnimationBinding.h new file mode 100644 index 00000000..b798071e --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnimationBinding.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include + +class hkaAnimationBinding : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkaAnimationBinding) + HK_DECLARE_REFLECTION() + + enum BlendHint { + NORMAL = 0, + ADDITIVE_DEPRECATED = 1, + ADDITIVE = 2, + }; + + HK_FORCE_INLINE hkaAnimationBinding(); + HK_FORCE_INLINE hkaAnimationBinding(const hkaAnimationBinding& other); + HK_FORCE_INLINE explicit hkaAnimationBinding(hkFinishLoadedObjectFlag flag); + + hkInt16 findTrackIndexFromBoneIndex(hkInt16 boneIndex) const; + hkInt16 findTrackIndexFromSlotIndex(hkInt16 slotIndex) const; + + static hkInt16 findTrackIndexFromBoneIndex(hkInt16 boneIndex, hkInt32 numTracks, + const hkInt16* trackToBoneIndices); + + bool isMonotonic() const; + + void setIdentity(); + + hkStringPtr m_originalSkeletonName; + hkRefPtr m_animation; + hkArray m_transformTrackToBoneIndices; + hkArray m_floatTrackToFloatSlotIndices; + hkArray m_partitionIndices; + hkEnum m_blendHint; +}; + +inline hkaAnimationBinding::hkaAnimationBinding() : m_blendHint(NORMAL) {} + +inline hkaAnimationBinding::hkaAnimationBinding(const hkaAnimationBinding& other) + : hkReferencedObject(other), m_originalSkeletonName(other.m_originalSkeletonName), + m_animation(other.m_animation), m_blendHint(other.m_blendHint) { + m_transformTrackToBoneIndices = other.m_transformTrackToBoneIndices; + m_floatTrackToFloatSlotIndices = other.m_floatTrackToFloatSlotIndices; + m_partitionIndices = other.m_partitionIndices; +} + +inline hkaAnimationBinding::hkaAnimationBinding(hkFinishLoadedObjectFlag flag) + : hkReferencedObject(flag), m_originalSkeletonName(flag), m_animation(flag), + m_transformTrackToBoneIndices(flag), m_floatTrackToFloatSlotIndices(flag), + m_partitionIndices(flag) {} diff --git a/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnnotationTrack.h b/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnnotationTrack.h new file mode 100644 index 00000000..207f9e91 --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Animation/Animation/hkaAnnotationTrack.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +class hkaAnnotationTrack { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkaAnnotationTrack) + HK_DECLARE_REFLECTION() + + hkaAnnotationTrack(); + hkaAnnotationTrack(const hkaAnnotationTrack&); + explicit hkaAnnotationTrack(hkFinishLoadedObjectFlag flag) + : m_trackName(flag), m_annotations(flag) {} + + struct Annotation { + HK_DECLARE_CLASS_ALLOCATOR(Annotation) + HK_DECLARE_REFLECTION() + + Annotation() : m_time(0) {} + explicit Annotation(hkFinishLoadedObjectFlag flag) : m_text(flag) {} + + hkReal m_time; + hkStringPtr m_text; + }; + + hkStringPtr m_trackName; + hkArray m_annotations; +}; diff --git a/lib/hkStubs/Havok/Animation/Animation/Mapper/hkaSkeletonMapper.h b/lib/hkStubs/Havok/Animation/Animation/Mapper/hkaSkeletonMapper.h new file mode 100644 index 00000000..89723c37 --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Animation/Mapper/hkaSkeletonMapper.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include +#include +#include + +class hkaPose; +class hkaAnimationBinding; + +/// This run-time class converts a pose from one skeleton (A) to another (B). The poses can be +/// specified by either hkaPose objects or arrays of transforms. It uses mapping data +/// (hkaSkeletonMapperData), which can be created using the hkaSkeletonMapperUtils utility class. +class hkaSkeletonMapper : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkaSkeletonMapper) + HK_DECLARE_REFLECTION() + + explicit hkaSkeletonMapper(const hkaSkeletonMapperData& mapping); + explicit hkaSkeletonMapper(hkFinishLoadedObjectFlag f) : hkReferencedObject(f), m_mapping(f) {} + + ~hkaSkeletonMapper() override; + + enum ConstraintSource { + NO_CONSTRAINTS, + REFERENCE_POSE, + CURRENT_POSE, + }; + + void mapPose(const hkQsTransform* poseAModelSpace, const hkQsTransform* originalPoseBLocalSpace, + hkQsTransform* poseBModelSpaceInOut, ConstraintSource source) const; + + void mapPoseLocalSpace(const hkQsTransform* poseALocalSpace, + hkQsTransform* poseBLocalSpaceInOut, + hkaAnimationBinding::BlendHint blendHint) const; + + void mapPoseLocalSpace(const hkQsTransform* poseALocalSpace, + hkQsTransform* poseBLocalSpaceInOut, const hkInt16* boneToTrackIndicesA, + const hkInt16* boneToTrackIndicesB, + hkaAnimationBinding::BlendHint blendHint, + const hkReal* weightsA = nullptr, hkReal* weightsBOut = nullptr) const; + + void mapPoseLocalSpace(const hkQsTransform* poseALocalSpace, + hkQsTransform* poseBLocalSpaceInOut, + const hkArray& partitionIndicesA, + hkaAnimationBinding::BlendHint blendHint, bool mapToFullPose = true, + const hkReal* weightsA = nullptr, hkReal* weightsBOut = nullptr) const; + + void mapPoseLocalSpace(const hkQsTransform* poseALocalSpace, + hkQsTransform* poseBLocalSpaceInOut, const hkInt16* boneToTrackIndicesA, + const hkInt16* boneToTrackIndicesB, + const hkArray& partitionIndicesA, + hkaAnimationBinding::BlendHint blendHint, bool mapToFullPose = true, + const hkReal* weightsA = nullptr, hkReal* weightsBOut = nullptr) const; + + void mapPose(const hkaPose& poseAIn, hkaPose& poseBInOut, + ConstraintSource source = NO_CONSTRAINTS) const; + + void mapExtractedMotion(const hkQsTransform& deltaMotionIn, + hkQsTransform& deltaMotionOut) const; + + void initializeBindingMaps(const hkaAnimationBinding* binding, + hkArray& srcBoneToTrackIndicesOut, + hkArray& dstBoneToTrackIndicesOut, + hkArray& dstTrackToBoneIndicesOut) const; + + static void combinedPoseFromAdditivePoseAndReferencePose( + const hkQsTransform* additivePose, const hkQsTransform* referencePose, + const hkInt16* boneToTrackIndices, hkInt32 startBoneIndex, hkInt32 numBones, + hkaAnimationBinding::BlendHint additiveHint, hkQsTransform* combinedPoseOut); + + static void additivePoseFromCombinedPoseAndReferencePose( + const hkQsTransform* combinedPose, const hkQsTransform* referencePose, + const hkInt16* boneToTrackIndices, hkInt32 startBoneIndex, hkInt32 numBones, + hkaAnimationBinding::BlendHint additiveHint, hkQsTransform* additivePoseOut); + + static void combineSparsePoseWithFullPose(const hkQsTransform* sparsePose, + const hkQsTransform* fullPose, + const hkInt16* sparsePoseBoneToTrackIndices, + hkInt32 startBoneIndex, hkInt32 numBones, + hkaAnimationBinding::BlendHint additiveHint, + hkQsTransform* sparseMulFull_sparseOut); + +public: + hkaSkeletonMapperData m_mapping; + +public: + // Debug only. + static void checkMapping(const hkaSkeletonMapperData& mapping); + static void checkMappingLocalSpace(const hkaSkeletonMapperData& mapping); + static bool checkTransform(hkaSkeletonMapperData::MappingType type, const hkQsTransform& q); + +private: + static void mapPoseLocalSpaceInternal( + const hkaSkeletonMapperData& mapping, const hkQsTransform* poseALocalSpaceOriginal, + hkQsTransform* poseBLocalSpaceInOut, const hkInt16* boneToTrackIndicesA, + const hkInt16* boneToTrackIndicesB, const hkArray& partitionIndicesA, + hkaAnimationBinding::BlendHint blendHint, bool mapToFullPose, const hkReal* weightsA, + hkReal* weightsBOut); + + static void setMulWithScaling(hkaSkeletonMapperData::MappingType type, hkQsTransform& dst, + const hkQsTransform& t1, const hkQsTransform& t2); +}; diff --git a/lib/hkStubs/Havok/Animation/Animation/Mapper/hkaSkeletonMapperData.h b/lib/hkStubs/Havok/Animation/Animation/Mapper/hkaSkeletonMapperData.h new file mode 100644 index 00000000..c3d502c5 --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Animation/Mapper/hkaSkeletonMapperData.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +class hkaSkeletonMapperData { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkaSkeletonMapperData) + HK_DECLARE_REFLECTION() + + enum MappingType { + HK_RAGDOLL_MAPPING = 0, + HK_RETARGETING_MAPPING = 1, + }; + + struct SimpleMapping { + HK_DECLARE_CLASS_ALLOCATOR(SimpleMapping) + HK_DECLARE_REFLECTION() + + hkInt16 m_boneA = 0; + hkInt16 m_boneB = 0; + hkQsTransform m_aFromBTransform{hkQsTransform::IdentityInitializer()}; + }; + + /// Defines a n-to-m mapping between a chain of bones of A and a chain of bones of B. + struct ChainMapping { + HK_DECLARE_CLASS_ALLOCATOR(ChainMapping) + HK_DECLARE_REFLECTION() + + hkInt16 m_startBoneA = 0; + hkInt16 m_endBoneA = 0; + hkInt16 m_startBoneB = 0; + hkInt16 m_endBoneB = 0; + hkQsTransform m_startAFromBTransform{hkQsTransform::IdentityInitializer()}; + hkQsTransform m_endAFromBTransform{hkQsTransform::IdentityInitializer()}; + }; + + /// Defines mapping between the partition and simple/chain mappings + struct PartitionMappingRange { + HK_DECLARE_CLASS_ALLOCATOR(PartitionMappingRange) + HK_DECLARE_REFLECTION() + + int m_startMappingIndex; + int m_numMappings; + }; + + hkaSkeletonMapperData(); + explicit hkaSkeletonMapperData(hkFinishLoadedObjectFlag f); + ~hkaSkeletonMapperData(); + + hkRefPtr m_skeletonA; + hkRefPtr m_skeletonB; + hkArray m_partitionMap; + hkArray m_simpleMappingPartitionRanges; + hkArray m_chainMappingPartitionRanges; + hkArray m_simpleMappings; + hkArray m_chainMappings; + hkArray m_unmappedBones; + hkQsTransform m_extractedMotionMapping; + hkBool m_keepUnmappedLocal; + hkEnum m_mappingType; +}; diff --git a/lib/hkStubs/Havok/Animation/Animation/Motion/hkaAnimatedReferenceFrame.h b/lib/hkStubs/Havok/Animation/Animation/Motion/hkaAnimatedReferenceFrame.h new file mode 100644 index 00000000..94329fa7 --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Animation/Motion/hkaAnimatedReferenceFrame.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +class hkaAnimatedReferenceFrame : public hkReferencedObject { +public: + enum hkaReferenceFrameTypeEnum { + REFERENCE_FRAME_UNKNOWN, + REFERENCE_FRAME_DEFAULT, + REFERENCE_FRAME_PARAMETRIC + }; + + HK_DECLARE_CLASS_ALLOCATOR(hkaAnimatedReferenceFrame) + HK_DECLARE_REFLECTION() + + inline explicit hkaAnimatedReferenceFrame(hkaReferenceFrameTypeEnum frameType) + : m_frameType(frameType) {} + + inline hkaAnimatedReferenceFrame(hkFinishLoadedObjectFlag flag, + hkaReferenceFrameTypeEnum frameType) + : hkReferencedObject(flag), m_frameType(frameType) {} + + virtual void getReferenceFrame(hkReal time, hkQsTransform& motionOut) const = 0; + + virtual void getDeltaReferenceFrame(hkReal time, hkReal nextTime, int loops, + hkQsTransform& deltaMotionOut, hkReal cropStartAmount, + hkReal cropEndAmount) const = 0; + + virtual hkReal getDuration() const = 0; + + hkEnum m_frameType; +}; diff --git a/lib/hkStubs/Havok/Animation/Animation/Rig/hkaBone.h b/lib/hkStubs/Havok/Animation/Animation/Rig/hkaBone.h new file mode 100644 index 00000000..7c881fc6 --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Animation/Rig/hkaBone.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +class hkaBone { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkaBone) + HK_DECLARE_REFLECTION() + + hkaBone() : m_lockTranslation(false) {} + explicit hkaBone(hkFinishLoadedObjectFlag f) : m_name(f) {} + + hkStringPtr m_name; + hkBool m_lockTranslation; +}; diff --git a/lib/hkStubs/Havok/Animation/Animation/Rig/hkaSkeleton.h b/lib/hkStubs/Havok/Animation/Animation/Rig/hkaSkeleton.h new file mode 100644 index 00000000..5c82c8de --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Animation/Rig/hkaSkeleton.h @@ -0,0 +1,138 @@ +#pragma once + +#include +#include +#include + +class hkaSkeleton : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkaSkeleton) + HK_DECLARE_REFLECTION() + + struct LocalFrameOnBone { + HK_DECLARE_CLASS_ALLOCATOR(LocalFrameOnBone) + HK_DECLARE_REFLECTION() + + hkRefPtr m_localFrame; + hkInt16 m_boneIndex; + + HK_FORCE_INLINE LocalFrameOnBone(); + HK_FORCE_INLINE explicit LocalFrameOnBone(hkFinishLoadedObjectFlag f); + }; + + struct Partition { + HK_DECLARE_CLASS_ALLOCATOR(Partition) + HK_DECLARE_REFLECTION() + + Partition() : m_name(nullptr), m_startBoneIndex(-1), m_numBones(-1) {} + + Partition(hkInt16 startIndex, hkInt16 numBones) + : m_name(nullptr), m_startBoneIndex(startIndex), m_numBones(numBones) {} + + explicit Partition(hkFinishLoadedObjectFlag f) : m_name(f) {} + + Partition(const Partition& partition) + : m_name(partition.m_name), m_startBoneIndex(partition.m_startBoneIndex), + m_numBones(partition.m_numBones) {} + + Partition& operator=(const Partition& other) = default; + + hkStringPtr m_name; + hkInt16 m_startBoneIndex; + hkInt16 m_numBones; + + HK_FORCE_INLINE void initWithoutName(hkInt16 startBoneIndex, hkInt16 numBones); + HK_FORCE_INLINE hkBool32 isBonePresentWithinPartition(hkInt16 boneIndex) const; + HK_FORCE_INLINE hkInt16 getEndBoneIndex() const; + }; + + struct PartitionStartBoneLess { + HK_FORCE_INLINE hkBool operator()(const Partition& a, const Partition& b) { + return (a.m_startBoneIndex < b.m_startBoneIndex); + } + }; + + HK_FORCE_INLINE hkaSkeleton(); + HK_FORCE_INLINE hkaSkeleton(const hkaSkeleton& skel); + HK_FORCE_INLINE explicit hkaSkeleton(hkFinishLoadedObjectFlag f); + + hkLocalFrame* getLocalFrameForBone(int boneIndex) const; + + hkInt16 getPartitionIndexFromName(const char* partitionName) const; + + hkInt16 getPartitionIndexForBone(hkInt16 boneIndex) const; + + hkStringPtr m_name; + hkArray m_parentIndices; + hkArray m_bones; + hkArray m_referencePose; + hkArray m_referenceFloats; + hkArray m_floatSlots; + hkArray m_localFrames; + hkArray m_partitions; +}; + +inline hkaSkeleton::LocalFrameOnBone::LocalFrameOnBone() = default; + +inline hkaSkeleton::LocalFrameOnBone::LocalFrameOnBone(hkFinishLoadedObjectFlag f) + : m_localFrame(f) {} + +inline void hkaSkeleton::Partition::initWithoutName(hkInt16 startBoneIndex, hkInt16 numBones) { + m_startBoneIndex = startBoneIndex; + m_numBones = numBones; +} + +inline hkBool32 hkaSkeleton::Partition::isBonePresentWithinPartition(hkInt16 boneIndex) const { + return hkMath::intInRange(boneIndex, m_startBoneIndex, m_startBoneIndex + m_numBones); +} + +inline hkInt16 hkaSkeleton::Partition::getEndBoneIndex() const { + return hkInt16(m_startBoneIndex + m_numBones - 1); +} + +inline hkaSkeleton::hkaSkeleton() = default; + +inline hkaSkeleton::hkaSkeleton(const hkaSkeleton& skel) : hkReferencedObject(skel) { + m_name = skel.m_name; + m_parentIndices = skel.m_parentIndices; + m_bones = skel.m_bones; + m_referencePose = skel.m_referencePose; + m_referenceFloats = skel.m_referenceFloats; + m_floatSlots = skel.m_floatSlots; + m_localFrames = skel.m_localFrames; + m_partitions = skel.m_partitions; +} + +inline hkaSkeleton::hkaSkeleton(hkFinishLoadedObjectFlag f) + : hkReferencedObject(f), m_name(f), m_parentIndices(f), m_bones(f), m_referencePose(f), + m_referenceFloats(f), m_floatSlots(f), m_localFrames(f), m_partitions(f) {} + +inline hkLocalFrame* hkaSkeleton::getLocalFrameForBone(int boneIndex) const { + for (int i = 0; i < m_localFrames.getSize(); i++) { + if (m_localFrames[i].m_boneIndex == boneIndex) + return m_localFrames[i].m_localFrame; + if (m_localFrames[i].m_boneIndex > boneIndex) + break; + } + return nullptr; +} + +inline hkInt16 hkaSkeleton::getPartitionIndexFromName(const char* partitionName) const { + const int numPartitions = m_partitions.getSize(); + + for (hkInt16 i = 0; i < numPartitions; ++i) { + if (hkString::strCmp(partitionName, m_partitions[i].m_name) == 0) + return i; + } + return -1; +} + +inline hkInt16 hkaSkeleton::getPartitionIndexForBone(hkInt16 boneIndex) const { + const int numPartitions = m_partitions.getSize(); + + for (hkInt16 i = 0; i < numPartitions; ++i) { + if (m_partitions[i].isBonePresentWithinPartition(boneIndex)) + return i; + } + return -1; +} diff --git a/lib/hkStubs/Havok/Animation/Physics2012Bridge/Instance/hkaRagdollInstance.h b/lib/hkStubs/Havok/Animation/Physics2012Bridge/Instance/hkaRagdollInstance.h new file mode 100644 index 00000000..090878f3 --- /dev/null +++ b/lib/hkStubs/Havok/Animation/Physics2012Bridge/Instance/hkaRagdollInstance.h @@ -0,0 +1,129 @@ +#pragma once + +#include +#include +#include + +class hkpRigidBody; + +class hkaRagdollInstance : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkaRagdollInstance) + HK_DECLARE_REFLECTION() + + hkaRagdollInstance(const hkArrayBase& rigidBodies, + const hkArrayBase& constraints, + const hkaSkeleton* skeleton); + + /// Same as the above constructor, but the extra bone-to-rigidbody map allows the ragdoll + /// skeleton to have extra bones + hkaRagdollInstance(const hkArrayBase& rigidBodies, + const hkArrayBase& constraints, + const hkaSkeleton* skeleton, const hkArrayBase& boneToRigidBody); + + explicit hkaRagdollInstance(hkFinishLoadedObjectFlag f); + + ~hkaRagdollInstance() override; + + virtual hkaRagdollInstance* clone(hkpConstraintInstance::CloningMode mode) const; + hkaRagdollInstance* clone() const { return clone(hkpConstraintInstance::CLONE_FORCE_SHALLOW); } + + inline int getNumBones() const; + + inline hkpRigidBody* getRigidBodyOfBone(int i) const; + inline int getBoneIndexOfRigidBody(hkpRigidBody* rb) const; + + inline hkpConstraintInstance* getConstraintOfBone(int i) const; + + inline const hkaSkeleton* getSkeleton() const; + + inline int getParentOfBone(int i) const; + + inline const hkArray& getRigidBodyArray() const; + + inline const hkArray& getConstraintArray() const; + + inline hkBool hasNonRigidBodyBones() const; + + void getPoseWorldSpace(hkQsTransform* poseWorldSpaceOut) const; + + void + getPoseWorldSpace(hkQsTransform* poseWorldSpaceOut, const hkQsTransform& worldFromModel, + const hkQsTransform* localSpacePoseForUnmappedBonesOptional = nullptr) const; + + void getApproxCurrentPoseWorldSpace(hkQsTransform* poseWorldSpaceOut) const; + + void getApproxPoseWorldSpaceAt(hkTime time, hkQsTransform* poseWorldSpaceOut) const; + + void setPoseWorldSpace(const hkQsTransform* poseWorldSpaceIn); + + void getPoseModelSpace(hkQsTransform* poseModelSpaceOut, + const hkQsTransform& worldFromModel) const; + + void setPoseModelSpace(const hkQsTransform* poseModelSpaceIn, + const hkQsTransform& worldFromModel); + + void setPoseAndVelocitiesModelSpace(const hkQsTransform* poseModelSpaceA, + const hkQsTransform& worldFromModelA, + const hkQsTransform* poseModelSpaceB, + const hkQsTransform& worldFromModelB, hkReal timestep); + + hkResult addToWorld(hkpWorld* world, hkBool updateFilter) const; + hkResult removeFromWorld() const; + hkpWorld* getWorld() const; + + void getWorldFromBoneTransform(int i, hkQsTransform& worldFromBoneOut) const; + void getApproxWorldFromBoneTransformAt(int i, hkTime time, + hkQsTransform& worldFromBoneOut) const; + + hkArray m_rigidBodies; + hkArray m_constraints; + hkArray m_boneToRigidBodyMap; + hkRefPtr m_skeleton; + +private: + void commonInit(const hkArrayBase& rigidBodies, + const hkArrayBase& constraints, + const hkaSkeleton* skeleton); +}; + +inline int hkaRagdollInstance::getNumBones() const { + return m_skeleton->m_bones.getSize(); +} + +inline hkpRigidBody* hkaRagdollInstance::getRigidBodyOfBone(int i) const { + const int index = m_boneToRigidBodyMap[i]; + return index < 0 ? nullptr : m_rigidBodies[index]; +} + +inline int hkaRagdollInstance::getBoneIndexOfRigidBody(hkpRigidBody* rb) const { + int rbIndex = m_rigidBodies.indexOf(rb); + if (rbIndex == -1) + return -1; + return m_boneToRigidBodyMap.indexOf(rbIndex); +} + +inline hkpConstraintInstance* hkaRagdollInstance::getConstraintOfBone(int i) const { + const int index = m_boneToRigidBodyMap[i] - 1; + return index < 0 ? nullptr : m_constraints[index]; +} + +inline const hkaSkeleton* hkaRagdollInstance::getSkeleton() const { + return m_skeleton; +} + +inline int hkaRagdollInstance::getParentOfBone(int i) const { + return m_skeleton->m_parentIndices[i]; +} + +inline const hkArray& hkaRagdollInstance::getRigidBodyArray() const { + return m_rigidBodies; +} + +inline const hkArray& hkaRagdollInstance::getConstraintArray() const { + return m_constraints; +} + +inline hkBool hkaRagdollInstance::hasNonRigidBodyBones() const { + return m_rigidBodies.getSize() != m_skeleton->m_bones.getSize(); +} diff --git a/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h b/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h index f9aa8ee7..a4afe8d6 100644 --- a/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h +++ b/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h @@ -241,6 +241,18 @@ inline void hkArrayBase::removeAtAndCopy(int index, int numToRemove) { (m_size - index) * sizeof(T)); } +template +inline int hkArrayBase::indexOf(const T& t, int start, int end) const { + if (end < 0) + end = m_size; + + for (int i = start; i < end; ++i) { + if (m_data[i] == t) + return i; + } + return -1; +} + template inline void hkArrayBase::popBack(int numElemsToRemove) { hkArrayUtil::destruct(m_data + m_size - numElemsToRemove, numElemsToRemove); @@ -359,7 +371,7 @@ inline hkArrayBase& hkArrayBase::copyFromArray(hkMemoryAllocator& allocato if ((m_capacityAndFlags & DONT_DEALLOCATE_FLAG) == 0) { allocator._bufFree(m_data, getCapacity()); } - const int n = src.getSize(); + int n = src.getSize(); m_data = allocator._bufAlloc(n); m_capacityAndFlags = n; } diff --git a/lib/hkStubs/Havok/Common/Base/Math/Header/hkMathHeaderConstants.h b/lib/hkStubs/Havok/Common/Base/Math/Header/hkMathHeaderConstants.h index b4e9a352..dea258a8 100644 --- a/lib/hkStubs/Havok/Common/Base/Math/Header/hkMathHeaderConstants.h +++ b/lib/hkStubs/Havok/Common/Base/Math/Header/hkMathHeaderConstants.h @@ -2,6 +2,9 @@ #include +#define HK_INT32_MIN (-2147483647 - 1) +#define HK_INT32_MAX 2147483647 + #define HK_FLOAT_PI 3.14159265358979f #define HK_FLOAT_DEG_TO_RAD (HK_FLOAT_PI / 180.0f) #define HK_FLOAT_RAD_TO_DEG (180.0f / HK_FLOAT_PI) diff --git a/lib/hkStubs/Havok/Common/Base/Math/QsTransform/hkQsTransformf.h b/lib/hkStubs/Havok/Common/Base/Math/QsTransform/hkQsTransformf.h index 72f8d268..8a602afc 100644 --- a/lib/hkStubs/Havok/Common/Base/Math/QsTransform/hkQsTransformf.h +++ b/lib/hkStubs/Havok/Common/Base/Math/QsTransform/hkQsTransformf.h @@ -21,6 +21,7 @@ public: hkQuaternionfParameter rotation); HK_FORCE_INLINE hkQsTransformf(const hkQsTransformf& other); + hkQsTransformf& operator=(const hkQsTransformf&) = default; HK_FORCE_INLINE const hkVector4f& getTranslation() const; HK_FORCE_INLINE const hkQuaternionf& getRotation() const; diff --git a/lib/hkStubs/Havok/Common/Base/Math/hkMath.h b/lib/hkStubs/Havok/Common/Base/Math/hkMath.h index 83c24e8a..055af896 100644 --- a/lib/hkStubs/Havok/Common/Base/Math/hkMath.h +++ b/lib/hkStubs/Havok/Common/Base/Math/hkMath.h @@ -55,4 +55,8 @@ HK_FORCE_INLINE int hkToIntFast(hkFloat32 r) { return int(r); } +HK_FORCE_INLINE hkBool32 intInRange(int value, int lowInclusive, int highExclusive) { + return (lowInclusive <= value) & (value < highExclusive); +} + } // namespace hkMath diff --git a/lib/hkStubs/Havok/Common/Base/Types/Geometry/LocalFrame/hkLocalFrame.h b/lib/hkStubs/Havok/Common/Base/Types/Geometry/LocalFrame/hkLocalFrame.h new file mode 100644 index 00000000..87e4746f --- /dev/null +++ b/lib/hkStubs/Havok/Common/Base/Types/Geometry/LocalFrame/hkLocalFrame.h @@ -0,0 +1,100 @@ +#pragma once + +#include + +class hkLocalFrameCollector; +class hkLocalFrameGroup; + +class hkLocalFrame : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkLocalFrame) + HK_DECLARE_REFLECTION() + + hkLocalFrame() {} + explicit hkLocalFrame(hkFinishLoadedObjectFlag flag) : hkReferencedObject(flag) {} + + void getTransformToRoot(hkTransform& transform) const; + + void getPositionInRoot(hkVector4& position) const; + + virtual void getLocalTransform(hkTransform& transform) const = 0; + virtual void setLocalTransform(const hkTransform& transform) = 0; + + virtual void getLocalPosition(hkVector4& position) const; + + virtual void getNearbyFrames(const hkVector4& target, hkReal maxDistance, + hkLocalFrameCollector& collector) const = 0; + + virtual const char* getName() const = 0; + + virtual const hkLocalFrame* getParentFrame() const = 0; + virtual void setParentFrame(const hkLocalFrame* parentFrame) = 0; + + virtual int getNumChildFrames() const = 0; + virtual hkLocalFrame* getChildFrame(int i) const = 0; + + virtual const hkLocalFrameGroup* getGroup() const = 0; + virtual void setGroup(const hkLocalFrameGroup* localFrameGroup) = 0; + + virtual void getDescendants(hkArrayBase& descendants, + hkMemoryAllocator& a) const; + + HK_FORCE_INLINE void getDescendants(hkArray& descendants) const { + getDescendants(descendants, hkContainerHeapAllocator::get()); + } +}; + +class hkLocalFrameCollector : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkLocalFrameCollector) + + virtual void addFrame(const hkLocalFrame* frame, hkReal distance) = 0; +}; + +class hkLocalFrameGroup : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkLocalFrameGroup) + HK_DECLARE_REFLECTION() + + explicit hkLocalFrameGroup(const char* name) : m_name(name) {} + + explicit hkLocalFrameGroup(hkFinishLoadedObjectFlag flag) + : hkReferencedObject(flag), m_name(flag) {} + + const char* getName() const { return m_name; } + +private: + hkStringPtr m_name; +}; + +class hkSimpleLocalFrame : public hkLocalFrame { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkSimpleLocalFrame) + HK_DECLARE_REFLECTION() + + hkSimpleLocalFrame() : m_parentFrame(nullptr), m_group(nullptr), m_name(nullptr) {} + + explicit hkSimpleLocalFrame(hkFinishLoadedObjectFlag flag) + : hkLocalFrame(flag), m_children(flag), m_name(flag) {} + + ~hkSimpleLocalFrame() override; + + void getLocalTransform(hkTransform& transform) const override; + void setLocalTransform(const hkTransform& transform) override; + void getLocalPosition(hkVector4& position) const override; + void getNearbyFrames(const hkVector4& target, hkReal maxDistance, + hkLocalFrameCollector& collector) const override; + const char* getName() const override { return m_name; } + const hkLocalFrame* getParentFrame() const override { return m_parentFrame; } + void setParentFrame(const hkLocalFrame* parentFrame) override { m_parentFrame = parentFrame; } + int getNumChildFrames() const override; + hkLocalFrame* getChildFrame(int i) const override; + const hkLocalFrameGroup* getGroup() const override { return m_group; } + void setGroup(const hkLocalFrameGroup* group) override; + + hkTransform m_transform; + hkArray m_children; + const hkLocalFrame* m_parentFrame; + const hkLocalFrameGroup* m_group; + hkStringPtr m_name; +};