mirror of https://github.com/zeldaret/botw.git
Implement ksys::phys::CharacterPrismShape class (#106)
This commit is contained in:
parent
9a01a6a883
commit
d38a6b546b
|
@ -95407,20 +95407,20 @@ Address,Quality,Size,Name
|
|||
0x00000071012b086c,O,000112,_ZN4ksys4phys17RigidBodySetParamD0Ev
|
||||
0x00000071012b08dc,O,000460,_ZN4ksys4phys17RigidBodySetParam5parseEN3agl3utl16ResParameterListEPN4sead4HeapE
|
||||
0x00000071012b0aa8,O,000008,_ZNK4ksys4phys17RigidBodySetParam17getNumRigidBodiesEv
|
||||
0x00000071012b0ab0,U,000992,CharacterPrismShape::make
|
||||
0x00000071012b0e90,U,000240,
|
||||
0x00000071012b0f80,U,000012,
|
||||
0x00000071012b0f8c,U,000068,CharacterPrismShape::dtor
|
||||
0x00000071012b0fd0,U,000068,CharacterPrismShape::dtord
|
||||
0x00000071012b1014,U,000008,
|
||||
0x00000071012b101c,U,000016,CharacterPrismShape::getVol
|
||||
0x00000071012b102c,U,000016,CharacterPrismShape::getShape
|
||||
0x00000071012b103c,U,000016,CharacterPrismShape::getShape_0
|
||||
0x00000071012b104c,U,000016,CharacterPrismShape::updateShape
|
||||
0x00000071012b105c,U,000444,CharacterPrismShape::setScale
|
||||
0x00000071012b1218,U,000204,CharacterPrismShape::rtti1
|
||||
0x00000071012b12e4,U,000092,CharacterPrismShape::rtti2
|
||||
0x00000071012b1340,U,000008,CharacterPrismShape::getType
|
||||
0x00000071012b0ab0,O,000992,_ZN4ksys4phys19CharacterPrismShape4makeERKNS0_24CharacterPrismShapeParamEPN4sead4HeapE
|
||||
0x00000071012b0e90,O,000240,_ZNK4ksys4phys19CharacterPrismShape5cloneEPN4sead4HeapE
|
||||
0x00000071012b0f80,O,000012,_ZNK4ksys4phys19CharacterPrismShape15getMaterialMaskEv
|
||||
0x00000071012b0f8c,O,000068,_ZN4ksys4phys19CharacterPrismShapeD1Ev
|
||||
0x00000071012b0fd0,O,000068,_ZN4ksys4phys19CharacterPrismShapeD0Ev
|
||||
0x00000071012b1014,O,000008,_ZN4ksys4phys19CharacterPrismShape15setMaterialMaskERKNS0_12MaterialMaskE
|
||||
0x00000071012b101c,O,000016,_ZNK4ksys4phys19CharacterPrismShape9getVolumeEv
|
||||
0x00000071012b102c,O,000016,_ZN4ksys4phys19CharacterPrismShape13getHavokShapeEv
|
||||
0x00000071012b103c,O,000016,_ZNK4ksys4phys19CharacterPrismShape13getHavokShapeEv
|
||||
0x00000071012b104c,O,000016,_ZN4ksys4phys19CharacterPrismShape16updateHavokShapeEv
|
||||
0x00000071012b105c,O,000444,_ZN4ksys4phys19CharacterPrismShape8setScaleEf
|
||||
0x00000071012b1218,O,000204,_ZNK4ksys4phys19CharacterPrismShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x00000071012b12e4,O,000092,_ZNK4ksys4phys19CharacterPrismShape18getRuntimeTypeInfoEv
|
||||
0x00000071012b1340,O,000008,_ZNK4ksys4phys19CharacterPrismShape7getTypeEv
|
||||
0x00000071012b1348,O,000096,_ZN4ksys4phys25TeraMeshRigidBodyResourceD1Ev
|
||||
0x00000071012b13a8,O,000096,_ZThn32_N4ksys4phys25TeraMeshRigidBodyResourceD1Ev
|
||||
0x00000071012b1408,O,000104,_ZN4ksys4phys25TeraMeshRigidBodyResourceD0Ev
|
||||
|
|
Can't render this file because it is too large.
|
|
@ -96,6 +96,7 @@ add_library(hkStubs OBJECT
|
|||
Havok/Common/Serialize/Util/hkRootLevelContainer.h
|
||||
|
||||
Havok/Geometry/Collide/Shapes/hkcdShape.h
|
||||
Havok/Geometry/Internal/Types/hkcdVertex.h
|
||||
|
||||
Havok/Physics/Constraint/Atom/hkpConstraintAtom.h
|
||||
Havok/Physics/Constraint/Data/hkpConstraintData.h
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "Havok/Common/Base/Math/hkMath.h"
|
||||
|
||||
class hkcdVertex : public hkVector4f {};
|
|
@ -1 +1,181 @@
|
|||
#include "KingSystem/Physics/RigidBody/Shape/CharacterPrism/physCharacterPrismShape.h"
|
||||
#include <Havok/Geometry/Internal/Types/hkcdVertex.h>
|
||||
#include <Havok/Physics2012/Collide/Shape/Convex/ConvexVertices/hkpConvexVerticesShape.h>
|
||||
#include <Havok/Physics2012/Collide/Shape/Convex/hkpConvexShape.h>
|
||||
#include "KingSystem/Physics/RigidBody/Shape/Polytope/physPolytopeShape.h"
|
||||
#include "KingSystem/Physics/physConversions.h"
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
void CharacterPrismShape::setMaterialMask(const MaterialMask& mask) {
|
||||
mShape->setMaterialMask(mask);
|
||||
}
|
||||
|
||||
const MaterialMask& CharacterPrismShape::getMaterialMask() const {
|
||||
return mShape->getMaterialMask();
|
||||
}
|
||||
|
||||
static const sead::Vector3f& sOrigin = sead::Vector3f::zero;
|
||||
|
||||
CharacterPrismShape* CharacterPrismShape::make(const CharacterPrismShapeParam& param,
|
||||
sead::Heap* heap) {
|
||||
PolytopeShapeParam polytope_shape_param;
|
||||
polytope_shape_param.vertex_num = SHAPE_VERTEX_NUM;
|
||||
polytope_shape_param.common.material = param.common.material;
|
||||
polytope_shape_param.common.sub_material = param.common.sub_material;
|
||||
polytope_shape_param.common.floor_code = param.common.floor_code;
|
||||
polytope_shape_param.common.wall_code = param.common.wall_code;
|
||||
polytope_shape_param.common.item_code_disable_stick = param.common.item_code_disable_stick;
|
||||
|
||||
auto* polytope_shape = PolytopeShape::make(polytope_shape_param, heap);
|
||||
|
||||
/*
|
||||
* Set all vertices.
|
||||
*/
|
||||
|
||||
// Set first vertex
|
||||
polytope_shape->setVertex(0, sOrigin + param.offset);
|
||||
|
||||
for (int i = 0, vertex_idx = 1; i < RING_VERTEX_NUM; i++, vertex_idx += 2) {
|
||||
float ring_x = param.radius * sin((float)i * (float)M_PI_4);
|
||||
float ring_z = param.radius * cos((float)i * (float)M_PI_4);
|
||||
|
||||
// First ring
|
||||
polytope_shape->setVertex(vertex_idx, sead::Vector3f(ring_x, param.ring0_distance, ring_z) +
|
||||
param.offset);
|
||||
|
||||
// Second ring
|
||||
polytope_shape->setVertex(
|
||||
vertex_idx + 1, sead::Vector3f(ring_x, param.ring1_distance, ring_z) + param.offset);
|
||||
}
|
||||
|
||||
// Set last vertex
|
||||
polytope_shape->setVertex(SHAPE_VERTEX_NUM - 1,
|
||||
param.end_vertex_distance * sead::Vector3f::ey + param.offset);
|
||||
|
||||
polytope_shape->updateHavokShape();
|
||||
|
||||
/*
|
||||
* Set all vertices again, but move the bottom so that it lies at y=0.
|
||||
* This is undone if `CharacterPrismShape::setScale` is called.
|
||||
*/
|
||||
|
||||
// Get lowest vertex
|
||||
hkcdVertex supporting_vertex;
|
||||
polytope_shape->getVerticesShape()->getSupportingVertex(hkVector4f(0.0f, -1.0f, 0.0f),
|
||||
supporting_vertex);
|
||||
// Get y-value of the lowest point of collision
|
||||
float min_vertex_y =
|
||||
supporting_vertex[1] + 0.0f - polytope_shape->getVerticesShape()->getRadius();
|
||||
|
||||
// Set first vertex
|
||||
// Move to lie at y=0
|
||||
polytope_shape->setVertex(0, sOrigin + param.offset - min_vertex_y * sead::Vector3f::ey);
|
||||
|
||||
for (int i = 0, vertex_idx = 1; i < RING_VERTEX_NUM; i++, vertex_idx += 2) {
|
||||
float ring_x = param.radius * sin((float)i * (float)M_PI_4);
|
||||
float ring_z = param.radius * cos((float)i * (float)M_PI_4);
|
||||
|
||||
// First ring
|
||||
polytope_shape->setVertex(vertex_idx, sead::Vector3f(ring_x, param.ring0_distance, ring_z) +
|
||||
param.offset - min_vertex_y * sead::Vector3f::ey);
|
||||
|
||||
// Second ring
|
||||
polytope_shape->setVertex(
|
||||
vertex_idx + 1, sead::Vector3f(ring_x, param.ring1_distance, ring_z) + param.offset);
|
||||
}
|
||||
|
||||
// Set last vertex
|
||||
polytope_shape->setVertex(SHAPE_VERTEX_NUM - 1,
|
||||
param.end_vertex_distance * sead::Vector3f::ey + param.offset);
|
||||
|
||||
polytope_shape->updateHavokShape();
|
||||
|
||||
auto* shape = new (heap) CharacterPrismShape;
|
||||
shape->mShape = polytope_shape;
|
||||
shape->mRadius = param.radius;
|
||||
shape->mRing0Distance = param.ring0_distance;
|
||||
shape->mRing1Distance = param.ring1_distance;
|
||||
shape->mEndVertexDistance = param.end_vertex_distance;
|
||||
shape->mOffset.e = param.offset.e;
|
||||
shape->mScale = 1.0f;
|
||||
return shape;
|
||||
}
|
||||
|
||||
CharacterPrismShape* CharacterPrismShape::clone(sead::Heap* heap) const {
|
||||
CharacterPrismShapeParam param;
|
||||
param.radius = mRadius;
|
||||
param.end_vertex_distance = mEndVertexDistance;
|
||||
param.ring1_distance = mRing1Distance;
|
||||
param.ring0_distance = mRing0Distance;
|
||||
param.offset = mOffset;
|
||||
param.common.material = mShape->getMaterialMask().getMaterial();
|
||||
param.common.sub_material = mShape->getMaterialMask().getSubMaterialName();
|
||||
param.common.floor_code = mShape->getMaterialMask().getFloorCode();
|
||||
param.common.wall_code = mShape->getMaterialMask().getWallCode();
|
||||
auto data = mShape->getMaterialMask().getData();
|
||||
param.common.item_code_disable_stick = data.getCustomFlag(MaterialMaskData::CustomFlag::_0);
|
||||
return make(param, heap);
|
||||
}
|
||||
|
||||
float CharacterPrismShape::getVolume() const {
|
||||
return mShape->getVolume();
|
||||
}
|
||||
|
||||
hkpShape* CharacterPrismShape::getHavokShape() {
|
||||
// For some reason, this non-const function is calling the const function `getHavokShapeConst`.
|
||||
return const_cast<hkpShape*>(mShape->getHavokShapeConst());
|
||||
}
|
||||
|
||||
const hkpShape* CharacterPrismShape::getHavokShape() const {
|
||||
return mShape->getHavokShapeConst();
|
||||
}
|
||||
|
||||
const hkpShape* CharacterPrismShape::updateHavokShape() {
|
||||
return mShape->updateHavokShape();
|
||||
}
|
||||
|
||||
void CharacterPrismShape::setScale(float scale) {
|
||||
// `mScale` is scaled relatively by `scale`, but vertices are scaled absolutely.
|
||||
// Using `CharacterPrismShape::setScale` more than once will put `mScale` out of sync with
|
||||
// the actual scale.
|
||||
mScale *= scale;
|
||||
|
||||
float volume = getVolume();
|
||||
|
||||
auto scaled_offset = mOffset * scale;
|
||||
float scaled_end_vertex_distance = mEndVertexDistance * scale;
|
||||
float scaled_radius = mRadius * scale;
|
||||
float ring_y0 = mRing0Distance * scale;
|
||||
float ring_y1 = mRing1Distance * scale;
|
||||
|
||||
// Set first vertex
|
||||
mShape->setVertex(0, sOrigin + scaled_offset);
|
||||
|
||||
for (int i = 0, vertex_idx = 1; i < RING_VERTEX_NUM; i++, vertex_idx += 2) {
|
||||
// For some reason `sin` is used for x and `cos` is used for z.
|
||||
float ring_x = scaled_radius * sin((float)i * (float)M_PI_4);
|
||||
float ring_z = scaled_radius * cos((float)i * (float)M_PI_4);
|
||||
|
||||
// First ring
|
||||
mShape->setVertex(vertex_idx, sead::Vector3f{ring_x, ring_y0, ring_z} + scaled_offset);
|
||||
|
||||
// Second ring
|
||||
mShape->setVertex(vertex_idx + 1, sead::Vector3f{ring_x, ring_y1, ring_z} + scaled_offset);
|
||||
}
|
||||
|
||||
// Set last vertex
|
||||
mShape->setVertex(SHAPE_VERTEX_NUM - 1,
|
||||
scaled_end_vertex_distance * sead::Vector3f::ey + scaled_offset);
|
||||
|
||||
mShape->setVolume(scale * scale * scale * volume);
|
||||
}
|
||||
|
||||
CharacterPrismShape::~CharacterPrismShape() {
|
||||
if (mShape) {
|
||||
delete mShape;
|
||||
mShape = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ksys::phys
|
||||
|
|
|
@ -9,25 +9,49 @@ class PolytopeShape;
|
|||
|
||||
struct CharacterPrismShapeParam {
|
||||
float radius = 0.35;
|
||||
sead::Vector3f translate_0 = {0.5, 1.5, 1.8};
|
||||
sead::Vector3f translate_1 = sead::Vector3f::zero;
|
||||
float ring0_distance = 0.5;
|
||||
float ring1_distance = 1.5;
|
||||
float end_vertex_distance = 1.8;
|
||||
sead::Vector3f offset = sead::Vector3f::zero;
|
||||
CommonShapeParam common;
|
||||
};
|
||||
|
||||
/// A "stretched bipyramid" shape with a top and bottom vertex and two rings of eight vertices
|
||||
/// between them.
|
||||
class CharacterPrismShape : public Shape {
|
||||
SEAD_RTTI_OVERRIDE(CharacterPrismShape, Shape)
|
||||
|
||||
public:
|
||||
~CharacterPrismShape() override;
|
||||
|
||||
static CharacterPrismShape* make(const CharacterPrismShapeParam& param, sead::Heap* heap);
|
||||
CharacterPrismShape* clone(sead::Heap* heap) const;
|
||||
|
||||
void setMaterialMask(const MaterialMask& mask);
|
||||
const MaterialMask& getMaterialMask() const;
|
||||
|
||||
ShapeType getType() const override { return ShapeType::CharacterPrism; }
|
||||
float getVolume() const override;
|
||||
hkpShape* getHavokShape() override;
|
||||
const hkpShape* getHavokShape() const override;
|
||||
const hkpShape* updateHavokShape() override;
|
||||
void setScale(float scale) override;
|
||||
|
||||
PolytopeShape* getUnderlyingShape() const { return mShape; }
|
||||
|
||||
private:
|
||||
static constexpr int RING_VERTEX_NUM = 8;
|
||||
static constexpr int SHAPE_VERTEX_NUM = RING_VERTEX_NUM * 2 + 2;
|
||||
|
||||
/// The underlying shape for this character prism shape.
|
||||
PolytopeShape* mShape{};
|
||||
|
||||
float mRadius;
|
||||
float mRing0Distance;
|
||||
float mRing1Distance;
|
||||
float mEndVertexDistance;
|
||||
sead::Vector3f mOffset;
|
||||
float mScale;
|
||||
};
|
||||
|
||||
} // namespace ksys::phys
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
void setMaterialMask(const MaterialMask& mask);
|
||||
const MaterialMask& getMaterialMask() const { return mMaterialMask; }
|
||||
|
||||
const hkpConvexVerticesShape* getVerticesShape() const { return mHavokShape; }
|
||||
|
||||
private:
|
||||
bool init(const PolytopeShapeParam& param, sead::Heap* heap);
|
||||
|
||||
|
|
|
@ -104,8 +104,10 @@ void ShapeParamObj::getPolytope(PolytopeShapeParam* param) const {
|
|||
|
||||
void ShapeParamObj::getCharacterPrism(CharacterPrismShapeParam* param) const {
|
||||
param->radius = *radius;
|
||||
param->translate_0 = *translate_0;
|
||||
param->translate_1 = *translate_1;
|
||||
param->ring0_distance = translate_0->x;
|
||||
param->ring1_distance = translate_0->y;
|
||||
param->end_vertex_distance = translate_0->z;
|
||||
param->offset = *translate_1;
|
||||
getCommon(¶m->common);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,10 @@ union MaterialMaskData {
|
|||
raw |= 1 << (decltype(custom_flags)::StartBit() + custom_flag);
|
||||
}
|
||||
|
||||
bool getCustomFlag(CustomFlag custom_flag) const {
|
||||
return (raw & 1 << (decltype(custom_flags)::StartBit() + custom_flag)) != 0;
|
||||
}
|
||||
|
||||
u32 raw;
|
||||
util::BitField<0, 6, u32> material;
|
||||
util::BitField<6, 4, int, u32> sub_material;
|
||||
|
|
Loading…
Reference in New Issue