mirror of https://github.com/AxioDL/metaforce.git
Various bug fixes
This commit is contained in:
parent
41edf5a226
commit
6854cb9df7
|
@ -4,6 +4,13 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
static std::remove_reference_t<decltype(std::declval<T>()[0])>& AccessElement(T& arr, S idx)
|
||||||
|
{
|
||||||
|
assert(std::extent<T>::value > idx && idx >= 0);
|
||||||
|
return arr[idx];
|
||||||
|
}
|
||||||
|
|
||||||
CSortedListManager::CSortedListManager()
|
CSortedListManager::CSortedListManager()
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
|
@ -20,17 +27,17 @@ void CSortedListManager::AddToLinkedList(s16 nodeId, s16& headId, s16& tailId) c
|
||||||
{
|
{
|
||||||
if (headId == -1)
|
if (headId == -1)
|
||||||
{
|
{
|
||||||
const_cast<SNode&>(x0_nodes[nodeId]).x28_next = headId;
|
const_cast<SNode&>(AccessElement(x0_nodes, nodeId)).x28_next = headId;
|
||||||
headId = nodeId;
|
headId = nodeId;
|
||||||
tailId = nodeId;
|
tailId = nodeId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (x0_nodes[nodeId].x28_next != -1)
|
if (AccessElement(x0_nodes, nodeId).x28_next != -1)
|
||||||
return;
|
return;
|
||||||
if (tailId == nodeId)
|
if (tailId == nodeId)
|
||||||
return;
|
return;
|
||||||
const_cast<SNode&>(x0_nodes[nodeId]).x28_next = headId;
|
const_cast<SNode&>(AccessElement(x0_nodes, nodeId)).x28_next = headId;
|
||||||
headId = nodeId;
|
headId = nodeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +47,8 @@ void CSortedListManager::RemoveFromList(ESortedList list, s16 idx)
|
||||||
SSortedList& sl = xb000_sortedLists[u32(list)];
|
SSortedList& sl = xb000_sortedLists[u32(list)];
|
||||||
while (idx < sl.x800_size - 1)
|
while (idx < sl.x800_size - 1)
|
||||||
{
|
{
|
||||||
x0_nodes[sl.x0_ids[idx+1]].x1c_selfIdxs[int(list)] = idx;
|
AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + 1)).x1c_selfIdxs[int(list)] = idx;
|
||||||
sl.x0_ids[idx] = sl.x0_ids[idx+1];
|
AccessElement(sl.x0_ids, idx) = AccessElement(sl.x0_ids, idx + 1);
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
--sl.x800_size;
|
--sl.x800_size;
|
||||||
|
@ -52,22 +59,24 @@ void CSortedListManager::MoveInList(ESortedList list, s16 idx)
|
||||||
SSortedList& sl = xb000_sortedLists[int(list)];
|
SSortedList& sl = xb000_sortedLists[int(list)];
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (idx > 0 ||
|
if (idx > 0 &&
|
||||||
x0_nodes[sl.x0_ids[idx-1]].x4_box[idx] > x0_nodes[sl.x0_ids[idx]].x4_box[idx])
|
AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx - 1)).x4_box[int(list)] >
|
||||||
|
AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx)).x4_box[int(list)])
|
||||||
{
|
{
|
||||||
x0_nodes[sl.x0_ids[idx-1]].x1c_selfIdxs[int(list)] = idx;
|
AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx - 1)).x1c_selfIdxs[int(list)] = idx;
|
||||||
x0_nodes[sl.x0_ids[idx]].x1c_selfIdxs[int(list)] = idx - 1;
|
AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx)).x1c_selfIdxs[int(list)] = idx - 1;
|
||||||
std::swap(sl.x0_ids[idx], sl.x0_ids[idx-1]);
|
std::swap(AccessElement(sl.x0_ids, idx), AccessElement(sl.x0_ids, idx - 1));
|
||||||
--idx;
|
--idx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (idx >= sl.x800_size - 1)
|
if (idx >= sl.x800_size - 1)
|
||||||
return;
|
return;
|
||||||
if (x0_nodes[sl.x0_ids[idx+1]].x4_box[int(list)] >= x0_nodes[sl.x0_ids[idx]].x4_box[int(list)])
|
if (AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + 1)).x4_box[int(list)] >=
|
||||||
|
AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx)).x4_box[int(list)])
|
||||||
return;
|
return;
|
||||||
x0_nodes[sl.x0_ids[idx+1]].x1c_selfIdxs[int(list)] = idx + 1;
|
AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + 1)).x1c_selfIdxs[int(list)] = idx + 1;
|
||||||
std::swap(sl.x0_ids[idx], sl.x0_ids[idx+1]);
|
std::swap(AccessElement(sl.x0_ids, idx), AccessElement(sl.x0_ids, idx + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,14 +85,14 @@ void CSortedListManager::InsertInList(ESortedList list, SNode& node)
|
||||||
{
|
{
|
||||||
SSortedList& sl = xb000_sortedLists[int(list)];
|
SSortedList& sl = xb000_sortedLists[int(list)];
|
||||||
int insIdx = 0;
|
int insIdx = 0;
|
||||||
for (int i=sl.x800_size ; i>0 ;)
|
for (int i = sl.x800_size ; i > 0 ;)
|
||||||
{
|
{
|
||||||
/* Binary search cycle to find insert index */
|
/* Binary search cycle to find insert index */
|
||||||
if (x0_nodes[sl.x0_ids[insIdx+i/2]].x4_box[int(list)] < node.x4_box[int(list)])
|
if (AccessElement(x0_nodes, AccessElement(sl.x0_ids, insIdx + i / 2)).x4_box[int(list)] < node.x4_box[int(list)])
|
||||||
{
|
{
|
||||||
/* Upper */
|
/* Upper */
|
||||||
insIdx += i / 2 + 1;
|
insIdx = insIdx + i / 2 + 1;
|
||||||
i -= i / 2 - 1;
|
i = i - i / 2 - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -93,14 +102,14 @@ void CSortedListManager::InsertInList(ESortedList list, SNode& node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shift ids for insert */
|
/* Shift ids for insert */
|
||||||
for (int i=sl.x800_size ; i>insIdx ; --i)
|
for (int i = sl.x800_size ; i > insIdx ; --i)
|
||||||
{
|
{
|
||||||
x0_nodes[sl.x0_ids[i]].x1c_selfIdxs[int(list)] = i;
|
AccessElement(x0_nodes, AccessElement(sl.x0_ids, i - 1)).x1c_selfIdxs[int(list)] = i;
|
||||||
sl.x0_ids[i] = sl.x0_ids[i-1];
|
AccessElement(sl.x0_ids, i) = AccessElement(sl.x0_ids, i - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do insert */
|
/* Do insert */
|
||||||
sl.x0_ids[insIdx] = node.x0_actor->GetUniqueId().Value();
|
AccessElement(sl.x0_ids, insIdx) = node.x0_actor->GetUniqueId().Value();
|
||||||
node.x1c_selfIdxs[int(list)] = insIdx;
|
node.x1c_selfIdxs[int(list)] = insIdx;
|
||||||
++sl.x800_size;
|
++sl.x800_size;
|
||||||
}
|
}
|
||||||
|
@ -109,14 +118,14 @@ s16 CSortedListManager::FindInListUpper(ESortedList list, float val) const
|
||||||
{
|
{
|
||||||
const SSortedList& sl = xb000_sortedLists[int(list)];
|
const SSortedList& sl = xb000_sortedLists[int(list)];
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (int i=sl.x800_size ; i>0 ;)
|
for (int i = sl.x800_size ; i > 0 ;)
|
||||||
{
|
{
|
||||||
/* Binary search cycle to find index */
|
/* Binary search cycle to find index */
|
||||||
if (!(val < x0_nodes[sl.x0_ids[idx+i/2]].x4_box[int(list)]))
|
if (!(val < AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[int(list)]))
|
||||||
{
|
{
|
||||||
/* Upper */
|
/* Upper */
|
||||||
idx += i / 2 + 1;
|
idx = idx + i / 2 + 1;
|
||||||
i -= i / 2 - 1;
|
i = i - i / 2 - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -131,14 +140,14 @@ s16 CSortedListManager::FindInListLower(ESortedList list, float val) const
|
||||||
{
|
{
|
||||||
const SSortedList& sl = xb000_sortedLists[int(list)];
|
const SSortedList& sl = xb000_sortedLists[int(list)];
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (int i=sl.x800_size ; i>0 ;)
|
for (int i = sl.x800_size ; i > 0 ;)
|
||||||
{
|
{
|
||||||
/* Binary search cycle to find index */
|
/* Binary search cycle to find index */
|
||||||
if (x0_nodes[sl.x0_ids[idx+i/2]].x4_box[int(list)] < val)
|
if (AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[int(list)] < val)
|
||||||
{
|
{
|
||||||
/* Upper */
|
/* Upper */
|
||||||
idx += i / 2 + 1;
|
idx = idx + i / 2 + 1;
|
||||||
i -= i / 2 - 1;
|
i = i - i / 2 - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -187,22 +196,22 @@ s16 CSortedListManager::ConstructIntersectionArray(const zeus::CAABox& aabb)
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 CSortedListManager::CalculateIntersections(ESortedList la, ESortedList lb, s16 a, s16 b, s16 c, s16 d,
|
s16 CSortedListManager::CalculateIntersections(ESortedList la, ESortedList lb, s16 a, s16 b, s16 c, s16 d,
|
||||||
ESortedList slA, ESortedList slB, ESortedList slC, ESortedList slD,
|
ESortedList slA, ESortedList slB, ESortedList slC, ESortedList slD,
|
||||||
const zeus::CAABox& aabb)
|
const zeus::CAABox& aabb)
|
||||||
{
|
{
|
||||||
s16 headId = -1;
|
s16 headId = -1;
|
||||||
s16 tailId = -1;
|
s16 tailId = -1;
|
||||||
for (int i=a ; i<b ; ++i)
|
for (int i=a ; i<b ; ++i)
|
||||||
AddToLinkedList(xb000_sortedLists[int(la)].x0_ids[i], headId, tailId);
|
AddToLinkedList(AccessElement(xb000_sortedLists[int(la)].x0_ids, i), headId, tailId);
|
||||||
for (int i=c ; i<d ; ++i)
|
for (int i=c ; i<d ; ++i)
|
||||||
AddToLinkedList(xb000_sortedLists[int(lb)].x0_ids[i], headId, tailId);
|
AddToLinkedList(AccessElement(xb000_sortedLists[int(lb)].x0_ids, i), headId, tailId);
|
||||||
|
|
||||||
if (a < xb000_sortedLists[int(lb)].x800_size - d)
|
if (a < xb000_sortedLists[int(lb)].x800_size - d)
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<a ; ++i)
|
for (int i=0 ; i<a ; ++i)
|
||||||
{
|
{
|
||||||
s16 id = xb000_sortedLists[int(la)].x0_ids[i];
|
s16 id = AccessElement(xb000_sortedLists[int(la)].x0_ids, i);
|
||||||
if (x0_nodes[id].x1c_selfIdxs[lb] > aabb[int(lb)])
|
if (AccessElement(x0_nodes, id).x1c_selfIdxs[lb] > aabb[int(lb)])
|
||||||
AddToLinkedList(id, headId, tailId);
|
AddToLinkedList(id, headId, tailId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,15 +219,15 @@ s16 CSortedListManager::CalculateIntersections(ESortedList la, ESortedList lb, s
|
||||||
{
|
{
|
||||||
for (int i=d ; i<xb000_sortedLists[int(lb)].x800_size ; ++i)
|
for (int i=d ; i<xb000_sortedLists[int(lb)].x800_size ; ++i)
|
||||||
{
|
{
|
||||||
s16 id = xb000_sortedLists[int(lb)].x0_ids[i];
|
s16 id = AccessElement(xb000_sortedLists[int(lb)].x0_ids, i);
|
||||||
if (x0_nodes[id].x1c_selfIdxs[la] < aabb[int(la)])
|
if (AccessElement(x0_nodes, id).x1c_selfIdxs[la] < aabb[int(la)])
|
||||||
AddToLinkedList(id, headId, tailId);
|
AddToLinkedList(id, headId, tailId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s16* id = &headId ; *id != -1 ;)
|
for (s16* id = &headId ; *id != -1 ;)
|
||||||
{
|
{
|
||||||
SNode& node = x0_nodes[*id];
|
SNode& node = AccessElement(x0_nodes, *id);
|
||||||
if (node.x4_box[int(slA)] > aabb[int(slB)] ||
|
if (node.x4_box[int(slA)] > aabb[int(slB)] ||
|
||||||
node.x4_box[int(slB)] < aabb[int(slA)] ||
|
node.x4_box[int(slB)] < aabb[int(slA)] ||
|
||||||
node.x4_box[int(slC)] > aabb[int(slD)] ||
|
node.x4_box[int(slC)] > aabb[int(slD)] ||
|
||||||
|
@ -255,7 +264,7 @@ void CSortedListManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& o
|
||||||
s16 id = const_cast<CSortedListManager&>(*this).ConstructIntersectionArray(aabb);
|
s16 id = const_cast<CSortedListManager&>(*this).ConstructIntersectionArray(aabb);
|
||||||
while (id != -1)
|
while (id != -1)
|
||||||
{
|
{
|
||||||
const SNode& node = x0_nodes[id];
|
const SNode& node = AccessElement(x0_nodes, id);
|
||||||
if (&actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList()) &&
|
if (&actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList()) &&
|
||||||
node.x0_actor->GetMaterialFilter().Passes(actor.GetMaterialList()))
|
node.x0_actor->GetMaterialFilter().Passes(actor.GetMaterialList()))
|
||||||
out.push_back(node.x0_actor->GetUniqueId());
|
out.push_back(node.x0_actor->GetUniqueId());
|
||||||
|
@ -271,7 +280,7 @@ void CSortedListManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& o
|
||||||
s16 id = const_cast<CSortedListManager&>(*this).ConstructIntersectionArray(aabb);
|
s16 id = const_cast<CSortedListManager&>(*this).ConstructIntersectionArray(aabb);
|
||||||
while (id != -1)
|
while (id != -1)
|
||||||
{
|
{
|
||||||
const SNode& node = x0_nodes[id];
|
const SNode& node = AccessElement(x0_nodes, id);
|
||||||
if (actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList()))
|
if (actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList()))
|
||||||
out.push_back(node.x0_actor->GetUniqueId());
|
out.push_back(node.x0_actor->GetUniqueId());
|
||||||
|
|
||||||
|
@ -282,7 +291,7 @@ void CSortedListManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& o
|
||||||
|
|
||||||
void CSortedListManager::Remove(const CActor* act)
|
void CSortedListManager::Remove(const CActor* act)
|
||||||
{
|
{
|
||||||
SNode& node = x0_nodes[act->GetUniqueId().Value()];
|
SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value());
|
||||||
if (!node.x2a_populated)
|
if (!node.x2a_populated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -297,7 +306,7 @@ void CSortedListManager::Remove(const CActor* act)
|
||||||
|
|
||||||
void CSortedListManager::Move(const CActor* act, const zeus::CAABox& aabb)
|
void CSortedListManager::Move(const CActor* act, const zeus::CAABox& aabb)
|
||||||
{
|
{
|
||||||
SNode& node = x0_nodes[act->GetUniqueId().Value()];
|
SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value());
|
||||||
node.x4_box = aabb;
|
node.x4_box = aabb;
|
||||||
|
|
||||||
MoveInList(ESortedList::MinX, node.x1c_selfIdxs[0]);
|
MoveInList(ESortedList::MinX, node.x1c_selfIdxs[0]);
|
||||||
|
@ -310,7 +319,7 @@ void CSortedListManager::Move(const CActor* act, const zeus::CAABox& aabb)
|
||||||
|
|
||||||
void CSortedListManager::Insert(const CActor* act, const zeus::CAABox& aabb)
|
void CSortedListManager::Insert(const CActor* act, const zeus::CAABox& aabb)
|
||||||
{
|
{
|
||||||
SNode& node = x0_nodes[act->GetUniqueId().Value()];
|
SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value());
|
||||||
if (node.x2a_populated)
|
if (node.x2a_populated)
|
||||||
{
|
{
|
||||||
Move(act, aabb);
|
Move(act, aabb);
|
||||||
|
@ -331,7 +340,7 @@ bool CSortedListManager::ActorInLists(const CActor* act) const
|
||||||
{
|
{
|
||||||
if (!act)
|
if (!act)
|
||||||
return false;
|
return false;
|
||||||
const SNode& node = x0_nodes[act->GetUniqueId().Value()];
|
const SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value());
|
||||||
return node.x2a_populated;
|
return node.x2a_populated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ class CSortedListManager
|
||||||
s16 FindInListLower(ESortedList, float) const;
|
s16 FindInListLower(ESortedList, float) const;
|
||||||
s16 ConstructIntersectionArray(const zeus::CAABox&);
|
s16 ConstructIntersectionArray(const zeus::CAABox&);
|
||||||
s16 CalculateIntersections(ESortedList, ESortedList, s16, s16, s16, s16,
|
s16 CalculateIntersections(ESortedList, ESortedList, s16, s16, s16, s16,
|
||||||
ESortedList, ESortedList, ESortedList, ESortedList, const zeus::CAABox&);
|
ESortedList, ESortedList, ESortedList, ESortedList, const zeus::CAABox&);
|
||||||
public:
|
public:
|
||||||
CSortedListManager();
|
CSortedListManager();
|
||||||
void BuildNearList(rstl::reserved_vector<TUniqueId, 1024>&, const zeus::CVector3f&, const zeus::CVector3f&,
|
void BuildNearList(rstl::reserved_vector<TUniqueId, 1024>&, const zeus::CVector3f&, const zeus::CVector3f&,
|
||||||
|
|
|
@ -271,25 +271,25 @@ void CStateManager::UpdateThermalVisor()
|
||||||
|
|
||||||
void CStateManager::RendererDrawCallback(const void* drawable, const void* ctx, int type)
|
void CStateManager::RendererDrawCallback(const void* drawable, const void* ctx, int type)
|
||||||
{
|
{
|
||||||
CStateManager& mgr = reinterpret_cast<CStateManager&>(ctx);
|
const CStateManager& mgr = *reinterpret_cast<const CStateManager*>(ctx);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
CActor& actor = reinterpret_cast<CActor&>(drawable);
|
const CActor& actor = *reinterpret_cast<const CActor*>(drawable);
|
||||||
if (actor.xc8_drawnToken == mgr.x8dc_objectDrawToken)
|
if (actor.xc8_drawnToken == mgr.x8dc_objectDrawToken)
|
||||||
break;
|
break;
|
||||||
if (actor.xc6_nextDrawNode != kInvalidUniqueId)
|
if (actor.xc6_nextDrawNode != kInvalidUniqueId)
|
||||||
mgr.RecursiveDrawTree(actor.xc6_nextDrawNode);
|
mgr.RecursiveDrawTree(actor.xc6_nextDrawNode);
|
||||||
actor.Render(mgr);
|
actor.Render(mgr);
|
||||||
actor.xc8_drawnToken = mgr.x8dc_objectDrawToken;
|
const_cast<CActor&>(actor).xc8_drawnToken = mgr.x8dc_objectDrawToken;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
reinterpret_cast<CSimpleShadow&>(drawable).Render(mgr.x8f0_shadowTex.GetObj());
|
reinterpret_cast<const CSimpleShadow*>(drawable)->Render(mgr.x8f0_shadowTex.GetObj());
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
reinterpret_cast<CDecal&>(drawable).Render();
|
reinterpret_cast<const CDecal*>(drawable)->Render();
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -711,7 +711,7 @@ void CStateManager::DrawWorld() const
|
||||||
|
|
||||||
for (TUniqueId id : x86c_stateManagerContainer->xf370_)
|
for (TUniqueId id : x86c_stateManagerContainer->xf370_)
|
||||||
if (const CActor* ent = static_cast<const CActor*>(GetObjectById(id)))
|
if (const CActor* ent = static_cast<const CActor*>(GetObjectById(id)))
|
||||||
if (!thermal || ent->xe6_27_renderVisorFlags & 0x2)
|
if (!thermal || ent->xe6_27_renderVisorFlags & 0x1)
|
||||||
ent->Render(*this);
|
ent->Render(*this);
|
||||||
|
|
||||||
bool morphingPlayerVisible = false;
|
bool morphingPlayerVisible = false;
|
||||||
|
@ -728,7 +728,7 @@ void CStateManager::DrawWorld() const
|
||||||
{
|
{
|
||||||
if (TCastToPtr<CActor> actor = ent)
|
if (TCastToPtr<CActor> actor = ent)
|
||||||
{
|
{
|
||||||
if (!actor->xe7_29_)
|
if (!actor->xe7_29_actorActive)
|
||||||
continue;
|
continue;
|
||||||
TUniqueId actorId = actor->GetUniqueId();
|
TUniqueId actorId = actor->GetUniqueId();
|
||||||
if (!thermal && area.LookupPVSUniqueID(actorId) == actorId)
|
if (!thermal && area.LookupPVSUniqueID(actorId) == actorId)
|
||||||
|
@ -749,9 +749,9 @@ void CStateManager::DrawWorld() const
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!thermal || actor->xe6_27_renderVisorFlags & 0x2)
|
if (!thermal || actor->xe6_27_renderVisorFlags & 0x1)
|
||||||
actor->AddToRenderer(frustum, *this);
|
actor->AddToRenderer(frustum, *this);
|
||||||
if (thermal && actor->xe6_27_renderVisorFlags & 0x4)
|
if (thermal && actor->xe6_27_renderVisorFlags & 0x2)
|
||||||
thermalActorArr[thermalActorCount++] = actor.GetPtr();
|
thermalActorArr[thermalActorCount++] = actor.GetPtr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -787,7 +787,7 @@ void CStateManager::DrawWorld() const
|
||||||
CGraphics::SetDepthRange(0.015625f, 0.03125f);
|
CGraphics::SetDepthRange(0.015625f, 0.03125f);
|
||||||
for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast)
|
for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast)
|
||||||
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
|
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
|
||||||
if (actor->xe6_27_renderVisorFlags & 0x2)
|
if (actor->xe6_27_renderVisorFlags & 0x1)
|
||||||
actor->Render(*this);
|
actor->Render(*this);
|
||||||
CGraphics::SetDepthRange(0.125f, 1.f);
|
CGraphics::SetDepthRange(0.125f, 1.f);
|
||||||
}
|
}
|
||||||
|
@ -795,7 +795,7 @@ void CStateManager::DrawWorld() const
|
||||||
|
|
||||||
for (TUniqueId id : x86c_stateManagerContainer->xf370_)
|
for (TUniqueId id : x86c_stateManagerContainer->xf370_)
|
||||||
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
|
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
|
||||||
if (actor->xe6_27_renderVisorFlags & 0x4)
|
if (actor->xe6_27_renderVisorFlags & 0x2)
|
||||||
actor->Render(*this);
|
actor->Render(*this);
|
||||||
|
|
||||||
for (int i=areaCount-1 ; i>=0 ; --i)
|
for (int i=areaCount-1 ; i>=0 ; --i)
|
||||||
|
@ -858,7 +858,7 @@ void CStateManager::DrawWorld() const
|
||||||
CGraphics::SetDepthRange(0.015625f, 0.03125f);
|
CGraphics::SetDepthRange(0.015625f, 0.03125f);
|
||||||
for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast)
|
for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast)
|
||||||
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
|
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
|
||||||
if (actor->xe6_27_renderVisorFlags & 0x4)
|
if (actor->xe6_27_renderVisorFlags & 0x2)
|
||||||
actor->Render(*this);
|
actor->Render(*this);
|
||||||
CGraphics::SetDepthRange(0.125f, 1.f);
|
CGraphics::SetDepthRange(0.125f, 1.f);
|
||||||
}
|
}
|
||||||
|
@ -943,7 +943,7 @@ void CStateManager::PreRender()
|
||||||
{
|
{
|
||||||
if (TCastToPtr<CActor> act = ent)
|
if (TCastToPtr<CActor> act = ent)
|
||||||
{
|
{
|
||||||
if (act->GetE7_29())
|
if (act->IsActorActive())
|
||||||
{
|
{
|
||||||
act->CalculateRenderBounds();
|
act->CalculateRenderBounds();
|
||||||
act->PreRender(*this, frustum);
|
act->PreRender(*this, frustum);
|
||||||
|
@ -2071,7 +2071,7 @@ void CStateManager::CrossTouchActors()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rstl::optional_object<zeus::CAABox> touchAABB2 = ent2->GetTouchBounds();
|
rstl::optional_object<zeus::CAABox> touchAABB2 = ent2->GetTouchBounds();
|
||||||
if (!ent2->GetActive() || touchAABB2)
|
if (!ent2->GetActive() || !touchAABB2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (visits[ent2->GetUniqueId().Value()])
|
if (visits[ent2->GetUniqueId().Value()])
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "World/CScriptCameraHint.hpp"
|
#include "World/CScriptCameraHint.hpp"
|
||||||
#include "CPathCamera.hpp"
|
#include "CPathCamera.hpp"
|
||||||
#include "World/CScriptSpindleCamera.hpp"
|
#include "World/CScriptSpindleCamera.hpp"
|
||||||
|
#include "World/CExplosion.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -80,7 +81,54 @@ int CCameraManager::AddCameraShaker(const CCameraShakeData& data, bool sfx)
|
||||||
return x2c_lastShakeId;
|
return x2c_lastShakeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCameraManager::AddCinemaCamera(TUniqueId id, CStateManager& stateMgr) { x4_cineCameras.push_back(id); }
|
void CCameraManager::EnterCinematic(CStateManager& mgr)
|
||||||
|
{
|
||||||
|
mgr.GetPlayer().GetPlayerGun()->CancelFiring(mgr);
|
||||||
|
mgr.GetPlayer().Stop(mgr);
|
||||||
|
|
||||||
|
for (CEntity* ent : mgr.GetAllObjectList())
|
||||||
|
{
|
||||||
|
if (TCastToPtr<CExplosion> explo = ent)
|
||||||
|
{
|
||||||
|
mgr.FreeScriptObject(explo->GetUniqueId());
|
||||||
|
}
|
||||||
|
else if (TCastToPtr<CWeapon> weap = ent)
|
||||||
|
{
|
||||||
|
if (weap->GetActive())
|
||||||
|
{
|
||||||
|
if ((weap->GetAttribField() & CWeapon::EProjectileAttrib::KeepInCinematic) ==
|
||||||
|
CWeapon::EProjectileAttrib::None)
|
||||||
|
{
|
||||||
|
if (TCastToConstPtr<CAi>(mgr.GetObjectById(weap->GetOwnerId())) ||
|
||||||
|
TCastToConstPtr<CPlayer>(mgr.GetObjectById(weap->GetOwnerId())))
|
||||||
|
mgr.FreeScriptObject(weap->GetUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCameraManager::AddCinemaCamera(TUniqueId id, CStateManager& stateMgr)
|
||||||
|
{
|
||||||
|
if (x4_cineCameras.empty())
|
||||||
|
EnterCinematic(stateMgr);
|
||||||
|
RemoveCinemaCamera(id, stateMgr);
|
||||||
|
x4_cineCameras.push_back(id);
|
||||||
|
if (TCastToPtr<CCinematicCamera> cam = stateMgr.ObjectById(id))
|
||||||
|
{
|
||||||
|
if (cam->GetFlags() & 0x4) // into player eye
|
||||||
|
{
|
||||||
|
float time = 4.f;
|
||||||
|
float delayTime = cam->GetDuration() - 4.f;
|
||||||
|
if (delayTime < 0.f)
|
||||||
|
{
|
||||||
|
delayTime = 0.f;
|
||||||
|
time = cam->GetDuration();
|
||||||
|
}
|
||||||
|
cam->SetFovInterpolation(cam->GetFov(), 55.f, time, delayTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CCameraManager::SetInsideFluid(bool val, TUniqueId fluidId)
|
void CCameraManager::SetInsideFluid(bool val, TUniqueId fluidId)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,6 +82,8 @@ class CCameraManager
|
||||||
void SkipBallCameraCinematic(CStateManager& mgr);
|
void SkipBallCameraCinematic(CStateManager& mgr);
|
||||||
void ApplyCameraHint(const CScriptCameraHint& hint, CStateManager& mgr);
|
void ApplyCameraHint(const CScriptCameraHint& hint, CStateManager& mgr);
|
||||||
|
|
||||||
|
void EnterCinematic(CStateManager& mgr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCameraManager(TUniqueId curCameraId=kInvalidUniqueId);
|
CCameraManager(TUniqueId curCameraId=kInvalidUniqueId);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#include "World/CPlayer.hpp"
|
#include "World/CPlayer.hpp"
|
||||||
#include "World/CScriptActor.hpp"
|
#include "World/CScriptActor.hpp"
|
||||||
#include "TCastTo.hpp"
|
#include "TCastTo.hpp"
|
||||||
|
#include "World/CScriptCameraWaypoint.hpp"
|
||||||
|
#include "GameGlobalObjects.hpp"
|
||||||
|
#include "Character/CAnimTreeNode.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -11,7 +14,7 @@ CCinematicCamera::CCinematicCamera(TUniqueId uid, std::string_view name, const C
|
||||||
const zeus::CTransform& xf, bool active, float shotDuration,
|
const zeus::CTransform& xf, bool active, float shotDuration,
|
||||||
float fovy, float znear, float zfar, float aspect, u32 flags)
|
float fovy, float znear, float zfar, float aspect, u32 flags)
|
||||||
: CGameCamera(uid, active, name, info, xf, fovy, znear, zfar, aspect, kInvalidUniqueId, flags & 0x20, 0),
|
: CGameCamera(uid, active, name, info, xf, fovy, znear, zfar, aspect, kInvalidUniqueId, flags & 0x20, 0),
|
||||||
x1e8_duration(shotDuration), x1f0_origFovy(fovy), x1fc_(zeus::CQuaternion(xf.basis)), x21c_flags(flags)
|
x1e8_duration(shotDuration), x1f0_origFovy(fovy), x1fc_origOrientation(zeus::CQuaternion(xf.basis)), x21c_flags(flags)
|
||||||
{
|
{
|
||||||
x220_24_ = false;
|
x220_24_ = false;
|
||||||
}
|
}
|
||||||
|
@ -37,12 +40,194 @@ void CCinematicCamera::WasDeactivated(CStateManager& mgr)
|
||||||
mgr.GetPlayer().GetMorphBall()->LoadMorphBallModel(mgr);
|
mgr.GetPlayer().GetMorphBall()->LoadMorphBallModel(mgr);
|
||||||
if (x21c_flags & 0x100)
|
if (x21c_flags & 0x100)
|
||||||
mgr.SetCinematicPause(false);
|
mgr.SetCinematicPause(false);
|
||||||
x188_.clear();
|
x188_viewPoints.clear();
|
||||||
x198_.clear();
|
x198_viewOrientations.clear();
|
||||||
x1a8_.clear();
|
x1a8_viewPointArrivals.clear();
|
||||||
x1b8_.clear();
|
x1b8_targets.clear();
|
||||||
x1c8_.clear();
|
x1c8_targetArrivals.clear();
|
||||||
x1d8_.clear();
|
x1d8_viewHFovs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f
|
||||||
|
CCinematicCamera::GetInterpolatedSplinePoint(const std::vector<zeus::CVector3f>& points, int& idxOut, float tin) const
|
||||||
|
{
|
||||||
|
if (points.size() > 0)
|
||||||
|
{
|
||||||
|
float cycleT = std::fmod(tin, x1e8_duration);
|
||||||
|
float durPerPoint = x1e8_duration / float(points.size() - 1);
|
||||||
|
idxOut = int(cycleT / durPerPoint);
|
||||||
|
float t = (cycleT - idxOut * durPerPoint) / durPerPoint;
|
||||||
|
|
||||||
|
if (points.size() == 1)
|
||||||
|
return points.front();
|
||||||
|
else if (points.size() == 2)
|
||||||
|
return (points[1] - points[0]) * t + points[0];
|
||||||
|
|
||||||
|
zeus::CVector3f ptA;
|
||||||
|
if (idxOut > 0)
|
||||||
|
ptA = points[idxOut - 1];
|
||||||
|
else
|
||||||
|
ptA = points[0] - (points[1] - points[0]);
|
||||||
|
|
||||||
|
zeus::CVector3f ptB = points[idxOut];
|
||||||
|
zeus::CVector3f ptC;
|
||||||
|
if (idxOut + 1 >= points.size())
|
||||||
|
{
|
||||||
|
const zeus::CVector3f& tmpA = points[points.size() - 1];
|
||||||
|
const zeus::CVector3f& tmpB = points[points.size() - 2];
|
||||||
|
ptC = tmpA - (tmpB - tmpA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptC = points[idxOut + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f ptD;
|
||||||
|
if (idxOut + 2 >= points.size())
|
||||||
|
{
|
||||||
|
const zeus::CVector3f& tmpA = points[points.size() - 1];
|
||||||
|
const zeus::CVector3f& tmpB = points[points.size() - 2];
|
||||||
|
ptD = tmpA - (tmpB - tmpA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptD = points[idxOut + 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
return zeus::getCatmullRomSplinePoint(ptA, ptB, ptC, ptD, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CQuaternion
|
||||||
|
CCinematicCamera::GetInterpolatedOrientation(const std::vector<zeus::CQuaternion>& rotations, float tin) const
|
||||||
|
{
|
||||||
|
if (rotations.size() == 0)
|
||||||
|
return x1fc_origOrientation;
|
||||||
|
else if (rotations.size() == 1)
|
||||||
|
return rotations.front();
|
||||||
|
|
||||||
|
float cycleT = std::fmod(tin, x1e8_duration);
|
||||||
|
float durPerPoint = x1e8_duration / float(rotations.size() - 1);
|
||||||
|
int idx = int(cycleT / durPerPoint);
|
||||||
|
float t = (cycleT - idx * durPerPoint) / durPerPoint;
|
||||||
|
return zeus::CQuaternion::slerp(rotations[idx], rotations[idx + 1], t);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CCinematicCamera::GetInterpolatedHFov(const std::vector<float>& fovs, float tin) const
|
||||||
|
{
|
||||||
|
if (fovs.size() == 0)
|
||||||
|
return x1f0_origFovy;
|
||||||
|
else if (fovs.size() == 1)
|
||||||
|
return fovs.front();
|
||||||
|
|
||||||
|
float cycleT = std::fmod(tin, x1e8_duration);
|
||||||
|
float durPerPoint = x1e8_duration / float(fovs.size() - 1);
|
||||||
|
int idx = int(cycleT / durPerPoint);
|
||||||
|
float t = (cycleT - idx * durPerPoint) / durPerPoint;
|
||||||
|
return (fovs[idx + 1] - fovs[idx]) * t + fovs[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
float CCinematicCamera::GetMoveOutofIntoAlpha() const
|
||||||
|
{
|
||||||
|
float startDist = 0.25f + x160_znear;
|
||||||
|
float endDist = 1.f * startDist;
|
||||||
|
float deltaMag = (GetTranslation() - x210_moveIntoEyePos).magnitude();
|
||||||
|
if (deltaMag >= startDist && deltaMag <= endDist)
|
||||||
|
return (deltaMag - startDist) / (endDist - startDist);
|
||||||
|
if (deltaMag > endDist)
|
||||||
|
return 1.f;
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCinematicCamera::DeactivateSelf(CStateManager& mgr)
|
||||||
|
{
|
||||||
|
SetActive(false);
|
||||||
|
SendScriptMsgs(EScriptObjectState::Inactive, mgr, EScriptObjectMessage::None);
|
||||||
|
WasDeactivated(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCinematicCamera::Think(float dt, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
if (GetActive())
|
||||||
|
{
|
||||||
|
zeus::CVector3f viewPoint = GetTranslation();
|
||||||
|
if (x188_viewPoints.size() > 0)
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
viewPoint = GetInterpolatedSplinePoint(x188_viewPoints, idx, x1ec_t);
|
||||||
|
if (idx > x1f4_passedViewPoint)
|
||||||
|
{
|
||||||
|
x1f4_passedViewPoint = idx;
|
||||||
|
SendArrivedMsg(x1a8_viewPointArrivals[x1f4_passedViewPoint], mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CQuaternion orientation = GetInterpolatedOrientation(x198_viewOrientations, x1ec_t);
|
||||||
|
|
||||||
|
if ((x21c_flags & 0x1) == 0)
|
||||||
|
{
|
||||||
|
if (x1b8_targets.size() > 0)
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
zeus::CVector3f target = GetInterpolatedSplinePoint(x1b8_targets, idx, x1ec_t);
|
||||||
|
if (x1b8_targets.size() == 1)
|
||||||
|
{
|
||||||
|
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(x1c8_targetArrivals.front()))
|
||||||
|
target = act->GetTranslation();
|
||||||
|
else
|
||||||
|
x1ec_t = x1e8_duration;
|
||||||
|
}
|
||||||
|
if (idx > x1f8_passedTarget)
|
||||||
|
{
|
||||||
|
x1f8_passedTarget = idx;
|
||||||
|
SendArrivedMsg(x1c8_targetArrivals[x1f8_passedTarget], mgr);
|
||||||
|
}
|
||||||
|
zeus::CVector3f upVec = orientation.transform(zeus::CVector3f::skUp);
|
||||||
|
if ((target - viewPoint).toVec2f().magnitude() < 0.0011920929f)
|
||||||
|
SetTranslation(target);
|
||||||
|
else
|
||||||
|
SetTransform(zeus::lookAt(viewPoint, target, upVec));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetTransform(zeus::CTransform(orientation, viewPoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zeus::CVector3f target = mgr.GetPlayer().GetTranslation();
|
||||||
|
if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed)
|
||||||
|
target.z += mgr.GetPlayer().GetMorphBall()->GetBallRadius();
|
||||||
|
else
|
||||||
|
target.z += mgr.GetPlayer().GetEyeHeight();
|
||||||
|
|
||||||
|
zeus::CVector3f upVec = orientation.transform(zeus::CVector3f::skUp);
|
||||||
|
if ((target - viewPoint).toVec2f().magnitude() < 0.0011920929f)
|
||||||
|
SetTranslation(target);
|
||||||
|
else
|
||||||
|
SetTransform(zeus::lookAt(viewPoint, target, upVec));
|
||||||
|
}
|
||||||
|
|
||||||
|
x15c_currentFov = GetInterpolatedHFov(x1d8_viewHFovs, x1ec_t) / x168_aspect;
|
||||||
|
x170_24_perspDirty = true;
|
||||||
|
|
||||||
|
if (x20c_lookAtId != kInvalidUniqueId)
|
||||||
|
if (TCastToPtr<CScriptActor> act = mgr.ObjectById(x20c_lookAtId))
|
||||||
|
if (act->IsCameraMoveIntoAlpha())
|
||||||
|
act->SetDrawFlags({5, 0, 3, zeus::CColor(1.f, GetMoveOutofIntoAlpha())});
|
||||||
|
|
||||||
|
x1ec_t += dt;
|
||||||
|
if (x1ec_t > x1e8_duration)
|
||||||
|
{
|
||||||
|
for (int i = x1f4_passedViewPoint + 1; i < x1a8_viewPointArrivals.size() ; ++i)
|
||||||
|
SendArrivedMsg(x1a8_viewPointArrivals[i], mgr);
|
||||||
|
for (int i = x1f8_passedTarget + 1; i < x1c8_targetArrivals.size() ; ++i)
|
||||||
|
SendArrivedMsg(x1c8_targetArrivals[i], mgr);
|
||||||
|
DeactivateSelf(mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCinematicCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
void CCinematicCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
||||||
|
@ -58,7 +243,7 @@ void CCinematicCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
|
||||||
TUniqueId id = mgr.GetIdForScript(conn.x8_objId);
|
TUniqueId id = mgr.GetIdForScript(conn.x8_objId);
|
||||||
if (TCastToPtr<CScriptActor> act = mgr.ObjectById(id))
|
if (TCastToPtr<CScriptActor> act = mgr.ObjectById(id))
|
||||||
{
|
{
|
||||||
if (act->GetX2E3_24())
|
if (act->IsCameraMoveIntoAlpha())
|
||||||
{
|
{
|
||||||
x20c_lookAtId = id;
|
x20c_lookAtId = id;
|
||||||
if (conn.x4_msg != EScriptObjectMessage::Deactivate &&
|
if (conn.x4_msg != EScriptObjectMessage::Deactivate &&
|
||||||
|
@ -71,17 +256,17 @@ void CCinematicCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
|
||||||
break;
|
break;
|
||||||
case EScriptObjectMessage::Activate:
|
case EScriptObjectMessage::Activate:
|
||||||
CalculateWaypoints(mgr);
|
CalculateWaypoints(mgr);
|
||||||
if ((x21c_flags & 1) == 0 && x220_24_ && x1b8_.empty())
|
if ((x21c_flags & 1) == 0 && x220_24_ && x1b8_targets.empty())
|
||||||
break;
|
break;
|
||||||
x1ec_ = 0.f;
|
x1ec_t = 0.f;
|
||||||
Think(0.f, mgr);
|
Think(0.f, mgr);
|
||||||
mgr.GetCameraManager()->AddCinemaCamera(GetUniqueId(), mgr);
|
mgr.GetCameraManager()->AddCinemaCamera(GetUniqueId(), mgr);
|
||||||
x1f4_ = 0;
|
x1f4_passedViewPoint = 0;
|
||||||
if (x1a8_.size() > 0)
|
if (x1a8_viewPointArrivals.size() > 0)
|
||||||
SendArrivedMsg(x1a8_[x1f4_], mgr);
|
SendArrivedMsg(x1a8_viewPointArrivals[x1f4_passedViewPoint], mgr);
|
||||||
x1f8_ = 0;
|
x1f8_passedTarget = 0;
|
||||||
if (x1c8_.size() > 0)
|
if (x1c8_targetArrivals.size() > 0)
|
||||||
SendArrivedMsg(x1c8_[x1f8_], mgr);
|
SendArrivedMsg(x1c8_targetArrivals[x1f8_passedTarget], mgr);
|
||||||
if (x21c_flags & 0x100)
|
if (x21c_flags & 0x100)
|
||||||
mgr.SetCinematicPause(true);
|
mgr.SetCinematicPause(true);
|
||||||
break;
|
break;
|
||||||
|
@ -93,9 +278,193 @@ void CCinematicCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCinematicCamera::CalculateMoveOutofIntoEyePosition(bool outOfEye, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
zeus::CQuaternion q(mgr.GetPlayer().GetTransform().basis);
|
||||||
|
zeus::CVector3f eyePos = mgr.GetPlayer().GetEyePosition();
|
||||||
|
if (x20c_lookAtId != kInvalidUniqueId)
|
||||||
|
{
|
||||||
|
if (TCastToConstPtr<CScriptActor> act = mgr.GetObjectById(x20c_lookAtId))
|
||||||
|
{
|
||||||
|
if (act->IsCameraMoveIntoAlpha())
|
||||||
|
{
|
||||||
|
if (const CModelData* mData = act->GetModelData())
|
||||||
|
{
|
||||||
|
if (const CAnimData* aData = mData->GetAnimationData())
|
||||||
|
{
|
||||||
|
if (const CAnimTreeNode* root = aData->GetRootAnimationTree().get())
|
||||||
|
{
|
||||||
|
CSegId lEye = aData->GetLocatorSegId("L_eye"sv);
|
||||||
|
CSegId rEye = aData->GetLocatorSegId("R_eye"sv);
|
||||||
|
if (lEye != 0xff && rEye != 0xff)
|
||||||
|
{
|
||||||
|
CCharAnimTime time =
|
||||||
|
outOfEye ? CCharAnimTime(0.f) : root->VGetSteadyStateAnimInfo().GetDuration();
|
||||||
|
CCharAnimTime* pTime = outOfEye ? nullptr : &time;
|
||||||
|
eyePos =
|
||||||
|
((act->GetTransform() * mData->GetScaledLocatorTransformDynamic("L_eye"sv, pTime)).origin +
|
||||||
|
(act->GetTransform() * mData->GetScaledLocatorTransformDynamic("R_eye"sv, pTime)).origin) * 0.5f;
|
||||||
|
q = zeus::CQuaternion(act->GetTransform().basis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f behindPos = eyePos;
|
||||||
|
zeus::CVector3f behindDelta = q.transform({0.f, -g_tweakPlayerRes->xf0_cinematicMoveOutofIntoPlayerDistance, 0.f});
|
||||||
|
if (!outOfEye)
|
||||||
|
{
|
||||||
|
behindPos += behindDelta;
|
||||||
|
behindDelta = -behindDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0 ; i<2 ; ++i)
|
||||||
|
{
|
||||||
|
x188_viewPoints[outOfEye ? i : x188_viewPoints.size() - (2 - i)] = behindPos;
|
||||||
|
x198_viewOrientations[outOfEye ? i : x198_viewOrientations.size() - (2 - i)] = q;
|
||||||
|
x1b8_targets[outOfEye ? i : x1b8_targets.size() - (2 - i)] = eyePos;
|
||||||
|
behindPos += behindDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
x210_moveIntoEyePos = eyePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCinematicCamera::GenerateMoveOutofIntoPoints(bool outOfEye, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
zeus::CQuaternion q(mgr.GetPlayer().GetTransform().basis);
|
||||||
|
zeus::CVector3f eyePos = mgr.GetPlayer().GetEyePosition();
|
||||||
|
zeus::CVector3f behindDelta = q.transform({0.f, -g_tweakPlayerRes->xf0_cinematicMoveOutofIntoPlayerDistance, 0.f});
|
||||||
|
zeus::CVector3f behindPos = eyePos;
|
||||||
|
if (!outOfEye)
|
||||||
|
{
|
||||||
|
behindPos += behindDelta;
|
||||||
|
behindDelta = -behindDelta;
|
||||||
|
}
|
||||||
|
for (int i=0 ; i<2 ; ++i)
|
||||||
|
{
|
||||||
|
x188_viewPoints.push_back(behindPos);
|
||||||
|
x198_viewOrientations.push_back(q);
|
||||||
|
x1a8_viewPointArrivals.push_back(mgr.GetPlayer().GetUniqueId());
|
||||||
|
x1b8_targets.push_back(eyePos);
|
||||||
|
x1c8_targetArrivals.push_back(kInvalidUniqueId);
|
||||||
|
behindPos += behindDelta;
|
||||||
|
}
|
||||||
|
CalculateMoveOutofIntoEyePosition(outOfEye, mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCinematicCamera::PickRandomActiveConnection(const std::vector<SConnection>& conns,
|
||||||
|
SConnection& randConn, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for (const SConnection& conn : conns)
|
||||||
|
if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next)
|
||||||
|
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId)))
|
||||||
|
if (act->GetActive())
|
||||||
|
++count;
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int randIdx = mgr.GetActiveRandom()->Next() % count;
|
||||||
|
int idx = 0;
|
||||||
|
for (const SConnection& conn : conns)
|
||||||
|
if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next)
|
||||||
|
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId)))
|
||||||
|
if (act->GetActive())
|
||||||
|
{
|
||||||
|
if (randIdx == idx)
|
||||||
|
{
|
||||||
|
randConn = conn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CCinematicCamera::CalculateWaypoints(CStateManager& mgr)
|
void CCinematicCamera::CalculateWaypoints(CStateManager& mgr)
|
||||||
{
|
{
|
||||||
|
const SConnection* firstVP = nullptr;
|
||||||
|
const SConnection* firstTarget = nullptr;
|
||||||
|
for (const SConnection& conn : x20_conns)
|
||||||
|
{
|
||||||
|
if (conn.x0_state == EScriptObjectState::CameraPath && conn.x4_msg == EScriptObjectMessage::Activate)
|
||||||
|
firstVP = &conn;
|
||||||
|
else if (conn.x0_state == EScriptObjectState::CameraTarget && conn.x4_msg == EScriptObjectMessage::Activate)
|
||||||
|
firstTarget = &conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
x188_viewPoints.clear();
|
||||||
|
x188_viewPoints.reserve(3);
|
||||||
|
x198_viewOrientations.clear();
|
||||||
|
x198_viewOrientations.reserve(3);
|
||||||
|
x1a8_viewPointArrivals.clear();
|
||||||
|
x1a8_viewPointArrivals.reserve(3);
|
||||||
|
x1b8_targets.clear();
|
||||||
|
x1b8_targets.reserve(3);
|
||||||
|
x1c8_targetArrivals.clear();
|
||||||
|
x1c8_targetArrivals.reserve(3);
|
||||||
|
x1d8_viewHFovs.clear();
|
||||||
|
x1d8_viewHFovs.reserve(3);
|
||||||
|
|
||||||
|
x220_24_ = false;
|
||||||
|
|
||||||
|
if ((x21c_flags & 0x2) != 0 && (x21c_flags & 0x200) == 0)
|
||||||
|
GenerateMoveOutofIntoPoints(true, mgr);
|
||||||
|
|
||||||
|
if (firstVP)
|
||||||
|
{
|
||||||
|
TCastToConstPtr<CActor> wp = mgr.GetObjectById(mgr.GetIdForScript(firstVP->x8_objId));
|
||||||
|
while (wp)
|
||||||
|
{
|
||||||
|
x188_viewPoints.push_back(wp->GetTranslation());
|
||||||
|
x198_viewOrientations.emplace_back(wp->GetTransform().basis);
|
||||||
|
if (TCastToConstPtr<CScriptCameraWaypoint> cwp = wp.GetPtr())
|
||||||
|
x1d8_viewHFovs.push_back(cwp->GetHFov());
|
||||||
|
auto search = std::find_if(x1a8_viewPointArrivals.begin(), x1a8_viewPointArrivals.end(),
|
||||||
|
[&](TUniqueId id) { return id == wp->GetUniqueId(); });
|
||||||
|
if (search == x1a8_viewPointArrivals.end())
|
||||||
|
{
|
||||||
|
x1a8_viewPointArrivals.push_back(wp->GetUniqueId());
|
||||||
|
SConnection randConn;
|
||||||
|
if (PickRandomActiveConnection(wp->GetConnectionList(), randConn, mgr))
|
||||||
|
wp = mgr.GetObjectById(mgr.GetIdForScript(randConn.x8_objId));
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstTarget)
|
||||||
|
{
|
||||||
|
TCastToConstPtr<CActor> tgt = mgr.GetObjectById(mgr.GetIdForScript(firstTarget->x8_objId));
|
||||||
|
while (tgt)
|
||||||
|
{
|
||||||
|
x1b8_targets.push_back(tgt->GetTranslation());
|
||||||
|
auto search = std::find_if(x1c8_targetArrivals.begin(), x1c8_targetArrivals.end(),
|
||||||
|
[&](TUniqueId id) { return id == tgt->GetUniqueId(); });
|
||||||
|
if (search == x1c8_targetArrivals.end())
|
||||||
|
{
|
||||||
|
x1c8_targetArrivals.push_back(tgt->GetUniqueId());
|
||||||
|
SConnection randConn;
|
||||||
|
if (PickRandomActiveConnection(tgt->GetConnectionList(), randConn, mgr))
|
||||||
|
tgt = mgr.GetObjectById(mgr.GetIdForScript(randConn.x8_objId));
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((x21c_flags & 0x4) != 0 && (x21c_flags & 0x200) == 0)
|
||||||
|
GenerateMoveOutofIntoPoints(false, mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCinematicCamera::SendArrivedMsg(TUniqueId reciever, CStateManager& mgr)
|
void CCinematicCamera::SendArrivedMsg(TUniqueId reciever, CStateManager& mgr)
|
||||||
|
|
|
@ -8,35 +8,48 @@ namespace urde
|
||||||
|
|
||||||
class CCinematicCamera : public CGameCamera
|
class CCinematicCamera : public CGameCamera
|
||||||
{
|
{
|
||||||
std::vector<zeus::CVector3f> x188_;
|
std::vector<zeus::CVector3f> x188_viewPoints;
|
||||||
std::vector<zeus::CQuaternion> x198_;
|
std::vector<zeus::CQuaternion> x198_viewOrientations;
|
||||||
std::vector<TUniqueId> x1a8_;
|
std::vector<TUniqueId> x1a8_viewPointArrivals;
|
||||||
std::vector<zeus::CVector3f> x1b8_;
|
std::vector<zeus::CVector3f> x1b8_targets;
|
||||||
std::vector<TUniqueId> x1c8_;
|
std::vector<TUniqueId> x1c8_targetArrivals;
|
||||||
std::vector<float> x1d8_;
|
std::vector<float> x1d8_viewHFovs;
|
||||||
float x1e8_duration;
|
float x1e8_duration;
|
||||||
float x1ec_ = 0.f;
|
float x1ec_t = 0.f;
|
||||||
float x1f0_origFovy;
|
float x1f0_origFovy;
|
||||||
u32 x1f4_ = 0;
|
int x1f4_passedViewPoint = 0;
|
||||||
u32 x1f8_ = 0;
|
int x1f8_passedTarget = 0;
|
||||||
zeus::CQuaternion x1fc_;
|
zeus::CQuaternion x1fc_origOrientation;
|
||||||
TUniqueId x20c_lookAtId = kInvalidUniqueId;
|
TUniqueId x20c_lookAtId = kInvalidUniqueId;
|
||||||
zeus::CVector3f x210_;
|
zeus::CVector3f x210_moveIntoEyePos;
|
||||||
u32 x21c_flags;
|
u32 x21c_flags; // 0x1: look at player, 0x2: out of player eye, 0x4: into player eye, 0x10: finish cine skip,
|
||||||
|
// 0x20: disable input, 0x40: draw player, 0x80: check failsafe, 0x100: cinematic pause,
|
||||||
|
// 0x200: disable out of into
|
||||||
bool x220_24_;
|
bool x220_24_;
|
||||||
|
zeus::CVector3f GetInterpolatedSplinePoint(const std::vector<zeus::CVector3f>& points, int& idxOut, float t) const;
|
||||||
|
zeus::CQuaternion GetInterpolatedOrientation(const std::vector<zeus::CQuaternion>& rotations, float t) const;
|
||||||
|
float GetInterpolatedHFov(const std::vector<float>& fovs, float t) const;
|
||||||
|
float GetMoveOutofIntoAlpha() const;
|
||||||
|
void DeactivateSelf(CStateManager& mgr);
|
||||||
|
void CalculateMoveOutofIntoEyePosition(bool outOfEye, CStateManager& mgr);
|
||||||
|
void GenerateMoveOutofIntoPoints(bool outOfEye, CStateManager& mgr);
|
||||||
|
static bool PickRandomActiveConnection(const std::vector<SConnection>& conns,
|
||||||
|
SConnection& randConn, CStateManager& mgr);
|
||||||
|
void CalculateWaypoints(CStateManager& mgr);
|
||||||
public:
|
public:
|
||||||
CCinematicCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
CCinematicCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
||||||
const zeus::CTransform& xf, bool active, float shotDuration,
|
const zeus::CTransform& xf, bool active, float shotDuration,
|
||||||
float fovy, float znear, float zfar, float aspect, u32 flags);
|
float fovy, float znear, float zfar, float aspect, u32 flags);
|
||||||
|
|
||||||
void Accept(IVisitor& visitor);
|
void Accept(IVisitor& visitor);
|
||||||
|
void Think(float dt, CStateManager& mgr);
|
||||||
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr);
|
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr);
|
||||||
void ProcessInput(const CFinalInput&, CStateManager& mgr);
|
void ProcessInput(const CFinalInput&, CStateManager& mgr);
|
||||||
void Reset(const zeus::CTransform&, CStateManager& mgr);
|
void Reset(const zeus::CTransform&, CStateManager& mgr);
|
||||||
u32 GetFlags() const { return x21c_flags; }
|
u32 GetFlags() const { return x21c_flags; }
|
||||||
void WasDeactivated(CStateManager& mgr);
|
void WasDeactivated(CStateManager& mgr);
|
||||||
void CalculateWaypoints(CStateManager& mgr);
|
|
||||||
void SendArrivedMsg(TUniqueId reciever, CStateManager& mgr);
|
void SendArrivedMsg(TUniqueId reciever, CStateManager& mgr);
|
||||||
|
float GetDuration() const { return x1e8_duration; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ CGameCamera::CGameCamera(TUniqueId uid, bool active, std::string_view name, cons
|
||||||
, x184_fov(fovy)
|
, x184_fov(fovy)
|
||||||
{
|
{
|
||||||
|
|
||||||
xe7_29_ = false;
|
xe7_29_actorActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
void CGameCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
||||||
|
@ -46,7 +46,7 @@ void CGameCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStat
|
||||||
void CGameCamera::SetActive(bool active)
|
void CGameCamera::SetActive(bool active)
|
||||||
{
|
{
|
||||||
CActor::SetActive(active);
|
CActor::SetActive(active);
|
||||||
xe7_29_ = false;
|
xe7_29_actorActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CMatrix4f CGameCamera::GetPerspectiveMatrix() const
|
zeus::CMatrix4f CGameCamera::GetPerspectiveMatrix() const
|
||||||
|
@ -103,9 +103,9 @@ zeus::CTransform CGameCamera::ValidateCameraTransform(const zeus::CTransform& a,
|
||||||
|
|
||||||
void CGameCamera::UpdatePerspective(float dt)
|
void CGameCamera::UpdatePerspective(float dt)
|
||||||
{
|
{
|
||||||
if (x174_ > 0.f)
|
if (x174_delayTime > 0.f)
|
||||||
{
|
{
|
||||||
x174_ -= dt;
|
x174_delayTime -= dt;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,18 +125,18 @@ void CGameCamera::UpdatePerspective(float dt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameCamera::SetFovInterpolation(float start, float fov, float time, float f4)
|
void CGameCamera::SetFovInterpolation(float start, float fov, float time, float delayTime)
|
||||||
{
|
{
|
||||||
if (time < 0.f)
|
if (time < 0.f)
|
||||||
{
|
{
|
||||||
x15c_currentFov = fov;
|
x15c_currentFov = fov;
|
||||||
x170_24_perspDirty = true;
|
x170_24_perspDirty = true;
|
||||||
x184_fov = fov;
|
x184_fov = fov;
|
||||||
x178_ = x174_ = 0.f;
|
x178_ = x174_delayTime = 0.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
x174_ = std::max(0.f, f4);
|
x174_delayTime = std::max(0.f, delayTime);
|
||||||
x17c_ = time;
|
x17c_ = time;
|
||||||
x178_ = time;
|
x178_ = time;
|
||||||
x180_ = start;
|
x180_ = start;
|
||||||
|
@ -154,6 +154,6 @@ void CGameCamera::SkipFovInterpolation()
|
||||||
x170_24_perspDirty = true;
|
x170_24_perspDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
x178_ = x174_ = 0.f;
|
x178_ = x174_delayTime = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ protected:
|
||||||
u32 x16c_controllerIdx;
|
u32 x16c_controllerIdx;
|
||||||
bool x170_24_perspDirty : 1;
|
bool x170_24_perspDirty : 1;
|
||||||
bool x170_25_disablesInput : 1;
|
bool x170_25_disablesInput : 1;
|
||||||
float x174_ = 0.f;
|
float x174_delayTime = 0.f;
|
||||||
float x178_ = 0.f;
|
float x178_ = 0.f;
|
||||||
float x17c_ = 0.f;
|
float x17c_ = 0.f;
|
||||||
float x180_;
|
float x180_;
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
void GetControllerNumber() const;
|
void GetControllerNumber() const;
|
||||||
bool DisablesInput() const;
|
bool DisablesInput() const;
|
||||||
void UpdatePerspective(float);
|
void UpdatePerspective(float);
|
||||||
void SetFovInterpolation(float start, float end, float time, float f4);
|
void SetFovInterpolation(float start, float end, float time, float delayTime);
|
||||||
void SkipFovInterpolation();
|
void SkipFovInterpolation();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,7 @@ public:
|
||||||
SAdvancementDeltas UpdateAdditiveAnims(float);
|
SAdvancementDeltas UpdateAdditiveAnims(float);
|
||||||
bool IsAdditiveAnimation(u32) const;
|
bool IsAdditiveAnimation(u32) const;
|
||||||
bool IsAdditiveAnimationAdded(u32) const;
|
bool IsAdditiveAnimationAdded(u32) const;
|
||||||
|
const std::shared_ptr<CAnimTreeNode>& GetRootAnimationTree() const { return x1f8_animRoot; }
|
||||||
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(u32) const;
|
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(u32) const;
|
||||||
bool IsAdditiveAnimationActive(u32) const;
|
bool IsAdditiveAnimationActive(u32) const;
|
||||||
void DelAdditiveAnimation(u32);
|
void DelAdditiveAnimation(u32);
|
||||||
|
|
|
@ -146,7 +146,7 @@ rstl::optional_object<zeus::CAABox> CCollisionActor::GetTouchBounds() const
|
||||||
else if (x258_primitiveType == EPrimitiveType::AABox)
|
else if (x258_primitiveType == EPrimitiveType::AABox)
|
||||||
aabox = {x280_aaboxPrimitive->CalculateAABox(x34_transform)};
|
aabox = {x280_aaboxPrimitive->CalculateAABox(x34_transform)};
|
||||||
else if (x258_primitiveType == EPrimitiveType::Sphere)
|
else if (x258_primitiveType == EPrimitiveType::Sphere)
|
||||||
aabox = {x280_aaboxPrimitive->CalculateAABox(x34_transform)};
|
aabox = {x284_spherePrimitive->CalculateAABox(x34_transform)};
|
||||||
|
|
||||||
aabox->accumulateBounds(aabox->max + x304_extendedTouchBounds);
|
aabox->accumulateBounds(aabox->max + x304_extendedTouchBounds);
|
||||||
aabox->accumulateBounds(aabox->min - x304_extendedTouchBounds);
|
aabox->accumulateBounds(aabox->min - x304_extendedTouchBounds);
|
||||||
|
|
|
@ -7,7 +7,7 @@ CSimpleShadow::CSimpleShadow(float, float, float, float)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimpleShadow::Render(const CTexture* tex)
|
void CSimpleShadow::Render(const CTexture* tex) const
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ class CSimpleShadow
|
||||||
public:
|
public:
|
||||||
CSimpleShadow() = default;
|
CSimpleShadow() = default;
|
||||||
CSimpleShadow(float, float, float, float);
|
CSimpleShadow(float, float, float, float);
|
||||||
void Render(const CTexture* tex);
|
void Render(const CTexture* tex) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ void CFluidPlaneShader::PrepareBinding(const boo::ObjToken<boo::IShaderPipeline>
|
||||||
[&](boo::IGraphicsDataFactory::Context& ctx)
|
[&](boo::IGraphicsDataFactory::Context& ctx)
|
||||||
{
|
{
|
||||||
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), maxVertCount);
|
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), maxVertCount);
|
||||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, 1024, 1);
|
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
|
||||||
|
|
||||||
switch (ctx.platform())
|
switch (ctx.platform())
|
||||||
{
|
{
|
||||||
|
|
|
@ -460,8 +460,15 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
||||||
|
|
||||||
combiner += " colorOut.a = kColor0.a;\n";
|
combiner += " colorOut.a = kColor0.a;\n";
|
||||||
|
|
||||||
finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
char *finalVSs, *finalFSs;
|
||||||
finalFS = hecl::Format(FS, textures.c_str(), combiner.c_str());
|
asprintf(&finalVSs, VS, additionalTCGs.c_str());
|
||||||
|
asprintf(&finalFSs, FS, textures.c_str(), combiner.c_str());
|
||||||
|
|
||||||
|
finalVS = finalVSs;
|
||||||
|
finalFS = finalFSs;
|
||||||
|
|
||||||
|
free(finalVSs);
|
||||||
|
free(finalFSs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTex, const char* texNames[3],
|
static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTex, const char* texNames[3],
|
||||||
|
@ -505,8 +512,15 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
||||||
|
|
||||||
combiner += " colorOut.a = kColor0.a;\n";
|
combiner += " colorOut.a = kColor0.a;\n";
|
||||||
|
|
||||||
finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
char *finalVSs, *finalFSs;
|
||||||
finalFS = hecl::Format(FSDoor, textures.c_str(), combiner.c_str());
|
asprintf(&finalVSs, VS, additionalTCGs.c_str());
|
||||||
|
asprintf(&finalFSs, FSDoor, textures.c_str(), combiner.c_str());
|
||||||
|
|
||||||
|
finalVS = finalVSs;
|
||||||
|
finalFS = finalFSs;
|
||||||
|
|
||||||
|
free(finalVSs);
|
||||||
|
free(finalFSs);
|
||||||
}
|
}
|
||||||
|
|
||||||
boo::ObjToken<boo::IShaderPipeline>
|
boo::ObjToken<boo::IShaderPipeline>
|
||||||
|
|
|
@ -456,14 +456,20 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
|
|
||||||
combiner += " colorOut.a = kColor0.a;\n";
|
combiner += " colorOut.a = kColor0.a;\n";
|
||||||
|
|
||||||
std::string finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
char *finalVS, *finalFS;
|
||||||
std::string finalFS = hecl::Format(FS, textures.c_str(), combiner.c_str());
|
asprintf(&finalVS, VS, additionalTCGs.c_str());
|
||||||
|
asprintf(&finalFS, FS, textures.c_str(), combiner.c_str());
|
||||||
|
|
||||||
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), nullptr, nullptr, nullptr, s_vtxFmt,
|
auto ret = ctx.newShaderPipeline(finalVS, finalFS, nullptr, nullptr, nullptr, s_vtxFmt,
|
||||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
||||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
||||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
boo::CullMode::None);
|
boo::CullMode::None);
|
||||||
|
|
||||||
|
free(finalVS);
|
||||||
|
free(finalFS);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
boo::ObjToken<boo::IShaderPipeline>
|
boo::ObjToken<boo::IShaderPipeline>
|
||||||
|
@ -512,13 +518,19 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
|
|
||||||
combiner += " colorOut.a = kColor0.a;\n";
|
combiner += " colorOut.a = kColor0.a;\n";
|
||||||
|
|
||||||
std::string finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
char *finalVS, *finalFS;
|
||||||
std::string finalFS = hecl::Format(FSDoor, textures.c_str(), combiner.c_str());
|
asprintf(&finalVS, VS, additionalTCGs.c_str());
|
||||||
|
asprintf(&finalFS, FSDoor, textures.c_str(), combiner.c_str());
|
||||||
|
|
||||||
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), nullptr, nullptr, nullptr, s_vtxFmt,
|
auto ret = ctx.newShaderPipeline(finalVS, finalFS, nullptr, nullptr, nullptr, s_vtxFmt,
|
||||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
boo::CullMode::None);
|
boo::CullMode::None);
|
||||||
|
|
||||||
|
free(finalVS);
|
||||||
|
free(finalFS);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
boo::ObjToken<boo::IShaderDataBinding>
|
boo::ObjToken<boo::IShaderDataBinding>
|
||||||
|
|
|
@ -17,7 +17,7 @@ static const char* VS =
|
||||||
" float4 colorIn [[ attribute(4) ]];\n"
|
" float4 colorIn [[ attribute(4) ]];\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"UBINDING0 uniform FluidPlaneUniform\n"
|
"struct FluidPlaneUniform\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float4x4 mv;\n"
|
" float4x4 mv;\n"
|
||||||
" float4x4 mvNorm;\n"
|
" float4x4 mvNorm;\n"
|
||||||
|
@ -27,13 +27,19 @@ static const char* VS =
|
||||||
"\n"
|
"\n"
|
||||||
"struct VertToFrag\n"
|
"struct VertToFrag\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float4 pos : [[ position ]];\n"
|
" float4 pos [[ position ]];\n"
|
||||||
" float4 mvPos;\n"
|
" float4 mvPos;\n"
|
||||||
" float4 mvNorm;\n"
|
" float4 mvNorm;\n"
|
||||||
" float4 mvBinorm;\n"
|
" float4 mvBinorm;\n"
|
||||||
" float4 mvTangent;\n"
|
" float4 mvTangent;\n"
|
||||||
" float4 color;\n"
|
" float4 color;\n"
|
||||||
" float2 uvs[7];\n"
|
" float2 uv0;\n"
|
||||||
|
" float2 uv1;\n"
|
||||||
|
" float2 uv2;\n"
|
||||||
|
" float2 uv3;\n"
|
||||||
|
" float2 uv4;\n"
|
||||||
|
" float2 uv5;\n"
|
||||||
|
" float2 uv6;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"vertex VertToFrag vmain(VertData v [[ stage_in ]],\n"
|
"vertex VertToFrag vmain(VertData v [[ stage_in ]],\n"
|
||||||
|
@ -46,9 +52,9 @@ static const char* VS =
|
||||||
" vtf.mvBinorm = fu.mvNorm * v.binormalIn;\n"
|
" vtf.mvBinorm = fu.mvNorm * v.binormalIn;\n"
|
||||||
" vtf.mvTangent = fu.mvNorm * v.tangentIn;\n"
|
" vtf.mvTangent = fu.mvNorm * v.tangentIn;\n"
|
||||||
" vtf.color = v.colorIn;\n"
|
" vtf.color = v.colorIn;\n"
|
||||||
" vtf.uvs[0] = (fu.texMtxs[0] * v.posIn).xy;\n"
|
" vtf.uv0 = (fu.texMtxs[0] * v.posIn).xy;\n"
|
||||||
" vtf.uvs[1] = (fu.texMtxs[1] * v.posIn).xy;\n"
|
" vtf.uv1 = (fu.texMtxs[1] * v.posIn).xy;\n"
|
||||||
" vtf.uvs[2] = (fu.texMtxs[2] * v.posIn).xy;\n"
|
" vtf.uv2 = (fu.texMtxs[2] * v.posIn).xy;\n"
|
||||||
"%s" // Additional TCGs here
|
"%s" // Additional TCGs here
|
||||||
" return vtf;\n"
|
" return vtf;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
@ -107,13 +113,19 @@ static const char* FS =
|
||||||
"\n"
|
"\n"
|
||||||
"struct VertToFrag\n"
|
"struct VertToFrag\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float4 pos : [[ position ]];\n"
|
" float4 pos [[ position ]];\n"
|
||||||
" float4 mvPos;\n"
|
" float4 mvPos;\n"
|
||||||
" float4 mvNorm;\n"
|
" float4 mvNorm;\n"
|
||||||
" float4 mvBinorm;\n"
|
" float4 mvBinorm;\n"
|
||||||
" float4 mvTangent;\n"
|
" float4 mvTangent;\n"
|
||||||
" float4 color;\n"
|
" float4 color;\n"
|
||||||
" float2 uvs[7];\n"
|
" float2 uv0;\n"
|
||||||
|
" float2 uv1;\n"
|
||||||
|
" float2 uv2;\n"
|
||||||
|
" float2 uv3;\n"
|
||||||
|
" float2 uv4;\n"
|
||||||
|
" float2 uv5;\n"
|
||||||
|
" float2 uv6;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
|
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
|
||||||
|
@ -130,18 +142,51 @@ static const char* FSDoor =
|
||||||
"using namespace metal;\n"
|
"using namespace metal;\n"
|
||||||
"constexpr sampler samp(address::repeat, filter::linear);\n"
|
"constexpr sampler samp(address::repeat, filter::linear);\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"struct Light\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 pos;\n"
|
||||||
|
" float4 dir;\n"
|
||||||
|
" float4 color;\n"
|
||||||
|
" float4 linAtt;\n"
|
||||||
|
" float4 angAtt;\n"
|
||||||
|
"};\n"
|
||||||
|
"struct Fog\n" // Reappropriated for indirect texture scaling
|
||||||
|
"{\n"
|
||||||
|
" float4 color;\n"
|
||||||
|
" float indScale;\n"
|
||||||
|
" float start;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"struct LightingUniform\n"
|
||||||
|
"{\n"
|
||||||
|
" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n"
|
||||||
|
" float4 ambient;\n"
|
||||||
|
" float4 kColor0;\n"
|
||||||
|
" float4 kColor1;\n"
|
||||||
|
" float4 kColor2;\n"
|
||||||
|
" float4 kColor3;\n"
|
||||||
|
" Fog fog;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
"struct VertToFrag\n"
|
"struct VertToFrag\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float4 pos : [[ position ]];\n"
|
" float4 pos [[ position ]];\n"
|
||||||
" float4 mvPos;\n"
|
" float4 mvPos;\n"
|
||||||
" float4 mvNorm;\n"
|
" float4 mvNorm;\n"
|
||||||
" float4 mvBinorm;\n"
|
" float4 mvBinorm;\n"
|
||||||
" float4 mvTangent;\n"
|
" float4 mvTangent;\n"
|
||||||
" float4 color;\n"
|
" float4 color;\n"
|
||||||
" float2 uvs[7];\n"
|
" float2 uv0;\n"
|
||||||
|
" float2 uv1;\n"
|
||||||
|
" float2 uv2;\n"
|
||||||
|
" float2 uv3;\n"
|
||||||
|
" float2 uv4;\n"
|
||||||
|
" float2 uv5;\n"
|
||||||
|
" float2 uv6;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]]%s)\n" // Textures here
|
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
|
||||||
|
" constant LightingUniform& lu [[ buffer(4) ]]%s)\n" // Textures here
|
||||||
"{\n"
|
"{\n"
|
||||||
" float4 colorOut;\n"
|
" float4 colorOut;\n"
|
||||||
"%s" // Combiner expression here
|
"%s" // Combiner expression here
|
||||||
|
@ -190,22 +235,22 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
if (info.m_hasBumpMap)
|
if (info.m_hasBumpMap)
|
||||||
{
|
{
|
||||||
bumpMapUv = nextTCG;
|
bumpMapUv = nextTCG;
|
||||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (fu.texMtxs[0] * v.posIn).xy;\n", nextTCG++);
|
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[0] * v.posIn).xy;\n", nextTCG++);
|
||||||
}
|
}
|
||||||
if (info.m_hasEnvBumpMap)
|
if (info.m_hasEnvBumpMap)
|
||||||
{
|
{
|
||||||
envBumpMapUv = nextTCG;
|
envBumpMapUv = nextTCG;
|
||||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (fu.texMtxs[3] * v.posIn).xy;\n", nextTCG++);
|
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[3] * v.posIn).xy;\n", nextTCG++);
|
||||||
}
|
}
|
||||||
if (info.m_hasEnvMap)
|
if (info.m_hasEnvMap)
|
||||||
{
|
{
|
||||||
envMapUv = nextTCG;
|
envMapUv = nextTCG;
|
||||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (fu.texMtxs[%d] * v.posIn).xy;\n", nextTCG++, nextMtx++);
|
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[%d] * v.posIn).xy;\n", nextTCG++, nextMtx++);
|
||||||
}
|
}
|
||||||
if (info.m_hasLightmap)
|
if (info.m_hasLightmap)
|
||||||
{
|
{
|
||||||
lightmapUv = nextTCG;
|
lightmapUv = nextTCG;
|
||||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (fu.texMtxs[%d] * v.posIn).xy;\n", nextTCG++, nextMtx++);
|
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[%d] * v.posIn).xy;\n", nextTCG++, nextMtx++);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (info.m_type)
|
switch (info.m_type)
|
||||||
|
@ -215,7 +260,7 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
case CFluidPlane::EFluidType::Four:
|
case CFluidPlane::EFluidType::Four:
|
||||||
if (info.m_hasLightmap)
|
if (info.m_hasLightmap)
|
||||||
{
|
{
|
||||||
combiner += hecl::Format(" float4 lightMapTexel = lightMap.sample(samp, vtf.uvs[%d]);\n", lightmapUv);
|
combiner += hecl::Format(" float4 lightMapTexel = lightMap.sample(samp, vtf.uv%d);\n", lightmapUv);
|
||||||
// 0: Tex4TCG, Tex4, doubleLightmapBlend ? NULL : GX_COLOR1A1
|
// 0: Tex4TCG, Tex4, doubleLightmapBlend ? NULL : GX_COLOR1A1
|
||||||
// ZERO, TEX, KONST, doubleLightmapBlend ? ZERO : RAS
|
// ZERO, TEX, KONST, doubleLightmapBlend ? ZERO : RAS
|
||||||
// Output reg 2
|
// Output reg 2
|
||||||
|
@ -253,10 +298,10 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
if (info.m_hasPatternTex2)
|
if (info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
if (info.m_hasPatternTex1)
|
if (info.m_hasPatternTex1)
|
||||||
combiner += " colorOut = (patternTex1.sample(samp, vtf.uvs[0]) * lu.kColor0 + lighting) *\n"
|
combiner += " colorOut = (patternTex1.sample(samp, vtf.uv0) * lu.kColor0 + lighting) *\n"
|
||||||
" patternTex2.sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
" patternTex2.sample(samp, vtf.uv1) + vtf.color;\n";
|
||||||
else
|
else
|
||||||
combiner += " colorOut = lighting * patternTex2.sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
combiner += " colorOut = lighting * patternTex2.sample(samp, vtf.uv1) + vtf.color;\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -267,9 +312,9 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
if (info.m_hasColorTex && !info.m_hasEnvMap && info.m_hasEnvBumpMap)
|
if (info.m_hasColorTex && !info.m_hasEnvMap && info.m_hasEnvBumpMap)
|
||||||
{
|
{
|
||||||
// Make previous stage indirect, mtx0
|
// Make previous stage indirect, mtx0
|
||||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uv%d).ra - float2(0.5, 0.5)) *\n"
|
||||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
||||||
combiner += " colorOut += colorTex.sample(samp, indUvs + vtf.uvs[2]) * lighting;\n";
|
combiner += " colorOut += colorTex.sample(samp, indUvs + vtf.uv2) * lighting;\n";
|
||||||
}
|
}
|
||||||
else if (info.m_hasEnvMap)
|
else if (info.m_hasEnvMap)
|
||||||
{
|
{
|
||||||
|
@ -280,15 +325,15 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
|
|
||||||
// Make previous stage indirect, mtx0
|
// Make previous stage indirect, mtx0
|
||||||
if (info.m_hasColorTex)
|
if (info.m_hasColorTex)
|
||||||
combiner += " colorOut += colorTex.sample(samp, vtf.uvs[2]) * lighting;\n";
|
combiner += " colorOut += colorTex.sample(samp, vtf.uv2) * lighting;\n";
|
||||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uv%d).ra - float2(0.5, 0.5)) *\n"
|
||||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
||||||
combiner += hecl::Format(" colorOut = mix(colorOut, envMap.sample(samp, indUvs + vtf.uvs[%d]), lu.kColor1);\n",
|
combiner += hecl::Format(" colorOut = mix(colorOut, envMap.sample(samp, indUvs + vtf.uv%d), lu.kColor1);\n",
|
||||||
envMapUv);
|
envMapUv);
|
||||||
}
|
}
|
||||||
else if (info.m_hasColorTex)
|
else if (info.m_hasColorTex)
|
||||||
{
|
{
|
||||||
combiner += " colorOut += colorTex.sample(samp, vtf.uvs[2]) * lighting;\n";
|
combiner += " colorOut += colorTex.sample(samp, vtf.uv2) * lighting;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -296,7 +341,7 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
case CFluidPlane::EFluidType::PoisonWater:
|
case CFluidPlane::EFluidType::PoisonWater:
|
||||||
if (info.m_hasLightmap)
|
if (info.m_hasLightmap)
|
||||||
{
|
{
|
||||||
combiner += hecl::Format(" float4 lightMapTexel = lightMap.sample(samp, vtf.uvs[%d]);\n", lightmapUv);
|
combiner += hecl::Format(" float4 lightMapTexel = lightMap.sample(samp, vtf.uv%d);\n", lightmapUv);
|
||||||
// 0: Tex4TCG, Tex4, doubleLightmapBlend ? NULL : GX_COLOR1A1
|
// 0: Tex4TCG, Tex4, doubleLightmapBlend ? NULL : GX_COLOR1A1
|
||||||
// ZERO, TEX, KONST, doubleLightmapBlend ? ZERO : RAS
|
// ZERO, TEX, KONST, doubleLightmapBlend ? ZERO : RAS
|
||||||
// Output reg 2
|
// Output reg 2
|
||||||
|
@ -334,10 +379,10 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
if (info.m_hasPatternTex2)
|
if (info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
if (info.m_hasPatternTex1)
|
if (info.m_hasPatternTex1)
|
||||||
combiner += " colorOut = (patternTex1.sample(samp, vtf.uvs[0]) * lu.kColor0 + lighting) *\n"
|
combiner += " colorOut = (patternTex1.sample(samp, vtf.uv0) * lu.kColor0 + lighting) *\n"
|
||||||
" patternTex2.sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
" patternTex2.sample(samp, vtf.uv1) + vtf.color;\n";
|
||||||
else
|
else
|
||||||
combiner += " colorOut = lighting * patternTex2.sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
combiner += " colorOut = lighting * patternTex2.sample(samp, vtf.uv1) + vtf.color;\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -349,13 +394,13 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
if (info.m_hasEnvBumpMap)
|
if (info.m_hasEnvBumpMap)
|
||||||
{
|
{
|
||||||
// Make previous stage indirect, mtx0
|
// Make previous stage indirect, mtx0
|
||||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uv%d).ra - float2(0.5, 0.5)) *\n"
|
||||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
||||||
combiner += " colorOut += colorTex.sample(samp, indUvs + vtf.uvs[2]) * lighting;\n";
|
combiner += " colorOut += colorTex.sample(samp, indUvs + vtf.uv2) * lighting;\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
combiner += " colorOut += colorTex.sample(samp, vtf.uvs[2]) * lighting;\n";
|
combiner += " colorOut += colorTex.sample(samp, vtf.uv2) * lighting;\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,10 +424,10 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
if (info.m_hasPatternTex2)
|
if (info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
if (info.m_hasPatternTex1)
|
if (info.m_hasPatternTex1)
|
||||||
combiner += " colorOut = (patternTex1.sample(samp, vtf.uvs[0]) * lu.kColor0 + vtf.color) *\n"
|
combiner += " colorOut = (patternTex1.sample(samp, vtf.uv0) * lu.kColor0 + vtf.color) *\n"
|
||||||
" patternTex2.sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
" patternTex2.sample(samp, vtf.uv1) + vtf.color;\n";
|
||||||
else
|
else
|
||||||
combiner += " colorOut = vtf.color * patternTex2.sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
combiner += " colorOut = vtf.color * patternTex2.sample(samp, vtf.uv1) + vtf.color;\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -390,7 +435,7 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.m_hasColorTex)
|
if (info.m_hasColorTex)
|
||||||
combiner += " colorOut += colorTex.sample(samp, vtf.uvs[2]);\n";
|
combiner += " colorOut += colorTex.sample(samp, vtf.uv2);\n";
|
||||||
|
|
||||||
if (info.m_hasBumpMap)
|
if (info.m_hasBumpMap)
|
||||||
{
|
{
|
||||||
|
@ -405,8 +450,8 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
combiner += " float3 lightVec = lights[3].pos.xyz - vtf.mvPos.xyz;\n"
|
combiner += " float3 lightVec = lights[3].pos.xyz - vtf.mvPos.xyz;\n"
|
||||||
" float lx = dot(vtf.mvTangent.xyz, lightVec);\n"
|
" float lx = dot(vtf.mvTangent.xyz, lightVec);\n"
|
||||||
" float ly = dot(vtf.mvBinorm.xyz, lightVec);\n";
|
" float ly = dot(vtf.mvBinorm.xyz, lightVec);\n";
|
||||||
combiner += hecl::Format(" float4 emboss1 = bumpMap.sample(samp, vtf.uvs[%d]) + float4(0.5);\n"
|
combiner += hecl::Format(" float4 emboss1 = bumpMap.sample(samp, vtf.uv%d) + float4(0.5);\n"
|
||||||
" float4 emboss2 = bumpMap.sample(samp, vtf.uvs[%d] + float2(lx, ly));\n",
|
" float4 emboss2 = bumpMap.sample(samp, vtf.uv%d + float2(lx, ly));\n",
|
||||||
bumpMapUv, bumpMapUv);
|
bumpMapUv, bumpMapUv);
|
||||||
|
|
||||||
// 5: NULL, NULL, NULL
|
// 5: NULL, NULL, NULL
|
||||||
|
@ -437,10 +482,10 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
if (info.m_hasPatternTex2)
|
if (info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
if (info.m_hasPatternTex1)
|
if (info.m_hasPatternTex1)
|
||||||
combiner += " colorOut = (patternTex1.sample(samp, vtf.uvs[0]) * lu.kColor0 + vtf.color) *\n"
|
combiner += " colorOut = (patternTex1.sample(samp, vtf.uv0) * lu.kColor0 + vtf.color) *\n"
|
||||||
" patternTex2.sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
" patternTex2.sample(samp, vtf.uv1) + vtf.color;\n";
|
||||||
else
|
else
|
||||||
combiner += " colorOut = vtf.color * patternTex2.sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
combiner += " colorOut = vtf.color * patternTex2.sample(samp, vtf.uv1) + vtf.color;\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -448,31 +493,37 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.m_hasColorTex)
|
if (info.m_hasColorTex)
|
||||||
combiner += " colorOut += colorTex.sample(samp, vtf.uvs[2]);\n";
|
combiner += " colorOut += colorTex.sample(samp, vtf.uv2);\n";
|
||||||
|
|
||||||
if (info.m_hasBumpMap)
|
if (info.m_hasBumpMap)
|
||||||
{
|
{
|
||||||
// 3: bumpMapTCG, bumpMap, NULL
|
// 3: bumpMapTCG, bumpMap, NULL
|
||||||
// ZERO, TEX, PREV, ZERO
|
// ZERO, TEX, PREV, ZERO
|
||||||
// Output reg prev, scale 2
|
// Output reg prev, scale 2
|
||||||
combiner += hecl::Format(" float4 emboss1 = bumpMap.sample(samp, vtf.uvs[%d]) + float4(0.5);\n", bumpMapUv);
|
combiner += hecl::Format(" float4 emboss1 = bumpMap.sample(samp, vtf.uv%d) + float4(0.5);\n", bumpMapUv);
|
||||||
combiner += "colorOut *= emboss1 * float4(2.0);\n";
|
combiner += "colorOut *= emboss1 * float4(2.0);\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
combiner += " colorOut.a = kColor0.a;\n";
|
combiner += " colorOut.a = lu.kColor0.a;\n";
|
||||||
|
|
||||||
std::string finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
char *finalVS, *finalFS;
|
||||||
std::string finalFS = hecl::Format(FS, textures.c_str(), combiner.c_str());
|
asprintf(&finalVS, VS, additionalTCGs.c_str());
|
||||||
|
asprintf(&finalFS, FS, textures.c_str(), combiner.c_str());
|
||||||
|
|
||||||
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), nullptr, nullptr,
|
auto ret = ctx.newShaderPipeline(finalVS, finalFS, nullptr, nullptr,
|
||||||
s_vtxFmt, CGraphics::g_ViewportSamples,
|
s_vtxFmt, CGraphics::g_ViewportSamples,
|
||||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
||||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
||||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
boo::CullMode::None);
|
boo::CullMode::None);
|
||||||
|
|
||||||
|
free(finalVS);
|
||||||
|
free(finalFS);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
boo::ObjToken<boo::IShaderPipeline>
|
boo::ObjToken<boo::IShaderPipeline>
|
||||||
|
@ -506,8 +557,8 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
// Tex0 * kColor0 * Tex1 + Tex2
|
// Tex0 * kColor0 * Tex1 + Tex2
|
||||||
if (info.m_hasPatternTex1 && info.m_hasPatternTex2)
|
if (info.m_hasPatternTex1 && info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
combiner += " colorOut = patternTex1.sample(samp, vtf.uvs[0]) * lu.kColor0 *\n"
|
combiner += " colorOut = patternTex1.sample(samp, vtf.uv0) * lu.kColor0 *\n"
|
||||||
" patternTex2.sample(samp, vtf.uvs[1]);\n";
|
" patternTex2.sample(samp, vtf.uv1);\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -516,19 +567,25 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
|
|
||||||
if (info.m_hasColorTex)
|
if (info.m_hasColorTex)
|
||||||
{
|
{
|
||||||
combiner += " colorOut += colorTex.sample(samp, vtf.uvs[2]);\n";
|
combiner += " colorOut += colorTex.sample(samp, vtf.uv2);\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
combiner += " colorOut.a = kColor0.a;\n";
|
combiner += " colorOut.a = lu.kColor0.a;\n";
|
||||||
|
|
||||||
std::string finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
char *finalVS, *finalFS;
|
||||||
std::string finalFS = hecl::Format(FSDoor, textures.c_str(), combiner.c_str());
|
asprintf(&finalVS, VS, additionalTCGs.c_str());
|
||||||
|
asprintf(&finalFS, FSDoor, textures.c_str(), combiner.c_str());
|
||||||
|
|
||||||
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), nullptr, nullptr,
|
auto ret = ctx.newShaderPipeline(finalVS, finalFS, nullptr, nullptr,
|
||||||
s_vtxFmt, CGraphics::g_ViewportSamples,
|
s_vtxFmt, CGraphics::g_ViewportSamples,
|
||||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
boo::CullMode::None);
|
boo::CullMode::None);
|
||||||
|
|
||||||
|
free(finalVS);
|
||||||
|
free(finalFS);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
boo::ObjToken<boo::IShaderDataBinding> CFluidPlaneShader::BuildBinding(boo::MetalDataFactory::Context& ctx,
|
boo::ObjToken<boo::IShaderDataBinding> CFluidPlaneShader::BuildBinding(boo::MetalDataFactory::Context& ctx,
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "IOStreams.hpp"
|
#include "IOStreams.hpp"
|
||||||
#include "hecl/hecl.hpp"
|
#include "hecl/hecl.hpp"
|
||||||
|
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,12 @@ public:
|
||||||
ArmCannon = (1 << 11),
|
ArmCannon = (1 << 11),
|
||||||
BigStrike = (1 << 12),
|
BigStrike = (1 << 12),
|
||||||
StaticInterference = (1 << 14),
|
StaticInterference = (1 << 14),
|
||||||
|
KeepInCinematic = (1 << 17),
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EProjectileAttrib xe8_projectileAttribs;
|
EProjectileAttrib xe8_projectileAttribs;
|
||||||
TUniqueId xec_uid;
|
TUniqueId xec_ownerId;
|
||||||
EWeaponType xf0_weaponType;
|
EWeaponType xf0_weaponType;
|
||||||
u32 xf4_;
|
u32 xf4_;
|
||||||
CMaterialFilter xf8_;
|
CMaterialFilter xf8_;
|
||||||
|
@ -52,8 +53,8 @@ public:
|
||||||
EProjectileAttrib GetAttribField() const { return xe8_projectileAttribs; }
|
EProjectileAttrib GetAttribField() const { return xe8_projectileAttribs; }
|
||||||
const CMaterialFilter& GetFilter() const;
|
const CMaterialFilter& GetFilter() const;
|
||||||
void SetFilter(const CMaterialFilter&);
|
void SetFilter(const CMaterialFilter&);
|
||||||
TUniqueId GetOwnerId() const;
|
TUniqueId GetOwnerId() const { return xec_ownerId; }
|
||||||
void SetOwnerId(TUniqueId);
|
void SetOwnerId(TUniqueId oid) { xec_ownerId = oid; }
|
||||||
EWeaponType GetType() const;
|
EWeaponType GetType() const;
|
||||||
const CDamageInfo& GetDamageInfo() const;
|
const CDamageInfo& GetDamageInfo() const;
|
||||||
CDamageInfo& DamageInfo();
|
CDamageInfo& DamageInfo();
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "Character/IAnimReader.hpp"
|
#include "Character/IAnimReader.hpp"
|
||||||
#include "Character/CActorLights.hpp"
|
#include "Character/CActorLights.hpp"
|
||||||
#include "Camera/CGameCamera.hpp"
|
#include "Camera/CGameCamera.hpp"
|
||||||
|
#include "GameGlobalObjects.hpp"
|
||||||
|
#include "CSimplePool.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -27,9 +29,38 @@ CActor::CActor(TUniqueId uid, bool active, std::string_view name, const CEntityI
|
||||||
, x70_materialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}))
|
, x70_materialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}))
|
||||||
, xc6_nextDrawNode(otherUid)
|
, xc6_nextDrawNode(otherUid)
|
||||||
{
|
{
|
||||||
|
x90_actorLights = mData.IsNull() ? std::unique_ptr<CActorLights>() : params.x0_lightParms.MakeActorLights();
|
||||||
if (mData.x10_animData || mData.x1c_normalModel)
|
if (mData.x10_animData || mData.x1c_normalModel)
|
||||||
x64_modelData = std::make_unique<CModelData>(std::move(mData));
|
x64_modelData = std::make_unique<CModelData>(std::move(mData));
|
||||||
|
xd0_ = params.x64_;
|
||||||
xd8_nonLoopingSfxHandles.resize(2);
|
xd8_nonLoopingSfxHandles.resize(2);
|
||||||
|
xe4_27_ = true;
|
||||||
|
xe4_28_ = true;
|
||||||
|
xe4_29_actorLightsDirty = true;
|
||||||
|
xe4_31_lightsDirty = true;
|
||||||
|
xe5_27_useInSortedLists = true;
|
||||||
|
xe5_28_callTouch = true;
|
||||||
|
xe5_29_ = params.x58_24_;
|
||||||
|
xe5_30_ = params.x58_26_;
|
||||||
|
xe6_27_renderVisorFlags = u8(params.x58_25_thermalHeat ? 2 : 1);
|
||||||
|
xe6_29_ = true;
|
||||||
|
xe6_31_targetableVisorFlags = params.GetVisorParameters().GetMask();
|
||||||
|
xe7_27_ = true;
|
||||||
|
xe7_29_actorActive = active;
|
||||||
|
xe7_30_doTargetDistanceTest = true;
|
||||||
|
xe7_31_targetable = true;
|
||||||
|
if (x64_modelData)
|
||||||
|
{
|
||||||
|
if (params.x44_xrayAssets.first.IsValid())
|
||||||
|
x64_modelData->SetXRayModel(params.x44_xrayAssets);
|
||||||
|
if (params.x4c_thermalAssets.first.IsValid())
|
||||||
|
x64_modelData->SetInfraModel(params.x4c_thermalAssets);
|
||||||
|
if (!params.x0_lightParms.x1c_makeLights || params.x0_lightParms.x3c_maxAreaLights == 0)
|
||||||
|
x64_modelData->x18_ambientColor = params.x0_lightParms.x18_noLightsAmbient;
|
||||||
|
x64_modelData->x14_25_sortThermal = !params.x58_27_noSortThermal;
|
||||||
|
}
|
||||||
|
if (params.x40_scanParms.GetScanId().IsValid())
|
||||||
|
x98_scanObjectInfo = g_SimplePool->GetObj(SObjectTag{FOURCC('SCAN'), params.x40_scanParms.GetScanId()});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
void CActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
||||||
|
@ -499,14 +530,9 @@ bool CActor::CanDrawStatic() const
|
||||||
|
|
||||||
const CScannableObjectInfo* CActor::GetScannableObjectInfo() const
|
const CScannableObjectInfo* CActor::GetScannableObjectInfo() const
|
||||||
{
|
{
|
||||||
if (!x98_scanObjectInfo)
|
if (!x98_scanObjectInfo || !x98_scanObjectInfo.IsLoaded())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
return x98_scanObjectInfo.GetObj();
|
||||||
TToken<CScannableObjectInfo>& info = *x98_scanObjectInfo;
|
|
||||||
if (!info || !info.IsLoaded())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return info.GetObj();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CActor::SetCalculateLighting(bool c)
|
void CActor::SetCalculateLighting(bool c)
|
||||||
|
|
|
@ -36,15 +36,15 @@ protected:
|
||||||
CSfxHandle x8c_loopingSfxHandle;
|
CSfxHandle x8c_loopingSfxHandle;
|
||||||
std::unique_ptr<CActorLights> x90_actorLights;
|
std::unique_ptr<CActorLights> x90_actorLights;
|
||||||
std::unique_ptr<CSimpleShadow> x94_simpleShadow;
|
std::unique_ptr<CSimpleShadow> x94_simpleShadow;
|
||||||
std::unique_ptr<TToken<CScannableObjectInfo>> x98_scanObjectInfo;
|
TLockedToken<CScannableObjectInfo> x98_scanObjectInfo;
|
||||||
zeus::CAABox x9c_renderBounds;
|
zeus::CAABox x9c_renderBounds;
|
||||||
CModelFlags xb4_drawFlags;
|
CModelFlags xb4_drawFlags;
|
||||||
float xbc_time = 0.f;
|
float xbc_time = 0.f;
|
||||||
float xc0_pitchBend = 0.f;
|
float xc0_pitchBend = 0.f;
|
||||||
TUniqueId xc4_fluidId = kInvalidUniqueId;
|
TUniqueId xc4_fluidId = kInvalidUniqueId;
|
||||||
TUniqueId xc6_nextDrawNode = kInvalidUniqueId;
|
TUniqueId xc6_nextDrawNode;
|
||||||
u32 xc8_drawnToken = -1;
|
int xc8_drawnToken = -1;
|
||||||
u32 xcc_addedToken = -1;
|
int xcc_addedToken = -1;
|
||||||
float xd0_;
|
float xd0_;
|
||||||
float xd4_maxVol = 1.f;
|
float xd4_maxVol = 1.f;
|
||||||
rstl::reserved_vector<CSfxHandle, 2> xd8_nonLoopingSfxHandles;
|
rstl::reserved_vector<CSfxHandle, 2> xd8_nonLoopingSfxHandles;
|
||||||
|
@ -63,14 +63,17 @@ protected:
|
||||||
bool xe5_26_muted : 1;
|
bool xe5_26_muted : 1;
|
||||||
bool xe5_27_useInSortedLists : 1;
|
bool xe5_27_useInSortedLists : 1;
|
||||||
bool xe5_28_callTouch : 1;
|
bool xe5_28_callTouch : 1;
|
||||||
|
bool xe5_29_ : 1;
|
||||||
|
bool xe5_30_ : 1;
|
||||||
bool xe5_31_ : 1;
|
bool xe5_31_ : 1;
|
||||||
u8 xe6_24_fluidCounter : 3;
|
u8 xe6_24_fluidCounter : 3;
|
||||||
u8 xe6_27_renderVisorFlags : 3; // 2: thermal cold, 4: thermal hot
|
u8 xe6_27_renderVisorFlags : 2; // 1: thermal cold, 2: thermal hot
|
||||||
|
bool xe6_29_ : 1;
|
||||||
bool xe6_30_enablePitchBend : 1;
|
bool xe6_30_enablePitchBend : 1;
|
||||||
u8 xe6_31_targetableVisorFlags : 4;
|
u8 xe6_31_targetableVisorFlags : 4;
|
||||||
bool xe7_27_ : 1;
|
bool xe7_27_ : 1;
|
||||||
bool xe7_28_worldLightingDirty : 1;
|
bool xe7_28_worldLightingDirty : 1;
|
||||||
bool xe7_29_ : 1;
|
bool xe7_29_actorActive : 1;
|
||||||
bool xe7_30_doTargetDistanceTest : 1;
|
bool xe7_30_doTargetDistanceTest : 1;
|
||||||
bool xe7_31_targetable : 1;
|
bool xe7_31_targetable : 1;
|
||||||
};
|
};
|
||||||
|
@ -94,8 +97,8 @@ public:
|
||||||
Done,
|
Done,
|
||||||
};
|
};
|
||||||
|
|
||||||
CActor(TUniqueId, bool, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
CActor(TUniqueId uid, bool active, std::string_view name, const CEntityInfo& info, const zeus::CTransform&,
|
||||||
const CMaterialList&, const CActorParameters&, TUniqueId);
|
CModelData&& mData, const CMaterialList& list, const CActorParameters& params, TUniqueId otherUid);
|
||||||
|
|
||||||
virtual void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
virtual void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||||
virtual void SetActive(bool active)
|
virtual void SetActive(bool active)
|
||||||
|
@ -103,7 +106,7 @@ public:
|
||||||
xe4_27_ = true;
|
xe4_27_ = true;
|
||||||
xe4_28_ = true;
|
xe4_28_ = true;
|
||||||
xe4_29_actorLightsDirty = true;
|
xe4_29_actorLightsDirty = true;
|
||||||
xe7_29_ = true;
|
xe7_29_actorActive = active;
|
||||||
CEntity::SetActive(active);
|
CEntity::SetActive(active);
|
||||||
}
|
}
|
||||||
virtual void PreRender(CStateManager&, const zeus::CFrustum&) {}
|
virtual void PreRender(CStateManager&, const zeus::CFrustum&) {}
|
||||||
|
@ -177,7 +180,7 @@ public:
|
||||||
const CActorLights* GetActorLights() const { return x90_actorLights.get(); }
|
const CActorLights* GetActorLights() const { return x90_actorLights.get(); }
|
||||||
CActorLights* ActorLights() { return x90_actorLights.get(); }
|
CActorLights* ActorLights() { return x90_actorLights.get(); }
|
||||||
bool CanDrawStatic() const;
|
bool CanDrawStatic() const;
|
||||||
bool GetE7_29() const { return xe7_29_; }
|
bool IsActorActive() const { return xe7_29_actorActive; }
|
||||||
void SetWorldLightingDirty(bool b) { xe7_28_worldLightingDirty = b; }
|
void SetWorldLightingDirty(bool b) { xe7_28_worldLightingDirty = b; }
|
||||||
const CScannableObjectInfo* GetScannableObjectInfo() const;
|
const CScannableObjectInfo* GetScannableObjectInfo() const;
|
||||||
const CHealthInfo* GetHealthInfo(const CStateManager& mgr) const
|
const CHealthInfo* GetHealthInfo(const CStateManager& mgr) const
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace urde
|
||||||
class CActorParameters
|
class CActorParameters
|
||||||
{
|
{
|
||||||
friend class ScriptLoader;
|
friend class ScriptLoader;
|
||||||
|
friend class CActor;
|
||||||
CLightParameters x0_lightParms;
|
CLightParameters x0_lightParms;
|
||||||
CScannableParameters x40_scanParms;
|
CScannableParameters x40_scanParms;
|
||||||
std::pair<CAssetId, CAssetId> x44_xrayAssets = {};
|
std::pair<CAssetId, CAssetId> x44_xrayAssets = {};
|
||||||
|
@ -23,7 +24,7 @@ class CActorParameters
|
||||||
bool x58_24_ : 1;
|
bool x58_24_ : 1;
|
||||||
bool x58_25_thermalHeat : 1;
|
bool x58_25_thermalHeat : 1;
|
||||||
bool x58_26_ : 1;
|
bool x58_26_ : 1;
|
||||||
bool x58_27_ : 1;
|
bool x58_27_noSortThermal : 1;
|
||||||
};
|
};
|
||||||
u32 _dummy = 0;
|
u32 _dummy = 0;
|
||||||
};
|
};
|
||||||
|
@ -32,7 +33,7 @@ class CActorParameters
|
||||||
float x64_ = 0.f;
|
float x64_ = 0.f;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CActorParameters() : x58_24_(true), x58_25_thermalHeat(false), x58_26_(false), x58_27_(false) {}
|
CActorParameters() : x58_24_(true), x58_25_thermalHeat(false), x58_26_(false), x58_27_noSortThermal(false) {}
|
||||||
CActorParameters(const CLightParameters& lightParms, const CScannableParameters& scanParms,
|
CActorParameters(const CLightParameters& lightParms, const CScannableParameters& scanParms,
|
||||||
const std::pair<CAssetId, CAssetId>& xrayAssets, const std::pair<CAssetId, CAssetId>& thermalAssets,
|
const std::pair<CAssetId, CAssetId>& xrayAssets, const std::pair<CAssetId, CAssetId>& thermalAssets,
|
||||||
const CVisorParameters& visorParms, bool b1, bool thermalHeat, bool c, bool d)
|
const CVisorParameters& visorParms, bool b1, bool thermalHeat, bool c, bool d)
|
||||||
|
@ -44,7 +45,7 @@ public:
|
||||||
, x58_24_(b1)
|
, x58_24_(b1)
|
||||||
, x58_25_thermalHeat(thermalHeat)
|
, x58_25_thermalHeat(thermalHeat)
|
||||||
, x58_26_(c)
|
, x58_26_(c)
|
||||||
, x58_27_(d)
|
, x58_27_noSortThermal(d)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
CActorParameters Scannable(const CScannableParameters& sParms) const
|
CActorParameters Scannable(const CScannableParameters& sParms) const
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace urde
|
||||||
|
|
||||||
class CLightParameters
|
class CLightParameters
|
||||||
{
|
{
|
||||||
|
friend class CActor;
|
||||||
public:
|
public:
|
||||||
enum class EShadowTesselation
|
enum class EShadowTesselation
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@ class CScannableParameters
|
||||||
public:
|
public:
|
||||||
CScannableParameters() = default;
|
CScannableParameters() = default;
|
||||||
CScannableParameters(CAssetId id) : x0_scanId(id) {}
|
CScannableParameters(CAssetId id) : x0_scanId(id) {}
|
||||||
|
CAssetId GetScanId() const { return x0_scanId; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ CScriptActor::CScriptActor(TUniqueId uid, std::string_view name, const CEntityIn
|
||||||
, x2e2_29_((x2e2_24_ && x2e2_25_dead && x2d8_ != 0))
|
, x2e2_29_((x2e2_24_ && x2e2_25_dead && x2d8_ != 0))
|
||||||
, x2e2_30_transposeRotate(b4)
|
, x2e2_30_transposeRotate(b4)
|
||||||
, x2e2_31_(b5)
|
, x2e2_31_(b5)
|
||||||
, x2e3_24_(false)
|
, x2e3_24_cameraMoveIntoAlpha(false)
|
||||||
{
|
{
|
||||||
if (x64_modelData && (x64_modelData->HasAnimData() || x64_modelData->HasNormalModel()) && castsShadow)
|
if (x64_modelData && (x64_modelData->HasAnimData() || x64_modelData->HasNormalModel()) && castsShadow)
|
||||||
CreateShadow(true);
|
CreateShadow(true);
|
||||||
|
|
|
@ -27,7 +27,7 @@ protected:
|
||||||
bool x2e2_29_ : 1;
|
bool x2e2_29_ : 1;
|
||||||
bool x2e2_30_transposeRotate : 1;
|
bool x2e2_30_transposeRotate : 1;
|
||||||
bool x2e2_31_ : 1;
|
bool x2e2_31_ : 1;
|
||||||
bool x2e3_24_ : 1;
|
bool x2e3_24_cameraMoveIntoAlpha : 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CScriptActor(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
CScriptActor(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
||||||
|
@ -44,7 +44,7 @@ public:
|
||||||
void Touch(CActor&, CStateManager&);
|
void Touch(CActor&, CStateManager&);
|
||||||
const CDamageVulnerability* GetDamageVulnerability() const { return &x268_damageVulnerability; }
|
const CDamageVulnerability* GetDamageVulnerability() const { return &x268_damageVulnerability; }
|
||||||
CHealthInfo* HealthInfo(CStateManager&) { return &x260_currentHealth; }
|
CHealthInfo* HealthInfo(CStateManager&) { return &x260_currentHealth; }
|
||||||
bool GetX2E3_24() const { return x2e3_24_; }
|
bool IsCameraMoveIntoAlpha() const { return x2e3_24_cameraMoveIntoAlpha; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,7 @@ void CScriptAiJumpPoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId oth
|
||||||
if (wpnt)
|
if (wpnt)
|
||||||
{
|
{
|
||||||
x10c_currentWaypoint = wpnt->GetUniqueId();
|
x10c_currentWaypoint = wpnt->GetUniqueId();
|
||||||
const CScriptWaypoint* nextWpnt = wpnt->NextWaypoint(mgr);
|
x10e_nextWaypoint = wpnt->NextWaypoint(mgr);
|
||||||
if (nextWpnt)
|
|
||||||
x10e_nextWaypoint = nextWpnt->GetUniqueId();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,10 @@ namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
CScriptCameraWaypoint::CScriptCameraWaypoint(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
CScriptCameraWaypoint::CScriptCameraWaypoint(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
||||||
const zeus::CTransform& xf, bool active, float f1, u32 w1)
|
const zeus::CTransform& xf, bool active, float hfov, u32 w1)
|
||||||
: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::Unknown),
|
: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::Unknown),
|
||||||
CActorParameters::None(), kInvalidUniqueId)
|
CActorParameters::None(), kInvalidUniqueId)
|
||||||
, xe8_(f1)
|
, xe8_hfov(hfov)
|
||||||
, xec_(w1)
|
, xec_(w1)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,18 @@ namespace urde
|
||||||
|
|
||||||
class CScriptCameraWaypoint : public CActor
|
class CScriptCameraWaypoint : public CActor
|
||||||
{
|
{
|
||||||
float xe8_;
|
float xe8_hfov;
|
||||||
u32 xec_;
|
u32 xec_;
|
||||||
public:
|
public:
|
||||||
CScriptCameraWaypoint(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
CScriptCameraWaypoint(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
||||||
const zeus::CTransform& xf, bool active, float, u32);
|
const zeus::CTransform& xf, bool active, float hfov, u32);
|
||||||
|
|
||||||
void Accept(IVisitor& visitor);
|
void Accept(IVisitor& visitor);
|
||||||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||||
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const {}
|
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const {}
|
||||||
void Render(const CStateManager&) const {}
|
void Render(const CStateManager&) const {}
|
||||||
TUniqueId GetRandomNextWaypointId(CStateManager& mgr) const;
|
TUniqueId GetRandomNextWaypointId(CStateManager& mgr) const;
|
||||||
|
float GetHFov() const { return xe8_hfov; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ void CScriptPlayerActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid
|
||||||
void CScriptPlayerActor::SetActive(bool active)
|
void CScriptPlayerActor::SetActive(bool active)
|
||||||
{
|
{
|
||||||
CActor::SetActive(active);
|
CActor::SetActive(active);
|
||||||
xe7_29_ = true;
|
xe7_29_actorActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptPlayerActor::PreRender(CStateManager&, const zeus::CFrustum&)
|
void CScriptPlayerActor::PreRender(CStateManager&, const zeus::CFrustum&)
|
||||||
|
|
|
@ -23,6 +23,7 @@ CScriptTrigger::CScriptTrigger(TUniqueId uid, std::string_view name, const CEnti
|
||||||
{
|
{
|
||||||
x148_26_deactivateOnEntered = deactivateOnEntered;
|
x148_26_deactivateOnEntered = deactivateOnEntered;
|
||||||
x148_27_deactivateOnExited = deactivateOnExited;
|
x148_27_deactivateOnExited = deactivateOnExited;
|
||||||
|
SetCallTouch(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptTrigger::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
void CScriptTrigger::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
#include "CScriptWaypoint.hpp"
|
#include "CScriptWaypoint.hpp"
|
||||||
#include "Character/CModelData.hpp"
|
|
||||||
#include "Collision/CMaterialList.hpp"
|
|
||||||
#include "CActorParameters.hpp"
|
#include "CActorParameters.hpp"
|
||||||
#include "TCastTo.hpp"
|
#include "TCastTo.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
CScriptWaypoint::CScriptWaypoint(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
CScriptWaypoint::CScriptWaypoint(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
||||||
const zeus::CTransform& xf, bool active, float, float,
|
const zeus::CTransform& xf, bool active, float f1, float f2,
|
||||||
u32, u32, u32, u32, u32, u32, u32)
|
u32 w1, u32 w2, u32 w3, u32 w4, u32 w5, u32 w6, u32 w7)
|
||||||
: CActor(uid, active, name, info, xf, CModelData(), CMaterialList(),
|
: CActor(uid, active, name, info, xf, CModelData(), CMaterialList(),
|
||||||
CActorParameters::None(), kInvalidUniqueId)
|
CActorParameters::None(), kInvalidUniqueId),
|
||||||
|
xe8_(f1), xec_(w7), xf0_(f2), xf4_(w1), xf5_(w2), xf6_(w3), xf7_(w4), xf8_(w5), xfa_jumpFlags(w6)
|
||||||
{
|
{
|
||||||
|
SetUseInSortedLists(false);
|
||||||
|
SetCallTouch(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptWaypoint::Accept(IVisitor& visitor)
|
void CScriptWaypoint::Accept(IVisitor& visitor)
|
||||||
|
@ -20,4 +22,46 @@ void CScriptWaypoint::Accept(IVisitor& visitor)
|
||||||
visitor.Visit(this);
|
visitor.Visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CScriptWaypoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
CActor::AcceptScriptMsg(msg, sender, mgr);
|
||||||
|
if (GetActive())
|
||||||
|
if (msg == EScriptObjectMessage::Arrived)
|
||||||
|
SendScriptMsgs(EScriptObjectState::Arrived, mgr, EScriptObjectMessage::None);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptWaypoint::AddToRenderer(const zeus::CFrustum&, const CStateManager&) const
|
||||||
|
{
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
TUniqueId CScriptWaypoint::FollowWaypoint(CStateManager& mgr) const
|
||||||
|
{
|
||||||
|
for (const SConnection& conn : x20_conns)
|
||||||
|
if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Follow)
|
||||||
|
return mgr.GetIdForScript(conn.x8_objId);
|
||||||
|
return kInvalidUniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
TUniqueId CScriptWaypoint::NextWaypoint(CStateManager& mgr) const
|
||||||
|
{
|
||||||
|
rstl::reserved_vector<TUniqueId, 10> ids;
|
||||||
|
for (const SConnection& conn : x20_conns)
|
||||||
|
{
|
||||||
|
if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next)
|
||||||
|
{
|
||||||
|
TUniqueId id = mgr.GetIdForScript(conn.x8_objId);
|
||||||
|
if (id != kInvalidUniqueId)
|
||||||
|
if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(id))
|
||||||
|
if (wp->GetActive())
|
||||||
|
ids.push_back(wp->GetUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ids.size() == 0)
|
||||||
|
return kInvalidUniqueId;
|
||||||
|
|
||||||
|
return ids[int(mgr.GetActiveRandom()->Float() * ids.size() * 0.99f)];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,14 @@ namespace urde
|
||||||
|
|
||||||
class CScriptWaypoint : public CActor
|
class CScriptWaypoint : public CActor
|
||||||
{
|
{
|
||||||
|
float xe8_;
|
||||||
|
u32 xec_;
|
||||||
|
float xf0_;
|
||||||
|
bool xf4_;
|
||||||
|
bool xf5_;
|
||||||
|
bool xf6_;
|
||||||
|
bool xf7_;
|
||||||
|
bool xf8_;
|
||||||
u16 xfa_jumpFlags;
|
u16 xfa_jumpFlags;
|
||||||
public:
|
public:
|
||||||
CScriptWaypoint(TUniqueId, std::string_view, const CEntityInfo&,
|
CScriptWaypoint(TUniqueId, std::string_view, const CEntityInfo&,
|
||||||
|
@ -15,8 +23,10 @@ public:
|
||||||
u32, u32, u32, u32, u32, u32, u32);
|
u32, u32, u32, u32, u32, u32, u32);
|
||||||
|
|
||||||
void Accept(IVisitor& visitor);
|
void Accept(IVisitor& visitor);
|
||||||
|
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr);
|
||||||
const CScriptWaypoint* NextWaypoint(CStateManager&) const { return nullptr; }
|
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
|
||||||
|
TUniqueId FollowWaypoint(CStateManager& mgr) const;
|
||||||
|
TUniqueId NextWaypoint(CStateManager& mgr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,16 @@ namespace urde
|
||||||
class CVisorParameters
|
class CVisorParameters
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
u32 x0_mask : 4;
|
u8 x0_mask : 4;
|
||||||
bool x0_4_b1 : 1;
|
bool x0_4_b1 : 1;
|
||||||
bool x0_5_b2 : 1;
|
bool x0_5_b2 : 1;
|
||||||
bool x0_28_b3 : 1;
|
bool x0_28_b3 : 1;
|
||||||
bool x0_29_b4 : 1;
|
bool x0_29_b4 : 1;
|
||||||
CVisorParameters()
|
CVisorParameters()
|
||||||
: x0_mask(0xf), x0_4_b1(false), x0_5_b2(false) {}
|
: x0_mask(0xf), x0_4_b1(false), x0_5_b2(false) {}
|
||||||
CVisorParameters(u32 mask, bool b1, bool b2)
|
CVisorParameters(u8 mask, bool b1, bool b2)
|
||||||
: x0_mask(mask), x0_4_b1(b1), x0_5_b2(b2) {}
|
: x0_mask(mask), x0_4_b1(b1), x0_5_b2(b2) {}
|
||||||
|
u8 GetMask() const { return x0_mask; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 2bfe803bf63aa17af34adac7c7b317dc8c646467
|
Subproject commit 2064c5ed258337bf71a2c855ab17592abf86e0d1
|
2
specter
2
specter
|
@ -1 +1 @@
|
||||||
Subproject commit 155d4553794a7428090c453c30dd15e17d0961f0
|
Subproject commit 726c42873311435b263e6bc41444b393f13abee2
|
Loading…
Reference in New Issue