summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-05-25 21:53:39 +0200
committerGitHub <noreply@github.com>2025-05-25 21:53:39 +0200
commitae4573a236e59f966ea1197bebd8976ccb09e596 (patch)
tree4dcb8e55213ac7c1755a4bbcadf517ccf2d480c6 /include
parentfd7d30d32283d03a412e8c401d04418351cf686a (diff)
parent133ac12fcf28a8b475796169e7e7beb0de99bda5 (diff)
Merge pull request #175 from robojumper/d_path
d_path 33%
Diffstat (limited to 'include')
-rw-r--r--include/d/a/obj/d_a_obj_dungeon_ship.h2
-rw-r--r--include/d/a/obj/d_a_obj_ivy_rope.h2
-rw-r--r--include/d/d_bzs_types.h33
-rw-r--r--include/d/d_room.h36
-rw-r--r--include/d/t/d_t_sound_area.h4
-rw-r--r--include/egg/math/eggRotation.h2
-rw-r--r--include/m/m_vec.h4
-rw-r--r--include/rvl/MTX/vec.h1
-rw-r--r--include/toBeSorted/actor_on_rail.h85
-rw-r--r--include/toBeSorted/d_path.h182
10 files changed, 246 insertions, 105 deletions
diff --git a/include/d/a/obj/d_a_obj_dungeon_ship.h b/include/d/a/obj/d_a_obj_dungeon_ship.h
index d8106eb8..259b33d1 100644
--- a/include/d/a/obj/d_a_obj_dungeon_ship.h
+++ b/include/d/a/obj/d_a_obj_dungeon_ship.h
@@ -11,7 +11,7 @@
#include "nw4r/g3d/res/g3d_resfile.h"
#include "s/s_State.hpp"
#include "toBeSorted/actor_event.h"
-#include "toBeSorted/actor_on_rail.h"
+#include "toBeSorted/d_path.h"
#include "toBeSorted/dowsing_target.h"
#include "toBeSorted/d_emitter.h"
#include "toBeSorted/time_proc.h"
diff --git a/include/d/a/obj/d_a_obj_ivy_rope.h b/include/d/a/obj/d_a_obj_ivy_rope.h
index 1f342416..c85d3ff4 100644
--- a/include/d/a/obj/d_a_obj_ivy_rope.h
+++ b/include/d/a/obj/d_a_obj_ivy_rope.h
@@ -12,7 +12,7 @@
#include "m/m_vec.h"
#include "s/s_State.hpp"
#include "toBeSorted/actor_event.h"
-#include "toBeSorted/actor_on_rail.h"
+#include "toBeSorted/d_path.h"
#include "toBeSorted/attention.h"
class dAcOivyRope_c : public dAcObjBase_c {
diff --git a/include/d/d_bzs_types.h b/include/d/d_bzs_types.h
index cf5264b4..638d98e0 100644
--- a/include/d/d_bzs_types.h
+++ b/include/d/d_bzs_types.h
@@ -24,10 +24,10 @@ struct AREA {
// TODO: double check, copied from ss-tools
// Size 0x28
struct BPNT {
- /* 0x00 */ mVec3_c position1;
- /* 0x0C */ mVec3_c position2;
- /* 0x18 */ mVec3_c position3;
- /* 0x24 */ u8 _0x24[4];
+ /* 0x00 */ Vec position;
+ /* 0x0C */ Vec control1;
+ /* 0x18 */ Vec control2;
+ /* 0x24 */ u8 params[4];
};
// TODO: double check, copied from ss-tools
@@ -99,15 +99,24 @@ struct OBJN {
/* 0x00 */ u16 offset;
};
+#define PATH_FLAG_WRAP_AROUND 1
+// 0 = spnt, pnt. 1 = bpnt, sbpt
+#define PATH_FLAG_SPLINE 2
+
// Size 0xC
struct PATH {
/* 0x00 */ u8 field_0x00;
- /* 0x01 */ u8 field_0x01;
+ /* 0x01 */ u8 pathId;
/* 0x02 */ u16 pointStartIndex;
/* 0x04 */ u16 pointCount;
- /* 0x06 */ u8 _0x06[4];
- /* 0x0A */ u8 firstBitIsWrapAround;
+ /* 0x06 */ u16 nextPath;
+ /* 0x08 */ u8 _0x08[2];
+ /* 0x0A */ u8 flags;
/* 0x0B */ u8 _0x0B[1];
+
+ u8 getNextId() const {
+ return nextPath;
+ }
};
// Size 0x24
@@ -135,8 +144,8 @@ struct PLY {
// Size 0x10
struct PNT {
- /* 0x00 */ mVec3_c position;
- /* 0x0C */ u8 _0x0C[4];
+ /* 0x00 */ Vec position;
+ /* 0x0C */ u8 params[4];
};
// Size 0x4
@@ -170,14 +179,12 @@ struct SOBJ {
/* 0x28 */ char name[8];
};
-// Size 0x???
-struct SBPT {
- // ???
-};
// Parsed the same way in ss-tools
typedef PNT SPNT;
typedef PATH SPTH;
+// Similarly accessed
+typedef BPNT SBPT;
// Size 0x14
struct STIF {
diff --git a/include/d/d_room.h b/include/d/d_room.h
index 30696fc2..287ae7c1 100644
--- a/include/d/d_room.h
+++ b/include/d/d_room.h
@@ -149,16 +149,40 @@ public:
mpPath = path;
}
+ const PATH *getPath(s32 off) const {
+ return mpPath + off;
+ }
+
+ const u16 getPathCount() const {
+ return mPathCount;
+ }
+
+ const SPTH *getSpth(s32 off) const {
+ return mpSpth + off;
+ }
+
+ const u16 getSpthCount() const {
+ return mSpthCount;
+ }
+
void setPnt(const PNT *pnt, u16 count) {
mPntCount = count;
mpPnt = pnt;
}
+ const PNT *getPnt(s32 off) const {
+ return mpPnt + off;
+ }
+
void setBpnt(const BPNT *bpnt, u16 count) {
mBpntCount = count;
mpBpnt = bpnt;
}
+ const BPNT *getBpnt(s32 off) const {
+ return mpBpnt + off;
+ }
+
void setSpth(const SPTH *spth, u16 count) {
mSpthCount = count;
mpSpth = spth;
@@ -169,14 +193,22 @@ public:
mpSpnt = spnt;
}
+ const SPNT *getSpnt(s32 off) const {
+ return mpSpnt + off;
+ }
+
void setSbpt(const SBPT *sbpt, u16 count) {
mSbptCount = count;
mpSbpt = sbpt;
}
- void setArea(const AREA *path, u16 count) {
+ const SBPT *getSbpt(s32 off) const {
+ return mpSbpt + off;
+ }
+
+ void setArea(const AREA *area, u16 count) {
mAreaCount = count;
- mpArea = path;
+ mpArea = area;
}
void setPly(const PLY *ply, u16 count) {
diff --git a/include/d/t/d_t_sound_area.h b/include/d/t/d_t_sound_area.h
index 377adee4..0258f846 100644
--- a/include/d/t/d_t_sound_area.h
+++ b/include/d/t/d_t_sound_area.h
@@ -4,7 +4,7 @@
#include "d/t/d_tg.h"
#include "m/m_mtx.h"
#include "m/m_vec.h"
-#include "toBeSorted/actor_on_rail.h"
+#include "toBeSorted/d_path.h"
class dTgSndAr_c : public dTg_c {
public:
@@ -27,7 +27,7 @@ private:
bool checkAlg3(const mVec3_c &pos);
mMtx_c mtx;
- ActorOnRail mRail;
+ dPath_c mRail;
};
#endif
diff --git a/include/egg/math/eggRotation.h b/include/egg/math/eggRotation.h
index 97910e97..b1e1e075 100644
--- a/include/egg/math/eggRotation.h
+++ b/include/egg/math/eggRotation.h
@@ -13,7 +13,7 @@ struct Rotation {
mRot = other.mRot;
}
Rotation &operator=(const Rotation &other) {
- mRot = val;
+ mRot = other.mRot;
return *this;
}
Rotation &operator=(T val) {
diff --git a/include/m/m_vec.h b/include/m/m_vec.h
index 877da205..0fb52aea 100644
--- a/include/m/m_vec.h
+++ b/include/m/m_vec.h
@@ -196,6 +196,10 @@ public:
return mVec3_c(x * f, y * f, z * f);
}
+ friend mVec3_c operator*(f32 f, const mVec3_c &v) {
+ return mVec3_c(v.x * f, v.y * f, v.z * f);
+ }
+
/// @brief Scalar division operator.
mVec3_c operator/(f32 f) const {
f32 r = 1.0f / f;
diff --git a/include/rvl/MTX/vec.h b/include/rvl/MTX/vec.h
index a5b330dc..e220fa40 100644
--- a/include/rvl/MTX/vec.h
+++ b/include/rvl/MTX/vec.h
@@ -15,6 +15,7 @@ f32 PSVECMag(const Vec *);
f32 PSVECDotProduct(const Vec *, const Vec *);
void PSVECCrossProduct(const Vec *, const Vec *, Vec *);
f32 PSVECSquareDistance(const Vec *, const Vec *);
+f32 PSVECDistance(const Vec *, const Vec *);
#define VECAdd PSVECAdd
#define VECSubtract PSVECSubtract
diff --git a/include/toBeSorted/actor_on_rail.h b/include/toBeSorted/actor_on_rail.h
deleted file mode 100644
index b4e1924e..00000000
--- a/include/toBeSorted/actor_on_rail.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef ACTOR_ON_RAIL_H
-#define ACTOR_ON_RAIL_H
-
-#include "common.h"
-#include "m/m_vec.h"
-
-class ActorOnRail {
-private:
- void *mpPathPtr;
- int mRoomIndex;
- u8 mPathSubtype;
-
-public:
- /* 800A6690 */
- ActorOnRail();
- /* 800A66D0 */
- virtual ~ActorOnRail();
-
- /* 800A6D90 */
- bool init(int pathIndex, int roomId, int pathSubtype);
- /* 800A68B0 */
- mVec3_c *getPntPosForIndex(int index);
-
- void fn_800A7C80(int segmentIndex, mVec3_c &vec, f32 segmentFraction);
-};
-
-class ActorOnRail_Ext : public ActorOnRail {
-public:
- ActorOnRail_Ext();
- virtual ~ActorOnRail_Ext();
-
- void setSegment(u16 segmentIndex, f32 segmentFraction);
- bool initExt(int pathIndex, int roomId, int, int pathSegment, int pathSubtype, f32, f32, f32);
- void fn_800A9650();
-
- s32 getSegmentIndex() const {
- return mSegmentIndex;
- }
-
- f32 getSegmentFraction() const {
- return mSegmentFraction;
- }
-
- bool CheckFlag(u32 flag) const {
- return (field_0x1C & flag) != 0;
- }
-
- void ClearFlag(u32 flag) {
- field_0x1C &= ~flag;
- }
-
- void SetFlag(u32 flag) {
- field_0x1C |= flag;
- }
-
- const mVec3_c &getPosition() const {
- return mPosition;
- }
-
- void setSpeed(f32 speed) {
- mSpeed = speed;
- }
-
-
-
-private:
- s32 mSegmentIndex;
- f32 mSegmentFraction;
- f32 mSpeed;
- u32 field_0x1C;
- f32 field_0x20;
- UNKWORD field_0x24;
- mVec3_c mPosition;
-};
-
-class ActorOnRail3 {
- ActorOnRail mPath;
- u16 mSomePntIdx;
- u32 mFlags;
-
-public:
- ActorOnRail3() : mSomePntIdx(0), mFlags(0) {}
-};
-
-#endif
diff --git a/include/toBeSorted/d_path.h b/include/toBeSorted/d_path.h
new file mode 100644
index 00000000..38891596
--- /dev/null
+++ b/include/toBeSorted/d_path.h
@@ -0,0 +1,182 @@
+#ifndef D_PATH_H
+#define D_PATH_H
+
+#include "common.h"
+#include "d/d_bzs_types.h"
+#include "m/m_vec.h"
+
+/**
+ * A dPath_c describes a parametric 3D curve in a stage.
+ * This base path class provides read-only evaluation of the curve.
+ *
+ * A path consists of a number of points that this curve passes through.
+ * Paths can have two ends, or wrap around, connecting the end point with the start point again.
+ * The curve can either linearly connect the points, or it can be implemented as a spline
+ * (splines are used for certain actors where smooth movement is necessary, e.g. Sandship).
+ *
+ * A curve point (or the segment between that point and the next) is identified by an integer point index [0; n-1], and
+ * each segment itself is parametrized by a float parameter in [0.0; 1.0]. We call this parameter "time", though since
+ * no requirements are imposed on the distance between points, there is no guarantee of constant speed across the curve.
+ * ActorOnRail_Ext (todo rename) provides calculations that allow actors to move along the curve with constant speed.
+ */
+class dPath_c {
+private:
+ const PATH *mpPathPtr;
+ s32 mRoomIndex;
+ bool mPathSubtype;
+
+ /** Must only be called for spline paths. Extracts the relevant path points and control points for the given segment. */
+ bool extractControlPoints(
+ s32 pointIndex, mVec3_c &currPos, mVec3_c &currControl2, mVec3_c &nextControl1, mVec3_c &nextPos
+ ) const;
+
+ /**
+ * Check if the given path segment is a linear segment - even splines can have linear segments!
+ * This can speed up some calculations.
+ */
+ bool isLinearSegment(s32 pointIndex) const;
+
+ void set(const PATH *path, s32 roomIndex, bool subtype);
+
+ const PNT *getPathPoint(s32 pointIndex) const;
+ const BPNT *getPathBpoint(s32 pointIndex) const;
+
+public:
+ /* 800A6690 */
+ dPath_c();
+ /* 800A66D0 */
+ virtual ~dPath_c();
+
+ bool isWrapping() const {
+ return mpPathPtr->flags & PATH_FLAG_WRAP_AROUND;
+ }
+
+ bool isLinear() const {
+ return (mpPathPtr->flags & PATH_FLAG_SPLINE) == 0;
+ }
+
+ s32 getNumPoints() const {
+ return mpPathPtr->pointCount;
+ }
+
+ /* 800A6D90 */
+ bool initWithPathId(s32 pathId, s32 roomId, bool pathSubtype);
+ bool initWithPathIndex(s32 pathIndex, s32 roomId, bool pathSubtype);
+
+ void clear();
+
+
+ /** Get a given point that the curve passes through. */
+ const Vec *getPoint(s32 pointIndex) const;
+ /** Evaluates the curve position for the given segment and time. */
+ void getPoint(s32 pointIndex, f64 time, mVec3_c &out) const;
+ /** Extract point param - TODO what is this used for? */
+ u8 getPointParam(s32 pointIndex, s32 param) const;
+
+ /** Return the index of this PATH in the current room. */
+ u16 getMyPathIndex(s32 roomId) const;
+ /** Apparently paths can be linked somehow. */
+ bool getNextPath(dPath_c *next) const;
+
+ /**
+ * Approximate the time for the given distance along the segment.
+ * The return value is clamped to [0.0, 1.0]. If the distance exceeds
+ * the length of this segment, write the excess to the provided pointer.
+ */
+ f32 getSegmentTime(s32 pointIndex, f32 segmentDistance, f32 stepSize, f32 *excess);
+
+ /**
+ * Approximates the distance already traveled on the given segment for the given time.
+ * Calling this with time == 1.0f returns the segment length.
+ * Higher resolution -> higher accuracy.
+ */
+ f32 getDistanceMovedOnSegment(s32 pointIndex, s32 resolution, f32 time) const;
+ /** Calculates the normalized direction of an actor moving along the segment for the given time. */
+ bool getDirection(s32 segmentIndex, f32 time, mVec3_c &result) const;
+ /** Calculates the speed (scalar) of an actor moving along the segment at the given time. */
+ bool getSpeed(s32 segmentIndex, f32 time, f32 *result) const;
+ /** Calculates the velocity (vector) of an actor moving along the segment at the given time. */
+ bool getVelocity(s32 segmentIndex, f32 time, mVec3_c &result) const;
+
+};
+
+/** A stateful "path driver" that moves along a given path with a given speed. */
+class ActorOnRail_Ext {
+public:
+ ActorOnRail_Ext();
+ ~ActorOnRail_Ext();
+
+ f32 getRemainingDistanceOnSegment() const;
+ s32 getClosestXZPoint(const mVec3_c &) const;
+ void setSegment(s32 segmentIndex, f32 segmentTime);
+ bool init(s32 pathIndex, s32 roomId, u32 flags, s32 segmentIndex, bool pathSubtype, f32 segmentTime, f32 speed, f32 unk);
+ s32 execute();
+
+ s32 getSegmentIndex() const {
+ return mSegmentIndex;
+ }
+
+ f32 getSegmentTime() const {
+ return mSegmentTime;
+ }
+
+ bool CheckFlag(u32 flag) const {
+ return (mFlags & flag) != 0;
+ }
+
+ void ClearFlag(u32 flag) {
+ mFlags &= ~flag;
+ }
+
+ void SetFlag(u32 flag) {
+ mFlags |= flag;
+ }
+
+ const mVec3_c &getPosition() const {
+ return mPosition;
+ }
+
+ void setSpeed(f32 speed) {
+ mSpeed = speed;
+ }
+
+ void getDirection(mVec3_c &result) {
+ mPath.getDirection(mSegmentIndex, mSegmentTime, result);
+ }
+
+ bool checkFlag(u32 flags) const {
+ return (mFlags & flags) != 0;
+ }
+
+ void offFlag(u32 flags) {
+ mFlags &= ~flags;
+ }
+
+ void onFlag(u32 flags) {
+ mFlags |= flags;
+ }
+
+private:
+ s32 getNextPointIndex(s32 point) const;
+ s32 getNextPointIndex() const;
+
+ /* 0x00 */ dPath_c mPath;
+ /* 0x10 */ s32 mSegmentIndex;
+ /* 0x14 */ f32 mSegmentTime;
+ /* 0x18 */ f32 mSpeed;
+ /* 0x1C */ u32 mFlags;
+ /* 0x20 */ f32 field_0x20;
+ /* 0x24 */ f32 mSegmentDistance;
+ /* 0x28 */ mVec3_c mPosition;
+};
+
+class ActorOnRail3 {
+ /* 0x00 */ dPath_c mPath;
+ /* 0x10 */ u16 mSomePntIdx;
+ /* 0x14 */ u32 mFlags;
+
+public:
+ ActorOnRail3() : mSomePntIdx(0), mFlags(0) {}
+};
+
+#endif