Files
ss/src/d/snd/d_snd_3d_actor.cpp
T
2025-09-13 11:10:27 +02:00

194 lines
5.8 KiB
C++

#include "d/snd/d_snd_3d_actor.h"
#include "common.h"
#include "d/a/d_a_player.h"
#include "d/snd/d_snd_3d_manager.h"
#include "d/snd/d_snd_checkers.h"
#include "d/snd/d_snd_mgr.h"
#include "d/snd/d_snd_player_mgr.h"
#include "d/snd/d_snd_state_mgr.h"
#include "nw4r/math/math_types.h"
#include <cmath>
dSnd3DActor_c::dSnd3DActor_c(dSndSourceParam *pSourceParam, s32 sourceType)
: nw4r::snd::Sound3DActor(
dSndPlayerMgr_c::GetInstance()->getSoundArchivePlayerForType(sourceType),
dSnd3DManager_c::GetInstance()->getManager()
),
a_field_0x7D(0),
mIsDisabled(false),
mIsDemoActor(false),
mIsPaused(false),
a_field_0x84(0.0f),
a_field_0x88(0.0f),
a_field_0x8C(0.0f),
a_field_0x90(INFINITY),
mDistanceToListener(INFINITY),
mCameraDirectionDot(0.0f),
mSpeed(0.0f),
mpSourceParam(pSourceParam),
mFlags(0),
mDistanceToPlayer(INFINITY),
mFxSend3D(0.0f) {
resetCachedRelativePositions();
// Portability hazard
SetUserParam(reinterpret_cast<u32>(this));
if (dSndPlayerMgr_c::GetInstance()->shouldUseDemoPlayer(sourceType)) {
mIsDemoActor = true;
}
}
void dSnd3DActor_c::setPosition(const nw4r::math::VEC3 &rPosition) {
SetPosition(rPosition);
mFxSend3D = dSndStateMgr_c::GetInstance()->getFxSend3D();
mFlags = 0;
}
void dSnd3DActor_c::resetCachedRelativePositions() {
mPositionRelativeToPlayer.x = INFINITY;
mPositionRelativeToPlayer.y = INFINITY;
mPositionRelativeToPlayer.z = INFINITY;
mPositionRelativeToListener.x = INFINITY;
mPositionRelativeToListener.y = INFINITY;
mPositionRelativeToListener.z = INFINITY;
mPositionTransformedByListener.x = INFINITY;
mPositionTransformedByListener.y = INFINITY;
mPositionTransformedByListener.z = INFINITY;
}
void dSnd3DActor_c::setSourceParam(const dSndSourceParam *param) {
*mpSourceParam = *param;
}
void dSnd3DActor_c::updatePositionRelativeToListener() {
if (!checkFlag(0x1)) {
calculatePositionRelativeToListener();
setFlag(0x1);
}
}
void dSnd3DActor_c::calculatePositionRelativeToListener() {
nw4r::math::VEC3Sub(
&mPositionRelativeToListener, &GetPosition(), &dSnd3DManager_c::GetInstance()->getSndListenerPos()
);
}
void dSnd3DActor_c::updateDistanceToListener() {
if (!checkFlag(0x2)) {
updatePositionRelativeToListener();
mDistanceToListener = VEC3Len(&mPositionRelativeToListener);
setFlag(0x2);
}
}
void dSnd3DActor_c::updatePositionTransformedByListener() {
if (!checkFlag(0x10)) {
MTXMultVec(
dSnd3DManager_c::GetInstance()->getSndListenerMatrix(), GetPosition(), mPositionTransformedByListener
);
setFlag(0x10);
}
}
void dSnd3DActor_c::updateCameraDirectionDot() {
if (!checkFlag(0x20)) {
updatePositionRelativeToListener();
nw4r::math::VEC3 norm;
VECNormalize(mPositionRelativeToListener, norm);
mCameraDirectionDot = nw4r::math::VEC3Dot(&norm, &dSnd3DManager_c::GetInstance()->getNrmCameraDirection());
setFlag(0x20);
}
}
void dSnd3DActor_c::updatePositionRelativeToCameraTarget() {
if (!checkFlag(0x4)) {
calculatePositionRelativeToCameraTarget();
setFlag(0x4);
}
}
void dSnd3DActor_c::calculatePositionRelativeToCameraTarget() {
nw4r::math::VEC3Sub(
&mPositionRelativeToCameraTarget, &GetPosition(), &dSnd3DManager_c::GetInstance()->getCameraTargetPos()
);
}
void dSnd3DActor_c::updateDistanceToCameraTarget() {
if (!checkFlag(0x8)) {
updatePositionRelativeToCameraTarget();
mDistanceToCameraTarget = VEC3Len(&mPositionRelativeToCameraTarget);
setFlag(0x8);
}
}
void dSnd3DActor_c::updatePositionRelativeToPlayer() {
if (!checkFlag(0x40)) {
nw4r::math::VEC3 linkTranslation = dAcPy_c::GetLink()->getCenterTranslation();
nw4r::math::VEC3 pos = GetPosition();
nw4r::math::VEC3Sub(&mPositionRelativeToPlayer, &pos, &linkTranslation);
setFlag(0x40);
}
}
const nw4r::math::VEC3 &dSnd3DActor_c::getPositionRelativeToPlayer() {
updatePositionRelativeToPlayer();
return mPositionRelativeToPlayer;
}
void dSnd3DActor_c::updateDistanceToPlayer() {
if (!checkFlag(0x80)) {
updatePositionRelativeToPlayer();
nw4r::math::VEC3 linkTranslation = dAcPy_c::GetLink()->getCenterTranslation();
nw4r::math::VEC3 pos = GetPosition();
if ((linkTranslation.x == 0.0f && linkTranslation.y == 0.0f && linkTranslation.z == 0.0f) ||
(pos.x == 0.0f && pos.y == 0.0f && pos.z == 0.0f)) {
// Don't bother if we received dummy values
mDistanceToPlayer = INFINITY;
} else {
mDistanceToPlayer = nw4r::math::VEC3Len(&mPositionRelativeToPlayer);
}
setFlag(0x80);
}
}
f32 dSnd3DActor_c::getDistanceToPlayer() {
updateDistanceToPlayer();
return mDistanceToPlayer;
}
// here are functions that are probably in part copied from nw4r::snd::Sound3DCalculator
bool dSnd3DActor_c::hasPlayingSounds() const {
for (int i = 0; i < ACTOR_PLAYER_COUNT; i++) {
if (GetPlayingSoundCount(i) > 0) {
return true;
}
}
return false;
}
bool dSnd3DActor_c::isPlayingSound(u32 id) {
bool result = false;
IsCurrentSoundIdChecker handler(id, &result);
ForEachSound(handler, false);
return result;
}
u32 dSnd3DActor_c::soundLabelToSoundId(const char *soundLabel) const {
return dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(soundLabel);
}
const char *dSnd3DActor_c::soundIdToSoundLabel(u32 soundId) const {
if (mIsDemoActor) {
return dSndPlayerMgr_c::GetInstance()->getDemoArchiveDirectly()->GetSoundLabelString(soundId);
} else {
return dSndMgr_c::getSoundLabelString(soundId);
}
}