This commit is contained in:
GRAnimated 2025-04-03 00:17:26 -04:00
commit 98496f02f9
810 changed files with 120852 additions and 6587 deletions

11
.github/files/HeadersCMakeLists.txt vendored Normal file
View file

@ -0,0 +1,11 @@
add_library(OdysseyHeaders INTERFACE)
target_include_directories(OdysseyHeaders INTERFACE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/game
${CMAKE_CURRENT_LIST_DIR}/al
${CMAKE_CURRENT_LIST_DIR}/agl
${CMAKE_CURRENT_LIST_DIR}/eui
${CMAKE_CURRENT_LIST_DIR}/sead
${CMAKE_CURRENT_LIST_DIR}/NintendoSDK
${CMAKE_CURRENT_LIST_DIR}/aarch64
)

View file

@ -0,0 +1,6 @@
#260
#337
#366
#370
#417
#481

3
.github/scripts/copy-headers.sh vendored Normal file → Executable file
View file

@ -24,6 +24,9 @@ cp -r ./lib/sead/include/* $DESTINATION_PATH/sead
mkdir $DESTINATION_PATH/game
rsync -a --prune-empty-dirs --include '*/' --include '*.h' --exclude '*' src/ $DESTINATION_PATH/game
# Copy CMakeLists.txt for header only library
cp ./.github/files/HeadersCMakeLists.txt $DESTINATION_PATH/CMakeLists.txt
# Make all contents of every class public
grep -rli 'private:' * | xargs -i@ sed -i 's/private:/public:/g' @
grep -rli 'protected:' * | xargs -i@ sed -i 's/protected:/public:/g' @

2
.github/scripts/push-headers.sh vendored Normal file → Executable file
View file

@ -12,7 +12,7 @@ cd "./OdysseyHeaders"
echo "Open root of OdysseyHeaders repo"
git add -A .
git config user.name $AUTHOR_NAME
git config user.name "$AUTHOR_NAME"
git config user.email $AUTHOR_MAIL
git commit -am "$MESSAGE"
git push -f -u origin $HEADER_BRANCH

View file

@ -37,7 +37,7 @@ jobs:
- name: Set up python
uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.13'
cache: 'pip'
- name: Set up python package dependencies
run: pip install capstone colorama cxxfilt pyelftools watchdog python-Levenshtein toml
@ -62,10 +62,10 @@ jobs:
run: tools/build.py
- name: Verify function states
run: |
var="$(tools/check 2>&1)"
if [[ "$var" == "OK" ]]; then
var="$(tools/check 2> errfile || true)"
if [[ "$(cat errfile)" == "OK" ]]; then
exit 0
else
echo $var;
cat errfile | tr '\n' '\f' | sed 's/Stack backtrace:.*//' | tr '\f' '\n'
exit 1
fi

View file

@ -9,7 +9,7 @@ jobs:
with:
source: 'src lib'
exclude: 'lib/NintendoSDK lib/aarch64 lib/agl lib/eui lib/sead'
clangFormatVersion: 14
clangFormatVersion: 18
custom-lint:
runs-on: ubuntu-latest
steps:
@ -19,9 +19,9 @@ jobs:
- name: Set up python
uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.13'
cache: 'pip'
- name: Set up python package dependencies
run: pip install capstone colorama cxxfilt pyelftools watchdog python-Levenshtein toml
- name: Run custom code styling checks
run: tools/check-format.py
run: tools/check-format.py --ci

View file

@ -20,7 +20,7 @@ jobs:
- name: Set up python
uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.13'
cache: 'pip'
- name: Set up python package dependencies
run: pip install toml colorama cxxfilt

View file

@ -0,0 +1,32 @@
name: Check that the commits of required PRs are in the git history
on:
pull_request_target:
types: [opened, synchronize]
permissions:
contents: read
pull-requests: read
jobs:
rebase-requirement:
runs-on: ubuntu-latest
steps:
- name: Check out PR branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Check out required PRs list to master
run: |
git checkout origin/master -- .github/files/rebase-requirement-prs.txt || true
- name: Run rebase requirement check
run: |
glog_out="$(git log --pretty=format:"%s")"
while read PR; do
if [[ $glog_out != *"(${PR})"* ]] && [[ "${PR}" != "#${PR_NUM}" ]]; then
echo "The commit of PR ${PR} is required to be part of this PR's commit history, but was not found. Please rebase your changes on top of it!"
exit 1
fi
done < .github/files/rebase-requirement-prs.txt
echo "No issues found with PR being outdated!"
env:
PR_NUM: ${{ github.event.pull_request.number }}

View file

@ -16,7 +16,7 @@ jobs:
- name: Set up python
uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.13'
cache: 'pip'
- name: Set up python package dependencies
run: pip install toml

2
.gitignore vendored
View file

@ -25,6 +25,8 @@ bin/
/cmake-build-*
compile_commands.json
.clangd
manifest.json
.lite_project.lua
# IDA
*.id0

View file

@ -36,7 +36,7 @@ endforeach ()
target_include_directories(odyssey PRIVATE src)
target_include_directories(odyssey PRIVATE lib/al)
target_compile_definitions(odyssey PRIVATE NON_MATCHING)
target_compile_options(odyssey PRIVATE -fno-rtti -fno-exceptions)
target_compile_options(odyssey PRIVATE -fno-exceptions)
target_compile_options(odyssey PRIVATE -Wall -Wextra -Wdeprecated)
target_compile_options(odyssey PRIVATE -Wno-unused-parameter -Wno-unused-private-field)
target_compile_options(odyssey PRIVATE -fno-strict-aliasing)

View file

@ -98,13 +98,13 @@ CLion interacts with CMake directly, so you need to make sure CLion's build prof
9. Before opening a PR, reformat the code with clang-format and run `tools/check`.
* You can use clang-format via your editor VSCode and CLion have built-in clang-format support — or by calling `git clang-format` (for files you have `git add`ed and not yet committed).
* If your editor does not have built-in support for clang-format, or if you need to invoke clang-format in a terminal, you'll need to install it manually.
* If your Linux distro or system (e.g. macOS) does not package clang-format 12, you can download it from [the LLVM project website here](https://releases.llvm.org/download.html)
* If your Linux distro or system (e.g. macOS) does not package clang-format, you can download it from [the LLVM project website here](https://releases.llvm.org/download.html)
## Code style
Super Mario Odyssey has 31MB of code and contributors *need* to read and modify existing parts of the codebase very often: inconsistencies lead to a loss of efficiency, and we literally cannot afford that considering our small number of contributors. To avoid wasting time on formatting issues, we use clang-format to automatically enforce a consistent coding style.
Before opening a PR, please format your code with clang-format 12 and ensure the following guidelines are followed. This will allow your contributions to be reviewed more quickly.
Before opening a PR, please format your code with clang-format and ensure the following guidelines are followed. This will allow your contributions to be reviewed more quickly.
### General

15
README.md Executable file → Normal file
View file

@ -11,7 +11,7 @@ Decompilation of all Super Mario Odyssey versions, from 1.0.0 to 1.3.0.
## For Windows users
While Linux is not a hard requirement, it is strongly advised
to [set up WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to simplify the setup process. Ubuntu 22.04
to [set up WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to simplify the setup process. Ubuntu 24.04
is usually a good choice.
The instructions below assume that you are using Linux (native or WSL) or macOS.
@ -121,19 +121,6 @@ Anyone is welcome to contribute to this project, just send a pull request!
- Enable comparison between different versions and check for mis-matches in all versions using `tools/check`
- 1.3.0 uses a different optimization method, find it and implement it into the toolchain
#### from the re-organization
- Rework the al/Library/Yaml-File structure (should be fewer files, merge a few of them)
- Find proper place for Factories (+Placement of ActorFactory?)
- Graph in Rails misordered
- LiveActorGroup vs. Kit are in the wrong order
- Split files/functions in Library/Resource
- Library/Stage: Proper place for StageInfo
- Library/Math: Split up into multiple files
- Library/Player: Re-organize Util
- game/Util/ResourceUtil remove/cleanup
- Once open-ead/sead#130 is merged, clean up RootTask
# Credits
This decompilation uses [this](https://github.com/open-ead/sead) as a reference for the sead library used. Big thanks to

View file

@ -21760,3 +21760,51 @@
0x710187fb58,"NoName"
0x710187fb60,"17AmiiboNpcDirector"
0x710187fb74,"N2al9ISceneObjE"
0x71018acfbc,u"NULL"
0x71018acfc8,u"%02d"
0x71018acfd2,u"?????"
0x71018acfde,u"%d"
0x71018acfe4,u"1"
0x71018acfe8,u"0"
0x71018acfec,u"%d位のひと"
0x71018acffa,u"%ls"
0x71018ad002,u"%u"
0x71018ad008,u"%03d"
0x71018ad012,u"\n"
0x71018ad016,u"%s"
0x71018ad01c,u"-----"
0x71018ad028,u"%d/%d"
0x71018ad034,u"??????"
0x71018ad042,u"----"
0x71018ad04c,u"@"
0x71018ad050,u"テストステージ"
0x71018ad060,u"---"
0x71018ad068,u"/////////////////"
0x71018ad08c,u"未設定"
0x71018ad094,u"66666"
0x71018ad0a0,u"56666"
0x71018ad0ac,u"55666"
0x71018ad0b8,u"55566"
0x71018ad0c4,u"55556"
0x71018ad0d0,u"55555"
0x71018ad0dc,u"%lld"
0x71018ad0e6,u"%.1f"
0x71018ad0f0,u"★30"
0x71018ad0f8,u"* +1"
0x71018ad102,u"None"
0x71018ad10c,u"<シャイン名>"
0x71018ad11c,u"@title"
0x71018ad12a,u"@space"
0x71018ad138,u"5"
0x71018ad13c,u"6"
0x71018ad140,u"シャイン名未設定"
0x71018ad152,u"メッセージ初期化失敗"
0x71018ad168,u"%01d"
0x71018ad172,u"%04d"
0x71018ad17c,u"%05d"
0x71018ad186,u"%06d"
0x71018ad190,u"/"
0x71018ad194,u"%2d"
0x71018ad19c,u"%3d"
0x71018ad1a4,u"%4d"
0x71018ad1ac,u"%5d"

Can't render this file because it is too large.

0
data/data_symbols.csv Executable file → Normal file
View file

79965
data/file_list.yml Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@
buildInputs = with pkgs; [
cmake
ninja
llvmPackages_14.clang
llvmPackages_18.clang
ccache
pkg-config
@ -37,7 +37,7 @@
python-pkgs.toml
]))
openssl
llvmPackages_14.libclang
llvmPackages_18.libclang
ncurses5
ncurses6
];

@ -1 +1 @@
Subproject commit 942a4ec40162fdee542778adbf6c6d1cc36a5296
Subproject commit 86d94df95e8cd540817a698016e7b5a0575d8b5d

View file

@ -3,7 +3,7 @@
#include "Library/Base/HashCodeUtil.h"
#include "Library/Base/StringUtil.h"
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorPoseKeeper.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/LiveActor.h"
#include "Library/Nerve/NerveExecutor.h"
#include "Library/Nerve/NerveKeeper.h"

View file

@ -30,6 +30,8 @@ public:
ActionAnimCtrl* getAnimCtrl() const { return mAnimCtrl; }
ActionSeCtrl* getSeCtrl() const { return mSeCtrl; }
private:
LiveActor* mParentActor;
const char* mActorName;

View file

@ -0,0 +1,22 @@
#include "Library/Area/AreaInitInfo.h"
namespace al {
AreaInitInfo::AreaInitInfo() = default;
AreaInitInfo::AreaInitInfo(const PlacementInfo& placementInfo,
StageSwitchDirector* stageSwitchDirector, SceneObjHolder* sceneObjHolder)
: PlacementInfo(placementInfo), mStageSwitchDirector(stageSwitchDirector),
mSceneObjHolder(sceneObjHolder) {}
AreaInitInfo::AreaInitInfo(const PlacementInfo& placementInfo, const AreaInitInfo& initInfo)
: PlacementInfo(placementInfo), mStageSwitchDirector(initInfo.mStageSwitchDirector),
mSceneObjHolder(initInfo.mSceneObjHolder) {}
void AreaInitInfo::set(const PlacementInfo& placementInfo, StageSwitchDirector* stageSwitchDirector,
SceneObjHolder* sceneObjHolder) {
setZoneIter(placementInfo.getZoneIter());
setPlacementIter(placementInfo.getPlacementIter());
mStageSwitchDirector = stageSwitchDirector;
mSceneObjHolder = sceneObjHolder;
}
} // namespace al

View file

@ -6,7 +6,7 @@ namespace al {
class StageSwitchDirector;
class SceneObjHolder;
class AreaInitInfo {
class AreaInitInfo : public PlacementInfo {
public:
AreaInitInfo();
AreaInitInfo(const PlacementInfo& placementInfo, StageSwitchDirector* stageSwitchDirector,
@ -16,15 +16,12 @@ public:
void set(const PlacementInfo& placementInfo, StageSwitchDirector* stageSwitchDirector,
SceneObjHolder* sceneObjHolder);
const PlacementInfo& getPlacementInfo() const { return mPlacementInfo; }
StageSwitchDirector* getStageSwitchDirector() const { return mStageSwitchDirector; }
SceneObjHolder* getSceneObjHolder() const { return mSceneObjHolder; }
private:
PlacementInfo mPlacementInfo;
StageSwitchDirector* mStageSwitchDirector;
SceneObjHolder* mSceneObjHolder;
StageSwitchDirector* mStageSwitchDirector = nullptr;
SceneObjHolder* mSceneObjHolder = nullptr;
};
} // namespace al

View file

@ -25,6 +25,12 @@ public:
virtual bool isInVolumeOffset(const sead::Vector3f& pos, f32 offset) const;
SceneObjHolder* getSceneObjHolder() const override;
PlacementInfo* getPlacementInfo() const { return mPlacementInfo; }
AreaShape* getAreaShape() const { return mAreaShape; }
const sead::Matrix34f& getAreaMtx() const { return mAreaTR; }
private:
const char* mName;
AreaShape* mAreaShape;

View file

@ -0,0 +1,31 @@
#pragma once
#include "Library/Factory/Factory.h"
namespace al {
class AreaObj;
using AreaCreatorFunction = AreaObj* (*)(const char* areaName);
struct AreaGroupInfo {
const char* name;
s32 size;
};
class AreaObjFactory : public Factory<AreaCreatorFunction> {
public:
AreaObjFactory(const char* factoryName);
s32 tryFindAddBufferSize(const char*) const;
template <s32 N>
inline void setAreaGroupInfos(const AreaGroupInfo (&areaInfos)[N]) {
mAreaGroupInfos = areaInfos;
mAreaGroupInfoCount = N;
}
private:
const AreaGroupInfo* mAreaGroupInfos = nullptr;
s32 mAreaGroupInfoCount = 0;
};
} // namespace al

View file

@ -0,0 +1,28 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadVector.h>
namespace al {
class AreaObj;
class AreaObjGroup {
public:
AreaObjGroup(const char* name, s32 size);
void incrementCount();
void createBuffer();
void createBuffer(s32 size);
void registerAreaObj(AreaObj*);
AreaObj* getAreaObj(s32 index) const;
AreaObj* getInVolumeAreaObj(const sead::Vector3f&) const;
private:
const char* mName;
AreaObj** mAreaObjEntries;
s32 mSize;
s32 mMaxSize;
};
static_assert(sizeof(AreaObjGroup) == 0x18);
} // namespace al

View file

@ -1,17 +1,26 @@
#pragma once
#include <math/seadMatrix.h>
#include <math/seadVector.h>
namespace al {
class AreaObj;
class AreaObjGroup;
class IUseAreaObj;
class AreaObjGroup;
AreaObj* tryFindAreaObj(const IUseAreaObj* area, const char* name, const sead::Vector3f& pos);
bool isInAreaObj(const AreaObjGroup* group, const sead::Vector3f& pos);
bool isInAreaObj(const IUseAreaObj* area, const char* name, const sead::Vector3f& pos);
bool isInDeathArea(const IUseAreaObj*, const sead::Vector3f&);
bool tryGetAreaObjArg(s32*, const AreaObj*, const char*);
bool tryGetAreaObjArg(f32*, const AreaObj*, const char*);
bool tryGetAreaObjArg(bool*, const AreaObj*, const char*);
bool tryGetAreaObjStringArg(const char**, const AreaObj*, const char*);
AreaObjGroup* tryFindAreaObjGroup(const IUseAreaObj* areaObj, const char* name);
AreaObj* tryGetAreaObj(const AreaObjGroup*, const sead::Vector3f&);
const sead::Matrix34f& getAreaObjBaseMtx(const AreaObj*);
} // namespace al

View file

@ -6,8 +6,7 @@
#include "Library/Area/AreaShapeCylinder.h"
#include "Library/Area/AreaShapeInfinite.h"
#include "Library/Area/AreaShapeSphere.h"
#include "Library/Math/MathAngleUtil.h"
#include "Library/Math/MathLengthUtil.h"
#include "Library/Math/MathUtil.h"
#include "Library/Matrix/MatrixUtil.h"
namespace al {
@ -35,11 +34,11 @@ bool AreaShape::calcLocalPos(sead::Vector3f* localPos, const sead::Vector3f& tra
else
localPos->e = trans.e;
auto localX = localPos->x;
f32 localX = localPos->x;
localPos->x = localX / mScale.x;
auto localY = localPos->y;
f32 localY = localPos->y;
localPos->y = localY / mScale.y;
auto localZ = localPos->z;
f32 localZ = localPos->z;
localPos->z = localZ / mScale.z;
return true;

View file

@ -0,0 +1,10 @@
#pragma once
namespace al {
class AreaObj;
template <typename T>
AreaObj* createAreaObjFunction(const char* areaObjName) {
return new T(areaObjName);
}
} // namespace al

View file

@ -0,0 +1,75 @@
#include "Library/Area/SwitchAreaDirector.h"
#include "Library/Area/AreaObjDirector.h"
#include "Library/Area/SwitchAreaTargetInfo.h"
#include "Library/Area/SwitchKeepOnAreaGroup.h"
#include "Library/Area/SwitchOnAreaGroup.h"
#include "Library/Camera/CameraDirector.h"
#include "Library/Camera/CameraUtil.h"
namespace al {
SwitchAreaDirector* SwitchAreaDirector::tryCreate(AreaObjDirector* areaObjDirector,
const PlayerHolder* playerHolder,
const CameraDirector* cameraDirector,
s32 switchOnAreaGroupCount,
s32 switchKeepOnAreaGroupCount) {
return new SwitchAreaDirector(areaObjDirector, playerHolder, cameraDirector,
switchOnAreaGroupCount, switchKeepOnAreaGroupCount);
}
void SwitchAreaDirector::update() {
if (!mHasSwitchAreas)
return;
mSwitchAreaTargetInfo->update(mPlayerHolder, mCameraDirector->getSceneCameraInfo());
for (SwitchOnAreaGroup& switchOnAreaGroup : mSwitchOnAreaGroups)
switchOnAreaGroup.update(mSwitchAreaTargetInfo->getPlayerTargetPositions(),
mSwitchAreaTargetInfo->getPlayerTargetPositionCount());
getCameraAt(mCameraDirector->getSceneCameraInfo(), 0);
for (SwitchKeepOnAreaGroup& switchKeepOnAreaGroup : mSwitchKeepOnAreaGroups)
switchKeepOnAreaGroup.update(mSwitchAreaTargetInfo);
}
void SwitchAreaDirector::endInit() {
mHasSwitchAreas = mSwitchOnAreaGroups.size() != 0 || mSwitchKeepOnAreaGroups.size() != 0;
}
void SwitchAreaDirector::registerSwitchOnAreaGroup(SwitchOnAreaGroup* switchOnAreaGroup) {
mSwitchOnAreaGroups.pushBack(switchOnAreaGroup);
}
void SwitchAreaDirector::registerSwitchKeepOnAreaGroup(
SwitchKeepOnAreaGroup* switchKeepOnAreaGroup) {
mSwitchKeepOnAreaGroups.pushBack(switchKeepOnAreaGroup);
}
SwitchAreaDirector::SwitchAreaDirector(AreaObjDirector* areaObjDirector,
const PlayerHolder* playerHolder,
const CameraDirector* cameraDirector,
s32 switchOnAreaGroupCount, s32 switchKeepOnAreaGroupCount)
: mAreaObjDirector(areaObjDirector), mPlayerHolder(playerHolder),
mCameraDirector(cameraDirector) {
mSwitchAreaTargetInfo = new SwitchAreaTargetInfo(16, 4);
if (switchOnAreaGroupCount > 0) {
mSwitchOnAreaGroups.allocBuffer(switchOnAreaGroupCount, nullptr);
AreaObjGroup* areaObjGroup = areaObjDirector->getAreaObjGroup("SwitchOnArea");
if (areaObjGroup)
registerSwitchOnAreaGroup(new SwitchOnAreaGroup(areaObjGroup));
}
if (switchKeepOnAreaGroupCount > 0) {
mSwitchKeepOnAreaGroups.allocBuffer(switchKeepOnAreaGroupCount, nullptr);
AreaObjGroup* areaObjGroup = areaObjDirector->getAreaObjGroup("SwitchKeepOnArea");
if (areaObjGroup)
registerSwitchKeepOnAreaGroup(new SwitchKeepOnAreaGroup(areaObjGroup));
}
}
AreaObjDirector* SwitchAreaDirector::getAreaObjDirector() const {
return mAreaObjDirector;
}
} // namespace al

View file

@ -1,6 +1,7 @@
#pragma once
#include <basis/seadTypes.h>
#include <container/seadPtrArray.h>
#include "Library/Area/IUseAreaObj.h"
@ -9,23 +10,35 @@ class PlayerHolder;
class CameraDirector;
class SwitchOnAreaGroup;
class SwitchKeepOnAreaGroup;
class SwitchAreaTargetInfo;
class SwitchAreaDirector : public IUseAreaObj {
public:
static SwitchAreaDirector* tryCreate(AreaObjDirector*, const PlayerHolder*,
const CameraDirector*, s32, s32);
static SwitchAreaDirector* tryCreate(AreaObjDirector* areaObjDirector,
const PlayerHolder* playerHolder,
const CameraDirector* cameraDirector,
s32 switchOnAreaGroupCount,
s32 switchKeepOnAreaGroupCount);
SwitchAreaDirector(AreaObjDirector*, const PlayerHolder*, const CameraDirector*, s32, s32);
SwitchAreaDirector(AreaObjDirector* areaObjDirector, const PlayerHolder* playerHolder,
const CameraDirector* cameraDirector, s32 switchOnAreaGroupCount,
s32 switchKeepOnAreaGroupCount);
AreaObjDirector* getAreaObjDirector() const override;
void update();
void endInit();
void registerSwitchOnAreaGroup(SwitchOnAreaGroup*);
void registerSwitchKeepOnAreaGroup(SwitchKeepOnAreaGroup*);
void registerSwitchOnAreaGroup(SwitchOnAreaGroup* switchOnAreaGroup);
void registerSwitchKeepOnAreaGroup(SwitchKeepOnAreaGroup* switchKeepOnAreaGroup);
private:
void* filler[9];
AreaObjDirector* mAreaObjDirector;
const PlayerHolder* mPlayerHolder;
const CameraDirector* mCameraDirector;
SwitchAreaTargetInfo* mSwitchAreaTargetInfo = nullptr;
sead::PtrArray<SwitchOnAreaGroup> mSwitchOnAreaGroups = {};
sead::PtrArray<SwitchKeepOnAreaGroup> mSwitchKeepOnAreaGroups = {};
bool mHasSwitchAreas = false;
};
static_assert(sizeof(SwitchAreaDirector) == 0x50);

View file

@ -0,0 +1,42 @@
#include "Library/Area/SwitchAreaTargetInfo.h"
#include "Library/Camera/CameraUtil.h"
#include "Library/Player/PlayerUtil.h"
namespace al {
SwitchAreaTargetInfo::SwitchAreaTargetInfo(s32 playerPositionCount, s32 cameraLookAtPositionSize)
: mPlayerTargetPositionSize(playerPositionCount), mPlayerPositionSize(playerPositionCount),
mCameraLookAtPositionSize(cameraLookAtPositionSize) {
mPlayerTargetPositions = new sead::Vector3f[mPlayerTargetPositionSize];
mPlayerPositions = new sead::Vector3f[mPlayerPositionSize];
mCameraLookAtPositions = new sead::Vector3f[mCameraLookAtPositionSize];
}
SwitchAreaTargetInfo::SwitchAreaTargetInfo(sead::Vector3f* mPlayerPositions,
s32 playerPositionCount)
: mPlayerTargetPositions(mPlayerPositions), mPlayerTargetPositionCount(playerPositionCount),
mPlayerTargetPositionSize(playerPositionCount), mPlayerPositions(mPlayerPositions),
mPlayerPositionCount(playerPositionCount), mPlayerPositionSize(playerPositionCount) {}
void SwitchAreaTargetInfo::update(const PlayerHolder* playerHolder,
const SceneCameraInfo* sceneCameraInfo) {
mPlayerTargetPositionCount = 0;
mPlayerPositionCount = 0;
s32 playerNumMax = getPlayerNumMax(playerHolder);
for (s32 i = 0; i < playerNumMax; i++) {
const sead::Vector3f& playerPos = getPlayerPos(playerHolder, i);
mPlayerPositions[mPlayerPositionCount] = playerPos;
mPlayerPositionCount++;
if (!isPlayerDead(playerHolder, i) && isPlayerAreaTarget(playerHolder, i)) {
mPlayerTargetPositions[mPlayerTargetPositionCount] = playerPos;
mPlayerTargetPositionCount++;
}
}
mCameraLookAtPositions[0] = getCameraAt(sceneCameraInfo, 0);
mCameraLookAtPositionCount = 1;
}
} // namespace al

View file

@ -0,0 +1,42 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadVector.h>
namespace al {
class PlayerHolder;
class SceneCameraInfo;
class SwitchAreaTargetInfo {
public:
/**
* @info mCameraLookAtPositions will be set to an array of cameraLookAtPositionMaxCount
* sead::Vector3f but only one is used/updated.
*/
SwitchAreaTargetInfo(s32 playerPositionSize, s32 cameraLookAtPositionSize);
/**
* @warning Using this ctor will cause a crash when calling update because
* mCameraLookAtPositions is nullptr by default.
*/
SwitchAreaTargetInfo(sead::Vector3f* mPlayerPositions, s32 playersPositionCount);
void update(const PlayerHolder* playerHolder, const SceneCameraInfo* sceneCameraInfo);
const sead::Vector3f* getPlayerTargetPositions() const { return mPlayerTargetPositions; }
s32 getPlayerTargetPositionCount() const { return mPlayerTargetPositionCount; }
private:
sead::Vector3f* mPlayerTargetPositions = nullptr;
s32 mPlayerTargetPositionCount = 0;
s32 mPlayerTargetPositionSize = 0;
sead::Vector3f* mPlayerPositions = nullptr;
s32 mPlayerPositionCount = 0;
s32 mPlayerPositionSize = 0;
sead::Vector3f* mCameraLookAtPositions = nullptr;
s32 mCameraLookAtPositionCount = 0;
s32 mCameraLookAtPositionSize = 0;
};
static_assert(sizeof(SwitchAreaTargetInfo) == 0x30);
} // namespace al

View file

@ -21,8 +21,8 @@ public:
private:
AreaObjGroup* mAreaObjGroup;
unsigned char padding[0x18];
unsigned char padding[0x10];
};
static_assert(sizeof(SwitchKeepOnAreaGroup) == 0x28);
static_assert(sizeof(SwitchKeepOnAreaGroup) == 0x20);
} // namespace al

View file

@ -10,7 +10,7 @@ class SwitchOnAreaGroup {
public:
SwitchOnAreaGroup(AreaObjGroup* areaObjGroup);
void update(const sead::Vector3f& trans, s32);
void update(const sead::Vector3f* trans, s32);
void update(const sead::Vector3f& trans);
virtual bool isExternalCondition() const;

View file

@ -28,7 +28,7 @@ class PlayerHolder;
class AudioDirector : public IUseAreaObj, public HioNode, public IAudioSystemPause {
public:
struct PauseSystemEntry {
const char* mName;
const char* name;
bool _8;
bool _9;
};

View file

@ -57,3 +57,7 @@ private:
static_assert(sizeof(AudioKeeper) == 0x38);
} // namespace al
namespace alAudioKeeperFunction {
al::AudioKeeper* createAudioKeeper(const al::AudioDirector*, const char*, const char*);
}

View file

@ -7,7 +7,7 @@
namespace al {
class AudioDirector;
class LayoutInitInfo;
class ActorInitInfo;
struct ActorInitInfo;
class SimpleAudioUser : public IUseAudioKeeper {
public:

View file

@ -3,7 +3,9 @@
#include <prim/seadSafeString.h>
namespace al {
class MatchStr;
struct MatchStr {
const char* str;
};
const char* createStringIfInStack(const char* str);
const char* createConcatString(const char* start, const char* end);

View file

@ -0,0 +1,34 @@
#include "Library/Bgm/BgmBeatCounter.h"
#include "Library/Bgm/BgmLineFunction.h"
namespace al {
BgmBeatCounter::BgmBeatCounter(IUseAudioKeeper* audioKeeper, f32 triggerBeatOffset)
: mAudioKeeper(audioKeeper), mTriggerBeatOffset(triggerBeatOffset) {}
void BgmBeatCounter::update() {
if (!isEnableRhythmAnim(mAudioKeeper, nullptr))
return;
f32 currentBeat = getCurBeatOnMeasure(mAudioKeeper);
if (currentBeat - (s32)currentBeat > mTriggerBeatOffset + 1.0f &&
mPrevBeat - (s32)currentBeat <= mTriggerBeatOffset + 1.0f) {
mIsOnBeat = true;
} else {
mIsOnBeat = false;
}
mCurBeatWithOffset = getCurBeat(mAudioKeeper) - mTriggerBeatOffset;
mPrevBeat = currentBeat;
}
bool BgmBeatCounter::isTriggerBeat(s32 interval, s32 delayTime) const {
if (!mIsOnBeat)
return false;
s32 beatValue = mCurBeatWithOffset + (mCurBeatWithOffset >= 0.0f ? 0.5f : -0.5f);
return beatValue % interval == delayTime;
}
} // namespace al

View file

@ -0,0 +1,24 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class IUseAudioKeeper;
class BgmBeatCounter {
public:
BgmBeatCounter(IUseAudioKeeper* audioKeeper, f32 triggerBeatOffset);
void update();
bool isTriggerBeat(s32 interval, s32 delayTime) const;
bool isOnBeat() const { return mIsOnBeat; }
private:
IUseAudioKeeper* mAudioKeeper = nullptr;
f32 mTriggerBeatOffset = 0.0f;
f32 mCurBeatWithOffset = 0.0f;
f32 mPrevBeat = 0.0f;
bool mIsOnBeat = false;
};
} // namespace al

View file

@ -27,6 +27,6 @@ void BgmKeeper::update() {}
const char* BgmKeeper::getUserName() const {
if (mBgmUserInfo == nullptr)
return nullptr;
return mBgmUserInfo->mName;
return mBgmUserInfo->name;
}
} // namespace al

View file

@ -1,8 +1,21 @@
#pragma once
#include <basis/seadTypes.h>
#include <container/seadPtrArray.h>
#include <math/seadVector.h>
namespace al {
class Resource;
class BgmDirector;
class BgmSituationDirector;
class Bgm3DParamsController;
class BgmLine;
class BgmMultiPlayingController;
class BgmPlayingRequest;
class FunctorBase;
class IBgmParamsChanger;
class IUseAudioKeeper;
class LiveActor;
class Resource;
class BgmDataBase {
public:
@ -11,5 +24,96 @@ public:
BgmDataBase(const Resource*, const Resource*);
};
BgmDirector* getBgmDirector(const IUseAudioKeeper*);
BgmDirector* tryGetBgmDirector(const IUseAudioKeeper*);
BgmSituationDirector* getBgmSituationDirector(const IUseAudioKeeper*);
Bgm3DParamsController* getBgm3DParamsController(const IUseAudioKeeper*);
BgmLine* getActiveBgmLine(const IUseAudioKeeper*);
BgmLine* getPlayingBgmLine(const IUseAudioKeeper*, const char*);
const char* getCurPlayingBgmPlayName(const IUseAudioKeeper*);
const char* getCurPlayingBgmResourceName(const IUseAudioKeeper*);
const char* getBgmPlayNameInCurPosition(const IUseAudioKeeper*, bool);
const char* getBgmResourceNameInCurPosition(const IUseAudioKeeper*, bool);
s64 getActiveBgmCurSamplePosition(const IUseAudioKeeper*);
s64 getBgmLoopEndSamplePosition(const IUseAudioKeeper*, const char*);
void startBgm(const IUseAudioKeeper*, const char*, s32, s32);
void startBgm(const IUseAudioKeeper*, const BgmPlayingRequest&, bool, bool);
void startBgmWithSuffix(const IUseAudioKeeper*, const char*, const char*, s32, s32);
void startAndStopBgmInCurPosition(const IUseAudioKeeper*, bool);
void startBgmSituation(const IUseAudioKeeper*, const char*, bool);
void prepareBgm(const IUseAudioKeeper*, const BgmPlayingRequest&);
void prepareBgmWithAreaCheck(const IUseAudioKeeper*);
void stopBgm(const IUseAudioKeeper*, const char*, s32);
void stopBgm(const IUseAudioKeeper*, const BgmPlayingRequest&);
void pauseBgm(const IUseAudioKeeper*, const char*, s32);
void resumeBgm(const IUseAudioKeeper*, const char*, s32);
bool isPlayingBgm(const IUseAudioKeeper*);
bool isPlayingBgm(const IUseAudioKeeper*, const char*);
bool isRunningBgm(const IUseAudioKeeper*, const char*);
bool isPlayingResourceCategoryBgm(const IUseAudioKeeper*, const char*);
void stopActiveBgm(const IUseAudioKeeper*, s32);
void pauseActiveBgm(const IUseAudioKeeper*, s32);
void resumeActiveBgm(const IUseAudioKeeper*, s32);
bool isPlayingActiveBgm(const IUseAudioKeeper*, const char*);
bool isPauseActiveBgm(const IUseAudioKeeper*);
void stopAllBgm(const IUseAudioKeeper*, s32);
void tryStopAllBgm(const IUseAudioKeeper*, s32);
void setTriggerEventForStopAllBgm(const IUseAudioKeeper*, const FunctorBase&);
void tryPauseBgmIfDifferBgmArea(const LiveActor*, const sead::Vector3f&, s32);
void tryPauseBgmIfLowPriority(const IUseAudioKeeper*, const char*, s32);
void startBgmSituation(const IUseAudioKeeper*, const char*, bool, bool);
void startBgmSituation(const IUseAudioKeeper*, sead::PtrArray<IBgmParamsChanger>*, const char*,
bool, bool);
void forceStartBgmSituation(const IUseAudioKeeper*, const char*, bool, bool);
void endBgmSituation(const IUseAudioKeeper*, const char*, bool);
void endBgmSituation(const IUseAudioKeeper*, sead::PtrArray<IBgmParamsChanger>*, const char*, bool);
void forceEndBgmSituation(const IUseAudioKeeper*, const char*, bool);
void startBgm3D(const IUseAudioKeeper*);
void endBgm3D(const IUseAudioKeeper*);
void changeBgm3DParams(const IUseAudioKeeper*, f32, f32, f32, f32, bool);
void activateBgm3DController(const IUseAudioKeeper*);
void deactivateBgm3DController(const IUseAudioKeeper*);
bool isActivateBgm3DController(const IUseAudioKeeper*);
s32 getActiveBgmSituationNum(const IUseAudioKeeper*);
const char* getActiveBgmSituationName(const IUseAudioKeeper*, s32);
s32 getDeactiveBgmSituationNum(const IUseAudioKeeper*);
const char* getDeactiveBgmSituationName(const IUseAudioKeeper*, s32);
void takeBgmSituationSnapShot(const IUseAudioKeeper*);
void applyBgmSituationSnapShot(const IUseAudioKeeper*);
void applyNoAppliedSituationRecord(const IUseAudioKeeper*);
bool isStartedBgmSituation(const IUseAudioKeeper*, const char*);
void endAllBgmSituation(const IUseAudioKeeper*);
void clearBgmDataForStepOverScene(const IUseAudioKeeper*);
void clearBgmPlayPointRecord(const IUseAudioKeeper*);
void startBgmSyncedCurBgmBeat(const IUseAudioKeeper*, const BgmPlayingRequest&, s32);
void stopBgmSyncedCurBgmBeat(const IUseAudioKeeper*, const BgmPlayingRequest&, s32);
void disableBgmLineChange(const IUseAudioKeeper*);
void enableBgmLineChange(const IUseAudioKeeper*);
bool isDisableBgmLineChange(const IUseAudioKeeper*);
void disableBgmSituationChange(const IUseAudioKeeper*);
void enableBgmSituationChange(const IUseAudioKeeper*, bool);
bool isDisableBgmSituationChange(const IUseAudioKeeper*);
BgmMultiPlayingController* tryAllocBgmMultiPlayingController(const IUseAudioKeeper*);
void tryReleaseBgmMultiPlayingController(const IUseAudioKeeper*, BgmMultiPlayingController*);
s32 getBgmLineNum(const IUseAudioKeeper*, bool);
BgmLine* getBgmLineAccessor(const IUseAudioKeeper*, s32, bool);
s32 getgBgmLineIndex(const IUseAudioKeeper*, const char*, bool);
void replaceBgmPlayInfoResourceName(const IUseAudioKeeper*, const char*, const char*);
bool isEnableRhythmAnim(const IUseAudioKeeper*, const char*);
bool isTriggerBeat(const IUseAudioKeeper*);
bool isTriggerBackBeat(const IUseAudioKeeper*);
bool isTriggerMeasureTop(const IUseAudioKeeper*);
f32 getBpm(const IUseAudioKeeper*);
f32 getBeatRate(const IUseAudioKeeper*);
f32 getCurBeat(const IUseAudioKeeper*);
f32 getCurBeatOnMeasure(const IUseAudioKeeper*);
f32 getLoopStartBeat(const IUseAudioKeeper*);
f32 getLoopEndBeat(const IUseAudioKeeper*);
f32 getFramePerMeasure(const IUseAudioKeeper*);
s32 getBeatPerMeasure(const IUseAudioKeeper*);
bool isChangeActiveBgmResourceName(const IUseAudioKeeper*);
bool tryRegistTargetBgmResourceName(const IUseAudioKeeper*, const char*);
void muteOnRunningLineTrack(IUseAudioKeeper*, u32, bool);
void muteOffRunningLineTrack(IUseAudioKeeper*, u32, bool);
} // namespace al

View file

@ -1,7 +1,7 @@
#include "Library/Camera/ActorCameraSubTarget.h"
#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/LiveActor/ActorPoseKeeper.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/LiveActor.h"
namespace al {

View file

@ -4,7 +4,7 @@
#include "Library/LiveActor/ActorCollisionFunction.h"
#include "Library/LiveActor/ActorFlagFunction.h"
#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/LiveActor/ActorPoseKeeper.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/LiveActor.h"
namespace al {

View file

@ -0,0 +1,32 @@
#pragma once
#include <gfx/seadCamera.h>
#include <math/seadVector.h>
#include "Library/Collision/IUseCollision.h"
#include "Library/Nerve/NerveExecutor.h"
namespace al {
class CameraPoser;
class CollisionDirector;
class CollisionParts;
class LookAtCamera;
class CameraArrowCollider : public NerveExecutor, public IUseCollision {
public:
CameraArrowCollider(CollisionDirector* director);
CollisionDirector* getCollisionDirector() const override;
void start();
void update(const sead::Vector3f& vec0, const sead::Vector3f& vec1, const sead::Vector3f& vec2);
void pushBackCollisionParts(CollisionParts* parts);
void makeLookAtCamera(sead::LookAtCamera* cam) const;
void exeKeep();
void exeShrink();
bool isShrink() const;
f32 getPushLength() const;
};
} // namespace al

View file

@ -6,32 +6,32 @@
#include "Library/HostIO/HioNode.h"
namespace al {
class SceneCameraInfo;
class SceneCameraCtrl;
class CameraPoseUpdater;
class CameraPoserFactory;
class CameraPoserSceneInfo;
class CameraTicketHolder;
class SpecialCameraHolder;
class CameraTargetCollideInfoHolder;
class CameraTargetHolder;
class CameraInputHolder;
class AreaObjDirector;
class CameraAngleVerticalRequester;
class CameraFlagCtrl;
class CameraInputHolder;
class CameraInSwitchOnAreaDirector;
class CameraParamTransfer;
class CameraPoser;
class CameraPoserFactory;
class CameraPoseUpdater;
class CameraRailHolder;
class CameraResourceHolder;
class CameraStartParamCtrl;
class CameraStopJudge;
class CameraParamTransfer;
class CameraResourceHolder;
class CameraFlagCtrl;
class CameraInSwitchOnAreaDirector;
class CameraTargetCollideInfoHolder;
class CameraTargetHolder;
class CameraTicket;
class CameraTicketHolder;
class ICameraInput;
class IUseAudioKeeper;
class NameToCameraParamTransferFunc;
class PlacementId;
class PlayerHolder;
class CameraPoser;
class AreaObjDirector;
class IUseAudioKeeper;
class CameraRailHolder;
class NameToCameraParamTransferFunc;
class SceneCameraCtrl;
class SceneCameraInfo;
class SpecialCameraHolder;
struct CameraPoserSceneInfo;
class CameraDirector : public HioNode, public IUseExecutor {
public:
@ -54,8 +54,8 @@ public:
CameraPoseUpdater* getPoseUpdater(s32 index);
CameraTicket* createCameraFromFactory(const char*, const PlacementId*, const char*, s32,
const sead::Matrix34f&);
CameraTicket* createCameraFromFactory(CameraPoser*, const PlacementId*, const char*, s32,
const sead::Matrix34f&, bool);
CameraTicket* createCamera(CameraPoser*, const PlacementId*, const char*, s32,
const sead::Matrix34f&, bool);
CameraTicket* createObjectCamera(const PlacementId*, const char*, const char*, s32,
const sead::Matrix34f&);
CameraTicket* createObjectEntranceCamera(const PlacementId*, const char*,
@ -80,6 +80,8 @@ public:
SceneCameraInfo* getSceneCameraInfo() const { return mSceneCameraInfo; }
SceneCameraCtrl* getSceneCameraCtrl() const { return mSceneCameraCtrl; }
private:
s32 mCountCameraPoseUpdaters;
SceneCameraInfo* mSceneCameraInfo;
@ -102,4 +104,7 @@ private:
CameraInSwitchOnAreaDirector* mInSwitchOnAreaDirector;
void* unk2;
};
static_assert(sizeof(CameraDirector) == 0xA8);
} // namespace al

View file

@ -0,0 +1,20 @@
#include "Library/Camera/CameraInputHolder.h"
#include <basis/seadTypes.h>
#include "Library/Camera/SimpleCameraInput.h"
al::CameraInputHolder::CameraInputHolder(s32 size) : mInputsSize(size) {
mInputs = new SimpleCameraInput*[mInputsSize];
for (s32 index = 0; index < mInputsSize; index++)
mInputs[index] = nullptr;
}
void al::CameraInputHolder::initAfterPlacement() {
if (mDefaultInput == nullptr)
mDefaultInput = new SimpleCameraInput(-1);
}
al::SimpleCameraInput* al::CameraInputHolder::getInput(s32 index) const {
return mInputs[index] ?: mDefaultInput;
}

View file

@ -0,0 +1,19 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class SimpleCameraInput;
class CameraInputHolder {
public:
CameraInputHolder(s32 size);
void initAfterPlacement();
SimpleCameraInput* getInput(s32 index) const;
private:
SimpleCameraInput* mDefaultInput = nullptr;
SimpleCameraInput** mInputs;
s32 mInputsSize;
}; // class CameraInputHolder
} // namespace al

View file

@ -0,0 +1,16 @@
#pragma once
#include <basis/seadTypes.h>
#include "Library/HostIO/HioNode.h"
namespace al {
class ByamlIter;
class CameraOffsetCtrl : public HioNode {
public:
virtual void load(const ByamlIter& iter) = 0;
virtual f32 getOffset() const = 0;
};
} // namespace al

View file

@ -0,0 +1,15 @@
#pragma once
#include "Library/Camera/CameraOffsetCtrl.h"
namespace al {
class ByamlIter;
class CameraOffsetCtrlPreset : public CameraOffsetCtrl {
public:
CameraOffsetCtrlPreset();
void load(const ByamlIter& iter) override;
f32 getOffset() const override;
};
} // namespace al

View file

@ -0,0 +1,67 @@
#pragma once
#include <gfx/seadCamera.h>
#include <math/seadMatrix.h>
#include <math/seadVector.h>
#include <nn/album/album_types.h>
#include "Library/Nerve/NerveExecutor.h"
namespace al {
class CameraInterpole;
class CameraParamTransfer;
class CameraShaker;
class CameraStartParamCtrl;
class CameraStopJudge;
class CameraSwitcher;
class CameraTicket;
class CameraViewFlag;
class CameraViewInfo;
class PauseCameraCtrl;
class Projection;
class SceneCameraInfo;
class CameraPoseUpdater : public NerveExecutor {
public:
CameraPoseUpdater(SceneCameraInfo*, s32 viewIdx);
void init(const CameraParamTransfer* paramTransfer, const CameraStopJudge* stopJudge,
const CameraStartParamCtrl* startParamCtrl);
void update();
bool trySwitchCamera();
bool isActiveInterpole() const;
void startInterpole(s32);
void setNearClipDistance(f32 distance) { mNearClipDistance = distance; }
void setFarClipDistance(f32 distance) { mFarClipDistance = distance; }
private:
nn::album::ImageOrientation mSnapShotOrientation;
SceneCameraInfo* mSceneCamInfo;
void* _20;
CameraViewInfo* mViewInfo;
CameraViewFlag* mViewFlag;
bool mIsMainView;
const s32 mViewIdx;
sead::LookAtCamera mLookAtCamera;
CameraTicket* mTicket;
Projection* mProjection;
sead::Vector2f _b0;
f32 mNearClipDistance;
f32 mFarClipDistance;
f32 mAspect;
f32 mFovyDegree;
CameraSwitcher* mSwitcher;
CameraStartParamCtrl* mStartParamCtrl;
CameraStopJudge* mStopJudge;
CameraParamTransfer* mParamTransfer;
PauseCameraCtrl* mCtrlPausePtr;
CameraInterpole* mInterpole;
CameraShaker* mShaker;
};
static_assert(sizeof(CameraPoseUpdater) == 0x100);
} // namespace al

View file

@ -1,22 +1,390 @@
#include "Library/Camera/CameraPoser.h"
#include <gfx/seadCamera.h>
#include "Library/Area/AreaObjDirector.h"
#include "Library/Audio/System/AudioKeeper.h"
#include "Library/Base/StringUtil.h"
#include "Library/Camera/CameraArrowCollider.h"
#include "Library/Camera/CameraOffsetCtrlPreset.h"
#include "Library/Camera/CameraParamMoveLimit.h"
#include "Library/Camera/CameraPoserFlag.h"
#include "Library/Camera/CameraPoserFunction.h"
#include "Library/Camera/CameraPoserSceneInfo.h"
#include "Library/Camera/CameraStartInfo.h"
#include "Library/Camera/CameraTargetAreaLimitter.h"
#include "Library/Camera/CameraViewCtrlGyro.h"
#include "Library/Camera/SnapShotCameraCtrl.h"
#include "Library/Math/MathUtil.h"
#include "Library/Nerve/NerveKeeper.h"
#include "Library/Play/Camera/CameraVerticalAbsorber.h"
#include "Library/Rail/RailKeeper.h"
#include "Library/Yaml/ByamlIter.h"
#include "Library/Yaml/ByamlUtil.h"
#include "Project/Camera/CameraAngleCtrlInfo.h"
#include "Project/Camera/CameraAngleSwingInfo.h"
#include "Project/Camera/CameraObjectRequestInfo.h"
namespace al {
CameraPoser::CameraPoser(const char* name) : mPoserName(name) {
mPoserFlag = new CameraPoserFlag();
mActiveInterpoleParam = new CameraInterpoleParam();
mEndInterpoleParam = new CameraInterpoleStep();
};
void CameraPoser::init() {}
void CameraPoser::initByPlacementObj(const PlacementInfo& mInfo) {}
void CameraPoser::endInit() {}
void CameraPoser::start(const CameraStartInfo& mInfo) {}
void CameraPoser::update() {}
void CameraPoser::end() {
mActiveState = ActiveState::End;
}
void CameraPoser::loadParam(const ByamlIter& iter) {}
void CameraPoser::makeLookAtCamera(sead::LookAtCamera* cam) const {}
bool CameraPoser::receiveRequestFromObject(const CameraObjectRequestInfo& mInfo) {
return false;
}
bool CameraPoser::isZooming() const {
return false;
}
void CameraPoser::startSnapShotMode() {}
void CameraPoser::endSnapShotMode() {}
const char* CameraPoser::getName() const {
return mPoserName;
}
NerveKeeper* CameraPoser::getNerveKeeper() const {
return mNerveKeeper;
}
AudioKeeper* CameraPoser::getAudioKeeper() const {
return mAudioKeeper;
}
bool CameraPoser::requestTurnToDirection(const CameraTurnInfo* mInfo) {
return false;
}
bool CameraPoser::tryCalcOrthoProjectionInfo(OrthoProjectionInfo* projectionInfo) const {
OrthoProjectionParam* param = mOrthoProjectionParam;
if (param && param->isSetInfo && param->info.nearClipWidth > 0.1f &&
param->info.nearClipHeight > 0.1f) {
*projectionInfo = {param->info.nearClipWidth, param->info.nearClipHeight};
return true;
}
return false;
}
bool CameraPoser::isEnableRotateByPad() const {
if (mAngleCtrlInfo != nullptr)
return !mAngleCtrlInfo->isFixByRangeHV();
if (mAngleSwingInfo != nullptr)
return !mAngleSwingInfo->isInvalidSwing();
return false;
}
f32 CameraPoser::getFovyDegree() const {
if (alCameraPoserFunction::isSnapShotMode(this) && mSnapShotCtrl)
return mSnapShotCtrl->getFovyDegree();
return mFovyDegree;
}
f32 CameraPoser::getSceneFovyDegree() const {
return mSceneInfo->sceneFovyDegree;
}
AreaObjDirector* CameraPoser::getAreaObjDirector() const {
return mSceneInfo->areaObjDirector;
}
CollisionDirector* CameraPoser::getCollisionDirector() const {
return mSceneInfo->collisionDirector;
}
CameraInputHolder* CameraPoser::getInputHolder() const {
return mSceneInfo->inputHolder;
}
CameraTargetHolder* CameraPoser::getTargetHolder() const {
return mSceneInfo->targetHolder;
}
CameraFlagCtrl* CameraPoser::getFlagCtrl() const {
return mSceneInfo->flagCtrl;
}
RailRider* CameraPoser::getRailRider() const {
return mRailKeeper ? mRailKeeper->getRailRider() : nullptr;
}
bool CameraPoser::isInterpoleByCameraDistance() const {
return mActiveInterpoleParam->stepType == CameraInterpoleStepType::ByCameraDistance;
}
s32 CameraPoser::getInterpoleStep() const {
return mActiveInterpoleParam->stepNum < 0 ? 60 : mActiveInterpoleParam->stepNum;
}
void CameraPoser::setInterpoleStep(s32 step) {
mActiveInterpoleParam->set(CameraInterpoleStepType::ByStep, step, true);
}
void CameraPoser::resetInterpoleStep() {
mActiveInterpoleParam->set(CameraInterpoleStepType::ByCameraDistance, -1, false);
}
bool CameraPoser::isInterpoleEaseOut() const {
return mActiveInterpoleParam->isEaseOut;
}
void CameraPoser::setInterpoleEaseOut() {
mActiveInterpoleParam->isEaseOut = true;
}
bool CameraPoser::isEndInterpoleByStep() const {
return mEndInterpoleParam->stepType == CameraInterpoleStepType::ByStep;
}
s32 CameraPoser::getEndInterpoleStep() const {
return mEndInterpoleParam->stepNum;
}
void CameraPoser::initNerve(const Nerve* nerve, s32 maxStates) {
mNerveKeeper = new NerveKeeper(this, nerve, maxStates);
}
void CameraPoser::initArrowCollider(CameraArrowCollider* arrowCollider) {
mArrowCollider = arrowCollider;
mPoserFlag->isInvalidCollider = false;
}
void CameraPoser::initAudioKeeper(const char* name) {
mAudioKeeper =
alAudioKeeperFunction::createAudioKeeper(mSceneInfo->audioDirector, name, nullptr);
}
void CameraPoser::initRail(const PlacementInfo& mInfo) {
mRailKeeper = new RailKeeper(mInfo);
}
void CameraPoser::initLocalInterpole() {
mLocalInterpole = new LocalInterpole();
}
void CameraPoser::initLookAtInterpole(f32 v) {
mLookAtInterpole = new LookAtInterpole(v);
}
void CameraPoser::initOrthoProjectionParam() {
mOrthoProjectionParam = new OrthoProjectionParam();
}
void CameraPoser::tryInitAreaLimitter(const PlacementInfo& mInfo) {
mTargetAreaLimitter = CameraTargetAreaLimitter::tryCreate(mInfo);
}
inline void CameraPoser::CameraInterpoleParam::set(CameraInterpoleStepType type, s32 step,
bool is_interpolate_by_step) {
stepType = type;
stepNum = step;
isInterpolateByStep = is_interpolate_by_step;
}
inline void CameraPoser::CameraInterpoleParam::load(const ByamlIter& iter) {
tryGetByamlS32((s32*)&stepType, iter, "InterpoleStepType");
const char* curveType = nullptr;
if (tryGetByamlString(&curveType, iter, "InterpoleCurveType") != 0 && curveType &&
isEqualString(curveType, "EaseOut"))
isEaseOut = true;
isInterpolateByStep = tryGetByamlS32(&stepNum, iter, "InterpoleStep");
if (isInterpolateByStep)
stepType = CameraInterpoleStepType::ByStep;
}
inline void CameraPoser::CameraInterpoleStep::load(const ByamlIter& iter) {
ByamlIter newIter;
if (tryGetByamlIterByKey(&newIter, iter, "EndInterpoleParam")) {
if (isEqualString(getByamlKeyString(newIter, "Type"), "Step"))
stepType = CameraInterpoleStepType::ByStep;
if (stepType == CameraInterpoleStepType::ByStep)
stepNum = getByamlKeyInt(newIter, "Step");
}
}
inline void CameraPoser::OrthoProjectionParam::load(const ByamlIter& iter) {
bool isExist = tryGetByamlBool(&isSetInfo, iter, "IsSetOrthoProjectionInfo");
if (isExist && isSetInfo) {
tryGetByamlF32(&info.nearClipWidth, iter, "OrthoProjectionNearClipWidth");
tryGetByamlF32(&info.nearClipHeight, iter, "OrthoProjectionNearClipHeight");
}
}
void CameraPoser::load(const ByamlIter& iter) {
loadParam(iter);
tryGetByamlF32(&mFovyDegree, iter, "FovyDegree");
mPoserFlag->load(iter);
mActiveInterpoleParam->load(iter);
mEndInterpoleParam->load(iter);
if (mVerticalAbsorber != nullptr)
mVerticalAbsorber->load(iter);
if (mAngleCtrlInfo != nullptr)
mAngleCtrlInfo->load(iter);
if (mAngleSwingInfo != nullptr)
mAngleSwingInfo->load(iter);
if (mOffsetCtrlPreset != nullptr)
mOffsetCtrlPreset->load(iter);
if (mParamMoveLimit != nullptr)
mParamMoveLimit->load(iter);
if (mSnapShotCtrl != nullptr)
mSnapShotCtrl->load(iter);
if (mOrthoProjectionParam != nullptr)
mOrthoProjectionParam->load(iter);
}
bool CameraPoser::isFirstCalc() const {
return mPoserFlag->isFirstCalc;
}
void CameraPoser::appear(const CameraStartInfo& mInfo) {
mActiveState = ActiveState::Active;
if (mAngleCtrlInfo != nullptr) {
sead::Vector3f vec = {0, 0, 0};
alCameraPoserFunction::calcPreCameraDir(&vec, this);
mAngleCtrlInfo->start(sead::Mathf::rad2deg(asinf(vec.y)));
}
if (mAngleSwingInfo != nullptr)
mAngleSwingInfo->setCurrentAngle({0, 0});
start(mInfo);
if (mArrowCollider != nullptr && !mPoserFlag->isInvalidCollider)
mArrowCollider->start();
if (mVerticalAbsorber != nullptr && !mPoserFlag->isOffVerticalAbsorb)
mVerticalAbsorber->start(mTargetTrans, mInfo);
if (mLookAtInterpole != nullptr)
mLookAtInterpole->lookAtPos.set(mTargetTrans);
}
// TODO: CameraPoser::movement
inline void CameraPoser::LocalInterpole::interpolate(sead::LookAtCamera* cam) {
if (step > -1) {
f32 rate = hermiteRate(normalize(step, 0, end), 1.5f, 0.0f);
sead::Vector3f camPosNext = sead::Vector3f(0, 0, 0);
sead::Vector3f lookAtPosNext = sead::Vector3f(0, 0, 0);
lerpVec(&camPosNext, prevCameraPos, cam->getPos(), rate);
lerpVec(&lookAtPosNext, prevLookAtPos, cam->getAt(), rate);
cam->setPos(camPosNext);
cam->setAt(lookAtPosNext);
}
}
void CameraPoser::makeLookAtCameraPrev(sead::LookAtCamera* cam) const {
cam->setPos(mPosition);
cam->setAt(mTargetTrans);
cam->setUp(mCameraUp);
cam->normalizeUp();
if (mVerticalAbsorber != nullptr && !mPoserFlag->isOffVerticalAbsorb)
mVerticalAbsorber->makeLookAtCamera(cam);
if (mLocalInterpole != nullptr)
mLocalInterpole->interpolate(cam);
if (mAngleSwingInfo != nullptr)
mAngleSwingInfo->makeLookAtCamera(cam);
if (mTargetAreaLimitter != nullptr) {
sead::Vector3f camPosNext = cam->getAt();
if (mTargetAreaLimitter->applyAreaLimit(&camPosNext, camPosNext)) {
sead::Vector3f camDiff = camPosNext - cam->getAt();
cam->setPos(camDiff + cam->getPos());
cam->setAt(camDiff + cam->getAt());
}
}
}
void CameraPoser::makeLookAtCameraPost(sead::LookAtCamera* cam) const {
if (alCameraPoserFunction::isSnapShotMode(this) && mSnapShotCtrl != nullptr)
mSnapShotCtrl->makeLookAtCameraPost(cam);
if (mParamMoveLimit != nullptr)
mParamMoveLimit->apply(cam);
}
void CameraPoser::makeLookAtCameraLast(sead::LookAtCamera* cam) const {
if (alCameraPoserFunction::isSnapShotMode(this) && mSnapShotCtrl != nullptr)
mSnapShotCtrl->makeLookAtCameraLast((cam));
}
void CameraPoser::makeLookAtCameraCollide(sead::LookAtCamera* cam) const {
if (!mPoserFlag->isInvalidCollider && mArrowCollider)
mArrowCollider->makeLookAtCamera(cam);
}
void CameraPoser::calcCameraPose(sead::LookAtCamera* cam) const {
makeLookAtCameraPrev(cam);
makeLookAtCamera(cam);
makeLookAtCameraPost(cam);
makeLookAtCameraCollide(cam);
makeLookAtCameraLast(cam);
}
bool CameraPoser::receiveRequestFromObjectCore(const CameraObjectRequestInfo& mInfo) {
if (receiveRequestFromObject(mInfo))
return true;
if (mVerticalAbsorber != nullptr && mInfo.isStopVerticalAbsorb) {
mVerticalAbsorber->liberateAbsorb();
return true;
}
if (mAngleCtrlInfo != nullptr && mAngleCtrlInfo->receiveRequestFromObject(mInfo))
return true;
return false;
}
void CameraPoser::startSnapShotModeCore() {
if (mSnapshotCtrl)
mSnapshotCtrl->start(mFovyDegree);
if (mSnapShotCtrl != nullptr)
mSnapShotCtrl->start(mFovyDegree);
startSnapShotMode();
}
void CameraPoser::endSnapShotModeCore() {
endSnapShotMode();
}
f32 CameraPoser::getFovyDegree() const {
if (alCameraPoserFunction::isSnapShotMode(this) && mSnapshotCtrl)
return mSnapshotCtrl->getFovyDegree();
return mFovyDegree;
}
} // namespace al

View file

@ -11,26 +11,37 @@
#include "Library/HostIO/HioNode.h"
#include "Library/HostIO/IUseName.h"
#include "Library/Nerve/IUseNerve.h"
#include "Library/Projection/OrthoProjectionInfo.h"
#include "Library/Rail/IUseRail.h"
namespace al {
class CameraVerticalAbsorber;
class AudioDirector;
class ByamlIter;
class CameraAngleCtrlInfo;
class CameraAngleSwingInfo;
class CameraArrowCollider;
class CameraFlagCtrl;
class CameraInputHolder;
class CameraOffsetCtrlPreset;
class CameraParamMoveLimit;
class GyroCameraCtrl;
class CameraViewInfo;
class CameraStartInfo;
class CameraObjectRequestInfo;
class CameraRequestParamHolder;
class CameraTargetAreaLimitter;
class CameraTargetCollideInfoHolder;
class CameraTargetHolder;
class CameraTurnInfo;
class CameraPoserFlag;
class RailKeeper;
class PlacementInfo;
class ByamlIter;
class CameraVerticalAbsorber;
class CameraViewInfo;
class GyroCameraCtrl;
class Nerve;
class PlacementInfo;
class RailKeeper;
class SnapShotCameraCtrl;
struct CameraObjectRequestInfo;
struct CameraPoserFlag;
struct CameraPoserSceneInfo;
struct CameraStartInfo;
struct OrthoProjectionInfo;
struct SnapShotCameraSceneInfo;
class CameraPoser : public HioNode,
public IUseAreaObj,
@ -40,8 +51,72 @@ class CameraPoser : public HioNode,
public IUseNerve,
public IUseRail {
public:
CameraPoser(const char* poserName);
enum class ActiveState : s32 {
Start = 0,
Active = 1,
End = 2,
};
enum class CameraInterpoleStepType : s32 {
Undefined = -1,
ByStep = 0,
ByCameraDistance = 1,
};
struct LocalInterpole {
inline void interpolate(sead::LookAtCamera* cam);
s32 step = -1;
s32 end = 0;
sead::Vector3f prevCameraPos = {0, 0, 0};
sead::Vector3f prevLookAtPos = {0, 0, 0};
};
static_assert(sizeof(LocalInterpole) == 0x20);
struct LookAtInterpole {
inline LookAtInterpole(f32 v) : _c(v) {}
sead::Vector3f lookAtPos = {0.0f, 0.0f, 0.0f};
f32 _c;
};
static_assert(sizeof(LookAtInterpole) == 0x10);
struct CameraInterpoleStep {
inline void load(const ByamlIter& iter);
CameraInterpoleStepType stepType = CameraInterpoleStepType::Undefined;
s32 stepNum = -1;
};
static_assert(sizeof(CameraInterpoleStep) == 0x8);
struct CameraInterpoleParam : public CameraInterpoleStep {
inline CameraInterpoleParam()
: CameraInterpoleStep({CameraInterpoleStepType::ByCameraDistance}) {}
inline void load(const ByamlIter& iter);
inline void set(CameraInterpoleStepType type, s32 step, bool isInterpolate);
s8 isEaseOut = false;
bool isInterpolateByStep = false;
};
static_assert(sizeof(CameraInterpoleParam) == 0xC);
struct OrthoProjectionParam {
OrthoProjectionParam() {}
inline void load(const ByamlIter& iter);
bool isSetInfo = false;
OrthoProjectionInfo info;
};
static_assert(sizeof(OrthoProjectionParam) == 0xC);
CameraPoser(const char* poserName);
virtual AreaObjDirector* getAreaObjDirector() const override;
virtual void init();
virtual void initByPlacementObj(const PlacementInfo&);
@ -51,7 +126,7 @@ public:
virtual void end();
virtual void loadParam(const ByamlIter&);
virtual void makeLookAtCamera(sead::LookAtCamera*) const;
virtual void receiveRequestFromObject(const CameraObjectRequestInfo&);
virtual bool receiveRequestFromObject(const CameraObjectRequestInfo&);
virtual bool isZooming() const;
virtual bool isEnableRotateByPad() const;
virtual void startSnapShotMode();
@ -63,82 +138,103 @@ public:
virtual AudioKeeper* getAudioKeeper() const override;
virtual RailRider* getRailRider() const override;
virtual void load(const ByamlIter&);
virtual void movement();
virtual void calcCameraPose(sead::LookAtCamera*) const;
virtual void requestTurnToDirection(const CameraTurnInfo*);
virtual void load(const ByamlIter& iter);
virtual void movement(); // TODO: implementation missing
virtual void calcCameraPose(sead::LookAtCamera* cam) const;
virtual bool requestTurnToDirection(const CameraTurnInfo*);
void appear(const CameraStartInfo& startInfo);
bool receiveRequestFromObjectCore(const CameraObjectRequestInfo& objRequestInfo);
bool isInterpoleByCameraDistance() const;
bool isInterpoleEaseOut() const;
bool isEndInterpoleByStep() const;
bool isFirstCalc() const;
void initNerve(const Nerve*, s32);
void initArrowCollider(CameraArrowCollider*);
void initAudioKeeper(const char*);
void initRail(const PlacementInfo&);
void initNerve(const Nerve* nerve, s32 maxStates);
void initArrowCollider(CameraArrowCollider* arrowCollider);
void initAudioKeeper(const char* name);
void initRail(const PlacementInfo& placementInfo);
void initLocalInterpole();
void initLookAtInterpole(f32);
void initOrthoProjectionParam();
void tryInitAreaLimitter(const PlacementInfo&);
void tryInitAreaLimitter(const PlacementInfo& placementInfo);
bool tryCalcOrthoProjectionInfo(OrthoProjectionInfo* projectionInfo) const;
void makeLookAtCameraPrev(sead::LookAtCamera*) const;
void makeLookAtCameraPost(sead::LookAtCamera*) const;
void makeLookAtCameraLast(sead::LookAtCamera*) const;
void makeLookAtCameraCollide(sead::LookAtCamera*) const;
void makeLookAtCameraPrev(sead::LookAtCamera* cam) const;
void makeLookAtCameraPost(sead::LookAtCamera* cam) const;
void makeLookAtCameraLast(sead::LookAtCamera* cam) const;
void makeLookAtCameraCollide(sead::LookAtCamera* cam) const;
void getInterpoleStep();
void setInterpoleStep(s32);
void resetInterpoleStep();
s32 getEndInterpoleStep() const;
s32 getInterpoleStep() const;
void setInterpoleStep(s32 step);
void setInterpoleEaseOut();
void getEndInterpoleStep();
void appear(const CameraStartInfo&);
void calcCameraPose(sead::LookAtCamera*);
void receiveRequestFromObjectCore(const CameraObjectRequestInfo&);
void resetInterpoleStep();
void startSnapShotModeCore();
void endSnapShotModeCore();
f32 getFovyDegree() const;
f32 getSceneFovyDegree() const;
CameraInputHolder* getInputHolder() const;
CameraTargetHolder* getTargetHolder() const;
CameraFlagCtrl* getFlagCtrl() const;
sead::Vector3f getPosition() const { return mPosition; };
// get
const sead::Vector3f& getPosition() const { return mPosition; };
sead::Vector3f getTargetTrans() const { return mTargetTrans; };
const sead::Vector3f& getTargetTrans() const { return mTargetTrans; };
sead::Vector3f getCameraUp() const { return mCameraUp; };
const sead::Vector3f& getCameraUp() const { return mCameraUp; };
const sead::Matrix34f& getViewMtx() const { return mViewMtx; };
private:
CameraViewInfo* getViewInfo() const { return mViewInfo; }
// set
void setPosition(const sead::Vector3f& vec) { mPosition.set(vec); };
void setTargetTrans(const sead::Vector3f& vec) { mTargetTrans.set(vec); };
void setCameraUp(const sead::Vector3f& vec) { mCameraUp.set(vec); };
void setViewMtx(const sead::Matrix34f& mtx) { mViewMtx = mtx; }
void setFovyDegree(f32 fovy) { mFovyDegree = fovy; }
protected:
const char* mPoserName;
f32 field_38;
sead::Vector3f mPosition;
sead::Vector3f mTargetTrans = sead::Vector3f::ex;
ActiveState mActiveState = ActiveState::Start;
sead::Vector3f mPosition = {0.0f, 0.0f, 0.0f};
sead::Vector3f mTargetTrans = {0.0f, 0.0f, 500.0f};
sead::Vector3f mCameraUp = sead::Vector3f::ey;
f32 mFovyDegree = 35.0f;
f32 field_64;
f32 _64 = -1.0f;
sead::Matrix34f mViewMtx = sead::Matrix34f::ident;
bool field_98 = false;
CameraViewInfo* mViewInfo;
AreaObjDirector* mAreaDirector;
CameraPoserFlag* mPoserFlags;
CameraVerticalAbsorber* mVerticalAbsorber;
CameraAngleCtrlInfo* mAngleCtrlInfo;
CameraAngleSwingInfo* mAngleSwingInfo;
CameraArrowCollider* mArrowCollider;
CameraOffsetCtrlPreset* mOffsetCtrlPreset;
f32* mLocalInterpole; // size = 0x20
f32* mLookAtInterpole; // size = 0x10
CameraParamMoveLimit* mParamMoveLimit;
void* field_f8;
GyroCameraCtrl* mGyroCtrl;
SnapShotCameraCtrl* mSnapshotCtrl;
AudioKeeper* mAudioKeeper;
NerveKeeper* mNerveKeeper;
RailKeeper* mRailKeeper;
s32* field_128; // (size = 0xC) interpolesteptype?
s32* field_130; // (size - 0x8)
sead::Vector3f* mOrthoProjectionParam;
bool _98 = false;
CameraPoserSceneInfo* mSceneInfo = nullptr;
CameraViewInfo* mViewInfo = nullptr;
CameraPoserFlag* mPoserFlag;
CameraVerticalAbsorber* mVerticalAbsorber = nullptr;
CameraAngleCtrlInfo* mAngleCtrlInfo = nullptr;
CameraAngleSwingInfo* mAngleSwingInfo = nullptr;
CameraArrowCollider* mArrowCollider = nullptr;
CameraOffsetCtrlPreset* mOffsetCtrlPreset = nullptr;
LocalInterpole* mLocalInterpole = nullptr;
LookAtInterpole* mLookAtInterpole = nullptr;
CameraParamMoveLimit* mParamMoveLimit = nullptr;
CameraTargetAreaLimitter* mTargetAreaLimitter = nullptr;
GyroCameraCtrl* mGyroCtrl = nullptr;
SnapShotCameraCtrl* mSnapShotCtrl = nullptr;
AudioKeeper* mAudioKeeper = nullptr;
NerveKeeper* mNerveKeeper = nullptr;
RailKeeper* mRailKeeper = nullptr;
CameraInterpoleParam* mActiveInterpoleParam = nullptr;
CameraInterpoleStep* mEndInterpoleParam = nullptr;
OrthoProjectionParam* mOrthoProjectionParam = nullptr;
};
static_assert(sizeof(CameraPoser) == 0x140);
} // namespace al

View file

@ -0,0 +1,26 @@
#pragma once
#include "Library/Camera/CameraPoser.h"
namespace al {
class CameraPoserActorRailParallel : public CameraPoser {
public:
CameraPoserActorRailParallel(const char* name, const RailKeeper* railKeeper);
void init() override;
void loadParam(const ByamlIter& iter) override;
void start(const CameraStartInfo& startInfo) override;
void update() override;
private:
const RailKeeper* mRailKeeper;
sead::Vector3f mOffset;
f32 mDistance;
f32 mAngleDegreeH;
f32 mAngleDegreeV;
f32 mFollowRate;
};
static_assert(sizeof(CameraPoserActorRailParallel) == 0x168);
} // namespace al

View file

@ -0,0 +1,51 @@
#pragma once
#include <math/seadMatrix.h>
#include "Library/Camera/CameraPoser.h"
namespace nn::g3d {
class CameraAnimResult;
class ResSceneAnim;
} // namespace nn::g3d
namespace al {
class CameraPoser;
class Resource;
struct CameraStartInfo;
class CameraPoserAnim : public CameraPoser {
public:
CameraPoserAnim();
void start(const CameraStartInfo& startInfo) override;
void update() override;
void initAnimResource(const Resource* resource, const sead::Matrix34f* mtx);
void setAnim(const char* animName, s32, s32, s32);
bool isExistAnim(const char* animName) const;
bool isAnimPlaying(const char* animName) const;
bool isAnimEnd() const;
u32 calcStepMax(const char* animName) const;
private:
Resource* mRes;
nn::g3d::ResSceneAnim* mResFile;
nn::g3d::CameraAnimResult* mAnimResult;
f32 _158[10];
const char* mPlayingAnimName;
f32 _188;
s32 _18c;
f32 _190;
f32 _194;
f32 _198;
f32 _19c;
const sead::Matrix34f* _1a0;
f32 _1a8;
bool mIsHoldZoom;
bool _1ad;
};
static_assert(sizeof(CameraPoserAnim) == 0x1B0);
} // namespace al

View file

@ -0,0 +1,38 @@
#pragma once
#include "Library/Factory/Factory.h"
namespace al {
class CameraPoser;
class CameraPoserEntrance;
using CameraPoserCreatorFunction = CameraPoser* (*)(const char* cameraPoserName);
class CameraPoserFactory : public Factory<CameraPoserCreatorFunction> {
public:
CameraPoserFactory(const char* factoryName);
virtual CameraPoserEntrance* createEntranceCameraPoser() const;
};
} // namespace al
namespace alCameraPoserFactoryFunction {
void initAndCreateTableFromOtherTable2(
al::CameraPoserFactory* out, const al::NameToCreator<al::CameraPoserCreatorFunction>* table1,
s32 table1Count, const al::NameToCreator<al::CameraPoserCreatorFunction>* table2,
s32 table2Count);
void initAndCreateTableWithAnotherFactory(
al::CameraPoserFactory* out, const al::CameraPoserFactory* factory,
const al::NameToCreator<al::CameraPoserCreatorFunction>* table, s32 tableCount);
void initAndCreateTableWithPresetPosers(
al::CameraPoserFactory* out, const al::NameToCreator<al::CameraPoserCreatorFunction>* table,
s32 tableCount);
template <s32 N1, s32 N2>
inline void initAndCreateTableFromOtherTable(
al::CameraPoserFactory* out,
const al::NameToCreator<al::CameraPoserCreatorFunction> (&table1)[N1],
const al::NameToCreator<al::CameraPoserCreatorFunction> (&table2)[N2]) {
initAndCreateTableFromOtherTable2(out, table1, N1, table2, N2);
}
} // namespace alCameraPoserFactoryFunction

View file

@ -0,0 +1,87 @@
#include "Library/Camera/CameraPoserFix.h"
#include "Library/Base/StringUtil.h"
#include "Library/Camera/CameraPoser.h"
#include "Library/Camera/CameraPoserFunction.h"
#include "Library/Camera/CameraStartInfo.h"
#include "Library/Math/MathUtil.h"
#include "Library/Yaml/ByamlUtil.h"
namespace al {
CameraPoserFix::CameraPoserFix(const char* name) : CameraPoser(name) {
if (isEqualString(name, getFixAbsoluteCameraName()))
alCameraPoserFunction::invalidateChangeSubjective(this);
else if (isEqualString(name, getFixDoorwayCameraName())) {
alCameraPoserFunction::invalidateChangeSubjective(this);
alCameraPoserFunction::initAngleSwing(this);
} else {
alCameraPoserFunction::initAngleSwing(this);
alCameraPoserFunction::validateCtrlSubjective(this);
}
initOrthoProjectionParam();
}
void CameraPoserFix::init() {
alCameraPoserFunction::initSnapShotCameraCtrlZoomAutoReset(this);
}
void CameraPoserFix::initCameraPosAndLookAtPos(const sead::Vector3f& cameraPos,
const sead::Vector3f& lookAtPos) {
mLookAtPos.set(lookAtPos);
mDistance = (lookAtPos - cameraPos).length();
sead::Vector3f viewDir;
viewDir.set(cameraPos - lookAtPos);
normalize(&viewDir);
mAngleV = sead::Mathf::rad2deg(asinf(viewDir.y));
sead::Vector3f viewDirPlane = viewDir;
viewDirPlane.y = 0;
tryNormalizeOrDirZ(&viewDirPlane);
mAngleH = calcAngleOnPlaneDegree(sead::Vector3f::ez, viewDirPlane, sead::Vector3f::ey);
}
void CameraPoserFix::loadParam(const ByamlIter& iter) {
tryGetByamlV3f(&mLookAtPos, iter, "LookAtPos");
tryGetByamlF32(&mDistance, iter, "Distance");
tryGetByamlF32(&mAngleV, iter, "AngleV");
tryGetByamlF32(&mAngleH, iter, "AngleH");
tryGetByamlBool(&mIsCalcNearestAtFromPreAt, iter, "IsCalcNearestAtFromPreAt");
}
void CameraPoserFix::start(const CameraStartInfo& startInfo) {
mPreLookAtPos.set(alCameraPoserFunction::getPreLookAtPos(this));
update();
}
void CameraPoserFix::update() {
mCameraUp.set(sead::Vector3f::ez);
mTargetTrans.set(mLookAtPos);
mTargetTrans *= mViewMtx;
f32 angleH = alCameraPoserFunction::calcZoneRotateAngleH(mAngleH, this);
f32 x = sinf(sead::Mathf::deg2rad(angleH)) * cosf(sead::Mathf::deg2rad(mAngleV));
f32 y = sinf(sead::Mathf::deg2rad(mAngleV));
f32 z = cosf(sead::Mathf::deg2rad(angleH)) * cosf(sead::Mathf::deg2rad(mAngleV));
sead::Vector3f viewDir = {x, y, z};
normalize(&viewDir);
mPosition.set((mDistance * viewDir) + mTargetTrans);
if (mIsCalcNearestAtFromPreAt) {
sead::Vector3f offset = mPreLookAtPos - mPosition;
parallelizeVec(&offset, viewDir, offset);
if (!isNearZero(offset, 0.001f) && viewDir.dot(offset) < 0.0f)
mTargetTrans.set(offset + mPosition);
}
}
const char* CameraPoserFix::getFixAbsoluteCameraName() {
return "完全固定";
}
const char* CameraPoserFix::getFixDoorwayCameraName() {
return "出入口専用固定";
}
} // namespace al

View file

@ -0,0 +1,34 @@
#pragma once
#include "Library/Camera/CameraPoser.h"
namespace al {
class LiveActor;
class CameraPoserFix : public CameraPoser {
public:
CameraPoserFix(const char* name);
static const char* getFixAbsoluteCameraName();
static const char* getFixDoorwayCameraName();
void initCameraPosAndLookAtPos(const sead::Vector3f& cameraPos,
const sead::Vector3f& lookAtPos);
void init() override;
void loadParam(const ByamlIter& iter) override;
void start(const CameraStartInfo& startInfo) override;
void update() override;
private:
sead::Vector3f mLookAtPos = {0.0f, 0.0f, 0.0f};
f32 mDistance = 1800.0f;
f32 mAngleV = 30.0f;
f32 mAngleH = 0.0f;
bool mIsCalcNearestAtFromPreAt = false;
sead::Vector3f mPreLookAtPos = {0.0f, 0.0f, 0.0f};
};
static_assert(sizeof(CameraPoserFix) == 0x168);
} // namespace al

View file

@ -0,0 +1,22 @@
#include "Library/Camera/CameraPoserFlag.h"
#include "Library/Yaml/ByamlUtil.h"
namespace al {
CameraPoserFlag::CameraPoserFlag() = default;
void CameraPoserFlag::load(const ByamlIter& iter) {
tryGetByamlBool(&isInvalidChangeSubjective, iter, "IsInvalidChangeSubjective");
tryGetByamlBool(&isValidKeepPreSelfPoseNextCameraByParam, iter,
"IsValidKeepPreSelfPoseNextCameraByParam");
tryGetByamlBool(&isInvalidKeepPreSelfPoseNextCameraOverWriteProgram, iter,
"IsInvalidKeepPreSelfPoseNextCameraOverWriteProgram");
tryGetByamlBool(&isInvalidKeepDistanceNextCamera, iter, "IsInvalidKeepDistanceNextCamera");
}
bool CameraPoserFlag::isValidKeepPreSelfPoseNextCamera() const {
return isOverWriteProgram ? !isInvalidKeepPreSelfPoseNextCameraOverWriteProgram :
isValidKeepPreSelfPoseNextCameraByParam;
}
} // namespace al

View file

@ -0,0 +1,34 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class ByamlIter;
struct CameraPoserFlag {
CameraPoserFlag();
void load(const ByamlIter& iter);
bool isValidKeepPreSelfPoseNextCamera() const;
bool isFirstCalc = true;
bool isOffVerticalAbsorb = false;
bool isInvalidCollider = true;
bool _3 = false;
bool isValidKeepPreSelfPoseNextCameraByParam = false;
bool isOverWriteProgram = false;
bool isInvalidKeepPreSelfPoseNextCameraOverWriteProgram = false;
bool isInvalidKeepDistanceNextCamera = false;
bool isInvalidKeepDistanceNextCameraIfNoCollide = false;
bool isValidCtrlSubjective = false;
bool isInvalidChangeSubjective = false;
bool isInvalidCameraBlur = false;
bool _c = false;
bool isInvalidPreCameraEndAfterInterpole = false;
bool isStopUpdateGyro = false;
};
static_assert(sizeof(CameraPoserFlag) == 0xF);
} // namespace al

View file

@ -7,8 +7,8 @@
namespace al {
class CameraPoser;
class CameraStartInfo;
class CameraObjectRequestInfo;
struct CameraStartInfo;
struct CameraObjectRequestInfo;
class IUseCollision;
class PlacementInfo;
} // namespace al
@ -24,8 +24,8 @@ void getProjectionMtx(const al::CameraPoser*);
f32 getNear(const al::CameraPoser*);
f32 getFar(const al::CameraPoser*);
f32 getAspect(const al::CameraPoser*);
void getPreCameraPos(const al::CameraPoser*);
sead::Vector3f& getPreLookAtPos(const al::CameraPoser*);
const sead::Vector3f& getPreCameraPos(const al::CameraPoser*);
const sead::Vector3f& getPreLookAtPos(const al::CameraPoser*);
void getPreUpDir(const al::CameraPoser*);
void getPreFovyDegree(const al::CameraPoser*);
void getPreFovyRadian(const al::CameraPoser*);
@ -202,9 +202,9 @@ void checkFirstCameraCollisionArrowOnlyCeiling(sead::Vector3f*, sead::Vector3f*,
const sead::Vector3f&);
void checkCameraCollisionMoveSphere(sead::Vector3f*, const al::IUseCollision*,
const sead::Vector3f&, const sead::Vector3f&, f32);
void calcZoneRotateAngleH(f32, const al::CameraPoser*);
void calcZoneRotateAngleH(f32, const sead::Matrix34f&);
void calcZoneInvRotateAngleH(f32, const sead::Matrix34f&);
f32 calcZoneRotateAngleH(f32, const al::CameraPoser*);
f32 calcZoneRotateAngleH(f32, const sead::Matrix34f&);
f32 calcZoneInvRotateAngleH(f32, const sead::Matrix34f&);
void multVecZone(sead::Vector3f*, const sead::Vector3f&, const al::CameraPoser*);
void multVecInvZone(sead::Vector3f*, const sead::Vector3f&, const al::CameraPoser*);
void rotateVecZone(sead::Vector3f*, const sead::Vector3f&, const al::CameraPoser*);
@ -216,7 +216,7 @@ void initCameraRail(al::CameraPoser*, const al::PlacementInfo&, const char*);
bool tryGetCameraRailArg(f32*, const al::PlacementInfo&, const char*, const char*);
// void getCameraRailPointObjId(al::CameraPoser const*, s32);
bool tryFindNearestLimitRailKeeper(const al::CameraPoser*, const sead::Vector3f&);
sead::Vector2f calcCameraRotateStick(sead::Vector2f*, const al::CameraPoser*);
void calcCameraRotateStick(sead::Vector2f*, const al::CameraPoser*);
f32 calcCameraRotateStickH(const al::CameraPoser*);
f32 calcCameraRotateStickV(const al::CameraPoser*);
f32 calcCameraRotateStickPower(const al::CameraPoser*);

View file

@ -0,0 +1,23 @@
#include "Library/Camera/CameraPoserSceneInfo.h"
#include "Library/Obj/CameraRailHolder.h"
namespace al {
CameraPoserSceneInfo::CameraPoserSceneInfo() {
railHolders = new CameraRailHolder*[16];
}
void CameraPoserSceneInfo::init(AreaObjDirector* areaObj, CollisionDirector* collision,
const AudioDirector* audio) {
areaObjDirector = areaObj;
collisionDirector = collision;
audioDirector = audio;
}
void CameraPoserSceneInfo::registerCameraRailHolder(CameraRailHolder* railHolder) {
railHolders[railHolderNum] = railHolder;
railHolderNum++;
}
} // namespace al

View file

@ -0,0 +1,36 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class AudioDirector;
class AreaObjDirector;
class CameraFlagCtrl;
class CameraInputHolder;
class CameraTargetCollideInfoHolder;
class CameraTargetHolder;
class CameraRailHolder;
class CameraRequestParamHolder;
class CollisionDirector;
struct SnapShotCameraSceneInfo;
struct CameraPoserSceneInfo {
CameraPoserSceneInfo();
void init(AreaObjDirector* areaObj, CollisionDirector* collision, const AudioDirector* audio);
void registerCameraRailHolder(CameraRailHolder* railHolder);
f32 sceneFovyDegree = 35.0f;
AreaObjDirector* areaObjDirector = nullptr;
CollisionDirector* collisionDirector = nullptr;
const AudioDirector* audioDirector = nullptr;
CameraInputHolder* inputHolder = nullptr;
CameraTargetHolder* targetHolder = nullptr;
CameraFlagCtrl* flagCtrl = nullptr;
CameraRequestParamHolder* requestParamHolder = nullptr;
CameraTargetCollideInfoHolder* targetCollideInfoHolder = nullptr;
SnapShotCameraSceneInfo* snapShotCameraSceneInfo = nullptr;
CameraRailHolder** railHolders = nullptr;
s32 railHolderNum = 0;
};
} // namespace al

View file

@ -0,0 +1,134 @@
#include "Library/Camera/CameraResourceHolder.h"
#include <prim/seadSafeString.h>
#include "Library/Base/StringUtil.h"
#include "Library/Camera/CameraTicketId.h"
#include "Library/Placement/PlacementId.h"
#include "Library/Resource/Resource.h"
#include "Library/Yaml/ByamlIter.h"
namespace al {
CameraResourceHolder::CameraResourceHolder(const char* stageName, s32 maxResources)
: mStageName(stageName), mMaxEntries(maxResources) {
mEntries = new Entry*[maxResources];
for (s32 i = 0; i < mMaxEntries; i++)
mEntries[i] = nullptr;
}
// too large to inline with heuristic, but needs to be explicit function (or inline lambda) for
// stack ordering to match original assembly
__attribute__((always_inline)) void getStageName(StringTmp<128>* stageName,
const char* archiveName) {
sead::FixedSafeString<256> safeArchiveName;
safeArchiveName.format("%s", archiveName);
if (safeArchiveName.endsWith("Map"))
stageName->copy(safeArchiveName, safeArchiveName.calcLength() - 3);
}
bool CameraResourceHolder::tryInitCameraResource(const Resource* resource, s32 unused) {
StringTmp<128> stageName = "";
getStageName(&stageName, resource->getArchiveName());
for (s32 i = 0; i < mNumEntries; i++)
if (isEqualString(stageName.cstr(), mEntries[i]->stageName))
return false;
Entry* entry = new Entry;
if (resource->isExistFile(StringTmp<64>{"%s.byml", "CameraParam"}))
entry->cameraParam = new ByamlIter(resource->getByml("CameraParam"));
if (resource->isExistFile(StringTmp<64>{"%s.byml", "InterpoleParam"}))
entry->interpoleParam = new ByamlIter(resource->getByml("InterpoleParam"));
entry->stageName = stageName;
mEntries[mNumEntries] = entry;
mNumEntries++;
return true;
}
bool CameraResourceHolder::tryFindParamResource(ByamlIter* ticket, const CameraTicketId* ticketId,
s32 paramType) const {
ByamlIter paramList;
const PlacementId* placementId = ticketId->getPlacementId();
const char* paramName;
if (paramType == 2)
paramName = "StartTickets";
else if (paramType == 0)
paramName = "DefaultTickets";
else
paramName = "Tickets";
if (!tryFindCameraParamList(&paramList, placementId, paramName))
return false;
for (s32 i = 0; i < paramList.getSize(); i++) {
if (paramList.tryGetIterByIndex(ticket, i)) {
ByamlIter id;
ticket->tryGetIterByKey(&id, "Id");
if (ticketId->isEqual(id))
return true;
}
}
return false;
}
bool CameraResourceHolder::tryFindCameraParamList(ByamlIter* paramList,
const PlacementId* placementId,
const char* paramName) const {
if (placementId && placementId->getUnitConfigName())
return tryFindCameraParamList(paramList, placementId->getUnitConfigName(), paramName);
else
return tryFindCameraParamList(paramList, mStageName, paramName);
}
s32 CameraResourceHolder::calcEntranceCameraParamNum() const {
ByamlIter startTickets;
if (!tryFindCameraParamList(&startTickets, mStageName, "StartTickets"))
return 0;
return startTickets.getSize();
}
bool CameraResourceHolder::tryFindCameraParamList(ByamlIter* paramList, const char* stageName,
const char* paramName) const {
CameraResourceHolder::Entry* entry = findCameraResource(stageName);
if (!entry || !entry->cameraParam)
return false;
return entry->cameraParam->tryGetIterByKey(paramList, paramName);
}
void CameraResourceHolder::getEntranceCameraParamResource(ByamlIter* ticket, s32 index) const {
ByamlIter startTickets;
tryFindCameraParamList(&startTickets, mStageName, "StartTickets");
startTickets.tryGetIterByIndex(ticket, index);
}
CameraResourceHolder::Entry* CameraResourceHolder::findCameraResource(const char* stageName) const {
for (s32 i = 0; i < mNumEntries; i++)
if (isEqualString(stageName, mEntries[i]->stageName))
return mEntries[i];
return nullptr;
}
CameraResourceHolder::Entry*
CameraResourceHolder::tryFindCameraResource(const char* stageName) const {
return findCameraResource(stageName);
}
CameraResourceHolder::Entry*
CameraResourceHolder::tryFindCameraResource(const PlacementId* placementId) const {
if (placementId) {
const char* name = placementId->getUnitConfigName();
if (!name)
name = mStageName;
return findCameraResource(name);
} else {
return findCameraResource(mStageName);
}
}
} // namespace al

View file

@ -0,0 +1,47 @@
#pragma once
#include <prim/seadSafeString.h>
namespace al {
class Resource;
class ByamlIter;
class CameraTicketId;
class PlacementId;
class CameraResourceHolder {
public:
struct Entry {
ByamlIter* cameraParam = nullptr;
ByamlIter* interpoleParam = nullptr;
sead::FixedSafeString<128> stageName = {""};
};
enum ParamType : s32 {
DefaultTickets = 0,
StartTickets = 2,
Tickets // any other value
};
CameraResourceHolder(const char* stageName, s32 maxResources);
bool tryInitCameraResource(const Resource* resource, s32 unused);
bool tryFindParamResource(ByamlIter* ticket, const CameraTicketId* ticketId,
s32 paramType) const;
bool tryFindCameraParamList(ByamlIter* paramList, const PlacementId* placementId,
const char* paramName) const;
s32 calcEntranceCameraParamNum() const;
bool tryFindCameraParamList(ByamlIter* paramList, const char* stageName,
const char* paramName) const;
void getEntranceCameraParamResource(ByamlIter* ticket, s32 index) const;
Entry* findCameraResource(const char* stageName) const;
Entry* tryFindCameraResource(const char* stageName) const;
Entry* tryFindCameraResource(const PlacementId* placementId) const;
private:
const char* mStageName;
s32 mMaxEntries;
s32 mNumEntries = 0;
Entry** mEntries;
};
} // namespace al

View file

@ -0,0 +1,153 @@
#include "Library/Camera/CameraShaker.h"
#include "Library/Base/StringUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
namespace {
using namespace al;
NERVE_IMPL(CameraShaker, Shake);
NERVE_IMPL(CameraShaker, Wait);
NERVE_IMPL(CameraShaker, ShakeLoop);
NERVES_MAKE_NOSTRUCT(CameraShaker, Shake);
NERVES_MAKE_STRUCT(CameraShaker, Wait, ShakeLoop);
} // namespace
namespace al {
const CameraShaker::ShakeInfo WeakShakeLoop = {"", -1, 7.5f, 0.0007f,
CameraShaker::ShakeDirection::Both};
const CameraShaker::ShakeInfo ShakeInfos[11] = {
{"微弱", 15, 2.5f, 0.0015f, CameraShaker::ShakeDirection::Both},
{"微弱[短]", 10, 2.0f, 0.0008f, CameraShaker::ShakeDirection::Both},
{"", 25, 2.5f, 0.0025f, CameraShaker::ShakeDirection::Both},
{"", 25, 2.5f, 0.004f, CameraShaker::ShakeDirection::Both},
{"", 30, 3.0f, 0.008f, CameraShaker::ShakeDirection::Both},
{"最強", 45, 3.5f, 0.015f, CameraShaker::ShakeDirection::Both},
{"超最強", 45, 3.5f, 0.05f, CameraShaker::ShakeDirection::Both},
{"長い微弱", 60, 6.0f, 0.0025f, CameraShaker::ShakeDirection::Both},
{"長い弱", 60, 6.0f, 0.004f, CameraShaker::ShakeDirection::Both},
{"船内振動", 100, 6.0f, 0.0005f, CameraShaker::ShakeDirection::Both},
{"弱[縦]", 25, 2.5f, 0.004f, CameraShaker::ShakeDirection::Vertical},
};
CameraShaker::CameraShaker() : NerveExecutor("カメラ振動") {
initNerve(&NrvCameraShaker.Wait, 0);
mEditedShake = {"NULL", 0, 0.0f, 0.0f, ShakeDirection::Both};
}
void CameraShaker::update(const char* shakeLoop) {
if (shakeLoop) {
mShakeLoop = isEqualString(shakeLoop, "") ? &WeakShakeLoop : nullptr;
if (isNerve(this, &NrvCameraShaker.Wait))
setNerve(this, &NrvCameraShaker.ShakeLoop);
} else {
mShakeLoop = nullptr;
if (isNerve(this, &NrvCameraShaker.ShakeLoop))
setNerve(this, &NrvCameraShaker.Wait);
}
updateNerve();
}
void CameraShaker::startShakeByAction(const char* name, const char* unused1, const char* unused2,
s32 steps) {
startShakeByName(name, steps);
}
void CameraShaker::startShakeByName(const char* name, s32 steps) {
s32 index = -1;
if (isEqualString(name, "微弱"))
index = 0;
else if (isEqualString(name, "微弱[短]"))
index = 1;
else if (isEqualString(name, ""))
index = 2;
else if (isEqualString(name, ""))
index = 3;
else if (isEqualString(name, ""))
index = 4;
else if (isEqualString(name, "最強"))
index = 5;
else if (isEqualString(name, "超最強"))
index = 6;
else if (isEqualString(name, "長い微弱"))
index = 7;
else if (isEqualString(name, "長い弱"))
index = 8;
else if (isEqualString(name, "船内振動"))
index = 9;
else if (isEqualString(name, "弱[縦]"))
index = 10;
startShakeByIndex(index, steps);
}
void CameraShaker::startShakeByHitReaction(const char* name, const char* unused1,
const char* unused2, s32 steps) {
startShakeByName(name, steps);
}
void CameraShaker::exeWait() {
if (isFirstStep(this)) {
mActiveShake = nullptr;
mShakeLoop = nullptr;
}
mOffset = {0.0f, 0.0f};
}
void CameraShaker::exeShake() {
if (isGreaterEqualStep(this, mActiveShake->steps)) {
if (mShakeLoop) {
setNerve(this, &NrvCameraShaker.ShakeLoop);
} else {
mOffset = {0.0f, 0.0f};
mActiveShake = nullptr;
setNerve(this, &NrvCameraShaker.Wait);
}
return;
}
f32 shakeSpeed = (mActiveShake->speed * 360.0f) / mActiveShake->steps;
f32 currentShakeStrength =
sead::Mathf::cos(sead::Mathf::deg2rad(shakeSpeed * getNerveStep(this)));
f32 shakeOffset =
currentShakeStrength *
(mActiveShake->strength * (mActiveShake->steps - getNerveStep(this)) / mActiveShake->steps);
mOffset = {shakeOffset, shakeOffset};
if (mActiveShake->direction == ShakeDirection::Vertical)
mOffset.x = 0.0f;
}
void CameraShaker::exeShakeLoop() {
s32 nerveStep = getNerveStep(this);
f32 shakeStep = nerveStep <= 0 ? 0.0f : nerveStep / mShakeLoop->speed * sead::Mathf::pi2();
f32 shakeOffset = mShakeLoop->strength * sead::Mathf::cos(shakeStep);
mOffset = {shakeOffset, shakeOffset};
if (mShakeLoop->direction == ShakeDirection::Vertical)
mOffset.x = 0.0f;
}
void CameraShaker::startShakeByIndex(s32 index, s32 steps) {
const ShakeInfo& shake = ShakeInfos[index];
if (mActiveShake && (*mActiveShake > shake))
return;
mActiveShake = &shake;
if (steps >= 1) {
// requires doing this copy to match
// https://decomp.me/scratch/asjPP
ShakeInfo shake2 = shake;
mEditedShake = {shake.name, steps, shake.speed, shake.strength, shake.direction};
mActiveShake = &mEditedShake;
mEditedShake.speed = ((f32)steps / (f32)shake2.steps) * shake.speed;
}
setNerve(this, &Shake);
}
} // namespace al

View file

@ -0,0 +1,72 @@
#pragma once
#include <math/seadVector.h>
#include "Library/Nerve/NerveExecutor.h"
namespace al {
class CameraShaker : public NerveExecutor {
public:
enum class ShakeDirection : s32 { Both, Vertical };
struct ShakeInfo {
const char* name = nullptr;
s32 steps = 0;
f32 speed = 0.0f;
f32 strength = 0.0f;
ShakeDirection direction = ShakeDirection::Both;
bool operator>(const ShakeInfo& other) const {
if (strength < other.strength)
return false;
if (other.strength < strength)
return true;
if (other.steps > 0 && steps < 0)
return false;
if (other.steps < 0 && steps > 0)
return true;
if (steps < other.steps)
return false;
if (other.steps < steps)
return true;
s32 otherDirection = (s32)other.direction;
s32 directionCopy = (s32)direction;
if (otherDirection < directionCopy)
return false;
if (directionCopy < otherDirection)
return true;
if (speed < other.speed)
return true;
return false;
}
};
CameraShaker();
void update(const char* shakeLoop);
void startShakeByAction(const char* name, const char* unused1, const char* unused2, s32 steps);
void startShakeByName(const char* name, s32 steps);
void startShakeByHitReaction(const char* name, const char* unused1, const char* unused2,
s32 steps);
void exeWait();
void exeShake();
void exeShakeLoop();
void startShakeByIndex(s32 index, s32 steps);
private:
sead::Vector2f mOffset = {0.0f, 0.0f};
const ShakeInfo* mActiveShake = nullptr;
const ShakeInfo* mShakeLoop = nullptr;
ShakeInfo mEditedShake = {};
};
static_assert(sizeof(CameraShaker) == 0x40);
} // namespace al

View file

@ -0,0 +1,33 @@
#pragma once
#include <basis/seadTypes.h>
#include "Library/Camera/CameraTicket.h"
namespace al {
struct CameraStartInfo {
CameraTicket::Priority prePriorityType;
const char* preCameraName;
f32 preCameraSwingAngleH;
f32 preCameraSwingAngleV;
f32 preCameraMaxSwingAngleH;
f32 preCameraMaxSwingAngleV;
bool isInvalidCollidePreCamera;
bool isInvalidKeepPreCameraDistance;
bool isInvalidKeepPreCameraDistanceIfNoCollide;
bool isValidResetPreCameraPose;
bool isValidKeepPreSelfCameraPose;
bool isGrounded;
bool isExistAreaAngleH;
f32 areaAngleH;
bool isExistAreaAngleV;
f32 areaAngleV;
bool isExistNextPoseByPreCamera;
f32 nextAngleHByPreCamera;
f32 nextAngleVByPreCamera;
};
static_assert(sizeof(CameraStartInfo) == 0x40);
} // namespace al

View file

@ -0,0 +1,23 @@
#include "Library/Camera/CameraStopJudge.h"
#include "Library/Area/AreaObjUtil.h"
#include "Library/Area/IUseAreaObj.h"
namespace al {
CameraStopJudge::CameraStopJudge() = default;
bool CameraStopJudge::isStop() const {
if (mIsInvalidStopJudgeByDemo)
return false;
return mIsInCameraStopArea || _9;
}
void CameraStopJudge::update(const sead::Vector3f& position) {
mIsInCameraStopArea = isInAreaObj(this, "CameraStopArea", position);
}
AreaObjDirector* al::CameraStopJudge::getAreaObjDirector() const {
return mAreaObjDirector;
}
} // Namespace al

View file

@ -0,0 +1,23 @@
#pragma once
#include <math/seadVector.h>
#include "Library/Area/IUseAreaObj.h"
#include "Library/HostIO/HioNode.h"
namespace al {
class CameraStopJudge : public HioNode, public IUseAreaObj {
public:
CameraStopJudge();
bool isStop() const;
void update(const sead::Vector3f&);
AreaObjDirector* getAreaObjDirector() const override;
private:
bool mIsInCameraStopArea = false;
bool _9 = false;
bool mIsInvalidStopJudgeByDemo = false;
AreaObjDirector* mAreaObjDirector = nullptr;
};
} // namespace al

View file

@ -0,0 +1,29 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class CameraTicket;
struct CameraPoseInfo;
class CameraSwitchRequestInfo {
public:
CameraSwitchRequestInfo();
void addRequest(CameraTicket* ticket, s32, bool);
void addRequestWithNextCameraPose(CameraTicket* ticket, const CameraPoseInfo* nextPose, s32);
bool tryRemoveRequestIfExist(CameraTicket* ticket);
void reset();
private:
CameraTicket** mRequests;
s32 mNumRequests;
s32 _c;
bool _10;
bool mHasNextCameraPose;
CameraPoseInfo* mNextCameraPose;
};
static_assert(sizeof(CameraSwitchRequestInfo) == 0x20);
} // namespace al

View file

@ -0,0 +1,33 @@
#include "Library/Camera/CameraSwitchRequester.h"
#include "Library/Camera/CameraSwitchRequestInfo.h"
#include "Library/Camera/CameraTicket.h"
namespace al {
CameraSwitchRequester::CameraSwitchRequester() = default;
void CameraSwitchRequester::init(CameraSwitchRequestInfo* start, CameraSwitchRequestInfo* end) {
mStart = start;
mEnd = end;
};
void CameraSwitchRequester::requestStart(CameraTicket* ticket, s32 i) {
ticket->setActiveCamera(true);
mStart[ticket->getPriority()].addRequest(ticket, i, false);
}
void CameraSwitchRequester::requestEnd(CameraTicket* ticket, s32 i, bool b) {
ticket->setActiveCamera(false);
if (!mStart[ticket->getPriority()].tryRemoveRequestIfExist(ticket))
mEnd[ticket->getPriority()].addRequest(ticket, i, b);
}
void CameraSwitchRequester::requestEndWithNextCameraPose(CameraTicket* ticket,
const CameraPoseInfo* poseInfo, s32 i) {
ticket->setActiveCamera(false);
if (!mStart[ticket->getPriority()].tryRemoveRequestIfExist(ticket))
mEnd[ticket->getPriority()].addRequestWithNextCameraPose(ticket, poseInfo, i);
}
} // namespace al

View file

@ -0,0 +1,27 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
struct CameraPoseInfo;
class CameraSwitchRequestInfo;
class CameraTicket;
class CameraSwitchRequester {
public:
CameraSwitchRequester();
void init(CameraSwitchRequestInfo* start, CameraSwitchRequestInfo* end);
void requestStart(CameraTicket* ticket, s32);
void requestEnd(CameraTicket* ticket, s32, bool);
void requestEndWithNextCameraPose(CameraTicket* ticket, const CameraPoseInfo* poseInfo, s32);
private:
CameraSwitchRequestInfo* mStart = nullptr;
CameraSwitchRequestInfo* mEnd = nullptr;
};
static_assert(sizeof(CameraSwitchRequester) == 0x10);
} // namespace al

View file

@ -0,0 +1,22 @@
#pragma once
#include <math/seadVector.h>
namespace al {
class AreaShape;
class PlacementInfo;
class CameraTargetAreaLimitter {
public:
CameraTargetAreaLimitter(const AreaShape* shape);
static CameraTargetAreaLimitter* tryCreate(const PlacementInfo& placementInfo);
bool applyAreaLimit(sead::Vector3f* out, const sead::Vector3f& vec);
private:
const AreaShape* mAreaShape;
};
static_assert(sizeof(CameraTargetAreaLimitter) == 0x8);
} // namespace al

View file

@ -15,7 +15,7 @@ public:
Priority_Capture = 4,
Priority_Object = 5,
Priority_ForceArea = 6,
// Priority_EntranceAll = 7,
Priority_Unknown = 7, // Mention in alCameraPoserFunction::isPrePriorityEntranceAll
Priority_SafetyPointRecovery = 8,
Priority_Player = 9,
Priority_DemoTalk = 10,
@ -32,6 +32,10 @@ public:
s32 getPriority() const { return mPriority; }
bool isActiveCamera() const { return mIsActiveCamera; }
void setActiveCamera(bool isActiveCamera) { mIsActiveCamera = isActiveCamera; }
private:
CameraPoser* mPoser;
const CameraTicketId* mTicketId;
@ -39,4 +43,6 @@ private:
bool mIsActiveCamera = false;
};
static_assert(sizeof(CameraTicket) == 0x18);
} // namespace al

View file

@ -15,6 +15,8 @@ public:
const char* tryGetObjId() const;
const char* getObjId() const;
const PlacementId* getPlacementId() const { return mPlacementId; }
const char* getSuffix() const { return mSuffix; }
private:

View file

@ -0,0 +1,169 @@
#include "Library/Camera/CameraUtil.h"
#include "Library/Camera/CameraDirector.h"
#include "Library/Camera/CameraViewInfo.h"
#include "Library/Camera/IUseCamera.h"
#include "Library/Camera/SceneCameraInfo.h"
#include "Library/Math/MathUtil.h"
#include "Library/Projection/Projection.h"
namespace al {
inline CameraDirector* getCameraDirector(const IUseCamera* user) {
return user->getCameraDirector();
}
SceneCameraInfo* getSceneCameraInfo(const IUseCamera* user) {
return getCameraDirector(user)->getSceneCameraInfo();
}
s32 getViewNumMax(const IUseCamera* user) {
return getViewNumMax(getSceneCameraInfo(user));
}
s32 getViewNumMax(const SceneCameraInfo* info) {
return info->getViewNumMax();
}
bool isValidView(const IUseCamera* user, s32 viewIdx) {
return isValidView(getSceneCameraInfo(user), viewIdx);
}
bool isValidView(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewAt(viewIdx)->isValid();
}
const char* getViewName(const IUseCamera* user, s32 viewIdx) {
return getViewName(getSceneCameraInfo(user), viewIdx);
}
const char* getViewName(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewName(viewIdx);
}
const sead::Matrix34f& getViewMtx(const IUseCamera* user, s32 viewIdx) {
return getViewMtx(getSceneCameraInfo(user), viewIdx);
}
const sead::Matrix34f& getViewMtx(const SceneCameraInfo* info, s32 viewIdx) {
return getLookAtCamera(info, viewIdx).getMatrix();
}
const sead::Matrix34f* getViewMtxPtr(const IUseCamera* user, s32 viewIdx) {
return getViewMtxPtr(getSceneCameraInfo(user), viewIdx);
}
const sead::Matrix34f* getViewMtxPtr(const SceneCameraInfo* info, s32 viewIdx) {
return &getViewMtx(info, viewIdx);
}
const sead::Matrix44f& getProjectionMtx(const IUseCamera* user, s32 viewIdx) {
return getProjectionMtx(getSceneCameraInfo(user), viewIdx);
}
const sead::Matrix44f& getProjectionMtx(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewAt(viewIdx)->getProjMtx();
}
const sead::LookAtCamera& getLookAtCamera(const IUseCamera* user, s32 viewIdx) {
return getLookAtCamera(getSceneCameraInfo(user), viewIdx);
}
const sead::LookAtCamera& getLookAtCamera(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewAt(viewIdx)->getLookAtCam();
}
const sead::Projection& getProjectionSead(const IUseCamera* user, s32 viewIdx) {
return getProjectionSead(getSceneCameraInfo(user), viewIdx);
}
const sead::Projection& getProjectionSead(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewAt(viewIdx)->getProjectionSead();
}
const Projection& getProjection(const IUseCamera* user, s32 viewIdx) {
return getProjection(getSceneCameraInfo(user), viewIdx);
}
const Projection& getProjection(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewAt(viewIdx)->getProjection();
}
const sead::Vector3f& getCameraPos(const IUseCamera* user, s32 viewIdx) {
return getCameraPos(getSceneCameraInfo(user), viewIdx);
}
const sead::Vector3f& getCameraPos(const SceneCameraInfo* info, s32 viewIdx) {
return getLookAtCamera(info, viewIdx).getPos();
}
const sead::Vector3f& getCameraAt(const IUseCamera* user, s32 viewIdx) {
return getCameraAt(getSceneCameraInfo(user), viewIdx);
}
const sead::Vector3f& getCameraAt(const SceneCameraInfo* info, s32 viewIdx) {
return getLookAtCamera(info, viewIdx).getAt();
}
const sead::Vector3f& getCameraUp(const IUseCamera* user, s32 viewIdx) {
return getCameraUp(getSceneCameraInfo(user), viewIdx);
}
const sead::Vector3f& getCameraUp(const SceneCameraInfo* info, s32 viewIdx) {
return getLookAtCamera(info, viewIdx).getUp();
}
f32 getFovyDegree(const IUseCamera* user, s32 viewIdx) {
return getFovyDegree(getSceneCameraInfo(user), viewIdx);
}
f32 getFovyDegree(const SceneCameraInfo* info, s32 viewIdx) {
return sead::Mathf::rad2deg(getFovy(info, viewIdx));
}
f32 getFovy(const IUseCamera* user, s32 viewIdx) {
return getFovy(getSceneCameraInfo(user), viewIdx);
}
f32 getFovy(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewAt(viewIdx)->getProjection().getFovy();
}
f32 getNear(const IUseCamera* user, s32 viewIdx) {
return getNear(getSceneCameraInfo(user), viewIdx);
}
f32 getNear(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewAt(viewIdx)->getNear();
}
f32 getFar(const IUseCamera* user, s32 viewIdx) {
return getFar(getSceneCameraInfo(user), viewIdx);
}
f32 getFar(const SceneCameraInfo* info, s32 viewIdx) {
return info->getViewAt(viewIdx)->getFar();
}
f32 calcCameraDistance(const IUseCamera* user, s32 viewIdx) {
sead::Vector3f diff = getCameraPos(user, viewIdx) - getCameraAt(user, viewIdx);
return diff.length();
}
f32 calcFovxDegree(const IUseCamera* user, s32 viewIdx) {
f32 aspect = getSceneCameraInfo(user)->getViewAt(viewIdx)->getAspect();
return aspect * getFovyDegree(user, viewIdx);
}
f32 calcCurrentFovyRate(const IUseCamera* user, s32 viewIdx) {
f32 fovy = getFovyDegree(user, viewIdx);
f32 fovy2 = getCameraDirector(user)->getSceneFovyDegree();
if (isNearZero(fovy, 0.001f) || isNearZero(fovy2, 0.001f))
return 0;
return fovy / fovy2;
}
} // namespace al

View file

@ -15,7 +15,7 @@ class CameraSubTargetTurnParam;
class SceneCameraInfo;
class PlacementId;
class Resource;
class ActorInitInfo;
struct ActorInitInfo;
class LiveActor;
class PlacementInfo;
class CameraPoser;
@ -39,12 +39,12 @@ const char* getViewName(const IUseCamera* user, s32 viewIdx);
const char* getViewName(const SceneCameraInfo* info, s32 viewIdx);
const sead::Matrix34f& getViewMtx(const IUseCamera* user, s32 viewIdx);
const sead::Matrix34f& getViewMtx(const SceneCameraInfo* info, s32 viewIdx);
sead::Matrix34f* getViewMtxPtr(const IUseCamera* user, s32 viewIdx);
sead::Matrix34f* getViewMtxPtr(const SceneCameraInfo* info, s32 viewIdx);
const sead::Matrix34f* getViewMtxPtr(const IUseCamera* user, s32 viewIdx);
const sead::Matrix34f* getViewMtxPtr(const SceneCameraInfo* info, s32 viewIdx);
const sead::Matrix44f& getProjectionMtx(const IUseCamera* user, s32 viewIdx);
const sead::Matrix44f& getProjectionMtx(const SceneCameraInfo* info, s32 viewIdx);
sead::Matrix44f* getProjectionMtxPtr(const IUseCamera* user, s32 viewIdx);
sead::Matrix44f* getProjectionMtxPtr(const SceneCameraInfo* info, s32 viewIdx);
const sead::Matrix44f* getProjectionMtxPtr(const IUseCamera* user, s32 viewIdx);
const sead::Matrix44f* getProjectionMtxPtr(const SceneCameraInfo* info, s32 viewIdx);
const sead::LookAtCamera& getLookAtCamera(const IUseCamera* user, s32 viewIdx);
const sead::LookAtCamera& getLookAtCamera(const SceneCameraInfo* info, s32 viewIdx);
const sead::Projection& getProjectionSead(const IUseCamera* user, s32 viewIdx);

View file

@ -0,0 +1,52 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadMatrix.h>
#include <math/seadVector.h>
namespace al {
class GyroCameraCtrl {
public:
GyroCameraCtrl();
void reset(const sead::Vector3f&, const sead::Vector3f&, const sead::Vector3f&);
void update(const sead::Vector3f&, const sead::Vector3f&, const sead::Vector3f&);
void reduceSensitivity();
void setIsValidGyro(bool isValidGyro) { mIsValidGyro = isValidGyro; }
void setSensitivityScale(f32 sensitivityScale) { mSensitivityScale = sensitivityScale; }
private:
sead::Matrix34f _0;
sead::Vector3f _30;
sead::Vector3f _3c;
sead::Vector3f _48;
sead::Vector3f _54;
sead::Vector3f _60;
sead::Vector3f _6c;
f32 _78;
f32 _7c;
f32 _80;
f32 _84;
f32 _88;
f32 _8c;
f32 _90;
f32 _94;
f32 _98;
s32 mSensitivityLevel;
f32 _a0;
f32 _a4;
f32 mSensitivityScale;
bool mIsValidGyro;
f32 _b0;
f32 _b4;
f32 _b8;
f32 _bc;
f32 _c0;
f32 _c4;
};
static_assert(sizeof(GyroCameraCtrl) == 0xC8);
} // namespace al

View file

@ -0,0 +1,7 @@
#include "Library/Camera/CameraViewCtrlPause.h"
namespace al {
PauseCameraCtrl::PauseCameraCtrl(f32 v) : _4(v) {}
} // namespace al

View file

@ -0,0 +1,18 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class PauseCameraCtrl {
public:
PauseCameraCtrl(f32 v);
private:
bool mIsCameraPause = false;
f32 _4;
};
static_assert(sizeof(PauseCameraCtrl) == 0x8);
} // namespace al

View file

@ -0,0 +1,14 @@
#include "Library/Camera/CameraViewCtrlScene.h"
namespace al {
SceneCameraViewCtrl::SceneCameraViewCtrl() = default;
SceneCameraCtrl::SceneCameraCtrl() = default;
void SceneCameraCtrl::init(s32 viewNum) {
mViewNum = viewNum;
mViewArray = new SceneCameraViewCtrl[viewNum];
}
} // namespace al

View file

@ -0,0 +1,41 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class CameraRequestParamHolder;
class CameraSwitchRequester;
class SpecialCameraHolder;
class SceneCameraViewCtrl {
public:
SceneCameraViewCtrl();
const CameraSwitchRequester* getSwitchRequester() const { return mSwitchRequester; }
private:
CameraSwitchRequester* mSwitchRequester = nullptr;
const char* mViewName = "Start";
void* _10 = nullptr;
};
static_assert(sizeof(SceneCameraViewCtrl) == 0x18);
class SceneCameraCtrl {
public:
SceneCameraCtrl();
void init(s32 viewNum);
const SceneCameraViewCtrl& getSceneViewAt(s32 idx) const { return mViewArray[idx]; }
private:
s32 mViewNum = 0;
SceneCameraViewCtrl* mViewArray = nullptr;
CameraRequestParamHolder* mRequestParamHolder = nullptr;
SpecialCameraHolder* mSpecialCameraHolder = nullptr;
};
static_assert(sizeof(SceneCameraCtrl) == 0x20);
} // namespace al

View file

@ -0,0 +1,11 @@
#include "Library/Camera/CameraViewFlag.h"
namespace al {
CameraViewFlag::CameraViewFlag() = default;
void CameraViewFlag::resetAllFlag() {
_0 = false;
}
} // namespace al

View file

@ -0,0 +1,15 @@
#pragma once
namespace al {
class CameraViewFlag {
public:
CameraViewFlag();
void resetAllFlag();
private:
bool _0 = false;
};
} // namespace al

View file

@ -0,0 +1,37 @@
#include "Library/Camera/CameraViewInfo.h"
#include "Library/Projection/Projection.h"
namespace al {
CameraViewInfo::CameraViewInfo(s32 index, const sead::LookAtCamera& lookAtCam,
const Projection& projection, const CameraViewFlag& flag,
const OrthoProjectionInfo& orthoProjectionInfo)
: mIndex(index), mLookAtCam(lookAtCam), mProjection(projection), mViewFlag(flag),
mOrthoProjectionInfo(orthoProjectionInfo) {}
const sead::Projection& CameraViewInfo::getProjectionSead() const {
return mProjection.getProjectionSead();
}
const sead::Matrix44f& CameraViewInfo::getProjMtx() const {
return mProjection.getProjMtx();
}
const sead::Matrix44f& CameraViewInfo::getProjMtxStd() const {
return mProjection.getMtxStd();
}
f32 CameraViewInfo::getAspect() const {
return mProjection.getAspect();
}
f32 CameraViewInfo::getNear() const {
return mProjection.getNear();
}
f32 CameraViewInfo::getFar() const {
return mProjection.getFar();
}
} // namespace al

View file

@ -0,0 +1,42 @@
#pragma once
#include <gfx/seadCamera.h>
#include <math/seadMatrix.h>
namespace al {
class CameraViewFlag;
struct OrthoProjectionInfo;
class Projection;
class CameraViewInfo {
public:
CameraViewInfo(s32 index, const sead::LookAtCamera& lookAtCam, const Projection& projection,
const CameraViewFlag& flag, const OrthoProjectionInfo& orthoProjectionInfo);
const sead::Projection& getProjectionSead() const;
const sead::Matrix44f& getProjMtx() const;
const sead::Matrix44f& getProjMtxStd() const;
f32 getAspect() const;
f32 getNear() const;
f32 getFar() const;
s32 getIndex() const { return mIndex; }
bool isValid() const { return mIsValid; }
const sead::LookAtCamera& getLookAtCam() const { return mLookAtCam; }
const Projection& getProjection() const { return mProjection; }
private:
s32 mIndex;
bool mIsValid = true;
bool mIsActiveInterpole = true;
bool _6 = false;
const sead::LookAtCamera& mLookAtCam;
const Projection& mProjection;
const CameraViewFlag& mViewFlag;
const OrthoProjectionInfo& mOrthoProjectionInfo;
};
} // namespace al

View file

@ -0,0 +1,10 @@
#pragma once
namespace al {
class CameraPoser;
template <typename T>
CameraPoser* createCameraPoserFunction(const char* cameraPoserName) {
return new T(cameraPoserName);
}
} // namespace al

View file

@ -0,0 +1,26 @@
#include "Library/Camera/SceneCameraInfo.h"
#include "Library/Camera/CameraViewInfo.h"
namespace al {
SceneCameraInfo::SceneCameraInfo(s32 maxViewNum) : mViewNumMax(maxViewNum) {
mViewArray = new CameraViewInfo*[maxViewNum];
for (s32 i = 0; i < mViewNumMax; i++)
mViewArray[i] = nullptr;
}
void SceneCameraInfo::initViewInfo(CameraViewInfo* cameraViewInfo) {
mViewArray[cameraViewInfo->getIndex()] = cameraViewInfo;
}
const char* SceneCameraInfo::getViewName(s32 num) const {
if (num == 0)
return "TV";
else if (num == 1)
return "サブ"; // Sub/Lower
else
return "メイン"; // Main
}
} // namespace al

View file

@ -0,0 +1,25 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class CameraViewInfo;
class SceneCameraInfo {
public:
SceneCameraInfo(s32 num);
void initViewInfo(CameraViewInfo* cameraViewInfo);
const char* getViewName(s32 num) const;
s32 getViewNumMax() const { return mViewNumMax; }
CameraViewInfo* getViewAt(s32 viewIdx) const { return mViewArray[viewIdx]; }
private:
s32 mViewNumMax;
CameraViewInfo** mViewArray;
};
} // namespace al

View file

@ -4,15 +4,15 @@
namespace al {
// NON_MATCHING
void SnapShotCameraCtrl::load(const ByamlIter& iter) {
ByamlIter param;
if (!tryGetByamlIterByKey(&param, iter, "SnapShotParam"))
CameraParam* param = mParam;
ByamlIter paramIter;
if (!tryGetByamlIterByKey(&paramIter, iter, "SnapShotParam"))
return;
if (tryGetByamlF32(&mParam->mMinFovyDegree, param, "MinFovyDegree"))
mParam->mHasMin = true;
if (tryGetByamlF32(&mParam->mMinFovyDegree, param, "MinFovyDegree"))
mParam->mHasMax = true;
if (tryGetByamlF32(&param->minFovyDegree, paramIter, "MinFovyDegree"))
param->hasMin = true;
if (tryGetByamlF32(&param->maxFovyDegree, paramIter, "MaxFovyDegree"))
param->hasMax = true;
}
} // namespace al

View file

@ -7,14 +7,14 @@
#include "Library/Yaml/ByamlIter.h"
struct CameraParam {
bool mHasMin;
bool mHasMax;
f32 mMinFovyDegree;
f32 mMaxFovyDegree;
bool hasMin;
bool hasMax;
f32 minFovyDegree;
f32 maxFovyDegree;
};
namespace al {
class SnapShotCameraSceneInfo;
struct SnapShotCameraSceneInfo;
class ICameraInput;
class IUseCollision;

View file

@ -27,7 +27,7 @@ void ViewIdHolder::init(const PlacementInfo& placementInfo) {
}
}
PlacementId& ViewIdHolder::getViewId(s32 idx) const {
const PlacementId& ViewIdHolder::getViewId(s32 idx) const {
return mPlacementIds[idx];
}
} // namespace al

View file

@ -10,7 +10,7 @@ class ViewIdHolder {
public:
ViewIdHolder();
void init(const PlacementInfo& placementInfo);
PlacementId& getViewId(s32 idx) const;
const PlacementId& getViewId(s32 idx) const;
static ViewIdHolder* tryCreate(const PlacementInfo& placementInfo);

View file

@ -9,8 +9,8 @@
namespace al {
struct SphereInterpolator;
struct SphereHitInfo;
struct CollisionPartsFilterBase;
struct TriangleFilterBase;
class CollisionPartsFilterBase;
class TriangleFilterBase;
class CollisionDirector;
class Collider : public HioNode, public IUseCollision {

View file

@ -13,4 +13,12 @@ namespace alCollisionUtil {
bool getFirstPolyOnArrow(const al::IUseCollision*, sead::Vector3f*, al::Triangle*,
const sead::Vector3f&, const sead::Vector3f&,
const al::CollisionPartsFilterBase*, const al::TriangleFilterBase*);
}
bool getHitPosAndNormalOnArrow(const al::IUseCollision*, sead::Vector3f*, sead::Vector3f*,
const sead::Vector3f&, const sead::Vector3f&,
const al::CollisionPartsFilterBase*, const al::TriangleFilterBase*);
bool getHitPosOnArrow(const al::IUseCollision*, sead::Vector3f*, const sead::Vector3f&,
const sead::Vector3f&, const al::CollisionPartsFilterBase*,
const al::TriangleFilterBase*);
s32 checkStrikeArrow(const al::IUseCollision*, const sead::Vector3f&, const sead::Vector3f&,
const al::CollisionPartsFilterBase*, const al::TriangleFilterBase*);
} // namespace alCollisionUtil

View file

@ -2,8 +2,7 @@
#include "Library/Collision/CollisionParts.h"
#include "Library/Collision/KCollisionServer.h"
#include "Library/Math/MathAngleUtil.h"
#include "Library/Math/MathLengthUtil.h"
#include "Library/Math/MathUtil.h"
namespace al {
@ -209,6 +208,99 @@ const sead::Matrix34f& Triangle::getPrevBaseMtx() const {
return mCollisionParts->getPrevBaseMtx();
}
HitInfo::HitInfo() {}
bool HitInfo::isCollisionAtFace() const {
return mCollisionLocation == CollisionLocation::Face;
}
bool HitInfo::isCollisionAtEdge() const {
return mCollisionLocation == CollisionLocation::Edge1 ||
mCollisionLocation == CollisionLocation::Edge2 ||
mCollisionLocation == CollisionLocation::Edge3;
}
bool HitInfo::isCollisionAtCorner() const {
return mCollisionLocation == CollisionLocation::Corner1 ||
mCollisionLocation == CollisionLocation::Corner2 ||
mCollisionLocation == CollisionLocation::Corner3;
}
const sead::Vector3f& HitInfo::tryGetHitEdgeNormal() const {
if (mCollisionLocation == CollisionLocation::Edge1)
return mTriangle.getEdgeNormal(0);
if (mCollisionLocation == CollisionLocation::Edge2)
return mTriangle.getEdgeNormal(1);
if (mCollisionLocation == CollisionLocation::Edge3)
return mTriangle.getEdgeNormal(2);
return sead::Vector3f::zero;
}
void SphereHitInfo::calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const {
// TODO add proper names here, once the missing names for _70 and _80 in HitInfo are found
if (mHitInfo->isCollisionAtFace()) {
calcFixVectorNormal(a1, a2);
return;
}
sead::Vector3f v20;
v20.x = mHitInfo->_80.x - mHitInfo->mCollisionHitPos.x;
v20.y = mHitInfo->_80.y - mHitInfo->mCollisionHitPos.y;
v20.z = mHitInfo->_80.z - mHitInfo->mCollisionHitPos.z;
tryNormalizeOrZero(&v20);
sead::Vector3f scaled_a1;
sead::Vector3f scaled_a2;
f32 v13 = v20.dot(mHitInfo->mTriangle.getFaceNormal() * mHitInfo->_70);
f32 v12 = v20.dot(mHitInfo->mTriangle.getFaceNormal());
sead::Vector3CalcCommon<f32>::multScalar(scaled_a1, v20, v13);
sead::Vector3CalcCommon<f32>::multScalar(scaled_a2, v20, v12);
*a1 = scaled_a1;
*a2 = scaled_a2;
}
void SphereHitInfo::calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2) const {
f32 unk = mHitInfo->_70;
a1->x = mHitInfo->mTriangle.getFaceNormal().x * unk;
a1->y = mHitInfo->mTriangle.getFaceNormal().y * unk;
a1->z = mHitInfo->mTriangle.getFaceNormal().z * unk;
if (a2)
a2->set(mHitInfo->mTriangle.getFaceNormal());
}
void DiskHitInfo::calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const {
// TODO add proper names here, once the missing names for _70 and _80 in HitInfo are found
if (mHitInfo->isCollisionAtFace()) {
calcFixVectorNormal(a1, a2);
return;
}
sead::Vector3f v20;
v20.x = mHitInfo->_80.x - mHitInfo->mCollisionHitPos.x;
v20.y = mHitInfo->_80.y - mHitInfo->mCollisionHitPos.y;
v20.z = mHitInfo->_80.z - mHitInfo->mCollisionHitPos.z;
tryNormalizeOrZero(&v20);
sead::Vector3f scaled_a1;
sead::Vector3f scaled_a2;
f32 v13 = v20.dot(mHitInfo->mTriangle.getFaceNormal() * mHitInfo->_70);
f32 v12 = v20.dot(mHitInfo->mTriangle.getFaceNormal());
sead::Vector3CalcCommon<f32>::multScalar(scaled_a1, v20, v13);
sead::Vector3CalcCommon<f32>::multScalar(scaled_a2, v20, v12);
*a1 = scaled_a1;
*a2 = scaled_a2;
}
void DiskHitInfo::calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2) const {
f32 unk = mHitInfo->_70;
a1->x = mHitInfo->mTriangle.getFaceNormal().x * unk;
a1->y = mHitInfo->mTriangle.getFaceNormal().y * unk;
a1->z = mHitInfo->mTriangle.getFaceNormal().z * unk;
if (a2)
a2->set(mHitInfo->mTriangle.getFaceNormal());
}
} // namespace al
bool operator==(const al::Triangle& lhs, const al::Triangle& rhs) {

View file

@ -2,6 +2,7 @@
#include <math/seadMatrix.h>
#include <math/seadVector.h>
#include <prim/seadStorageFor.h>
namespace al {
class Triangle;
@ -15,8 +16,8 @@ namespace al {
class ByamlIter;
class CollisionParts;
class HitSensor;
class KCPrismData;
class KCPrismHeader;
struct KCPrismData;
struct KCPrismHeader;
class LiveActor;
class Triangle {
@ -48,8 +49,10 @@ public:
const sead::Matrix34f& getBaseInvMtx() const;
const sead::Matrix34f& getPrevBaseMtx() const;
// clang-format off
friend bool ::operator==(const Triangle& tri1, const Triangle& tri2);
friend bool ::operator!=(const Triangle& tri1, const Triangle& tri2);
// clang-format on
private:
const CollisionParts* mCollisionParts;
@ -59,4 +62,82 @@ private:
sead::Vector3f mPositions[3];
};
enum class CollisionLocation : u8 {
None = 0,
Face = 1,
Edge1 = 2,
Edge2 = 3,
Edge3 = 4,
Corner1 = 5,
Corner2 = 6,
Corner3 = 7,
};
class HitInfo {
public:
HitInfo();
bool isCollisionAtFace() const;
bool isCollisionAtEdge() const;
bool isCollisionAtCorner() const;
const sead::Vector3f& tryGetHitEdgeNormal() const;
friend class ArrowHitInfo;
friend class SphereHitInfo;
friend class DiskHitInfo;
protected:
Triangle mTriangle;
f32 _70 = 0.0f;
sead::Vector3f mCollisionHitPos = {0.0f, 0.0f, 0.0f};
sead::Vector3f _80 = {0.0f, 0.0f, 0.0f};
sead::Vector3f mCollisionMovingReaction = {0.0f, 0.0f, 0.0f};
CollisionLocation mCollisionLocation = CollisionLocation::None;
};
class ArrowHitInfo {
public:
HitInfo* operator*() { return mHitInfo.data(); }
const HitInfo* operator*() const { return mHitInfo.data(); }
HitInfo& operator->() { return *mHitInfo; }
const HitInfo& operator->() const { return *mHitInfo; }
sead::StorageFor<HitInfo> mHitInfo{sead::ZeroInitializeTag{}};
};
class SphereHitInfo {
public:
void calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const;
void calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2) const;
HitInfo* operator*() { return mHitInfo.data(); }
const HitInfo* operator*() const { return mHitInfo.data(); }
HitInfo& operator->() { return *mHitInfo; }
const HitInfo& operator->() const { return *mHitInfo; }
sead::StorageFor<HitInfo> mHitInfo{sead::ZeroInitializeTag{}};
};
class DiskHitInfo {
public:
void calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const;
void calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2) const;
HitInfo* operator*() { return mHitInfo.data(); }
const HitInfo* operator*() const { return mHitInfo.data(); }
HitInfo& operator->() { return *mHitInfo; }
const HitInfo& operator->() const { return *mHitInfo; }
sead::StorageFor<HitInfo> mHitInfo{sead::ZeroInitializeTag{}};
};
} // namespace al

View file

@ -12,29 +12,29 @@ class CollisionParts;
class LiveActor;
struct KCPrismHeader {
u32 mPositionsOffset;
u32 mNormalsOffset;
u32 mTrianglesOffset;
u32 mOctreeOffset;
f32 mThickness;
sead::Vector3f mOctreeOrigin;
sead::Vector3u mWidthMask;
sead::Vector3u mWidthShift;
f32 mHitboxRadiusCap;
u32 positionsOffset;
u32 normalsOffset;
u32 trianglesOffset;
u32 octreeOffset;
f32 thickness;
sead::Vector3f octreeOrigin;
sead::Vector3u widthMask;
sead::Vector3u widthShift;
f32 hitboxRadiusCap;
};
struct KCPrismData {
f32 mLength;
u16 mPosIndex;
u16 mFaceNormalIndex;
u16 mEdgeNormalIndex[3];
u16 mCollisionType;
u32 mTriIndex;
f32 length;
u16 posIndex;
u16 faceNormalIndex;
u16 edgeNormalIndex[3];
u16 collisionType;
u32 triIndex;
};
struct KCHitInfo {
const KCPrismHeader* mHeader;
const KCPrismData* mData;
const KCPrismHeader* header;
const KCPrismData* data;
f32 _16;
u8 _20; // collision location, enum
};

Some files were not shown because too many files have changed in this diff Show more