mirror of https://github.com/zeldaret/botw.git
ksys/phys: Add ListShape
This commit is contained in:
parent
4a1bb88bd5
commit
bc66305e3d
|
@ -83603,27 +83603,27 @@ Address,Quality,Size,Name
|
|||
0x0000007100fabf40,O,000204,_ZNK4ksys4phys12CapsuleShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100fac00c,O,000092,_ZNK4ksys4phys12CapsuleShape18getRuntimeTypeInfoEv
|
||||
0x0000007100fac068,O,000008,_ZNK4ksys4phys12CapsuleShape7getTypeEv
|
||||
0x0000007100fac070,U,000420,
|
||||
0x0000007100fac214,U,000192,
|
||||
0x0000007100fac2d4,U,000884,
|
||||
0x0000007100fac648,U,000316,
|
||||
0x0000007100fac784,U,000036,
|
||||
0x0000007100fac7a8,U,000156,
|
||||
0x0000007100fac844,U,000156,
|
||||
0x0000007100fac8e0,U,000156,
|
||||
0x0000007100fac97c,U,000156,
|
||||
0x0000007100faca18,U,000156,
|
||||
0x0000007100facab4,U,000156,
|
||||
0x0000007100facb50,U,001052,
|
||||
0x0000007100facf6c,U,001044,
|
||||
0x0000007100fad380,U,000152,
|
||||
0x0000007100fad418,U,000008,
|
||||
0x0000007100fad420,U,000008,
|
||||
0x0000007100fad428,U,000796,
|
||||
0x0000007100fad744,U,000160,
|
||||
0x0000007100fad7e4,U,000204,
|
||||
0x0000007100fad8b0,U,000092,
|
||||
0x0000007100fad90c,U,000008,
|
||||
0x0000007100fac070,O,000420,_ZN4ksys4phys9ListShape4makeERKNS0_14ListShapeParamEPN4sead4HeapE
|
||||
0x0000007100fac214,O,000192,_ZNK4ksys4phys9ListShape5cloneEPN4sead4HeapE
|
||||
0x0000007100fac2d4,O,000884,_ZN4ksys4phys9ListShape16replaceWithCloneEiPKNS0_5ShapeEPN4sead4HeapE
|
||||
0x0000007100fac648,O,000316,_ZN4ksys4phys9ListShapeD1Ev
|
||||
0x0000007100fac784,O,000036,_ZN4ksys4phys9ListShapeD0Ev
|
||||
0x0000007100fac7a8,O,000156,_ZN4ksys4phys9ListShape20replaceWithNewSphereEiRKNS0_16SphereShapeParamEPN4sead4HeapE
|
||||
0x0000007100fac844,O,000156,_ZN4ksys4phys9ListShape21replaceWithNewCapsuleEiRKNS0_17CapsuleShapeParamEPN4sead4HeapE
|
||||
0x0000007100fac8e0,O,000156,_ZN4ksys4phys9ListShape22replaceWithNewCylinderEiRKNS0_18CylinderShapeParamEPN4sead4HeapE
|
||||
0x0000007100fac97c,O,000156,_ZN4ksys4phys9ListShape17replaceWithNewBoxEiRKNS0_13BoxShapeParamEPN4sead4HeapE
|
||||
0x0000007100faca18,O,000156,_ZN4ksys4phys9ListShape22replaceWithNewPolytopeEiRKNS0_18PolytopeShapeParamEPN4sead4HeapE
|
||||
0x0000007100facab4,O,000156,_ZN4ksys4phys9ListShape28replaceWithNewCharacterPrismEiRKNS0_24CharacterPrismShapeParamEPN4sead4HeapE
|
||||
0x0000007100facb50,O,001052,_ZN4ksys4phys9ListShape15setMaterialMaskERKNS0_12MaterialMaskEi
|
||||
0x0000007100facf6c,O,001044,_ZNK4ksys4phys9ListShape15getMaterialMaskEi
|
||||
0x0000007100fad380,O,000152,_ZNK4ksys4phys9ListShape9getVolumeEv
|
||||
0x0000007100fad418,O,000008,_ZN4ksys4phys9ListShape13getHavokShapeEv
|
||||
0x0000007100fad420,O,000008,_ZNK4ksys4phys9ListShape13getHavokShapeEv
|
||||
0x0000007100fad428,O,000796,_ZN4ksys4phys9ListShape16updateHavokShapeEv
|
||||
0x0000007100fad744,O,000160,_ZN4ksys4phys9ListShape8setScaleEf
|
||||
0x0000007100fad7e4,O,000204,_ZNK4ksys4phys9ListShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100fad8b0,O,000092,_ZNK4ksys4phys9ListShape18getRuntimeTypeInfoEv
|
||||
0x0000007100fad90c,O,000008,_ZNK4ksys4phys9ListShape7getTypeEv
|
||||
0x0000007100fad914,O,000344,_ZN4ksys4phys13CylinderShape4makeERKNS0_18CylinderShapeParamEPN4sead4HeapE
|
||||
0x0000007100fada6c,O,000032,_ZN4ksys4phys13CylinderShape15setMaterialMaskERKNS0_12MaterialMaskE
|
||||
0x0000007100fada8c,O,000064,_ZN4ksys4phys13CylinderShapeD1Ev
|
||||
|
|
Can't render this file because it is too large.
|
|
@ -34,6 +34,9 @@ public:
|
|||
HK_FORCE_INLINE int getCapacityAndFlags() const;
|
||||
HK_FORCE_INLINE hkBool isEmpty() const;
|
||||
|
||||
HK_FORCE_INLINE T* data() { return m_data; }
|
||||
HK_FORCE_INLINE const T* data() const { return m_data; }
|
||||
|
||||
HK_FORCE_INLINE T& operator[](int i);
|
||||
HK_FORCE_INLINE const T& operator[](int i) const;
|
||||
|
||||
|
|
|
@ -64,6 +64,10 @@ target_sources(uking PRIVATE
|
|||
RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h
|
||||
RigidBody/Shape/CylinderWater/physCylinderWaterShape.cpp
|
||||
RigidBody/Shape/CylinderWater/physCylinderWaterShape.h
|
||||
RigidBody/Shape/List/physListShape.cpp
|
||||
RigidBody/Shape/List/physListShape.h
|
||||
RigidBody/Shape/List/physListShapeRigidBody.cpp
|
||||
RigidBody/Shape/List/physListShapeRigidBody.h
|
||||
RigidBody/Shape/Polytope/physPolytopeRigidBody.cpp
|
||||
RigidBody/Shape/Polytope/physPolytopeRigidBody.h
|
||||
RigidBody/Shape/Polytope/physPolytopeShape.cpp
|
||||
|
@ -133,4 +137,5 @@ target_sources(uking PRIVATE
|
|||
System/physUserTag.h
|
||||
|
||||
physConversions.h
|
||||
physHeapUtil.h
|
||||
)
|
||||
|
|
|
@ -145,7 +145,7 @@ const hkpShape* BoxShape::updateHavokShape() {
|
|||
|
||||
if (mFlags.isOn(Flag::DirtyTransform)) {
|
||||
mFlags.reset(Flag::DirtyTransform);
|
||||
return std::as_const(*this).getHavokShape();
|
||||
return getHavokShapeConst();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
bool setExtents(const sead::Vector3f& extents);
|
||||
bool setTranslate(const sead::Vector3f& translate);
|
||||
void setMaterialMask(const MaterialMask& mask);
|
||||
const MaterialMask& getMaterialMask() const { return mMaterialMask; }
|
||||
|
||||
ShapeType getType() const override { return ShapeType::Box; }
|
||||
float getVolume() const override;
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
bool setVertices(const sead::Vector3f& va, const sead::Vector3f& vb);
|
||||
void transformVertices(sead::Vector3f* veca, sead::Vector3f* vecb, const hkTransformf& rb_vec);
|
||||
void setMaterialMask(const MaterialMask& mask);
|
||||
const MaterialMask& getMaterialMask() const { return material_mask; }
|
||||
|
||||
sead::Vector3f vertex_a;
|
||||
sead::TypedBitFlag<Flag, sead::Atomic<u32>> flags{};
|
||||
|
|
|
@ -12,4 +12,14 @@ struct CharacterPrismShapeParam {
|
|||
CommonShapeParam common;
|
||||
};
|
||||
|
||||
class CharacterPrismShape : public Shape {
|
||||
SEAD_RTTI_OVERRIDE(CharacterPrismShape, Shape)
|
||||
public:
|
||||
static CharacterPrismShape* make(const CharacterPrismShapeParam& param, sead::Heap* heap);
|
||||
CharacterPrismShape* clone(sead::Heap* heap) const;
|
||||
|
||||
void setMaterialMask(const MaterialMask& mask);
|
||||
const MaterialMask& getMaterialMask() const;
|
||||
};
|
||||
|
||||
} // namespace ksys::phys
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
#include "KingSystem/Physics/RigidBody/Shape/List/physListShape.h"
|
||||
#include <Havok/Physics2012/Collide/Shape/Compound/Collection/List/hkpListShape.h>
|
||||
#include <Havok/Physics2012/Collide/Shape/Convex/Sphere/hkpSphereShape.h>
|
||||
#include <basis/seadRawPrint.h>
|
||||
#include <container/seadSafeArray.h>
|
||||
#include "KingSystem/Physics/RigidBody/Shape/Box/physBoxShape.h"
|
||||
#include "KingSystem/Physics/RigidBody/Shape/Capsule/physCapsuleShape.h"
|
||||
#include "KingSystem/Physics/RigidBody/Shape/CharacterPrism/physCharacterPrismShape.h"
|
||||
#include "KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderShape.h"
|
||||
#include "KingSystem/Physics/RigidBody/Shape/Polytope/physPolytopeShape.h"
|
||||
#include "KingSystem/Physics/RigidBody/Shape/Sphere/physSphereShape.h"
|
||||
#include "KingSystem/Physics/physHeapUtil.h"
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
ListShape* ListShape::make(const ListShapeParam& param, sead::Heap* heap) {
|
||||
auto* sphere = new hkpSphereShape(1.0);
|
||||
if (!sphere)
|
||||
return nullptr;
|
||||
|
||||
auto shapes = sead::toArray<const hkpShape*>({sphere});
|
||||
auto* list_shape = new hkpListShape(shapes.getBufferPtr(), shapes.size());
|
||||
sphere->removeReference();
|
||||
|
||||
if (!list_shape)
|
||||
return nullptr;
|
||||
|
||||
return new (heap) ListShape(param, list_shape, heap);
|
||||
}
|
||||
|
||||
ListShape* ListShape::clone(sead::Heap* heap) const {
|
||||
ListShapeParam param;
|
||||
param.num_shapes = static_cast<decltype(param.num_shapes)>(mShapes.size());
|
||||
|
||||
auto* cloned = make(param, heap);
|
||||
if (!cloned)
|
||||
return nullptr;
|
||||
|
||||
for (int i = 0, n = mShapes.size(); i < n; ++i)
|
||||
cloned->replaceWithClone(i, mShapes[i], heap);
|
||||
|
||||
return cloned;
|
||||
}
|
||||
|
||||
ListShape::ListShape(const ListShapeParam& param, hkpListShape* shape, sead::Heap* heap)
|
||||
: mHavokShape(shape) {
|
||||
mShapes.allocBufferAssert(param.num_shapes, heap);
|
||||
for (int i = 0; i < int(param.num_shapes); ++i)
|
||||
mShapes[i] = nullptr;
|
||||
}
|
||||
|
||||
ListShape::~ListShape() {
|
||||
deleteRefCountedHavokObject(mHavokShape);
|
||||
|
||||
for (int i = 0, n = mShapes.size(); i < n; ++i) {
|
||||
if (mShapes[i]) {
|
||||
delete mShapes[i];
|
||||
mShapes[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
mShapes.freeBuffer();
|
||||
}
|
||||
|
||||
Shape* ListShape::replaceWithClone(int index, const Shape* shape_to_clone, sead::Heap* heap) {
|
||||
delete mShapes[index];
|
||||
|
||||
switch (shape_to_clone->getType()) {
|
||||
case ShapeType::Sphere:
|
||||
mShapes[index] = sead::DynamicCast<const SphereShape>(shape_to_clone)->clone(heap);
|
||||
break;
|
||||
case ShapeType::Capsule:
|
||||
mShapes[index] = sead::DynamicCast<const CapsuleShape>(shape_to_clone)->clone(heap);
|
||||
break;
|
||||
case ShapeType::Box:
|
||||
mShapes[index] = sead::DynamicCast<const BoxShape>(shape_to_clone)->clone(heap);
|
||||
break;
|
||||
case ShapeType::Cylinder:
|
||||
mShapes[index] = sead::DynamicCast<const CylinderShape>(shape_to_clone)->clone(heap);
|
||||
break;
|
||||
case ShapeType::Polytope:
|
||||
mShapes[index] = sead::DynamicCast<const PolytopeShape>(shape_to_clone)->clone(heap);
|
||||
break;
|
||||
case ShapeType::CharacterPrism:
|
||||
mShapes[index] = sead::DynamicCast<const CharacterPrismShape>(shape_to_clone)->clone(heap);
|
||||
break;
|
||||
case ShapeType::List:
|
||||
case ShapeType::BoxWater:
|
||||
case ShapeType::CylinderWater:
|
||||
case ShapeType::Unknown:
|
||||
SEAD_ASSERT_MSG(false, "unexpected shape type");
|
||||
break;
|
||||
}
|
||||
|
||||
mFlags.set(Flag::NeedsHavokShapeUpdate);
|
||||
return mShapes[index];
|
||||
}
|
||||
|
||||
Shape* ListShape::replaceWithNewSphere(int index, const SphereShapeParam& param, sead::Heap* heap) {
|
||||
return replaceWithNewShape<SphereShape, SphereShapeParam>(index, param, heap);
|
||||
}
|
||||
|
||||
Shape* ListShape::replaceWithNewCapsule(int index, const CapsuleShapeParam& param,
|
||||
sead::Heap* heap) {
|
||||
return replaceWithNewShape<CapsuleShape, CapsuleShapeParam>(index, param, heap);
|
||||
}
|
||||
|
||||
Shape* ListShape::replaceWithNewCylinder(int index, const CylinderShapeParam& param,
|
||||
sead::Heap* heap) {
|
||||
return replaceWithNewShape<CylinderShape, CylinderShapeParam>(index, param, heap);
|
||||
}
|
||||
|
||||
Shape* ListShape::replaceWithNewBox(int index, const BoxShapeParam& param, sead::Heap* heap) {
|
||||
return replaceWithNewShape<BoxShape, BoxShapeParam>(index, param, heap);
|
||||
}
|
||||
|
||||
Shape* ListShape::replaceWithNewPolytope(int index, const PolytopeShapeParam& param,
|
||||
sead::Heap* heap) {
|
||||
return replaceWithNewShape<PolytopeShape, PolytopeShapeParam>(index, param, heap);
|
||||
}
|
||||
|
||||
Shape* ListShape::replaceWithNewCharacterPrism(int index, const CharacterPrismShapeParam& param,
|
||||
sead::Heap* heap) {
|
||||
return replaceWithNewShape<CharacterPrismShape, CharacterPrismShapeParam>(index, param, heap);
|
||||
}
|
||||
|
||||
void ListShape::setMaterialMask(const MaterialMask& mask, int index) {
|
||||
switch (mShapes[index]->getType()) {
|
||||
case ShapeType::Sphere:
|
||||
sead::DynamicCast<SphereShape>(mShapes[index])->setMaterialMask(mask);
|
||||
break;
|
||||
case ShapeType::Capsule:
|
||||
sead::DynamicCast<CapsuleShape>(mShapes[index])->setMaterialMask(mask);
|
||||
break;
|
||||
case ShapeType::Box:
|
||||
sead::DynamicCast<BoxShape>(mShapes[index])->setMaterialMask(mask);
|
||||
break;
|
||||
case ShapeType::Cylinder:
|
||||
sead::DynamicCast<CylinderShape>(mShapes[index])->setMaterialMask(mask);
|
||||
break;
|
||||
case ShapeType::Polytope:
|
||||
sead::DynamicCast<PolytopeShape>(mShapes[index])->setMaterialMask(mask);
|
||||
break;
|
||||
case ShapeType::CharacterPrism:
|
||||
sead::DynamicCast<CharacterPrismShape>(mShapes[index])->setMaterialMask(mask);
|
||||
break;
|
||||
case ShapeType::List:
|
||||
case ShapeType::BoxWater:
|
||||
case ShapeType::CylinderWater:
|
||||
case ShapeType::Unknown:
|
||||
SEAD_ASSERT_MSG(false, "unexpected shape type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const MaterialMask& ListShape::getMaterialMask(int index) const {
|
||||
if (index >= mShapes.size())
|
||||
index = 0;
|
||||
|
||||
switch (mShapes[index]->getType()) {
|
||||
case ShapeType::Sphere:
|
||||
return sead::DynamicCast<SphereShape>(mShapes[index])->getMaterialMask();
|
||||
case ShapeType::Capsule:
|
||||
return sead::DynamicCast<CapsuleShape>(mShapes[index])->getMaterialMask();
|
||||
case ShapeType::Box:
|
||||
return sead::DynamicCast<BoxShape>(mShapes[index])->getMaterialMask();
|
||||
case ShapeType::Cylinder:
|
||||
return sead::DynamicCast<CylinderShape>(mShapes[index])->getMaterialMask();
|
||||
case ShapeType::Polytope:
|
||||
return sead::DynamicCast<PolytopeShape>(mShapes[index])->getMaterialMask();
|
||||
case ShapeType::CharacterPrism:
|
||||
return sead::DynamicCast<CharacterPrismShape>(mShapes[index])->getMaterialMask();
|
||||
case ShapeType::List:
|
||||
case ShapeType::BoxWater:
|
||||
case ShapeType::CylinderWater:
|
||||
case ShapeType::Unknown:
|
||||
SEAD_ASSERT_MSG(false, "unexpected shape type");
|
||||
break;
|
||||
}
|
||||
return sead::DynamicCast<SphereShape>(mShapes[index])->getMaterialMask();
|
||||
}
|
||||
|
||||
float ListShape::getVolume() const {
|
||||
float volume = 0.0;
|
||||
for (int i = 0, n = mShapes.size(); i < n; ++i) {
|
||||
if (mShapes[i])
|
||||
volume += mShapes[i]->getVolume();
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
|
||||
hkpShape* ListShape::getHavokShape() {
|
||||
return mHavokShape;
|
||||
}
|
||||
|
||||
const hkpShape* ListShape::getHavokShape() const {
|
||||
return mHavokShape;
|
||||
}
|
||||
|
||||
const hkpShape* ListShape::updateHavokShape() {
|
||||
bool updated = false;
|
||||
|
||||
if (mFlags.isOn(Flag::NeedsHavokShapeUpdate)) {
|
||||
hkArray<const hkpShape*> havok_shapes;
|
||||
int num_shapes = 0;
|
||||
|
||||
for (int i = 0, n = mShapes.size(); i < n; ++i) {
|
||||
if (!mShapes[i])
|
||||
continue;
|
||||
|
||||
const hkpShape* havok_shape = mShapes[i]->updateHavokShape();
|
||||
if (havok_shape) {
|
||||
// If one of the shapes was recreated, then we need to recreate the list shape.
|
||||
havok_shapes.pushBack(havok_shape);
|
||||
updated = true;
|
||||
} else {
|
||||
havok_shape = mShapes[i]->getHavokShapeConst();
|
||||
havok_shapes.pushBack(havok_shape);
|
||||
|
||||
// Otherwise, we only need to recreate the list shape if the list has changed.
|
||||
if (!updated && mHavokShape->m_childInfo.getSize() > num_shapes &&
|
||||
mHavokShape->getChildShapeInl(num_shapes) != havok_shapes[num_shapes]) {
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
++num_shapes;
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
const auto collision_filter_info =
|
||||
mHavokShape->getCollisionFilterInfo(mHavokShape->getFirstKey());
|
||||
|
||||
mHavokShape->removeReference();
|
||||
mHavokShape = new hkpListShape(havok_shapes.data(), num_shapes);
|
||||
|
||||
for (auto key = mHavokShape->getFirstKey(); key != HK_INVALID_SHAPE_KEY;
|
||||
key = mHavokShape->getNextKey(key)) {
|
||||
mHavokShape->setCollisionFilterInfo(key, collision_filter_info);
|
||||
}
|
||||
} else {
|
||||
mHavokShape->recalcAabbExtents();
|
||||
}
|
||||
|
||||
mFlags.reset(Flag::NeedsHavokShapeUpdate);
|
||||
}
|
||||
|
||||
return updated ? mHavokShape : nullptr;
|
||||
}
|
||||
|
||||
void ListShape::setScale(float scale) {
|
||||
for (int i = 0, n = mShapes.size(); i < n; ++i) {
|
||||
if (mShapes[i])
|
||||
mShapes[i]->setScale(scale);
|
||||
}
|
||||
|
||||
mFlags.set(Flag::NeedsHavokShapeUpdate);
|
||||
}
|
||||
|
||||
} // namespace ksys::phys
|
|
@ -0,0 +1,107 @@
|
|||
#pragma once
|
||||
|
||||
#include <container/seadBuffer.h>
|
||||
#include <prim/seadTypedBitFlag.h>
|
||||
#include <thread/seadAtomic.h>
|
||||
#include "KingSystem/Physics/RigidBody/Shape/physShape.h"
|
||||
#include "KingSystem/Physics/RigidBody/physRigidBodyParam.h"
|
||||
|
||||
class hkpListShape;
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
struct BoxShapeParam;
|
||||
struct CapsuleShapeParam;
|
||||
struct CharacterPrismShapeParam;
|
||||
struct CylinderShapeParam;
|
||||
struct PolytopeShapeParam;
|
||||
struct SphereShapeParam;
|
||||
|
||||
class MaterialMask;
|
||||
|
||||
struct ListShapeParam {
|
||||
u8 num_shapes = 1;
|
||||
};
|
||||
|
||||
class ListShape : public Shape {
|
||||
SEAD_RTTI_OVERRIDE(ListShape, Shape)
|
||||
public:
|
||||
static ListShape* make(const ListShapeParam& param, sead::Heap* heap);
|
||||
ListShape* clone(sead::Heap* heap) const;
|
||||
|
||||
ListShape(const ListShapeParam& param, hkpListShape* shape, sead::Heap* heap);
|
||||
~ListShape() override;
|
||||
|
||||
/// Replace the shape at the specified index with a clone of `shape_to_clone`.
|
||||
/// The shape that is being replaced will be deleted.
|
||||
/// @return the cloned heap
|
||||
Shape* replaceWithClone(int index, const Shape* shape_to_clone, sead::Heap* heap);
|
||||
|
||||
/// Replace the shape at the specified index with a new sphere shape.
|
||||
/// The shape that is being replaced will be deleted.
|
||||
Shape* replaceWithNewSphere(int index, const SphereShapeParam& param, sead::Heap* heap);
|
||||
|
||||
/// Replace the shape at the specified index with a new capsule shape.
|
||||
/// The shape that is being replaced will be deleted.
|
||||
Shape* replaceWithNewCapsule(int index, const CapsuleShapeParam& param, sead::Heap* heap);
|
||||
|
||||
/// Replace the shape at the specified index with a new cylinder shape.
|
||||
/// The shape that is being replaced will be deleted.
|
||||
Shape* replaceWithNewCylinder(int index, const CylinderShapeParam& param, sead::Heap* heap);
|
||||
|
||||
/// Replace the shape at the specified index with a new box shape.
|
||||
/// The shape that is being replaced will be deleted.
|
||||
Shape* replaceWithNewBox(int index, const BoxShapeParam& param, sead::Heap* heap);
|
||||
|
||||
/// Replace the shape at the specified index with a new polytope shape.
|
||||
/// The shape that is being replaced will be deleted.
|
||||
Shape* replaceWithNewPolytope(int index, const PolytopeShapeParam& param, sead::Heap* heap);
|
||||
|
||||
/// Replace the shape at the specified index with a new character prism.
|
||||
/// The shape that is being replaced will be deleted.
|
||||
Shape* replaceWithNewCharacterPrism(int index, const CharacterPrismShapeParam& param,
|
||||
sead::Heap* heap);
|
||||
|
||||
/// Set the material mask for the shape at the specified index.
|
||||
void setMaterialMask(const MaterialMask& mask, int index);
|
||||
|
||||
/// Get the material mask for the shape at the specified index.
|
||||
const MaterialMask& getMaterialMask(int index) const;
|
||||
|
||||
ShapeType getType() const override { return ShapeType::List; }
|
||||
float getVolume() const override;
|
||||
hkpShape* getHavokShape() override;
|
||||
const hkpShape* getHavokShape() const override;
|
||||
const hkpShape* updateHavokShape() override;
|
||||
void setScale(float scale) override;
|
||||
|
||||
private:
|
||||
enum class Flag {
|
||||
/// Whether the Havok list shape needs to be recreated.
|
||||
NeedsHavokShapeUpdate = 1 << 0,
|
||||
};
|
||||
|
||||
template <typename T, typename ParamType>
|
||||
Shape* replaceWithNewShape(int index, const ParamType& param, sead::Heap* heap) {
|
||||
delete mShapes[index];
|
||||
auto* shape = T::make(param, heap);
|
||||
mShapes[index] = shape;
|
||||
mFlags.set(Flag::NeedsHavokShapeUpdate);
|
||||
return shape;
|
||||
}
|
||||
|
||||
/// Child shapes. These are owned by this class.
|
||||
sead::Buffer<Shape*> mShapes;
|
||||
/// The Havok list shape. This is owned by this class.
|
||||
hkpListShape* mHavokShape{};
|
||||
sead::TypedBitFlag<Flag, sead::Atomic<u32>> mFlags{Flag::NeedsHavokShapeUpdate};
|
||||
};
|
||||
|
||||
class ListShapeRigidBodyParam : public RigidBodyInstanceParam {
|
||||
SEAD_RTTI_OVERRIDE(ListShapeRigidBodyParam, RigidBodyInstanceParam)
|
||||
public:
|
||||
u8 _90;
|
||||
ListShapeParam shape;
|
||||
};
|
||||
|
||||
} // namespace ksys::phys
|
|
@ -0,0 +1 @@
|
|||
#include "KingSystem/Physics/RigidBody/Shape/List/physListShapeRigidBody.h"
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "KingSystem/Physics/RigidBody/physRigidBodyFromShape.h"
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
class ListShapeRigidBody : public RigidBodyFromShape {
|
||||
SEAD_RTTI_OVERRIDE(ListShapeRigidBody, RigidBodyFromShape)
|
||||
public:
|
||||
static ListShapeRigidBody* make(RigidBodyInstanceParam* param, sead::Heap* heap);
|
||||
};
|
||||
|
||||
} // namespace ksys::phys
|
|
@ -4,6 +4,7 @@
|
|||
#include <Havok/Physics2012/Collide/Shape/Convex/ConvexVertices/hkpConvexVerticesShape.h>
|
||||
#include <math/seadMathCalcCommon.h>
|
||||
#include <prim/seadScopedLock.h>
|
||||
#include "KingSystem/Physics/physHeapUtil.h"
|
||||
#include "KingSystem/Utils/HeapUtil.h"
|
||||
#include "KingSystem/Utils/SafeDelete.h"
|
||||
|
||||
|
@ -71,14 +72,7 @@ PolytopeShape::PolytopeShape(const PolytopeShapeParam& param)
|
|||
}
|
||||
|
||||
PolytopeShape::~PolytopeShape() {
|
||||
if (mHavokShape) {
|
||||
/// @bug This is not how reference counting is supposed to work.
|
||||
for (int i = 0, n = mHavokShape->getReferenceCount(); i < n; ++i)
|
||||
mHavokShape->removeReference();
|
||||
|
||||
mHavokShape = nullptr;
|
||||
}
|
||||
|
||||
deleteRefCountedHavokObject(mHavokShape);
|
||||
util::deallocateObjectUnsafe(mTransformShape);
|
||||
mVertices.freeBuffer();
|
||||
}
|
||||
|
@ -147,7 +141,7 @@ const hkpShape* PolytopeShape::updateHavokShape() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return std::as_const(*this).getHavokShape();
|
||||
return getHavokShapeConst();
|
||||
}
|
||||
|
||||
void PolytopeShape::setScale(float scale) {
|
||||
|
|
|
@ -19,6 +19,14 @@ class SphereShape : public Shape {
|
|||
SEAD_RTTI_OVERRIDE(SphereShape, Shape)
|
||||
public:
|
||||
static SphereShape* make(const SphereShapeParam& param, sead::Heap* heap);
|
||||
SphereShape* clone(sead::Heap* heap) const;
|
||||
|
||||
void setMaterialMask(const MaterialMask& mask);
|
||||
const MaterialMask& getMaterialMask() const { return mMaterialMask; }
|
||||
|
||||
private:
|
||||
char _8[0x28 - 0x8];
|
||||
MaterialMask mMaterialMask;
|
||||
};
|
||||
|
||||
class SphereParam : public RigidBodyInstanceParam {
|
||||
|
|
|
@ -15,6 +15,7 @@ enum class ShapeType {
|
|||
Box = 2,
|
||||
Cylinder = 3,
|
||||
Polytope = 4,
|
||||
List = 5,
|
||||
CharacterPrism = 6,
|
||||
BoxWater = 7,
|
||||
CylinderWater = 8,
|
||||
|
@ -29,11 +30,18 @@ public:
|
|||
virtual ShapeType getType() const = 0;
|
||||
virtual float getVolume() const = 0;
|
||||
virtual ~Shape() = default;
|
||||
|
||||
virtual hkpShape* getHavokShape() = 0;
|
||||
virtual const hkpShape* getHavokShape() const = 0;
|
||||
|
||||
/// Update the underlying Havok shape if necessary. This may recreate the Havok shape.
|
||||
/// @return a pointer to the new underlying Havok shape if it was recreated, null otherwise
|
||||
virtual const hkpShape* updateHavokShape() = 0;
|
||||
|
||||
/// @param scale New scale (relative to the current scale)
|
||||
virtual void setScale(float scale) = 0;
|
||||
|
||||
const hkpShape* getHavokShapeConst() const { return getHavokShape(); }
|
||||
};
|
||||
|
||||
struct CommonShapeParam {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <Havok/Common/Base/Object/hkReferencedObject.h>
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
template <typename T>
|
||||
inline std::enable_if_t<std::is_base_of_v<hkReferencedObject, T>, void>
|
||||
deleteRefCountedHavokObject(T*& object) {
|
||||
if (!object)
|
||||
return;
|
||||
|
||||
/// @bug This should just be a delete expression. Decrementing the reference count
|
||||
/// n times (with n = the reference count) is not how reference counting is supposed to work.
|
||||
for (int i = 0, n = object->getReferenceCount(); i < n; ++i)
|
||||
object->removeReference();
|
||||
|
||||
object = nullptr;
|
||||
}
|
||||
|
||||
} // namespace ksys::phys
|
Loading…
Reference in New Issue