mirror of https://github.com/zeldaret/botw.git
ksys/phys: Add BoxWaterShape
This commit is contained in:
parent
b87f406cfa
commit
2af9e079d0
|
@ -82101,7 +82101,7 @@ Address,Quality,Size,Name
|
|||
0x0000007100f5dc24,U,000096,
|
||||
0x0000007100f5dc84,U,002704,phys::CharacterControllerRigidBody::create
|
||||
0x0000007100f5e714,U,000060,
|
||||
0x0000007100f5e750,U,000004,hkBaseObject::dtor
|
||||
0x0000007100f5e750,O,000004,_ZN12hkBaseObjectD2Ev
|
||||
0x0000007100f5e754,U,000016,
|
||||
0x0000007100f5e764,U,000140,
|
||||
0x0000007100f5e7f0,U,000096,
|
||||
|
@ -83564,27 +83564,27 @@ Address,Quality,Size,Name
|
|||
0x0000007100faab34,O,000204,_ZNK4ksys4phys8BoxShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100faac00,O,000092,_ZNK4ksys4phys8BoxShape18getRuntimeTypeInfoEv
|
||||
0x0000007100faac5c,O,000008,_ZNK4ksys4phys8BoxShape7getTypeEv
|
||||
0x0000007100faac64,U,000260,
|
||||
0x0000007100faad68,U,000432,
|
||||
0x0000007100faaf18,U,000032,
|
||||
0x0000007100faaf38,U,000380,
|
||||
0x0000007100fab0b4,U,000064,
|
||||
0x0000007100fab0f4,U,000072,
|
||||
0x0000007100fab13c,U,000120,
|
||||
0x0000007100fab1b4,U,000240,
|
||||
0x0000007100fab2a4,U,000020,
|
||||
0x0000007100fab2b8,U,000008,
|
||||
0x0000007100fab2c0,U,000008,
|
||||
0x0000007100fab2c8,U,000308,
|
||||
0x0000007100fab3fc,U,000256,
|
||||
0x0000007100fab4fc,U,000204,
|
||||
0x0000007100fab5c8,U,000092,
|
||||
0x0000007100fab624,U,000008,
|
||||
0x0000007100fab62c,U,000084,
|
||||
0x0000007100fab680,U,000008,
|
||||
0x0000007100fab688,U,000276,
|
||||
0x0000007100fab79c,U,000008,
|
||||
0x0000007100fab7a4,U,000184,
|
||||
0x0000007100faac64,O,000260,_ZN4ksys4phys13BoxWaterShape4makeERKNS0_13BoxShapeParamEPN4sead4HeapE
|
||||
0x0000007100faad68,O,000432,_ZNK4ksys4phys13BoxWaterShape5cloneEPN4sead4HeapE
|
||||
0x0000007100faaf18,O,000032,_ZN4ksys4phys13BoxWaterShape15setMaterialMaskERKNS0_12MaterialMaskE
|
||||
0x0000007100faaf38,O,000380,_ZN4ksys4phys13BoxWaterShapeC1ERKNS0_13BoxShapeParamEP13hkpPlaneShape
|
||||
0x0000007100fab0b4,O,000064,_ZN4ksys4phys13BoxWaterShapeD1Ev
|
||||
0x0000007100fab0f4,O,000072,_ZN4ksys4phys13BoxWaterShapeD0Ev
|
||||
0x0000007100fab13c,O,000120,_ZN4ksys4phys13BoxWaterShape10setExtentsERKN4sead7Vector3IfEE
|
||||
0x0000007100fab1b4,O,000240,_ZN4ksys4phys13BoxWaterShape12setTranslateERKN4sead7Vector3IfEE
|
||||
0x0000007100fab2a4,O,000020,_ZNK4ksys4phys13BoxWaterShape9getVolumeEv
|
||||
0x0000007100fab2b8,O,000008,_ZN4ksys4phys13BoxWaterShape13getHavokShapeEv
|
||||
0x0000007100fab2c0,O,000008,_ZNK4ksys4phys13BoxWaterShape13getHavokShapeEv
|
||||
0x0000007100fab2c8,O,000308,_ZN4ksys4phys13BoxWaterShape16updateHavokShapeEv
|
||||
0x0000007100fab3fc,O,000256,_ZN4ksys4phys13BoxWaterShape8setScaleEf
|
||||
0x0000007100fab4fc,O,000204,_ZNK4ksys4phys13BoxWaterShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100fab5c8,O,000092,_ZNK4ksys4phys13BoxWaterShape18getRuntimeTypeInfoEv
|
||||
0x0000007100fab624,O,000008,_ZNK4ksys4phys13BoxWaterShape7getTypeEv
|
||||
0x0000007100fab62c,O,000084,_ZN4ksys4phys15HavokPlaneShapeD0Ev
|
||||
0x0000007100fab680,O,000008,_ZNK12hkpShapeBase8isConvexEv
|
||||
0x0000007100fab688,O,000276,_ZNK4ksys4phys15HavokPlaneShape7castRayERK20hkpShapeRayCastInputR21hkpShapeRayCastOutput
|
||||
0x0000007100fab79c,O,000008,_ZNK8hkpShape12getContainerEv
|
||||
0x0000007100fab7a4,O,000184,_ZNK4ksys4phys15HavokPlaneShape14collideSpheresERKN19hkpHeightFieldShape19CollideSpheresInputEP10hkVector4f
|
||||
0x0000007100fab85c,O,000332,_ZN4ksys4phys17CapsuleShapeParam11createShapeEPN4sead4HeapE
|
||||
0x0000007100fab9a8,O,000184,_ZN4ksys4phys12CapsuleShape5cloneEPN4sead4HeapE
|
||||
0x0000007100faba60,O,000008,_ZNK4ksys4phys12CapsuleShape9getRadiusEv
|
||||
|
|
Can't render this file because it is too large.
|
|
@ -42,6 +42,8 @@ target_sources(uking PRIVATE
|
|||
|
||||
RigidBody/Shape/physBoxShape.cpp
|
||||
RigidBody/Shape/physBoxShape.h
|
||||
RigidBody/Shape/physBoxWaterShape.cpp
|
||||
RigidBody/Shape/physBoxWaterShape.h
|
||||
RigidBody/Shape/physBoxRigidBody.cpp
|
||||
RigidBody/Shape/physBoxRigidBody.h
|
||||
RigidBody/Shape/physCapsuleShape.cpp
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
#include "KingSystem/Physics/RigidBody/Shape/physBoxWaterShape.h"
|
||||
#include <Havok/Common/Base/Types/Geometry/Aabb/hkAabb.h>
|
||||
#include <Havok/Common/Base/Types/Geometry/Sphere/hkSphere.h>
|
||||
#include <Havok/Physics2012/Collide/Shape/HeightField/Plane/hkpPlaneShape.h>
|
||||
#include <Havok/Physics2012/Collide/Shape/Query/hkpShapeRayCastOutput.h>
|
||||
#include "KingSystem/Physics/RigidBody/Shape/physBoxShape.h"
|
||||
#include "KingSystem/Physics/physConversions.h"
|
||||
#include "KingSystem/Utils/HeapUtil.h"
|
||||
#include "KingSystem/Utils/SafeDelete.h"
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
class HavokPlaneShape : public hkpPlaneShape {
|
||||
public:
|
||||
HK_DECLARE_CLASS_ALLOCATOR(HavokPlaneShape)
|
||||
|
||||
HavokPlaneShape(const hkVector4& plane, const hkAabb& aabb) : hkpPlaneShape(plane, aabb) {}
|
||||
|
||||
hkBool castRay(const hkpShapeRayCastInput& input,
|
||||
hkpShapeRayCastOutput& results) const override {
|
||||
const auto dot_from = getPlane().dot4xyz1(input.m_from);
|
||||
const auto dot_to = getPlane().dot4xyz1(input.m_to);
|
||||
if (dot_from.isGreaterZero() && dot_to.isGreaterZero())
|
||||
return false;
|
||||
|
||||
hkSimdReal hit_fraction;
|
||||
if (dot_from.isLessEqualZero())
|
||||
hit_fraction = 0;
|
||||
else
|
||||
hit_fraction = dot_from * (dot_from - dot_to).reciprocal();
|
||||
|
||||
if (!hkSimdReal(results.m_hitFraction).isGreater(hit_fraction))
|
||||
return false;
|
||||
|
||||
hkVector4f position;
|
||||
position.setInterpolate(input.m_from, input.m_to, hit_fraction.val());
|
||||
|
||||
hkVector4f rel_pos;
|
||||
rel_pos.setSub(position, getAabbCenter());
|
||||
rel_pos.setAbs(rel_pos);
|
||||
rel_pos.sub(0.0001);
|
||||
|
||||
if (!getAabbHalfExtents().greaterEqual(rel_pos).allAreSet<hkVector4fComparison::MASK_XYZ>())
|
||||
return false;
|
||||
|
||||
results.m_hitFraction = hit_fraction;
|
||||
results.m_normal = getPlane();
|
||||
results.setKey(HK_INVALID_SHAPE_KEY);
|
||||
return true;
|
||||
}
|
||||
|
||||
void collideSpheres(const CollideSpheresInput& input,
|
||||
SphereCollisionOutput* outputArray) const override {
|
||||
auto* sphere = input.m_spheres;
|
||||
for (int i = input.m_numSpheres - 1; i >= 0; --i) {
|
||||
const auto r =
|
||||
getPlane().dot4xyz1(sphere->getPositionAndRadius()) - sphere->getRadiusSimdReal();
|
||||
|
||||
auto w = hkSimdReal::getConstant<HK_QUADREAL_MAX>();
|
||||
|
||||
if (r < input.m_tolerance) {
|
||||
const auto r_ = sphere->getRadiusSimdReal() + hkSimdReal(input.m_tolerance);
|
||||
|
||||
hkVector4f half_extents;
|
||||
half_extents.setAdd(getAabbHalfExtents(), r_);
|
||||
|
||||
hkVector4f rel_pos;
|
||||
rel_pos.setSub(sphere->getPositionAndRadius(), getAabbCenter());
|
||||
rel_pos.setAbs(rel_pos);
|
||||
|
||||
if (!rel_pos.greater(half_extents).anyIsSet(hkVector4fComparison::MASK_XYZ))
|
||||
w = r;
|
||||
}
|
||||
|
||||
outputArray->setXYZ_W(getPlane(), w);
|
||||
++sphere;
|
||||
++outputArray;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BoxWaterShape* BoxWaterShape::make(const BoxShapeParam& param, sead::Heap* heap) {
|
||||
void* storage = util::allocStorage<HavokPlaneShape>(heap);
|
||||
if (!storage)
|
||||
return nullptr;
|
||||
|
||||
hkVector4f plane(0, 1, 0);
|
||||
plane.setW(param.translate.y + param.extents.y / 2);
|
||||
|
||||
hkAabb aabb;
|
||||
aabb.m_min.setSub(toHkVec4(param.translate), toHkVec4(param.extents / 2));
|
||||
aabb.m_max.setAdd(toHkVec4(param.translate), toHkVec4(param.extents / 2));
|
||||
|
||||
auto* hk_shape = new (storage) HavokPlaneShape(plane, aabb);
|
||||
return new (heap) BoxWaterShape(param, hk_shape);
|
||||
}
|
||||
|
||||
BoxWaterShape* BoxWaterShape::clone(sead::Heap* heap) const {
|
||||
BoxShapeParam param;
|
||||
param.extents = mExtents;
|
||||
param.translate = mTranslate;
|
||||
param.rotate = mRotate;
|
||||
|
||||
auto* cloned = make(param, heap);
|
||||
cloned->setMaterialMask(mMaterialMask);
|
||||
return cloned;
|
||||
}
|
||||
|
||||
BoxWaterShape::BoxWaterShape(const BoxShapeParam& param, hkpPlaneShape* hk_shape)
|
||||
: mExtents(param.extents), mTranslate(param.translate), mRotate(param.rotate),
|
||||
mHavokShape(hk_shape), mMaterialMask(param.common.getMaterialMask()) {
|
||||
mFlags.change(Flag::IsWater, param.common.material == Material::Water);
|
||||
|
||||
const bool no_transform =
|
||||
mTranslate == sead::Vector3f(0, 0, 0) && mRotate == sead::Vector3f(0, 0, 0);
|
||||
mFlags.change(Flag::HasTransform, !no_transform);
|
||||
|
||||
if (param.common.item_code_disable_stick)
|
||||
mMaterialMask.getData().setCustomFlag(MaterialMaskData::CustomFlag::_0);
|
||||
|
||||
setMaterialMask(mMaterialMask);
|
||||
}
|
||||
|
||||
BoxWaterShape::~BoxWaterShape() {
|
||||
util::deallocateObjectUnsafe(mHavokShape);
|
||||
}
|
||||
|
||||
void BoxWaterShape::setMaterialMask(const MaterialMask& mask) {
|
||||
mMaterialMask = mask;
|
||||
|
||||
if (mHavokShape)
|
||||
mHavokShape->setUserData(mask.getRawData());
|
||||
}
|
||||
|
||||
bool BoxWaterShape::setExtents(const sead::Vector3f& extents) {
|
||||
if (mExtents == extents)
|
||||
return false;
|
||||
|
||||
mExtents = extents;
|
||||
mFlags.set(Flag::Dirty);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BoxWaterShape::setTranslate(const sead::Vector3f& translate) {
|
||||
if (mTranslate == translate)
|
||||
return false;
|
||||
|
||||
mTranslate = translate;
|
||||
|
||||
mFlags.change(Flag::HasTransform, !hasNoTransform());
|
||||
mFlags.set(Flag::Dirty);
|
||||
return true;
|
||||
}
|
||||
|
||||
float BoxWaterShape::getVolume() const {
|
||||
return mExtents.x * mExtents.y * mExtents.z;
|
||||
}
|
||||
|
||||
hkpShape* BoxWaterShape::getHavokShape() {
|
||||
return mHavokShape;
|
||||
}
|
||||
|
||||
const hkpShape* BoxWaterShape::getHavokShape() const {
|
||||
return mHavokShape;
|
||||
}
|
||||
|
||||
const hkpShape* BoxWaterShape::updateHavokShape() {
|
||||
if (!mFlags.isOn(Flag::Dirty))
|
||||
return nullptr;
|
||||
|
||||
const auto ref_count = mHavokShape->getReferenceCount();
|
||||
|
||||
hkVector4f plane(0, 1, 0);
|
||||
plane.setW(mTranslate.y + mExtents.y / 2);
|
||||
|
||||
hkAabb aabb;
|
||||
aabb.m_min.setSub(toHkVec4(mTranslate), toHkVec4(mExtents / 2));
|
||||
aabb.m_max.setAdd(toHkVec4(mTranslate), toHkVec4(mExtents / 2));
|
||||
|
||||
mHavokShape = new (mHavokShape) HavokPlaneShape(plane, aabb);
|
||||
mHavokShape->setReferenceCount(ref_count);
|
||||
|
||||
setMaterialMask(mMaterialMask);
|
||||
|
||||
mFlags.reset(Flag::Dirty);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BoxWaterShape::setScale(float scale) {
|
||||
setExtents(mExtents * scale);
|
||||
setTranslate(mTranslate * scale);
|
||||
}
|
||||
|
||||
} // namespace ksys::phys
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include <math/seadVector.h>
|
||||
#include <prim/seadTypedBitFlag.h>
|
||||
#include <thread/seadAtomic.h>
|
||||
#include "KingSystem/Physics/RigidBody/Shape/physShape.h"
|
||||
#include "KingSystem/Physics/System/physMaterialMask.h"
|
||||
|
||||
class hkpPlaneShape;
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
struct BoxShapeParam;
|
||||
|
||||
class BoxWaterShape : public Shape {
|
||||
SEAD_RTTI_OVERRIDE(BoxWaterShape, Shape)
|
||||
public:
|
||||
enum class Flag {
|
||||
IsWater = 1 << 0,
|
||||
Dirty = 1 << 1,
|
||||
/// Whether we have a transform (translation and/or rotation).
|
||||
HasTransform = 1 << 2,
|
||||
};
|
||||
|
||||
static BoxWaterShape* make(const BoxShapeParam& param, sead::Heap* heap);
|
||||
BoxWaterShape* clone(sead::Heap* heap) const;
|
||||
|
||||
BoxWaterShape(const BoxShapeParam& param, hkpPlaneShape* hk_shape);
|
||||
~BoxWaterShape() override;
|
||||
|
||||
void setMaterialMask(const MaterialMask& mask);
|
||||
bool setExtents(const sead::Vector3f& extents);
|
||||
bool setTranslate(const sead::Vector3f& translate);
|
||||
|
||||
float getVolume() const override;
|
||||
hkpShape* getHavokShape() override;
|
||||
const hkpShape* getHavokShape() const override;
|
||||
const hkpShape* updateHavokShape() override;
|
||||
void setScale(float scale) override;
|
||||
ShapeType getType() const override { return ShapeType::BoxWater; }
|
||||
|
||||
bool hasNoTransform() const {
|
||||
return mTranslate == sead::Vector3f(0, 0, 0) && mRotate == sead::Vector3f(0, 0, 0);
|
||||
}
|
||||
|
||||
sead::Vector3f mExtents;
|
||||
sead::TypedBitFlag<Flag, sead::Atomic<u32>> mFlags;
|
||||
sead::Vector3f mTranslate;
|
||||
sead::Vector3f mRotate;
|
||||
hkpPlaneShape* mHavokShape{};
|
||||
MaterialMask mMaterialMask{};
|
||||
};
|
||||
|
||||
} // namespace ksys::phys
|
|
@ -16,6 +16,7 @@ enum class ShapeType {
|
|||
Cylinder = 3,
|
||||
Polytope = 4,
|
||||
CharacterPrism = 6,
|
||||
BoxWater = 7,
|
||||
Unknown = -1,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue