summaryrefslogtreecommitdiff
path: root/src/KingSystem/Physics/RigidBody/Shape/Polytope/physPolytopeShape.h
blob: 3a62e7a616e246aff231c5ebc6e8c2f7f3fa7b2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#pragma once

#include <basis/seadTypes.h>
#include <container/seadBuffer.h>
#include <math/seadVector.h>
#include <prim/seadTypedBitFlag.h>
#include <thread/seadAtomic.h>
#include <thread/seadCriticalSection.h>
#include "KingSystem/Physics/RigidBody/Shape/physShape.h"
#include "KingSystem/Physics/RigidBody/physRigidBodyParam.h"
#include "KingSystem/Physics/physMaterialMask.h"

class hkpConvexTransformShape;
class hkpConvexVerticesShape;

namespace ksys::phys {

struct PolytopeShapeParam {
    /// Number of vertices.
    u16 vertex_num = 32;
    CommonShapeParam common;
};

class PolytopeShape : public Shape {
    SEAD_RTTI_OVERRIDE(PolytopeShape, Shape)
public:
    enum class Flag {
        _1 = 1 << 0,
        InvalidVolume = 1 << 1,
        _4 = 1 << 2,
        HasCustomScale = 1 << 3,
        _10 = 1 << 4,
    };

    static PolytopeShape* make(const PolytopeShapeParam& param, sead::Heap* heap);
    PolytopeShape* clone(sead::Heap* heap) const;

    explicit PolytopeShape(const PolytopeShapeParam& param);
    ~PolytopeShape() override;

    const sead::Vector3f& getVertex(int vertex_idx) const { return mVertices[vertex_idx]; }
    bool setVertex(int vertex_idx, const sead::Vector3f& vertex);
    u16 getNumVertices() const { return mNumVertices; }
    void setNumVertices(u16 num);

    ShapeType getType() const override { return ShapeType::Polytope; }
    float getVolume() const override;
    hkpShape* getHavokShape() override;
    const hkpShape* getHavokShape() const override;
    const hkpShape* updateHavokShape() override;

    void setScale(float scale) override;
    float getScale() const { return mScale; }

    void setVolume(float volume);

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

    sead::CriticalSection mCS;
    hkpConvexVerticesShape* mHavokShape{};
    hkpConvexTransformShape* mTransformShape{};
    sead::TypedBitFlag<Flag, sead::Atomic<u32>> mFlags;
    MaterialMask mMaterialMask;
    float mVolume = -1.0;
    float mScale = 1.0;
    sead::Buffer<sead::Vector3f> mVertices;
    u16 mNumVertices{};
};

constexpr PolytopeShape::Flag operator|(PolytopeShape::Flag a, PolytopeShape::Flag b) {
    return PolytopeShape::Flag(u32(a) | u32(b));
}

class PolytopeParam : public RigidBodyInstanceParam, public PolytopeShapeParam {
    SEAD_RTTI_OVERRIDE(PolytopeParam, RigidBodyInstanceParam)
public:
    PolytopeParam() : RigidBodyInstanceParam(ShapeType::Polytope) {}
};

}  // namespace ksys::phys