mirror of https://github.com/AxioDL/metaforce.git
Implement CScriptSpindleCamera
This commit is contained in:
parent
88591f48f0
commit
01af7b735d
|
@ -12,6 +12,25 @@
|
||||||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||||
</Objective-C>
|
</Objective-C>
|
||||||
<Objective-C-extensions>
|
<Objective-C-extensions>
|
||||||
|
<file>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||||
|
</file>
|
||||||
|
<class>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||||
|
</class>
|
||||||
<extensions>
|
<extensions>
|
||||||
<pair source="cpp" header="hpp" fileNamingConvention="NONE" />
|
<pair source="cpp" header="hpp" fileNamingConvention="NONE" />
|
||||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||||
|
|
|
@ -11,15 +11,15 @@ struct NewCameraShaker : IScriptObject {
|
||||||
String<-1> name;
|
String<-1> name;
|
||||||
Value<atVec3f> location;
|
Value<atVec3f> location;
|
||||||
Value<bool> active;
|
Value<bool> active;
|
||||||
PlayerParameters flags;
|
PropertyFlags flags;
|
||||||
Value<float> duration;
|
Value<float> duration;
|
||||||
Value<float> sfxDist;
|
Value<float> sfxDist;
|
||||||
struct CameraShakerComponent : BigDNA {
|
struct CameraShakerComponent : BigDNA {
|
||||||
AT_DECL_DNA
|
AT_DECL_DNA
|
||||||
PlayerParameters flags;
|
PropertyFlags flags;
|
||||||
struct CameraShakePoint : BigDNA {
|
struct CameraShakePoint : BigDNA {
|
||||||
AT_DECL_DNA
|
AT_DECL_DNA
|
||||||
PlayerParameters flags;
|
PropertyFlags flags;
|
||||||
Value<float> attackTime;
|
Value<float> attackTime;
|
||||||
Value<float> sustainTime;
|
Value<float> sustainTime;
|
||||||
Value<float> duration;
|
Value<float> duration;
|
||||||
|
|
|
@ -350,7 +350,7 @@ struct VisorParameters : BigDNA {
|
||||||
Value<atUint32> visorMask;
|
Value<atUint32> visorMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerParameters : BigDNA {
|
struct PropertyFlags : BigDNA {
|
||||||
AT_DECL_DNA_YAML
|
AT_DECL_DNA_YAML
|
||||||
Value<atUint32> propertyCount;
|
Value<atUint32> propertyCount;
|
||||||
Vector<bool, AT_DNA_COUNT(propertyCount)> bools;
|
Vector<bool, AT_DNA_COUNT(propertyCount)> bools;
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct PlayerActor : IScriptObject {
|
||||||
Value<bool> snow;
|
Value<bool> snow;
|
||||||
Value<bool> solid;
|
Value<bool> solid;
|
||||||
Value<bool> active;
|
Value<bool> active;
|
||||||
PlayerParameters playerParameters;
|
PropertyFlags playerParameters;
|
||||||
Value<atUint32> beamId;
|
Value<atUint32> beamId;
|
||||||
|
|
||||||
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
|
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
|
||||||
|
|
|
@ -5,26 +5,59 @@
|
||||||
#include "Parameters.hpp"
|
#include "Parameters.hpp"
|
||||||
|
|
||||||
namespace DataSpec::DNAMP1 {
|
namespace DataSpec::DNAMP1 {
|
||||||
|
|
||||||
struct SpindleCamera : IScriptObject {
|
struct SpindleCamera : IScriptObject {
|
||||||
AT_DECL_DNA_YAML
|
AT_DECL_DNA_YAML
|
||||||
AT_DECL_DNAV
|
AT_DECL_DNAV
|
||||||
String<-1> name;
|
String<-1> name;
|
||||||
Value<atVec3f> location;
|
Value<atVec3f> location;
|
||||||
Value<atVec3f> orientation;
|
Value<atVec3f> orientation;
|
||||||
Value<bool> unknown1;
|
Value<bool> active;
|
||||||
PlayerParameters playerParameters;
|
/*
|
||||||
Value<float> unknown2;
|
* 0x1: Look toward hint
|
||||||
Value<float> unknown3;
|
* 0x2: Flat look delta
|
||||||
Value<float> unknown4;
|
* 0x8: force minimum-clamp ball-to-cam azimuth
|
||||||
Value<float> unknown5;
|
* 0x10: minimum-clamp ball-to-cam azimuth
|
||||||
|
* 0x20: Enable clampedAzimuthFromHintDir
|
||||||
|
* 0x40: Enable distOffsetFromBallDist
|
||||||
|
* 0x80: Use ball pos for cam pos Z (vs. hint pos)
|
||||||
|
* 0x100: Enable deltaAngleScaleWithCamDist
|
||||||
|
* 0x200: Use ball pos for look pos Z (vs. hint pos)
|
||||||
|
* 0x400: unused
|
||||||
|
* 0x800: Variable hint-to-ball direction
|
||||||
|
* 0x1000: Damp look azimuth with hint ball-to-cam azimuth < 10-degrees
|
||||||
|
* 0x2000: Enable deleteHintBallDist
|
||||||
|
* 0x4000: Ignore ball-to-cam azimuth sign
|
||||||
|
*/
|
||||||
|
PropertyFlags flags;
|
||||||
|
Value<float> hintToCamDistMin;
|
||||||
|
Value<float> hintToCamDistMax;
|
||||||
|
Value<float> hintToCamVOffMin;
|
||||||
|
Value<float> hintToCamVOffMax;
|
||||||
struct SpindleCameraParameters : BigDNA {
|
struct SpindleCameraParameters : BigDNA {
|
||||||
AT_DECL_DNA
|
AT_DECL_DNA_YAML
|
||||||
Value<atUint32> unknown1;
|
Value<atUint32> input;
|
||||||
PlayerParameters playerParameters;
|
PropertyFlags flags; // high reflect, low reflect
|
||||||
Value<float> unknown5;
|
Value<float> lowOut;
|
||||||
Value<float> unknown6;
|
Value<float> highOut;
|
||||||
Value<float> unknown7;
|
Value<float> lowIn;
|
||||||
Value<float> unknown8;
|
Value<float> highIn;
|
||||||
} spindleCameraParameters[15];
|
|
||||||
};
|
};
|
||||||
|
SpindleCameraParameters targetHintToCamDeltaAngleVel;
|
||||||
|
SpindleCameraParameters deltaAngleScaleWithCamDist;
|
||||||
|
SpindleCameraParameters hintToCamDist;
|
||||||
|
SpindleCameraParameters distOffsetFromBallDist;
|
||||||
|
SpindleCameraParameters hintBallToCamAzimuth;
|
||||||
|
SpindleCameraParameters unused;
|
||||||
|
SpindleCameraParameters maxHintBallToCamAzimuth;
|
||||||
|
SpindleCameraParameters camLookRelAzimuth;
|
||||||
|
SpindleCameraParameters lookPosZOffset;
|
||||||
|
SpindleCameraParameters camPosZOffset;
|
||||||
|
SpindleCameraParameters clampedAzimuthFromHintDir;
|
||||||
|
SpindleCameraParameters dampingAzimuthSpeed;
|
||||||
|
SpindleCameraParameters targetHintToCamDeltaAngleVelRange;
|
||||||
|
SpindleCameraParameters deleteHintBallDist;
|
||||||
|
SpindleCameraParameters recoverClampedAzimuthFromHintDir;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace DataSpec::DNAMP1
|
} // namespace DataSpec::DNAMP1
|
||||||
|
|
|
@ -35,7 +35,7 @@ void CRelayTracker::RemoveRelay(TEditorId id) {
|
||||||
x0_relayStates.erase(std::remove(x0_relayStates.begin(), x0_relayStates.end(), id), x0_relayStates.end());
|
x0_relayStates.erase(std::remove(x0_relayStates.begin(), x0_relayStates.end(), id), x0_relayStates.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRelayTracker::SendMsgs(const TAreaId& areaId, CStateManager& stateMgr) {
|
void CRelayTracker::SendMsgs(TAreaId areaId, CStateManager& stateMgr) {
|
||||||
const CWorld* world = stateMgr.WorldNC();
|
const CWorld* world = stateMgr.WorldNC();
|
||||||
u32 relayCount = world->GetRelayCount();
|
u32 relayCount = world->GetRelayCount();
|
||||||
|
|
||||||
|
@ -73,8 +73,11 @@ void CRelayTracker::PutTo(CBitStreamWriter& out, const CSaveWorld& saveworld) {
|
||||||
u32 relayCount = saveworld.GetRelayCount();
|
u32 relayCount = saveworld.GetRelayCount();
|
||||||
std::vector<bool> relays(relayCount);
|
std::vector<bool> relays(relayCount);
|
||||||
|
|
||||||
for (const TEditorId& id : x0_relayStates)
|
for (const TEditorId& id : x0_relayStates) {
|
||||||
relays[saveworld.GetRelayIndex(id)] = true;
|
s32 idx = saveworld.GetRelayIndex(id);
|
||||||
|
if (idx >= 0)
|
||||||
|
relays[idx] = true;
|
||||||
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < relayCount; ++i)
|
for (u32 i = 0; i < relayCount; ++i)
|
||||||
out.WriteEncoded(u32(relays[i]), 1);
|
out.WriteEncoded(u32(relays[i]), 1);
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
bool HasRelay(TEditorId);
|
bool HasRelay(TEditorId);
|
||||||
void AddRelay(TEditorId);
|
void AddRelay(TEditorId);
|
||||||
void RemoveRelay(TEditorId);
|
void RemoveRelay(TEditorId);
|
||||||
void SendMsgs(const TAreaId&, CStateManager&);
|
void SendMsgs(TAreaId, CStateManager&);
|
||||||
void PutTo(CBitStreamWriter&, const CSaveWorld&);
|
void PutTo(CBitStreamWriter&, const CSaveWorld&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -259,6 +259,7 @@ public:
|
||||||
void ResetPosition(CStateManager& mgr);
|
void ResetPosition(CStateManager& mgr);
|
||||||
void DoorClosed(TUniqueId doorId);
|
void DoorClosed(TUniqueId doorId);
|
||||||
void DoorClosing(TUniqueId doorId);
|
void DoorClosing(TUniqueId doorId);
|
||||||
|
const zeus::CVector3f& GetLookPosAhead() const { return x1c0_lookPosAhead; }
|
||||||
const zeus::CVector3f& GetFixedLookPos() const { return x1cc_fixedLookPos; }
|
const zeus::CVector3f& GetFixedLookPos() const { return x1cc_fixedLookPos; }
|
||||||
|
|
||||||
static bool IsBallNearDoor(const zeus::CVector3f& pos, CStateManager& mgr);
|
static bool IsBallNearDoor(const zeus::CVector3f& pos, CStateManager& mgr);
|
||||||
|
|
|
@ -322,7 +322,7 @@ bool CCollidableOBBTree::AABoxCollideWithLeafMoving(const COBBTree::CLeafData& l
|
||||||
|
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
u16 vertIdx = vertIndices[k];
|
u16 vertIdx = vertIndices[k];
|
||||||
const zeus::CVector3f& vtx = x10_tree->GetVert(vertIdx);
|
const zeus::CVector3f& vtx = surf.GetVert(k);
|
||||||
if (CMetroidAreaCollider::g_DupPrimitiveCheckCount != CMetroidAreaCollider::g_DupVertexList[vertIdx]) {
|
if (CMetroidAreaCollider::g_DupPrimitiveCheckCount != CMetroidAreaCollider::g_DupVertexList[vertIdx]) {
|
||||||
CMetroidAreaCollider::g_DupVertexList[vertIdx] = CMetroidAreaCollider::g_DupPrimitiveCheckCount;
|
CMetroidAreaCollider::g_DupVertexList[vertIdx] = CMetroidAreaCollider::g_DupPrimitiveCheckCount;
|
||||||
if (movedAABB.pointInside(vtx)) {
|
if (movedAABB.pointInside(vtx)) {
|
||||||
|
@ -346,7 +346,6 @@ bool CCollidableOBBTree::AABoxCollideWithLeafMoving(const COBBTree::CLeafData& l
|
||||||
CMaterialList edgeMat(x10_tree->GetEdgeMaterial(edgeIdx));
|
CMaterialList edgeMat(x10_tree->GetEdgeMaterial(edgeIdx));
|
||||||
if (!edgeMat.HasMaterial(EMaterialTypes::NoEdgeCollision)) {
|
if (!edgeMat.HasMaterial(EMaterialTypes::NoEdgeCollision)) {
|
||||||
d = dOut;
|
d = dOut;
|
||||||
const CCollisionEdge& edge = x10_tree->GetEdge(edgeIdx);
|
|
||||||
if (CMetroidAreaCollider::MovingAABoxCollisionCheck_Edge(surf.GetVert(k), surf.GetVert((k + 1) % 3),
|
if (CMetroidAreaCollider::MovingAABoxCollisionCheck_Edge(surf.GetVert(k), surf.GetVert((k + 1) % 3),
|
||||||
components.x0_edges, dir, d, normal, point) &&
|
components.x0_edges, dir, d, normal, point) &&
|
||||||
d < dOut) {
|
d < dOut) {
|
||||||
|
|
|
@ -24,13 +24,17 @@ CIOWin::EMessageReturn CStateSetterFlow::OnMessage(const CArchitectureMessage& m
|
||||||
m->ResetGameState();
|
m->ResetGameState();
|
||||||
|
|
||||||
g_GameState->SetCurrentWorldId(worldId);
|
g_GameState->SetCurrentWorldId(worldId);
|
||||||
CWorldLayerState& layers = *g_GameState->StateForWorld(worldId).GetLayerState();
|
CWorldState& ws = g_GameState->StateForWorld(worldId);
|
||||||
|
CWorldLayerState& layers = *ws.GetLayerState();
|
||||||
if (m->m_warpAreaId < layers.GetAreaCount()) {
|
if (m->m_warpAreaId < layers.GetAreaCount()) {
|
||||||
g_GameState->StateForWorld(worldId).SetAreaId(m->m_warpAreaId);
|
ws.SetAreaId(m->m_warpAreaId);
|
||||||
if (m->m_warpLayerBits) {
|
if (m->m_warpLayerBits) {
|
||||||
for (u32 i = 0; i < layers.GetAreaLayerCount(m->m_warpAreaId); ++i)
|
for (u32 i = 0; i < layers.GetAreaLayerCount(m->m_warpAreaId); ++i)
|
||||||
layers.SetLayerActive(m->m_warpAreaId, i, ((m->m_warpLayerBits >> i) & 1) != 0);
|
layers.SetLayerActive(m->m_warpAreaId, i, ((m->m_warpLayerBits >> i) & 1) != 0);
|
||||||
}
|
}
|
||||||
|
CRelayTracker& relays = *ws.RelayTracker();
|
||||||
|
for (const auto& r : m->m_warpMemoryRelays)
|
||||||
|
relays.AddRelay(r);
|
||||||
}
|
}
|
||||||
g_GameState->GameOptions().ResetToDefaults();
|
g_GameState->GameOptions().ResetToDefaults();
|
||||||
g_GameState->WriteBackupBuf();
|
g_GameState->WriteBackupBuf();
|
||||||
|
|
|
@ -474,7 +474,7 @@ void CMain::Teleport(hecl::Console*, const std::vector<std::string>& args) {
|
||||||
zeus::CTransform xf = g_StateManager->Player()->GetTransform();
|
zeus::CTransform xf = g_StateManager->Player()->GetTransform();
|
||||||
xf.origin = loc;
|
xf.origin = loc;
|
||||||
|
|
||||||
if (args.size() == 6) {
|
if (args.size() >= 6) {
|
||||||
zeus::CVector3f angle;
|
zeus::CVector3f angle;
|
||||||
for (u32 i = 0; i < 3; ++i)
|
for (u32 i = 0; i < 3; ++i)
|
||||||
angle[i] = zeus::degToRad(strtof(args[i + 3].c_str(), nullptr));
|
angle[i] = zeus::degToRad(strtof(args[i + 3].c_str(), nullptr));
|
||||||
|
@ -676,10 +676,10 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarMana
|
||||||
const hecl::SystemChar* areaIdxStr = (*(it + 2)).c_str();
|
const hecl::SystemChar* areaIdxStr = (*(it + 2)).c_str();
|
||||||
|
|
||||||
hecl::SystemChar* endptr;
|
hecl::SystemChar* endptr;
|
||||||
m_warpWorldIdx = hecl::StrToUl(worldIdxStr, &endptr, 0);
|
m_warpWorldIdx = TAreaId(hecl::StrToUl(worldIdxStr, &endptr, 0));
|
||||||
if (endptr == worldIdxStr)
|
if (endptr == worldIdxStr)
|
||||||
m_warpWorldIdx = 0;
|
m_warpWorldIdx = 0;
|
||||||
m_warpAreaId = hecl::StrToUl(areaIdxStr, &endptr, 0);
|
m_warpAreaId = TAreaId(hecl::StrToUl(areaIdxStr, &endptr, 0));
|
||||||
if (endptr == areaIdxStr)
|
if (endptr == areaIdxStr)
|
||||||
m_warpAreaId = 0;
|
m_warpAreaId = 0;
|
||||||
|
|
||||||
|
@ -696,15 +696,21 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarMana
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.end() - it >= 4) {
|
while (args.end() - it >= 4) {
|
||||||
const hecl::SystemChar* layerStr = (*(it + 3)).c_str();
|
const hecl::SystemChar* layerStr = (*(it + 3)).c_str();
|
||||||
if (layerStr[0] == _SYS_STR('0') || layerStr[0] == _SYS_STR('1'))
|
if (!(layerStr[0] == _SYS_STR('0') && layerStr[1] == _SYS_STR('x')) &&
|
||||||
|
(layerStr[0] == _SYS_STR('0') || layerStr[0] == _SYS_STR('1'))) {
|
||||||
for (const auto* cur = layerStr; *cur != _SYS_STR('\0'); ++cur)
|
for (const auto* cur = layerStr; *cur != _SYS_STR('\0'); ++cur)
|
||||||
if (*cur == _SYS_STR('1'))
|
if (*cur == _SYS_STR('1'))
|
||||||
m_warpLayerBits |= u64(1) << (cur - layerStr);
|
m_warpLayerBits |= u64(1) << (cur - layerStr);
|
||||||
|
} else if (layerStr[0] == _SYS_STR('0') && layerStr[1] == _SYS_STR('x')) {
|
||||||
|
m_warpMemoryRelays.push_back(TAreaId(hecl::StrToUl(layerStr + 2, nullptr, 16)));
|
||||||
|
}
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFlowState(EFlowState::StateSetter);
|
SetFlowState(EFlowState::StateSetter);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,7 +718,7 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarMana
|
||||||
x164_archSupport.reset(new CGameArchitectureSupport(*this, voiceEngine, backend));
|
x164_archSupport.reset(new CGameArchitectureSupport(*this, voiceEngine, backend));
|
||||||
g_archSupport = x164_archSupport.get();
|
g_archSupport = x164_archSupport.get();
|
||||||
x164_archSupport->PreloadAudio();
|
x164_archSupport->PreloadAudio();
|
||||||
std::srand(std::time(nullptr));
|
std::srand(static_cast<unsigned int>(std::time(nullptr)));
|
||||||
// g_TweakManager->ReadFromMemoryCard("AudioTweaks");
|
// g_TweakManager->ReadFromMemoryCard("AudioTweaks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -313,6 +313,7 @@ public:
|
||||||
int m_warpWorldIdx = -1;
|
int m_warpWorldIdx = -1;
|
||||||
TAreaId m_warpAreaId = 0;
|
TAreaId m_warpAreaId = 0;
|
||||||
u64 m_warpLayerBits = 0;
|
u64 m_warpLayerBits = 0;
|
||||||
|
std::vector<TEditorId> m_warpMemoryRelays;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MP1
|
} // namespace MP1
|
||||||
|
|
|
@ -101,5 +101,6 @@ public:
|
||||||
s32 GetPriority() const { return xe8_priority; }
|
s32 GetPriority() const { return xe8_priority; }
|
||||||
const CCameraHint& GetHint() const { return xec_hint; }
|
const CCameraHint& GetHint() const { return xec_hint; }
|
||||||
TUniqueId GetDelegatedCamera() const { return x164_delegatedCamera; }
|
TUniqueId GetDelegatedCamera() const { return x164_delegatedCamera; }
|
||||||
|
const zeus::CTransform& GetOriginalTransform() const { return x168_origXf; }
|
||||||
};
|
};
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -13,6 +13,8 @@ CScriptSpawnPoint::CScriptSpawnPoint(TUniqueId uid, std::string_view name, const
|
||||||
bool defaultSpawn, bool active, bool morphed)
|
bool defaultSpawn, bool active, bool morphed)
|
||||||
: CEntity(uid, info, active, name), x34_xf(xf), x64_itemCounts(itemCounts) {
|
: CEntity(uid, info, active, name), x34_xf(xf), x64_itemCounts(itemCounts) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
x64_itemCounts[int(CPlayerState::EItemType::MorphBall)] = 1;
|
||||||
|
x64_itemCounts[int(CPlayerState::EItemType::MorphBallBombs)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::GravitySuit)] = 1;
|
x64_itemCounts[int(CPlayerState::EItemType::GravitySuit)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::ThermalVisor)] = 1;
|
x64_itemCounts[int(CPlayerState::EItemType::ThermalVisor)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::XRayVisor)] = 1;
|
x64_itemCounts[int(CPlayerState::EItemType::XRayVisor)] = 1;
|
||||||
|
|
|
@ -3,65 +3,340 @@
|
||||||
#include "CStateManager.hpp"
|
#include "CStateManager.hpp"
|
||||||
#include "ScriptLoader.hpp"
|
#include "ScriptLoader.hpp"
|
||||||
#include "Camera/CBallCamera.hpp"
|
#include "Camera/CBallCamera.hpp"
|
||||||
|
#include "World/CPlayer.hpp"
|
||||||
|
#include "World/CScriptCameraHint.hpp"
|
||||||
#include "TCastTo.hpp"
|
#include "TCastTo.hpp"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
SSpindleProperty::SSpindleProperty(CInputStream& in)
|
SSpindleProperty::SSpindleProperty(CInputStream& in) {
|
||||||
: x0_(in.readUint32Big())
|
x4_input = ESpindleInput(in.readUint32Big());
|
||||||
, x4_paramFlags(ScriptLoader::LoadParameterFlags(in))
|
x0_flags = ScriptLoader::LoadParameterFlags(in);
|
||||||
, x8_(in.readFloatBig())
|
x8_lowOut = in.readFloatBig();
|
||||||
, xc_(in.readFloatBig())
|
xc_highOut = in.readFloatBig();
|
||||||
, x10_(in.readFloatBig())
|
x10_lowIn = in.readFloatBig();
|
||||||
, x14_(in.readFloatBig()) {}
|
x14_highIn = in.readFloatBig();
|
||||||
|
switch (x4_input) {
|
||||||
|
case ESpindleInput::HintBallAngle:
|
||||||
|
case ESpindleInput::HintBallRightAngle:
|
||||||
|
case ESpindleInput::HintBallLeftAngle:
|
||||||
|
x10_lowIn = zeus::degToRad(x10_lowIn);
|
||||||
|
x14_highIn = zeus::degToRad(x14_highIn);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CScriptSpindleCamera::CScriptSpindleCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
CScriptSpindleCamera::CScriptSpindleCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
||||||
const zeus::CTransform& xf, bool active, u32 r9, float f1, float f2,
|
const zeus::CTransform& xf, bool active, u32 flags, float hintToCamDistMin,
|
||||||
float f3, float f4, const SSpindleProperty& seg1,
|
float hintToCamDistMax, float hintToCamVOffMin, float hintToCamVOffMax,
|
||||||
const SSpindleProperty& seg2, const SSpindleProperty& seg3,
|
const SSpindleProperty& targetHintToCamDeltaAngleVel,
|
||||||
const SSpindleProperty& seg4, const SSpindleProperty& seg5,
|
const SSpindleProperty& deltaAngleScaleWithCamDist,
|
||||||
const SSpindleProperty& seg6, const SSpindleProperty& seg7,
|
const SSpindleProperty& hintToCamDist,
|
||||||
const SSpindleProperty& seg8, const SSpindleProperty& seg9,
|
const SSpindleProperty& distOffsetFromBallDist,
|
||||||
const SSpindleProperty& seg10, const SSpindleProperty& seg11,
|
const SSpindleProperty& hintBallToCamAzimuth,
|
||||||
const SSpindleProperty& seg12, const SSpindleProperty& seg13,
|
const SSpindleProperty& unused,
|
||||||
const SSpindleProperty& seg14, const SSpindleProperty& seg15)
|
const SSpindleProperty& maxHintBallToCamAzimuth,
|
||||||
|
const SSpindleProperty& camLookRelAzimuth,
|
||||||
|
const SSpindleProperty& lookPosZOffset,
|
||||||
|
const SSpindleProperty& camPosZOffset,
|
||||||
|
const SSpindleProperty& clampedAzimuthFromHintDir,
|
||||||
|
const SSpindleProperty& dampingAzimuthSpeed,
|
||||||
|
const SSpindleProperty& targetHintToCamDeltaAngleVelRange,
|
||||||
|
const SSpindleProperty& deleteHintBallDist,
|
||||||
|
const SSpindleProperty& recoverClampedAzimuthFromHintDir)
|
||||||
: CGameCamera(uid, active, name, info, xf, CCameraManager::ThirdPersonFOV(), CCameraManager::NearPlane(),
|
: CGameCamera(uid, active, name, info, xf, CCameraManager::ThirdPersonFOV(), CCameraManager::NearPlane(),
|
||||||
CCameraManager::FarPlane(), CCameraManager::Aspect(), kInvalidUniqueId, false, 0)
|
CCameraManager::FarPlane(), CCameraManager::Aspect(), kInvalidUniqueId, false, 0)
|
||||||
, x188_r9(r9)
|
, x188_flags(flags)
|
||||||
, x1b0_f1(f1)
|
, x1b0_hintToCamDistMin(hintToCamDistMin)
|
||||||
, x1b4_f2(f2)
|
, x1b4_hintToCamDistMax(hintToCamDistMax)
|
||||||
, x1b8_f3(f2)
|
, x1b8_hintToCamVOffMin(hintToCamVOffMin)
|
||||||
, x1bc_f4(f4)
|
, x1bc_hintToCamVOffMax(hintToCamVOffMax)
|
||||||
, x1c0_seg1(seg1)
|
, x1c0_targetHintToCamDeltaAngleVel(targetHintToCamDeltaAngleVel)
|
||||||
, x1d8_seg2(seg2)
|
, x1d8_deltaAngleScaleWithCamDist(deltaAngleScaleWithCamDist)
|
||||||
, x1f0_seg3(seg3)
|
, x1f0_hintToCamDist(hintToCamDist)
|
||||||
, x208_seg4(seg4)
|
, x208_distOffsetFromBallDist(distOffsetFromBallDist)
|
||||||
, x220_seg5(seg5)
|
, x220_hintBallToCamAzimuth(hintBallToCamAzimuth)
|
||||||
, x238_seg6(seg6)
|
, x238_unused(unused)
|
||||||
, x250_seg7(seg7)
|
, x250_maxHintBallToCamAzimuth(maxHintBallToCamAzimuth)
|
||||||
, x268_seg8(seg8)
|
, x268_camLookRelAzimuth(camLookRelAzimuth)
|
||||||
, x280_seg9(seg9)
|
, x280_lookPosZOffset(lookPosZOffset)
|
||||||
, x298_seg10(seg10)
|
, x298_camPosZOffset(camPosZOffset)
|
||||||
, x2b0_seg11(seg11)
|
, x2b0_clampedAzimuthFromHintDir(clampedAzimuthFromHintDir)
|
||||||
, x2c8_seg12(seg12)
|
, x2c8_dampingAzimuthSpeed(dampingAzimuthSpeed)
|
||||||
, x2e0_seg13(seg13)
|
, x2e0_targetHintToCamDeltaAngleVelRange(targetHintToCamDeltaAngleVelRange)
|
||||||
, x2f8_seg14(seg14)
|
, x2f8_deleteHintBallDist(deleteHintBallDist)
|
||||||
, x310_seg15(seg15)
|
, x310_recoverClampedAzimuthFromHintDir(recoverClampedAzimuthFromHintDir)
|
||||||
, x330_lookDir(xf.basis[1]) {}
|
, x330_lookDir(xf.basis[1]) {}
|
||||||
|
|
||||||
void CScriptSpindleCamera::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
void CScriptSpindleCamera::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||||
|
|
||||||
void CScriptSpindleCamera::ProcessInput(const CFinalInput& input, CStateManager& mgr) {}
|
void CScriptSpindleCamera::ProcessInput(const CFinalInput& input, CStateManager& mgr) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
void CScriptSpindleCamera::Reset(const zeus::CTransform& xf, CStateManager& mgr) {
|
void CScriptSpindleCamera::Reset(const zeus::CTransform& xf, CStateManager& mgr) {
|
||||||
const CScriptCameraHint* hint = mgr.GetCameraManager()->GetCameraHint(mgr);
|
const CScriptCameraHint* hint = mgr.GetCameraManager()->GetCameraHint(mgr);
|
||||||
if (!GetActive() || hint == nullptr)
|
if (!GetActive() || hint == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
x33c_24_ = true;
|
x33c_24_inResetThink = true;
|
||||||
mgr.GetCameraManager()->GetBallCamera()->UpdateLookAtPosition(0.01f, mgr);
|
mgr.GetCameraManager()->GetBallCamera()->UpdateLookAtPosition(0.01f, mgr);
|
||||||
|
Think(0.01f, mgr);
|
||||||
|
x33c_24_inResetThink = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptSpindleCamera::Think(float, CStateManager&) {}
|
void CScriptSpindleCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) {
|
||||||
|
CGameCamera::AcceptScriptMsg(msg, sender, mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
float SSpindleProperty::GetValue(float inVar) const {
|
||||||
|
if (x4_input == ESpindleInput::Constant)
|
||||||
|
return x8_lowOut;
|
||||||
|
|
||||||
|
float reflectRange = x14_highIn - x10_lowIn;
|
||||||
|
if (zeus::close_enough(reflectRange, 0.f))
|
||||||
|
return x8_lowOut;
|
||||||
|
|
||||||
|
float reflectedVar = inVar;
|
||||||
|
if (x0_flags & 0x1 && inVar > x14_highIn)
|
||||||
|
reflectedVar = x14_highIn - (inVar - x14_highIn);
|
||||||
|
if (x0_flags & 0x2 && inVar < x10_lowIn)
|
||||||
|
reflectedVar = x10_lowIn + (x10_lowIn - inVar);
|
||||||
|
|
||||||
|
float outRange = xc_highOut - x8_lowOut;
|
||||||
|
float res = (reflectedVar - x10_lowIn) * outRange / reflectRange + x8_lowOut;
|
||||||
|
if (x8_lowOut < xc_highOut)
|
||||||
|
return zeus::clamp(x8_lowOut, res, xc_highOut);
|
||||||
|
else
|
||||||
|
return zeus::clamp(xc_highOut, res, x8_lowOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptSpindleCamera::Think(float dt, CStateManager& mgr) {
|
||||||
|
const CScriptCameraHint* hint = mgr.GetCameraManager()->GetCameraHint(mgr);
|
||||||
|
if (!GetActive() || hint == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
zeus::CVector3f hintPos = hint->GetTranslation();
|
||||||
|
zeus::CVector2f lookAheadPos = mgr.GetCameraManager()->GetBallCamera()->GetLookPosAhead().toVec2f();
|
||||||
|
zeus::CVector3f hintToCamDir = GetTranslation() - hintPos;
|
||||||
|
hintToCamDir.z() = 0.f;
|
||||||
|
zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition();
|
||||||
|
zeus::CVector3f hintToBallDir = ballPos - hintPos;
|
||||||
|
float hintToBallVOff = hintToBallDir.z();
|
||||||
|
hintToBallDir.z() = 0.f;
|
||||||
|
zeus::CVector3f hintDir = hint->GetTransform().basis[1];
|
||||||
|
hintDir.z() = 0.f;
|
||||||
|
if (hintDir.canBeNormalized())
|
||||||
|
hintDir.normalize();
|
||||||
|
else
|
||||||
|
hintDir = zeus::CVector3f::skForward;
|
||||||
|
float hintToBallDist = 0.f;
|
||||||
|
if (hintToBallDir.canBeNormalized()) {
|
||||||
|
hintToBallDist = hintToBallDir.magnitude();
|
||||||
|
hintToBallDir.normalize();
|
||||||
|
} else {
|
||||||
|
hintToBallDir = hintDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
x18c_inVars.clear();
|
||||||
|
x18c_inVars.push_back(0.f); // Zero
|
||||||
|
x18c_inVars.push_back(hintToBallDist); // HintToBallDist
|
||||||
|
x18c_inVars.push_back(std::fabs(hintToBallVOff)); // HintToBallVOff
|
||||||
|
float hintBallAngle = std::fabs(std::acos(zeus::clamp(-1.f, hintToBallDir.dot(hintDir), 1.f)));
|
||||||
|
x18c_inVars.push_back(hintBallAngle); // HintBallAngle
|
||||||
|
float hintBallCross = hintToBallDir.toVec2f().cross(hintDir.toVec2f());
|
||||||
|
if (hintBallCross >= 0.f) {
|
||||||
|
x18c_inVars.push_back(hintBallAngle); // HintBallRightAngle
|
||||||
|
x18c_inVars.push_back(2.f * M_PIF - hintBallAngle); // HintBallLeftAngle
|
||||||
|
} else {
|
||||||
|
x18c_inVars.push_back(2.f * M_PIF - hintBallAngle); // HintBallRightAngle
|
||||||
|
x18c_inVars.push_back(hintBallAngle); // HintBallLeftAngle
|
||||||
|
}
|
||||||
|
zeus::CVector3f hintDelta = hint->GetTranslation() - hint->GetOriginalTransform().origin;
|
||||||
|
float hintDeltaVOff = std::fabs(hintDelta.z());
|
||||||
|
hintDelta.z() = 0.f;
|
||||||
|
x18c_inVars.push_back(hintDelta.canBeNormalized() ? hintDelta.magnitude() : 0.f); // HintDeltaDist
|
||||||
|
x18c_inVars.push_back(hintDeltaVOff); // HintDeltaVOff
|
||||||
|
|
||||||
|
if ((x188_flags & 0x2000) && hintToBallDist >
|
||||||
|
x2f8_deleteHintBallDist.GetValue(GetInVar(x2f8_deleteHintBallDist))) {
|
||||||
|
|
||||||
|
if (hint->GetDelegatedCamera() == GetUniqueId())
|
||||||
|
mgr.GetCameraManager()->DeleteCameraHint(hint->GetUniqueId(), mgr);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (!(x188_flags & 0x800))
|
||||||
|
hintToBallDir = hintDir;
|
||||||
|
if (x188_flags & 0x20) {
|
||||||
|
if (!x32c_outsideClampedAzimuth) {
|
||||||
|
if (hintBallAngle > x2b0_clampedAzimuthFromHintDir.GetValue(GetInVar(x2b0_clampedAzimuthFromHintDir))) {
|
||||||
|
x330_lookDir = hintToBallDir;
|
||||||
|
x32c_outsideClampedAzimuth = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
float hintCamCross = hintToCamDir.toVec2f().cross(hintDir.toVec2f());
|
||||||
|
if ((hintBallAngle < x310_recoverClampedAzimuthFromHintDir.
|
||||||
|
GetValue(GetInVar(x310_recoverClampedAzimuthFromHintDir)) && hintBallCross * hintCamCross < 0.f) ||
|
||||||
|
hintBallAngle <= x2b0_clampedAzimuthFromHintDir.GetValue(GetInVar(x2b0_clampedAzimuthFromHintDir))) {
|
||||||
|
x32c_outsideClampedAzimuth = false;
|
||||||
|
} else {
|
||||||
|
hintToBallDir = x330_lookDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float newHintToCamDist = x1f0_hintToCamDist.GetValue(GetInVar(x1f0_hintToCamDist));
|
||||||
|
if (x188_flags & 0x40)
|
||||||
|
newHintToCamDist = hintToBallDist +
|
||||||
|
x208_distOffsetFromBallDist.GetValue(GetInVar(x208_distOffsetFromBallDist));
|
||||||
|
newHintToCamDist = zeus::clamp(x1b0_hintToCamDistMin, newHintToCamDist, x1b4_hintToCamDistMax);
|
||||||
|
zeus::CVector3f newCamPos = GetTranslation();
|
||||||
|
float hintToCamDist = hintToCamDir.magnitude();
|
||||||
|
if (hintToCamDir.canBeNormalized()) {
|
||||||
|
hintToCamDir.normalize();
|
||||||
|
} else {
|
||||||
|
hintToCamDir = hintDir;
|
||||||
|
hintToCamDist = x1f0_hintToCamDist.GetValue(GetInVar(x1f0_hintToCamDist));
|
||||||
|
}
|
||||||
|
|
||||||
|
float hintBallToCamTargetAzimuth =
|
||||||
|
x220_hintBallToCamAzimuth.GetValue(GetInVar(x220_hintBallToCamAzimuth));
|
||||||
|
if (!(x188_flags & 0x4000) && hintToCamDir.cross(hintToBallDir).z() >= 0.f)
|
||||||
|
hintBallToCamTargetAzimuth = -hintBallToCamTargetAzimuth;
|
||||||
|
zeus::CQuaternion hintBallToCamTargetAzimuthQuat;
|
||||||
|
hintBallToCamTargetAzimuthQuat.rotateZ(hintBallToCamTargetAzimuth);
|
||||||
|
zeus::CVector3f targetHintToCam = hintBallToCamTargetAzimuthQuat.transform(hintToBallDir);
|
||||||
|
zeus::CVector3f newHintToCamDir = hintToCamDir;
|
||||||
|
float hintToCamDeltaAngleRange = std::fabs(std::acos(zeus::clamp(-1.f, hintToCamDir.dot(targetHintToCam), 1.f)));
|
||||||
|
float hintToCamDeltaAngleSpeedFactor =
|
||||||
|
zeus::clamp(-1.f, hintToCamDeltaAngleRange /
|
||||||
|
x2c8_dampingAzimuthSpeed.GetValue(GetInVar(x2c8_dampingAzimuthSpeed)), 1.f);
|
||||||
|
float targetHintToCamDeltaAngleVel =
|
||||||
|
x1c0_targetHintToCamDeltaAngleVel.GetValue(GetInVar(x1c0_targetHintToCamDeltaAngleVel));
|
||||||
|
if (x188_flags & 0x100)
|
||||||
|
targetHintToCamDeltaAngleVel = zeus::clamp(-targetHintToCamDeltaAngleVel,
|
||||||
|
x1d8_deltaAngleScaleWithCamDist.GetValue(GetInVar(x1d8_deltaAngleScaleWithCamDist)) / hintToCamDist,
|
||||||
|
targetHintToCamDeltaAngleVel);
|
||||||
|
if ((hintToBallDir.cross(hintToCamDir).z() >= 0.f && targetHintToCam.cross(hintToCamDir).z() < 0.f) ||
|
||||||
|
(hintToBallDir.cross(hintToCamDir).z() < 0.f && targetHintToCam.cross(hintToCamDir).z() >= 0.f)) {
|
||||||
|
float targetHintToCamDeltaAngleVelRange =
|
||||||
|
x2e0_targetHintToCamDeltaAngleVelRange.GetValue(GetInVar(x2e0_targetHintToCamDeltaAngleVelRange));
|
||||||
|
targetHintToCamDeltaAngleVel = zeus::clamp(-targetHintToCamDeltaAngleVelRange,
|
||||||
|
targetHintToCamDeltaAngleVel, targetHintToCamDeltaAngleVelRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f camToBall = ballPos - GetTranslation();
|
||||||
|
camToBall.z() = 0.f;
|
||||||
|
float targetHintToCamDeltaAngle = targetHintToCamDeltaAngleVel * dt * hintToCamDeltaAngleSpeedFactor;
|
||||||
|
float camToBallDist = 0.f;
|
||||||
|
if (camToBall.canBeNormalized())
|
||||||
|
camToBallDist = camToBall.magnitude();
|
||||||
|
targetHintToCamDeltaAngle *= (1.f - zeus::clamp(0.f, (camToBallDist - 2.f) * 0.5f, 1.f)) * 10.f + 1.f;
|
||||||
|
targetHintToCamDeltaAngle = zeus::clamp(-hintToCamDeltaAngleRange,
|
||||||
|
targetHintToCamDeltaAngle, hintToCamDeltaAngleRange);
|
||||||
|
if (std::fabs(zeus::clamp(-1.f, hintToCamDir.dot(targetHintToCam), 1.f)) < 0.99999f)
|
||||||
|
newHintToCamDir = zeus::CQuaternion::lookAt(hintToCamDir, targetHintToCam,
|
||||||
|
targetHintToCamDeltaAngle).transform(hintToCamDir);
|
||||||
|
float hintBallToCamAzimuth = std::acos(zeus::clamp(-1.f, hintToBallDir.dot(newHintToCamDir), 1.f));
|
||||||
|
if (x188_flags & 0x10) {
|
||||||
|
if (std::fabs(hintBallToCamAzimuth) <
|
||||||
|
x220_hintBallToCamAzimuth.GetValue(GetInVar(x220_hintBallToCamAzimuth)) ||
|
||||||
|
(x188_flags & 0x8) || x33c_24_inResetThink)
|
||||||
|
newHintToCamDir = targetHintToCam;
|
||||||
|
}
|
||||||
|
|
||||||
|
float maxHintBallToCamAzimuth = x250_maxHintBallToCamAzimuth.GetValue(GetInVar(x250_maxHintBallToCamAzimuth));
|
||||||
|
if (std::fabs(hintBallToCamAzimuth) > maxHintBallToCamAzimuth) {
|
||||||
|
x328_maxAzimuthInterpTimer += dt;
|
||||||
|
if (x328_maxAzimuthInterpTimer < 3.f) {
|
||||||
|
float ballToCamAzimuthInterp = zeus::clamp(-1.f, x328_maxAzimuthInterpTimer / 3.f, 1.f);
|
||||||
|
float hintBallToCamAzimuthDelta = std::fabs(maxHintBallToCamAzimuth - hintBallToCamAzimuth);
|
||||||
|
if (hintToBallDir.cross(newHintToCamDir).z() > 0.f)
|
||||||
|
hintBallToCamAzimuthDelta = -hintBallToCamAzimuthDelta;
|
||||||
|
zeus::CQuaternion hintBallToCamAzimuthQuat;
|
||||||
|
hintBallToCamAzimuthQuat.rotateZ(hintBallToCamAzimuthDelta * ballToCamAzimuthInterp);
|
||||||
|
newHintToCamDir = hintBallToCamAzimuthQuat.transform(newHintToCamDir);
|
||||||
|
} else {
|
||||||
|
zeus::CQuaternion hintBallToCamAzimuthQuat;
|
||||||
|
if (hintBallToCamTargetAzimuth > 0.f)
|
||||||
|
hintBallToCamAzimuthQuat.rotateZ(maxHintBallToCamAzimuth);
|
||||||
|
else
|
||||||
|
hintBallToCamAzimuthQuat.rotateZ(-maxHintBallToCamAzimuth);
|
||||||
|
newHintToCamDir = hintBallToCamAzimuthQuat.transform(hintToBallDir);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x328_maxAzimuthInterpTimer = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x188_flags & 0x20) {
|
||||||
|
zeus::CVector3f hintDir2 = hint->GetTransform().basis[1];
|
||||||
|
hintDir2.z() = 0.f;
|
||||||
|
if (hintDir2.canBeNormalized()) {
|
||||||
|
hintDir2.normalize();
|
||||||
|
float hintCamAzimuth = std::fabs(std::acos(zeus::clamp(-1.f, hintDir2.dot(newHintToCamDir), 1.f)));
|
||||||
|
float hintCamAzimuthRange =
|
||||||
|
x2b0_clampedAzimuthFromHintDir.GetValue(GetInVar(x2b0_clampedAzimuthFromHintDir));
|
||||||
|
hintCamAzimuth = zeus::clamp(-hintCamAzimuthRange, hintCamAzimuth, hintCamAzimuthRange);
|
||||||
|
if (hintDir2.cross(newHintToCamDir).z() < 0.f)
|
||||||
|
hintCamAzimuth = -hintCamAzimuth;
|
||||||
|
zeus::CQuaternion hintCamAzimuthQuat;
|
||||||
|
hintCamAzimuthQuat.rotateZ(hintCamAzimuth);
|
||||||
|
newHintToCamDir = hintCamAzimuthQuat.transform(hintDir2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newCamPos = hintPos + newHintToCamDir * newHintToCamDist;
|
||||||
|
if (x188_flags & 0x80)
|
||||||
|
newCamPos.z() = ballPos.z() + x298_camPosZOffset.GetValue(GetInVar(x298_camPosZOffset));
|
||||||
|
else
|
||||||
|
newCamPos.z() = hintPos.z() + x298_camPosZOffset.GetValue(GetInVar(x298_camPosZOffset));
|
||||||
|
newCamPos.z() = zeus::clamp(x1b8_hintToCamVOffMin, newCamPos.z() - hintPos.z(), x1bc_hintToCamVOffMax) +
|
||||||
|
hintPos.z();
|
||||||
|
|
||||||
|
float lookPosZ;
|
||||||
|
if (x188_flags & 0x200)
|
||||||
|
lookPosZ = ballPos.z() + x280_lookPosZOffset.GetValue(GetInVar(x280_lookPosZOffset));
|
||||||
|
else
|
||||||
|
lookPosZ = hintPos.z() + x280_lookPosZOffset.GetValue(GetInVar(x280_lookPosZOffset));
|
||||||
|
|
||||||
|
zeus::CVector3f newLookDelta(lookAheadPos - newCamPos.toVec2f(), lookPosZ - newCamPos.z());
|
||||||
|
zeus::CVector3f newLookDirFlat = newLookDelta;
|
||||||
|
newLookDirFlat.z() = 0.f;
|
||||||
|
if (newLookDirFlat.canBeNormalized()) {
|
||||||
|
float newLookDistFlat = newLookDirFlat.magnitude();
|
||||||
|
newLookDirFlat.normalize();
|
||||||
|
float camLookRelAzimuth = -x268_camLookRelAzimuth.GetValue(GetInVar(x268_camLookRelAzimuth));
|
||||||
|
zeus::CVector3f newHintToCamDirFlat = newCamPos - hintPos;
|
||||||
|
newHintToCamDirFlat.z() = 0.f;
|
||||||
|
if (newHintToCamDirFlat.canBeNormalized())
|
||||||
|
newHintToCamDirFlat.normalize();
|
||||||
|
else
|
||||||
|
newHintToCamDirFlat = zeus::CVector3f::skForward;
|
||||||
|
if (newHintToCamDirFlat.cross(hintToBallDir).z() >= 0.f)
|
||||||
|
camLookRelAzimuth = -camLookRelAzimuth;
|
||||||
|
if (x188_flags & 0x1000)
|
||||||
|
camLookRelAzimuth *= zeus::clamp(-1.f, std::acos(std::fabs(
|
||||||
|
zeus::clamp(-1.f, hintToBallDir.dot(newHintToCamDirFlat), 1.f))) / zeus::degToRad(10.f), 1.f);
|
||||||
|
zeus::CQuaternion azimuthQuat;
|
||||||
|
azimuthQuat.rotateZ(camLookRelAzimuth);
|
||||||
|
lookAheadPos = azimuthQuat.transform(newLookDirFlat).toVec2f() * std::cos(camLookRelAzimuth) * newLookDistFlat +
|
||||||
|
newCamPos.toVec2f();
|
||||||
|
}
|
||||||
|
newLookDelta = zeus::CVector3f(lookAheadPos, lookPosZ) - newCamPos;
|
||||||
|
if (x188_flags & 0x1)
|
||||||
|
newLookDelta = zeus::CVector3f(hintPos.toVec2f() - newCamPos.toVec2f(), newLookDelta.z());
|
||||||
|
if (x188_flags & 0x2)
|
||||||
|
newLookDelta = lookAheadPos - hintPos.toVec2f();
|
||||||
|
if (newLookDelta.canBeNormalized())
|
||||||
|
SetTransform(zeus::lookAt(newCamPos, newCamPos + newLookDelta.normalized()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptSpindleCamera::Render(const CStateManager&) const {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -4,59 +4,102 @@
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
|
enum class ESpindleInput {
|
||||||
|
Constant,
|
||||||
|
HintToBallDist,
|
||||||
|
HintToBallVOff,
|
||||||
|
HintBallAngle,
|
||||||
|
HintBallRightAngle,
|
||||||
|
HintBallLeftAngle,
|
||||||
|
HintDeltaDist,
|
||||||
|
HintDeltaVOff
|
||||||
|
};
|
||||||
|
|
||||||
struct SSpindleProperty {
|
struct SSpindleProperty {
|
||||||
u32 x0_;
|
u32 x0_flags;
|
||||||
u32 x4_paramFlags;
|
ESpindleInput x4_input;
|
||||||
float x8_;
|
float x8_lowOut;
|
||||||
float xc_;
|
float xc_highOut;
|
||||||
float x10_;
|
float x10_lowIn;
|
||||||
float x14_;
|
float x14_highIn;
|
||||||
|
|
||||||
SSpindleProperty(CInputStream& in);
|
SSpindleProperty(CInputStream& in);
|
||||||
void FixupAngles() {
|
void FixupAngles() {
|
||||||
x8_ = zeus::degToRad(x8_);
|
x8_lowOut = zeus::degToRad(x8_lowOut);
|
||||||
xc_ = zeus::degToRad(xc_);
|
xc_highOut = zeus::degToRad(xc_highOut);
|
||||||
}
|
}
|
||||||
|
float GetValue(float inVar) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CScriptSpindleCamera : public CGameCamera {
|
class CScriptSpindleCamera : public CGameCamera {
|
||||||
u32 x188_r9;
|
/*
|
||||||
u32 x18c_ = 0;
|
* 0x1: Look toward hint
|
||||||
float x1b0_f1;
|
* 0x2: Flat look delta
|
||||||
float x1b4_f2;
|
* 0x8: force minimum-clamp ball-to-cam azimuth
|
||||||
float x1b8_f3;
|
* 0x10: minimum-clamp ball-to-cam azimuth
|
||||||
float x1bc_f4;
|
* 0x20: Enable clampedAzimuthFromHintDir
|
||||||
SSpindleProperty x1c0_seg1;
|
* 0x40: Enable distOffsetFromBallDist
|
||||||
SSpindleProperty x1d8_seg2;
|
* 0x80: Use ball pos for cam pos Z (vs. hint pos)
|
||||||
SSpindleProperty x1f0_seg3;
|
* 0x100: Enable deltaAngleScaleWithCamDist
|
||||||
SSpindleProperty x208_seg4;
|
* 0x200: Use ball pos for look pos Z (vs. hint pos)
|
||||||
SSpindleProperty x220_seg5;
|
* 0x400: unused
|
||||||
SSpindleProperty x238_seg6;
|
* 0x800: Variable hint-to-ball direction
|
||||||
SSpindleProperty x250_seg7;
|
* 0x1000: Damp look azimuth with hint ball-to-cam azimuth < 10-degrees
|
||||||
SSpindleProperty x268_seg8;
|
* 0x2000: Enable deleteHintBallDist
|
||||||
SSpindleProperty x280_seg9;
|
* 0x4000: Ignore ball-to-cam azimuth sign
|
||||||
SSpindleProperty x298_seg10;
|
*/
|
||||||
SSpindleProperty x2b0_seg11;
|
u32 x188_flags;
|
||||||
SSpindleProperty x2c8_seg12;
|
rstl::reserved_vector<float, 8> x18c_inVars;
|
||||||
SSpindleProperty x2e0_seg13;
|
float x1b0_hintToCamDistMin;
|
||||||
SSpindleProperty x2f8_seg14;
|
float x1b4_hintToCamDistMax;
|
||||||
SSpindleProperty x310_seg15;
|
float x1b8_hintToCamVOffMin;
|
||||||
float x328_ = 0.f;
|
float x1bc_hintToCamVOffMax;
|
||||||
bool x32c_24 = false;
|
SSpindleProperty x1c0_targetHintToCamDeltaAngleVel;
|
||||||
|
SSpindleProperty x1d8_deltaAngleScaleWithCamDist;
|
||||||
|
SSpindleProperty x1f0_hintToCamDist;
|
||||||
|
SSpindleProperty x208_distOffsetFromBallDist;
|
||||||
|
SSpindleProperty x220_hintBallToCamAzimuth;
|
||||||
|
SSpindleProperty x238_unused;
|
||||||
|
SSpindleProperty x250_maxHintBallToCamAzimuth;
|
||||||
|
SSpindleProperty x268_camLookRelAzimuth;
|
||||||
|
SSpindleProperty x280_lookPosZOffset;
|
||||||
|
SSpindleProperty x298_camPosZOffset;
|
||||||
|
SSpindleProperty x2b0_clampedAzimuthFromHintDir;
|
||||||
|
SSpindleProperty x2c8_dampingAzimuthSpeed;
|
||||||
|
SSpindleProperty x2e0_targetHintToCamDeltaAngleVelRange;
|
||||||
|
SSpindleProperty x2f8_deleteHintBallDist;
|
||||||
|
SSpindleProperty x310_recoverClampedAzimuthFromHintDir;
|
||||||
|
float x328_maxAzimuthInterpTimer = 0.f;
|
||||||
|
bool x32c_outsideClampedAzimuth = false;
|
||||||
zeus::CVector3f x330_lookDir;
|
zeus::CVector3f x330_lookDir;
|
||||||
bool x33c_24_;
|
bool x33c_24_inResetThink;
|
||||||
|
|
||||||
|
float GetInVar(const SSpindleProperty& seg) const { return x18c_inVars[int(seg.x4_input)]; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CScriptSpindleCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
CScriptSpindleCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
||||||
bool active, u32 r9, float f1, float f2, float f3, float f4, const SSpindleProperty& seg1,
|
const zeus::CTransform& xf, bool active, u32 flags, float hintToCamDistMin,
|
||||||
const SSpindleProperty& seg2, const SSpindleProperty& seg3, const SSpindleProperty& seg4,
|
float hintToCamDistMax, float hintToCamVOffMin, float hintToCamVOffMax,
|
||||||
const SSpindleProperty& seg5, const SSpindleProperty& seg6, const SSpindleProperty& seg7,
|
const SSpindleProperty& targetHintToCamDeltaAngleVel,
|
||||||
const SSpindleProperty& seg8, const SSpindleProperty& seg9, const SSpindleProperty& seg10,
|
const SSpindleProperty& deltaAngleScaleWithCamDist,
|
||||||
const SSpindleProperty& seg11, const SSpindleProperty& seg12, const SSpindleProperty& seg13,
|
const SSpindleProperty& hintToCamDist,
|
||||||
const SSpindleProperty& seg14, const SSpindleProperty& seg15);
|
const SSpindleProperty& distOffsetFromBallDist,
|
||||||
|
const SSpindleProperty& hintBallToCamAzimuth,
|
||||||
|
const SSpindleProperty& unused,
|
||||||
|
const SSpindleProperty& maxHintBallToCamAzimuth,
|
||||||
|
const SSpindleProperty& camLookRelAzimuth,
|
||||||
|
const SSpindleProperty& lookPosZOffset,
|
||||||
|
const SSpindleProperty& camPosZOffset,
|
||||||
|
const SSpindleProperty& clampedAzimuthFromHintDir,
|
||||||
|
const SSpindleProperty& dampingAzimuthSpeed,
|
||||||
|
const SSpindleProperty& targetHintToCamDeltaAngleVelRange,
|
||||||
|
const SSpindleProperty& deleteHintBallDist,
|
||||||
|
const SSpindleProperty& recoverClampedAzimuthFromHintDir);
|
||||||
|
|
||||||
void Accept(IVisitor& visitor);
|
void Accept(IVisitor& visitor);
|
||||||
|
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||||
void Think(float, CStateManager&);
|
void Think(float, CStateManager&);
|
||||||
|
void Render(const CStateManager&) const;
|
||||||
void Reset(const zeus::CTransform& xf, CStateManager& mgr);
|
void Reset(const zeus::CTransform& xf, CStateManager& mgr);
|
||||||
void ProcessInput(const CFinalInput& input, CStateManager& mgr);
|
void ProcessInput(const CFinalInput& input, CStateManager& mgr);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2943,39 +2943,43 @@ CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, i
|
||||||
SActorHead aHead = LoadActorHead(in, mgr);
|
SActorHead aHead = LoadActorHead(in, mgr);
|
||||||
bool active = in.readBool();
|
bool active = in.readBool();
|
||||||
u32 flags = LoadParameterFlags(in);
|
u32 flags = LoadParameterFlags(in);
|
||||||
float f1 = in.readFloatBig();
|
float hintToCamDistMin = in.readFloatBig();
|
||||||
float f2 = in.readFloatBig();
|
float hintToCamDistMax = in.readFloatBig();
|
||||||
float f3 = in.readFloatBig();
|
float hintToCamVOffMin = in.readFloatBig();
|
||||||
float f4 = in.readFloatBig();
|
float hintToCamVOffMax = in.readFloatBig();
|
||||||
|
|
||||||
SSpindleProperty seg1(in);
|
SSpindleProperty targetHintToCamDeltaAngleVel(in);
|
||||||
seg1.FixupAngles();
|
targetHintToCamDeltaAngleVel.FixupAngles();
|
||||||
SSpindleProperty seg2(in);
|
SSpindleProperty deltaAngleScaleWithCamDist(in);
|
||||||
SSpindleProperty seg3(in);
|
SSpindleProperty hintToCamDist(in);
|
||||||
SSpindleProperty seg4(in);
|
SSpindleProperty distOffsetFromBallDist(in);
|
||||||
SSpindleProperty seg5(in);
|
SSpindleProperty hintBallToCamAzimuth(in);
|
||||||
seg5.FixupAngles();
|
hintBallToCamAzimuth.FixupAngles();
|
||||||
SSpindleProperty seg6(in);
|
SSpindleProperty unused(in);
|
||||||
seg6.FixupAngles();
|
unused.FixupAngles();
|
||||||
SSpindleProperty seg7(in);
|
SSpindleProperty maxHintBallToCamAzimuth(in);
|
||||||
seg7.FixupAngles();
|
maxHintBallToCamAzimuth.FixupAngles();
|
||||||
SSpindleProperty seg8(in);
|
SSpindleProperty camLookRelAzimuth(in);
|
||||||
seg8.FixupAngles();
|
camLookRelAzimuth.FixupAngles();
|
||||||
SSpindleProperty seg9(in);
|
SSpindleProperty lookPosZOffset(in);
|
||||||
SSpindleProperty seg10(in);
|
SSpindleProperty camPosZOffset(in);
|
||||||
SSpindleProperty seg11(in);
|
SSpindleProperty clampedAzimuthFromHintDir(in);
|
||||||
seg11.FixupAngles();
|
clampedAzimuthFromHintDir.FixupAngles();
|
||||||
SSpindleProperty seg12(in);
|
SSpindleProperty dampingAzimuthSpeed(in);
|
||||||
seg12.FixupAngles();
|
dampingAzimuthSpeed.FixupAngles();
|
||||||
SSpindleProperty seg13(in);
|
SSpindleProperty targetHintToCamDeltaAngleVelRange(in);
|
||||||
seg13.FixupAngles();
|
targetHintToCamDeltaAngleVelRange.FixupAngles();
|
||||||
SSpindleProperty seg14(in);
|
SSpindleProperty deleteHintBallDist(in);
|
||||||
SSpindleProperty seg15(in);
|
SSpindleProperty recoverClampedAzimuthFromHintDir(in);
|
||||||
seg15.FixupAngles();
|
recoverClampedAzimuthFromHintDir.FixupAngles();
|
||||||
|
|
||||||
return new CScriptSpindleCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, active, flags, f1,
|
return new CScriptSpindleCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, active, flags,
|
||||||
f2, f3, f4, seg1, seg2, seg3, seg4, seg5, seg6, seg7, seg8, seg9, seg10, seg11, seg12,
|
hintToCamDistMin, hintToCamDistMax, hintToCamVOffMin, hintToCamVOffMax,
|
||||||
seg13, seg14, seg15);
|
targetHintToCamDeltaAngleVel, deltaAngleScaleWithCamDist, hintToCamDist,
|
||||||
|
distOffsetFromBallDist, hintBallToCamAzimuth, unused, maxHintBallToCamAzimuth,
|
||||||
|
camLookRelAzimuth, lookPosZOffset, camPosZOffset, clampedAzimuthFromHintDir,
|
||||||
|
dampingAzimuthSpeed, targetHintToCamDeltaAngleVelRange, deleteHintBallDist,
|
||||||
|
recoverClampedAzimuthFromHintDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadAtomicAlpha(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
|
CEntity* ScriptLoader::LoadAtomicAlpha(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 8357df410e1a0d7671e70f0446342dd8b9268d02
|
Subproject commit 7fb911e44819ce6890a46b9b39b26ece50be37e9
|
Loading…
Reference in New Issue