1#include "Library/Nature/WaterSurfaceFinder.h"
2
3#include "Library/Nature/NatureUtil.h"
4
5namespace al {
6
7WaterSurfaceFinder::WaterSurfaceFinder(const LiveActor* actor) : mActor(actor) {}
8
9void WaterSurfaceFinder::update(const sead::Vector3f& position, const sead::Vector3f& gravity,
10 f32 distance) {
11 updateLocal(position, gravity, maxDistance: distance, isFlat: false, isDisplacement: false, isOverGround: false);
12}
13
14void WaterSurfaceFinder::updateLocal(const sead::Vector3f& position, const sead::Vector3f& gravity,
15 f32 maxDistance, bool isFlat, bool isDisplacement,
16 bool isOverGround) {
17 sead::Vector3f surfacePos = {0.0f, 0.0f, 0.0f};
18 sead::Vector3f surfaceNormal = {0.0f, 0.0f, 0.0f};
19 mIsFoundSurface = false;
20
21 if (isFlat)
22 mIsFoundSurface = calcFindWaterSurfaceFlat(&surfacePos, &surfaceNormal, mActor, position,
23 gravity, maxDistance);
24 else if (isDisplacement)
25 mIsFoundSurface = calcFindWaterSurfaceDisplacement(&surfacePos, &surfaceNormal, mActor,
26 position, gravity, maxDistance);
27 else if (isOverGround)
28 mIsFoundSurface = calcFindWaterSurfaceOverGround(&surfacePos, &surfaceNormal, mActor,
29 position, gravity, maxDistance);
30 else
31 mIsFoundSurface = calcFindWaterSurface(&surfacePos, &surfaceNormal, mActor, position,
32 gravity, maxDistance);
33
34 if (mIsFoundSurface) {
35 // requires this manual dot product calculation to match
36 mSurface.setDistance(gravity.x * (surfacePos.x - position.x) +
37 gravity.y * (surfacePos.y - position.y) +
38 gravity.z * (surfacePos.z - position.z));
39 mSurface.setPosition(surfacePos);
40 mSurface.setNormal(surfaceNormal);
41 } else {
42 mSurface.setDistance(0.0f);
43 mSurface.setPosition({0.0f, 0.0f, 0.0f});
44 mSurface.setNormal({0.0f, 0.0f, 0.0f});
45 }
46
47 mSurface.set1c({0.0f, 0.0f, 0.0f});
48}
49
50void WaterSurfaceFinder::updateForSurfaceShadow(const sead::Vector3f& position,
51 const sead::Vector3f& gravity, f32 distance) {
52 updateLocal(position, gravity, maxDistance: distance, isFlat: true, isDisplacement: false, isOverGround: false);
53}
54
55void WaterSurfaceFinder::updateForDisplacement(const sead::Vector3f& position,
56 const sead::Vector3f& gravity, f32 distance) {
57 updateLocal(position, gravity, maxDistance: distance, isFlat: false, isDisplacement: true, isOverGround: false);
58}
59
60void WaterSurfaceFinder::updateConsiderGround(const sead::Vector3f& position,
61 const sead::Vector3f& gravity, f32 distance) {
62 updateLocal(position, gravity, maxDistance: distance, isFlat: false, isDisplacement: false, isOverGround: true);
63}
64
65bool WaterSurfaceFinder::isNearSurface(f32 distance) const {
66 return mIsFoundSurface && sead::Mathf::abs(x: mSurface.distance) < distance;
67}
68
69} // namespace al
70