Havok: Add ragdoll stuff

This commit is contained in:
Léo Lam 2022-03-27 00:24:52 +01:00
parent 5df0fb2a6d
commit 8c01d32ac4
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
15 changed files with 863 additions and 1 deletions

View File

@ -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

View File

@ -0,0 +1,171 @@
#pragma once
#include <Havok/Animation/Animation/Animation/hkaAnnotationTrack.h>
#include <Havok/Animation/Animation/Motion/hkaAnimatedReferenceFrame.h>
#include <Havok/Common/Base/hkBase.h>
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<hkaAnimation::AnimationType, hkInt32> m_type;
public:
hkReal m_duration;
int m_numberOfTransformTracks;
int m_numberOfFloatTracks;
protected:
hkRefPtr<const hkaAnimatedReferenceFrame> m_extractedMotion;
public:
hkArray<hkaAnnotationTrack> 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);
}

View File

@ -0,0 +1,53 @@
#pragma once
#include <Havok/Animation/Animation/Animation/hkaAnimation.h>
#include <Havok/Animation/Animation/Rig/hkaSkeleton.h>
#include <Havok/Common/Base/hkBase.h>
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<hkaAnimation> m_animation;
hkArray<hkInt16> m_transformTrackToBoneIndices;
hkArray<hkInt16> m_floatTrackToFloatSlotIndices;
hkArray<hkInt16> m_partitionIndices;
hkEnum<BlendHint, hkInt8> 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) {}

View File

@ -0,0 +1,28 @@
#pragma once
#include <Havok/Common/Base/hkBase.h>
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<Annotation> m_annotations;
};

View File

@ -0,0 +1,103 @@
#pragma once
#include <Havok/Animation/Animation/Animation/hkaAnimationBinding.h>
#include <Havok/Animation/Animation/Mapper/hkaSkeletonMapperData.h>
#include <Havok/Animation/Animation/Rig/hkaSkeleton.h>
#include <Havok/Common/Base/hkBase.h>
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<hkInt16>& 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<hkInt16>& 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<hkInt16>& srcBoneToTrackIndicesOut,
hkArray<hkInt16>& dstBoneToTrackIndicesOut,
hkArray<hkInt16>& 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<hkInt16>& 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);
};

View File

@ -0,0 +1,62 @@
#pragma once
#include <Havok/Animation/Animation/Rig/hkaSkeleton.h>
#include <Havok/Common/Base/hkBase.h>
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<hkaSkeleton> m_skeletonA;
hkRefPtr<hkaSkeleton> m_skeletonB;
hkArray<hkInt16> m_partitionMap;
hkArray<PartitionMappingRange> m_simpleMappingPartitionRanges;
hkArray<PartitionMappingRange> m_chainMappingPartitionRanges;
hkArray<SimpleMapping> m_simpleMappings;
hkArray<ChainMapping> m_chainMappings;
hkArray<hkInt16> m_unmappedBones;
hkQsTransform m_extractedMotionMapping;
hkBool m_keepUnmappedLocal;
hkEnum<hkaSkeletonMapperData::MappingType, hkInt32> m_mappingType;
};

View File

@ -0,0 +1,32 @@
#pragma once
#include <Havok/Common/Base/hkBase.h>
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<hkaReferenceFrameTypeEnum, hkInt8> m_frameType;
};

View File

@ -0,0 +1,15 @@
#pragma once
#include <Havok/Common/Base/hkBase.h>
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;
};

View File

@ -0,0 +1,138 @@
#pragma once
#include <Havok/Animation/Animation/Rig/hkaBone.h>
#include <Havok/Common/Base/Types/Geometry/LocalFrame/hkLocalFrame.h>
#include <Havok/Common/Base/hkBase.h>
class hkaSkeleton : public hkReferencedObject {
public:
HK_DECLARE_CLASS_ALLOCATOR(hkaSkeleton)
HK_DECLARE_REFLECTION()
struct LocalFrameOnBone {
HK_DECLARE_CLASS_ALLOCATOR(LocalFrameOnBone)
HK_DECLARE_REFLECTION()
hkRefPtr<hkLocalFrame> 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<hkInt16> m_parentIndices;
hkArray<hkaBone> m_bones;
hkArray<hkQsTransform> m_referencePose;
hkArray<hkReal> m_referenceFloats;
hkArray<hkStringPtr> m_floatSlots;
hkArray<LocalFrameOnBone> m_localFrames;
hkArray<Partition> 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;
}

View File

@ -0,0 +1,129 @@
#pragma once
#include <Havok/Animation/Animation/Rig/hkaSkeleton.h>
#include <Havok/Common/Base/hkBase.h>
#include <Havok/Physics2012/Dynamics/Constraint/hkpConstraintInstance.h>
class hkpRigidBody;
class hkaRagdollInstance : public hkReferencedObject {
public:
HK_DECLARE_CLASS_ALLOCATOR(hkaRagdollInstance)
HK_DECLARE_REFLECTION()
hkaRagdollInstance(const hkArrayBase<hkpRigidBody*>& rigidBodies,
const hkArrayBase<hkpConstraintInstance*>& 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<hkpRigidBody*>& rigidBodies,
const hkArrayBase<hkpConstraintInstance*>& constraints,
const hkaSkeleton* skeleton, const hkArrayBase<int>& 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<hkpRigidBody*>& getRigidBodyArray() const;
inline const hkArray<hkpConstraintInstance*>& 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<hkpRigidBody*> m_rigidBodies;
hkArray<hkpConstraintInstance*> m_constraints;
hkArray<int> m_boneToRigidBodyMap;
hkRefPtr<const hkaSkeleton> m_skeleton;
private:
void commonInit(const hkArrayBase<hkpRigidBody*>& rigidBodies,
const hkArrayBase<hkpConstraintInstance*>& 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<hkpRigidBody*>& hkaRagdollInstance::getRigidBodyArray() const {
return m_rigidBodies;
}
inline const hkArray<hkpConstraintInstance*>& hkaRagdollInstance::getConstraintArray() const {
return m_constraints;
}
inline hkBool hkaRagdollInstance::hasNonRigidBodyBones() const {
return m_rigidBodies.getSize() != m_skeleton->m_bones.getSize();
}

View File

@ -241,6 +241,18 @@ inline void hkArrayBase<T>::removeAtAndCopy(int index, int numToRemove) {
(m_size - index) * sizeof(T));
}
template <typename T>
inline int hkArrayBase<T>::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 <typename T>
inline void hkArrayBase<T>::popBack(int numElemsToRemove) {
hkArrayUtil::destruct(m_data + m_size - numElemsToRemove, numElemsToRemove);
@ -359,7 +371,7 @@ inline hkArrayBase<T>& hkArrayBase<T>::copyFromArray(hkMemoryAllocator& allocato
if ((m_capacityAndFlags & DONT_DEALLOCATE_FLAG) == 0) {
allocator._bufFree<T>(m_data, getCapacity());
}
const int n = src.getSize();
int n = src.getSize();
m_data = allocator._bufAlloc<T>(n);
m_capacityAndFlags = n;
}

View File

@ -2,6 +2,9 @@
#include <cfloat>
#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)

View File

@ -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;

View File

@ -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

View File

@ -0,0 +1,100 @@
#pragma once
#include <Havok/Common/Base/hkBase.h>
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<const hkLocalFrame*>& descendants,
hkMemoryAllocator& a) const;
HK_FORCE_INLINE void getDescendants(hkArray<const hkLocalFrame*>& 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<hkLocalFrame*> m_children;
const hkLocalFrame* m_parentFrame;
const hkLocalFrameGroup* m_group;
hkStringPtr m_name;
};