mirror of https://github.com/AxioDL/metaforce.git
CFishCloud: Brace statements where applicable
Makes the code more uniform and consistent. While we're in the same area, we can make use of const where applicable.
This commit is contained in:
parent
3715e6dcbb
commit
fa9f0fdc61
|
@ -63,14 +63,18 @@ CFishCloud::CFishCloud(TUniqueId uid, bool active, std::string_view name, const
|
||||||
x1b0_models.emplace_back(std::make_unique<CModelData>(aRes));
|
x1b0_models.emplace_back(std::make_unique<CModelData>(aRes));
|
||||||
x250_27_validModel = true;
|
x250_27_validModel = true;
|
||||||
}
|
}
|
||||||
if (part1.IsValid())
|
if (part1.IsValid()) {
|
||||||
x1c4_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part1}));
|
x1c4_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part1}));
|
||||||
if (part2.IsValid())
|
}
|
||||||
|
if (part2.IsValid()) {
|
||||||
x1c4_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part2}));
|
x1c4_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part2}));
|
||||||
if (part3.IsValid())
|
}
|
||||||
|
if (part3.IsValid()) {
|
||||||
x1c4_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part3}));
|
x1c4_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part3}));
|
||||||
if (part4.IsValid())
|
}
|
||||||
|
if (part4.IsValid()) {
|
||||||
x1c4_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part4}));
|
x1c4_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part4}));
|
||||||
|
}
|
||||||
for (const auto& p : x1c4_particleDescs) {
|
for (const auto& p : x1c4_particleDescs) {
|
||||||
x1f8_particleGens.emplace_back(std::make_unique<CElementGen>(p));
|
x1f8_particleGens.emplace_back(std::make_unique<CElementGen>(p));
|
||||||
x1f8_particleGens.back()->SetParticleEmission(false);
|
x1f8_particleGens.back()->SetParticleEmission(false);
|
||||||
|
@ -79,7 +83,7 @@ CFishCloud::CFishCloud(TUniqueId uid, bool active, std::string_view name, const
|
||||||
x21c_deathParticleCounts.push_back(partCount2);
|
x21c_deathParticleCounts.push_back(partCount2);
|
||||||
x21c_deathParticleCounts.push_back(partCount3);
|
x21c_deathParticleCounts.push_back(partCount3);
|
||||||
x21c_deathParticleCounts.push_back(partCount4);
|
x21c_deathParticleCounts.push_back(partCount4);
|
||||||
zeus::CAABox aabb = GetBoundingBox();
|
const zeus::CAABox aabb = GetBoundingBox();
|
||||||
x238_partitionPitch = (aabb.max - aabb.min) / 7.f;
|
x238_partitionPitch = (aabb.max - aabb.min) / 7.f;
|
||||||
x244_ooPartitionPitch = 1.f / x238_partitionPitch;
|
x244_ooPartitionPitch = 1.f / x238_partitionPitch;
|
||||||
}
|
}
|
||||||
|
@ -87,17 +91,18 @@ CFishCloud::CFishCloud(TUniqueId uid, bool active, std::string_view name, const
|
||||||
void CFishCloud::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
void CFishCloud::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||||
|
|
||||||
void CFishCloud::UpdateParticles(float dt) {
|
void CFishCloud::UpdateParticles(float dt) {
|
||||||
for (auto& p : x1f8_particleGens)
|
for (auto& p : x1f8_particleGens) {
|
||||||
p->Update(dt);
|
p->Update(dt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CFishCloud::UpdatePartitionList() {
|
void CFishCloud::UpdatePartitionList() {
|
||||||
xf8_boidPartitionLists.clear();
|
xf8_boidPartitionLists.clear();
|
||||||
xf8_boidPartitionLists.resize(xf8_boidPartitionLists.capacity());
|
xf8_boidPartitionLists.resize(xf8_boidPartitionLists.capacity());
|
||||||
auto aabb = GetBoundingBox();
|
const auto aabb = GetBoundingBox();
|
||||||
for (auto& b : xe8_boids) {
|
for (auto& b : xe8_boids) {
|
||||||
zeus::CVector3f idxs = (b.x0_pos - aabb.min) * x244_ooPartitionPitch;
|
const zeus::CVector3f idxs = (b.x0_pos - aabb.min) * x244_ooPartitionPitch;
|
||||||
int idx = int(idxs.x()) + int(idxs.y()) * 7 + int(idxs.z()) * 49;
|
const int idx = int(idxs.x()) + int(idxs.y()) * 7 + int(idxs.z()) * 49;
|
||||||
if (idx >= 0 && idx < 343) {
|
if (idx >= 0 && idx < 343) {
|
||||||
b.x1c_next = xf8_boidPartitionLists[idx];
|
b.x1c_next = xf8_boidPartitionLists[idx];
|
||||||
xf8_boidPartitionLists[idx] = &b;
|
xf8_boidPartitionLists[idx] = &b;
|
||||||
|
@ -106,39 +111,41 @@ void CFishCloud::UpdatePartitionList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFishCloud::PointInBox(const zeus::CAABox& aabb, const zeus::CVector3f& point) const {
|
bool CFishCloud::PointInBox(const zeus::CAABox& aabb, const zeus::CVector3f& point) const {
|
||||||
if (!x250_25_worldSpace)
|
if (!x250_25_worldSpace) {
|
||||||
return aabb.pointInside(point);
|
return aabb.pointInside(point);
|
||||||
|
}
|
||||||
return GetUntransformedBoundingBox().pointInside(GetTransform().transposeRotate(point - GetTranslation()));
|
return GetUntransformedBoundingBox().pointInside(GetTransform().transposeRotate(point - GetTranslation()));
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CPlane CFishCloud::FindClosestPlane(const zeus::CAABox& aabb, const zeus::CVector3f& point) const {
|
zeus::CPlane CFishCloud::FindClosestPlane(const zeus::CAABox& aabb, const zeus::CVector3f& point) const {
|
||||||
if (!x250_25_worldSpace) {
|
if (!x250_25_worldSpace) {
|
||||||
float minDist = FLT_MAX;
|
float minDist = FLT_MAX;
|
||||||
zeus::CAABox::EBoxFaceId minFace = zeus::CAABox::EBoxFaceId::YMin;
|
auto minFace = zeus::CAABox::EBoxFaceId::YMin;
|
||||||
for (int i = 0; i < 6; ++i) {
|
for (int i = 0; i < 6; ++i) {
|
||||||
auto tri = aabb.getTri(zeus::CAABox::EBoxFaceId(i), 0);
|
const auto tri = aabb.getTri(zeus::CAABox::EBoxFaceId(i), 0);
|
||||||
float dist = zeus::CPlane(tri.x10_verts[0], tri.x10_verts[2], tri.x10_verts[1]).pointToPlaneDist(point);
|
const float dist = zeus::CPlane(tri.x10_verts[0], tri.x10_verts[2], tri.x10_verts[1]).pointToPlaneDist(point);
|
||||||
if (dist >= 0.f && dist < minDist) {
|
if (dist >= 0.f && dist < minDist) {
|
||||||
minDist = dist;
|
minDist = dist;
|
||||||
minFace = zeus::CAABox::EBoxFaceId(i);
|
minFace = zeus::CAABox::EBoxFaceId(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto tri = aabb.getTri(minFace, 0);
|
const auto tri = aabb.getTri(minFace, 0);
|
||||||
return zeus::CPlane(tri.x10_verts[0], tri.x10_verts[2], tri.x10_verts[1]);
|
return zeus::CPlane(tri.x10_verts[0], tri.x10_verts[2], tri.x10_verts[1]);
|
||||||
} else {
|
} else {
|
||||||
auto unPoint = GetTransform().transposeRotate(point - GetTranslation());
|
const auto unPoint = GetTransform().transposeRotate(point - GetTranslation());
|
||||||
auto unAabb = GetUntransformedBoundingBox();
|
const auto unAabb = GetUntransformedBoundingBox();
|
||||||
float minDist = FLT_MAX;
|
float minDist = FLT_MAX;
|
||||||
zeus::CAABox::EBoxFaceId minFace = zeus::CAABox::EBoxFaceId::YMin;
|
auto minFace = zeus::CAABox::EBoxFaceId::YMin;
|
||||||
for (int i = 0; i < 6; ++i) {
|
for (int i = 0; i < 6; ++i) {
|
||||||
auto tri = unAabb.getTri(zeus::CAABox::EBoxFaceId(i), 0);
|
const auto tri = unAabb.getTri(zeus::CAABox::EBoxFaceId(i), 0);
|
||||||
float dist = zeus::CPlane(tri.x10_verts[0], tri.x10_verts[2], tri.x10_verts[1]).pointToPlaneDist(unPoint);
|
const float dist = zeus::CPlane(tri.x10_verts[0], tri.x10_verts[2], tri.x10_verts[1]).pointToPlaneDist(unPoint);
|
||||||
if (dist >= 0.f && dist < minDist) {
|
if (dist >= 0.f && dist < minDist) {
|
||||||
minDist = dist;
|
minDist = dist;
|
||||||
minFace = zeus::CAABox::EBoxFaceId(i);
|
minFace = zeus::CAABox::EBoxFaceId(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto tri = unAabb.getTri(minFace, 0);
|
|
||||||
|
const auto tri = unAabb.getTri(minFace, 0);
|
||||||
return zeus::CPlane(GetTransform() * tri.x10_verts[0],
|
return zeus::CPlane(GetTransform() * tri.x10_verts[0],
|
||||||
GetTransform() * tri.x10_verts[2],
|
GetTransform() * tri.x10_verts[2],
|
||||||
GetTransform() * tri.x10_verts[1]);
|
GetTransform() * tri.x10_verts[1]);
|
||||||
|
@ -146,71 +153,85 @@ zeus::CPlane CFishCloud::FindClosestPlane(const zeus::CAABox& aabb, const zeus::
|
||||||
}
|
}
|
||||||
|
|
||||||
CFishCloud::CBoid* CFishCloud::GetListAt(const zeus::CVector3f& pos) {
|
CFishCloud::CBoid* CFishCloud::GetListAt(const zeus::CVector3f& pos) {
|
||||||
zeus::CAABox aabb = GetBoundingBox();
|
const zeus::CAABox aabb = GetBoundingBox();
|
||||||
zeus::CVector3f ints = (pos - aabb.min) * x244_ooPartitionPitch;
|
const zeus::CVector3f ints = (pos - aabb.min) * x244_ooPartitionPitch;
|
||||||
int idx = int(ints.x()) + int(ints.y()) * 7 + int(ints.z()) * 49;
|
const int idx = int(ints.x()) + int(ints.y()) * 7 + int(ints.z()) * 49;
|
||||||
if (idx < 0 || idx >= 343)
|
|
||||||
|
if (idx < 0 || idx >= 343) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return xf8_boidPartitionLists[idx];
|
return xf8_boidPartitionLists[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::BuildBoidNearList(const zeus::CVector3f& pos, float radius,
|
void CFishCloud::BuildBoidNearList(const zeus::CVector3f& pos, float radius,
|
||||||
rstl::reserved_vector<CBoid*, 25>& nearList) {
|
rstl::reserved_vector<CBoid*, 25>& nearList) {
|
||||||
float radiusSq = radius * radius;
|
const float radiusSq = radius * radius;
|
||||||
CBoid* b = GetListAt(pos);
|
CBoid* b = GetListAt(pos);
|
||||||
while (b && nearList.size() < 25) {
|
|
||||||
|
while (b != nullptr && nearList.size() < 25) {
|
||||||
if (b->x20_active) {
|
if (b->x20_active) {
|
||||||
float distSq = (b->GetTranslation() - pos).magSquared();
|
const float distSq = (b->GetTranslation() - pos).magSquared();
|
||||||
if (distSq != 0.f && distSq < radiusSq)
|
if (distSq != 0.f && distSq < radiusSq) {
|
||||||
nearList.push_back(b);
|
nearList.push_back(b);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
b = b->x1c_next;
|
b = b->x1c_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::BuildBoidNearPartitionList(const zeus::CVector3f& pos, float radius,
|
void CFishCloud::BuildBoidNearPartitionList(const zeus::CVector3f& pos, float radius,
|
||||||
rstl::reserved_vector<CBoid*, 25>& nearList) {
|
rstl::reserved_vector<CBoid*, 25>& nearList) {
|
||||||
float radiusSq = radius * radius;
|
const float radiusSq = radius * radius;
|
||||||
zeus::CAABox aabb = GetBoundingBox();
|
const zeus::CAABox aabb = GetBoundingBox();
|
||||||
float x = std::max(radius * x244_ooPartitionPitch.x(), float(x238_partitionPitch.x()));
|
const float x = std::max(radius * x244_ooPartitionPitch.x(), float(x238_partitionPitch.x()));
|
||||||
float y = std::max(radius * x244_ooPartitionPitch.y(), float(x238_partitionPitch.y()));
|
const float y = std::max(radius * x244_ooPartitionPitch.y(), float(x238_partitionPitch.y()));
|
||||||
float z = std::max(radius * x244_ooPartitionPitch.z(), float(x238_partitionPitch.z()));
|
const float z = std::max(radius * x244_ooPartitionPitch.z(), float(x238_partitionPitch.z()));
|
||||||
float nx = 0.01f - x;
|
const float nx = 0.01f - x;
|
||||||
float ny = 0.01f - y;
|
const float ny = 0.01f - y;
|
||||||
float nz = 0.01f - z;
|
const float nz = 0.01f - z;
|
||||||
|
|
||||||
for (float lnx = nx; lnx < x; lnx += x238_partitionPitch.x()) {
|
for (float lnx = nx; lnx < x; lnx += x238_partitionPitch.x()) {
|
||||||
float cx = lnx + pos.x();
|
const float cx = lnx + pos.x();
|
||||||
if (cx < aabb.min.x())
|
if (cx < aabb.min.x()) {
|
||||||
continue;
|
continue;
|
||||||
if (cx >= aabb.max.x())
|
}
|
||||||
|
if (cx >= aabb.max.x()) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
for (float lny = ny; lny < y; lny += x238_partitionPitch.y()) {
|
for (float lny = ny; lny < y; lny += x238_partitionPitch.y()) {
|
||||||
float cy = lny + pos.y();
|
const float cy = lny + pos.y();
|
||||||
if (cy < aabb.min.y())
|
if (cy < aabb.min.y()) {
|
||||||
continue;
|
continue;
|
||||||
if (cy >= aabb.max.y())
|
}
|
||||||
|
if (cy >= aabb.max.y()) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
for (float lnz = nz; lnz < z; lnz += x238_partitionPitch.z()) {
|
for (float lnz = nz; lnz < z; lnz += x238_partitionPitch.z()) {
|
||||||
float cz = lnz + pos.z();
|
const float cz = lnz + pos.z();
|
||||||
if (cz < aabb.min.z())
|
if (cz < aabb.min.z()) {
|
||||||
continue;
|
continue;
|
||||||
if (cz >= aabb.max.z())
|
}
|
||||||
|
if (cz >= aabb.max.z()) {
|
||||||
break;
|
break;
|
||||||
zeus::CVector3f ints = (zeus::CVector3f(cx, cy, cz) - aabb.min) * x244_ooPartitionPitch;
|
}
|
||||||
int idx = int(ints.x()) + int(ints.y()) * 7 + int(ints.z()) * 49;
|
const zeus::CVector3f ints = (zeus::CVector3f(cx, cy, cz) - aabb.min) * x244_ooPartitionPitch;
|
||||||
if (idx < 0)
|
const int idx = int(ints.x()) + int(ints.y()) * 7 + int(ints.z()) * 49;
|
||||||
|
if (idx < 0) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (idx < 343) {
|
if (idx < 343) {
|
||||||
CBoid* boid = xf8_boidPartitionLists[idx];
|
CBoid* boid = xf8_boidPartitionLists[idx];
|
||||||
while (boid) {
|
while (boid != nullptr) {
|
||||||
if (boid->x20_active) {
|
if (boid->x20_active) {
|
||||||
float distSq = (boid->x0_pos - pos).magSquared();
|
const float distSq = (boid->x0_pos - pos).magSquared();
|
||||||
if (distSq != 0.f && distSq < radiusSq) {
|
if (distSq != 0.f && distSq < radiusSq) {
|
||||||
nearList.push_back(boid);
|
nearList.push_back(boid);
|
||||||
if (nearList.size() == 25)
|
if (nearList.size() == 25) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
boid = boid->x1c_next;
|
boid = boid->x1c_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +241,7 @@ void CFishCloud::BuildBoidNearPartitionList(const zeus::CVector3f& pos, float ra
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::PlaceBoid(CStateManager& mgr, CBoid& boid, const zeus::CAABox& aabb) const {
|
void CFishCloud::PlaceBoid(CStateManager& mgr, CBoid& boid, const zeus::CAABox& aabb) const {
|
||||||
auto plane = FindClosestPlane(aabb, boid.x0_pos);
|
const auto plane = FindClosestPlane(aabb, boid.x0_pos);
|
||||||
boid.x0_pos -= plane.pointToPlaneDist(boid.x0_pos) * plane.normal() + 0.0001f * plane.normal();
|
boid.x0_pos -= plane.pointToPlaneDist(boid.x0_pos) * plane.normal() + 0.0001f * plane.normal();
|
||||||
boid.xc_vel.y() = mgr.GetActiveRandom()->Float() - 0.5f;
|
boid.xc_vel.y() = mgr.GetActiveRandom()->Float() - 0.5f;
|
||||||
boid.xc_vel.x() = mgr.GetActiveRandom()->Float() - 0.5f;
|
boid.xc_vel.x() = mgr.GetActiveRandom()->Float() - 0.5f;
|
||||||
|
@ -233,7 +254,7 @@ void CFishCloud::PlaceBoid(CStateManager& mgr, CBoid& boid, const zeus::CAABox&
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!PointInBox(aabb, boid.x0_pos)) {
|
if (!PointInBox(aabb, boid.x0_pos)) {
|
||||||
auto unAabb = GetUntransformedBoundingBox();
|
const auto unAabb = GetUntransformedBoundingBox();
|
||||||
boid.x0_pos.z() = mgr.GetActiveRandom()->Float() * (unAabb.max.z() - unAabb.min.z()) + unAabb.min.z();
|
boid.x0_pos.z() = mgr.GetActiveRandom()->Float() * (unAabb.max.z() - unAabb.min.z()) + unAabb.min.z();
|
||||||
boid.x0_pos.y() = mgr.GetActiveRandom()->Float() * (unAabb.max.y() - unAabb.min.y()) + unAabb.min.y();
|
boid.x0_pos.y() = mgr.GetActiveRandom()->Float() * (unAabb.max.y() - unAabb.min.y()) + unAabb.min.y();
|
||||||
boid.x0_pos.x() = mgr.GetActiveRandom()->Float() * (unAabb.max.x() - unAabb.min.x()) + unAabb.min.x();
|
boid.x0_pos.x() = mgr.GetActiveRandom()->Float() * (unAabb.max.x() - unAabb.min.x()) + unAabb.min.x();
|
||||||
|
@ -243,57 +264,75 @@ void CFishCloud::PlaceBoid(CStateManager& mgr, CBoid& boid, const zeus::CAABox&
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::ApplySeparation(CBoid& boid, const rstl::reserved_vector<CBoid*, 25>& nearList) const {
|
void CFishCloud::ApplySeparation(CBoid& boid, const rstl::reserved_vector<CBoid*, 25>& nearList) const {
|
||||||
if (nearList.empty())
|
if (nearList.empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float minDist = FLT_MAX;
|
float minDist = FLT_MAX;
|
||||||
zeus::CVector3f pos;
|
zeus::CVector3f pos;
|
||||||
for (CBoid* b : nearList) {
|
for (const CBoid* b : nearList) {
|
||||||
float dist = (boid.GetTranslation() - b->GetTranslation()).magSquared();
|
const float dist = (boid.GetTranslation() - b->GetTranslation()).magSquared();
|
||||||
if (dist < minDist) {
|
if (dist < minDist) {
|
||||||
minDist = dist;
|
minDist = dist;
|
||||||
pos = b->GetTranslation();
|
pos = b->GetTranslation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplySeparation(boid, pos, x138_separationRadius, x144_separationMagnitude);
|
ApplySeparation(boid, pos, x138_separationRadius, x144_separationMagnitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::ApplySeparation(CBoid& boid, const zeus::CVector3f& separateFrom,
|
void CFishCloud::ApplySeparation(CBoid& boid, const zeus::CVector3f& separateFrom,
|
||||||
float separationRadius, float separationMagnitude) const {
|
float separationRadius, float separationMagnitude) const {
|
||||||
zeus::CVector3f delta = boid.GetTranslation() - separateFrom;
|
const zeus::CVector3f delta = boid.GetTranslation() - separateFrom;
|
||||||
if (delta.canBeNormalized()) {
|
if (!delta.canBeNormalized()) {
|
||||||
float deltaDistSq = delta.magSquared();
|
return;
|
||||||
float capDeltaDistSq = separationRadius * separationRadius;
|
|
||||||
if (deltaDistSq < capDeltaDistSq)
|
|
||||||
boid.xc_vel += (1.f - deltaDistSq / capDeltaDistSq) * delta.normalized() * separationMagnitude;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float deltaDistSq = delta.magSquared();
|
||||||
|
const float capDeltaDistSq = separationRadius * separationRadius;
|
||||||
|
if (deltaDistSq >= capDeltaDistSq) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boid.xc_vel += (1.f - deltaDistSq / capDeltaDistSq) * delta.normalized() * separationMagnitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::ApplyCohesion(CBoid& boid, const rstl::reserved_vector<CBoid*, 25>& nearList) const {
|
void CFishCloud::ApplyCohesion(CBoid& boid, const rstl::reserved_vector<CBoid*, 25>& nearList) const {
|
||||||
if (nearList.empty())
|
if (nearList.empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
zeus::CVector3f avg;
|
zeus::CVector3f avg;
|
||||||
for (CBoid* b : nearList)
|
for (const CBoid* b : nearList) {
|
||||||
avg += b->GetTranslation();
|
avg += b->GetTranslation();
|
||||||
|
}
|
||||||
|
|
||||||
avg = avg / float(nearList.size());
|
avg = avg / float(nearList.size());
|
||||||
ApplyCohesion(boid, avg, x138_separationRadius, x13c_cohesionMagnitude);
|
ApplyCohesion(boid, avg, x138_separationRadius, x13c_cohesionMagnitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::ApplyCohesion(CBoid& boid, const zeus::CVector3f& cohesionFrom,
|
void CFishCloud::ApplyCohesion(CBoid& boid, const zeus::CVector3f& cohesionFrom,
|
||||||
float cohesionRadius, float cohesionMagnitude) const {
|
float cohesionRadius, float cohesionMagnitude) const {
|
||||||
zeus::CVector3f delta = cohesionFrom - boid.GetTranslation();
|
const zeus::CVector3f delta = cohesionFrom - boid.GetTranslation();
|
||||||
if (delta.canBeNormalized()) {
|
if (!delta.canBeNormalized()) {
|
||||||
float distSq = delta.magSquared();
|
return;
|
||||||
float capDistSq = cohesionRadius * cohesionRadius;
|
|
||||||
boid.xc_vel += ((distSq > capDistSq) ? 1.f : distSq / capDistSq) * delta.normalized() * cohesionMagnitude;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float distSq = delta.magSquared();
|
||||||
|
const float capDistSq = cohesionRadius * cohesionRadius;
|
||||||
|
boid.xc_vel += ((distSq > capDistSq) ? 1.f : distSq / capDistSq) * delta.normalized() * cohesionMagnitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::ApplyAlignment(CBoid& boid, const rstl::reserved_vector<CBoid*, 25>& nearList) const {
|
void CFishCloud::ApplyAlignment(CBoid& boid, const rstl::reserved_vector<CBoid*, 25>& nearList) const {
|
||||||
if (nearList.empty())
|
if (nearList.empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
zeus::CVector3f avg;
|
zeus::CVector3f avg;
|
||||||
for (CBoid* b : nearList)
|
for (const CBoid* b : nearList) {
|
||||||
avg += b->xc_vel;
|
avg += b->xc_vel;
|
||||||
|
}
|
||||||
|
|
||||||
avg = avg / float(nearList.size());
|
avg = avg / float(nearList.size());
|
||||||
boid.xc_vel += zeus::CVector3f::getAngleDiff(boid.xc_vel, avg) / M_PIF *
|
boid.xc_vel += zeus::CVector3f::getAngleDiff(boid.xc_vel, avg) / M_PIF *
|
||||||
(avg * x140_alignmentWeight);
|
(avg * x140_alignmentWeight);
|
||||||
|
@ -301,12 +340,14 @@ void CFishCloud::ApplyAlignment(CBoid& boid, const rstl::reserved_vector<CBoid*,
|
||||||
|
|
||||||
void CFishCloud::ApplyAttraction(CBoid& boid, const zeus::CVector3f& attractTo,
|
void CFishCloud::ApplyAttraction(CBoid& boid, const zeus::CVector3f& attractTo,
|
||||||
float attractionRadius, float attractionMagnitude) const {
|
float attractionRadius, float attractionMagnitude) const {
|
||||||
zeus::CVector3f delta = attractTo - boid.GetTranslation();
|
const zeus::CVector3f delta = attractTo - boid.GetTranslation();
|
||||||
if (delta.canBeNormalized()) {
|
if (!delta.canBeNormalized()) {
|
||||||
float distSq = delta.magSquared();
|
return;
|
||||||
float capDistSq = attractionRadius * attractionRadius;
|
|
||||||
boid.xc_vel += ((distSq > capDistSq) ? 0.f : (1.f - distSq / capDistSq)) * delta.normalized() * attractionMagnitude;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float distSq = delta.magSquared();
|
||||||
|
const float capDistSq = attractionRadius * attractionRadius;
|
||||||
|
boid.xc_vel += ((distSq > capDistSq) ? 0.f : (1.f - distSq / capDistSq)) * delta.normalized() * attractionMagnitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::ApplyRepulsion(CBoid& boid, const zeus::CVector3f& attractTo,
|
void CFishCloud::ApplyRepulsion(CBoid& boid, const zeus::CVector3f& attractTo,
|
||||||
|
@ -316,74 +357,93 @@ void CFishCloud::ApplyRepulsion(CBoid& boid, const zeus::CVector3f& attractTo,
|
||||||
|
|
||||||
void CFishCloud::ApplySwirl(CBoid& boid, const zeus::CVector3f& swirlPoint, bool clockwise,
|
void CFishCloud::ApplySwirl(CBoid& boid, const zeus::CVector3f& swirlPoint, bool clockwise,
|
||||||
float magnitude, float radius) const {
|
float magnitude, float radius) const {
|
||||||
zeus::CVector3f delta = boid.x0_pos - swirlPoint;
|
const zeus::CVector3f delta = boid.x0_pos - swirlPoint;
|
||||||
float deltaMag = delta.magnitude();
|
const float deltaMag = delta.magnitude();
|
||||||
|
|
||||||
zeus::CVector3f alignVec;
|
zeus::CVector3f alignVec;
|
||||||
if (clockwise)
|
if (clockwise) {
|
||||||
alignVec = delta.normalized().cross(zeus::skUp);
|
alignVec = delta.normalized().cross(zeus::skUp);
|
||||||
else
|
} else {
|
||||||
alignVec = zeus::skUp.cross(delta / deltaMag);
|
alignVec = zeus::skUp.cross(delta / deltaMag);
|
||||||
float weight = deltaMag > radius ? 0.f : 1.f - deltaMag / radius;
|
}
|
||||||
|
|
||||||
|
const float weight = deltaMag > radius ? 0.f : 1.f - deltaMag / radius;
|
||||||
boid.xc_vel += zeus::CVector3f::getAngleDiff(boid.xc_vel, alignVec) / M_PIF *
|
boid.xc_vel += zeus::CVector3f::getAngleDiff(boid.xc_vel, alignVec) / M_PIF *
|
||||||
weight * (magnitude * alignVec);
|
weight * (magnitude * alignVec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::ApplyContainment(CBoid& boid, const zeus::CAABox& aabb) const {
|
void CFishCloud::ApplyContainment(CBoid& boid, const zeus::CAABox& aabb) const {
|
||||||
if (boid.xc_vel.canBeNormalized()) {
|
if (!boid.xc_vel.canBeNormalized()) {
|
||||||
if (!PointInBox(aabb, boid.xc_vel.normalized() * x130_speed * x174_containmentRadius + boid.x0_pos)) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PointInBox(aabb, boid.xc_vel.normalized() * x130_speed * x174_containmentRadius + boid.x0_pos)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ApplyAttraction(boid, aabb.center(), 100000.f, x158_containmentMagnitude);
|
ApplyAttraction(boid, aabb.center(), 100000.f, x158_containmentMagnitude);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFishCloud::ScatterBoid(CStateManager& mgr, CBoid& b) const {
|
void CFishCloud::ScatterBoid(CStateManager& mgr, CBoid& b) const {
|
||||||
float angle = (mgr.GetActiveRandom()->Float() - 0.5f) * M_PIF * x154_maxScatterAngle;
|
const float angle = (mgr.GetActiveRandom()->Float() - 0.5f) * M_PIF * x154_maxScatterAngle;
|
||||||
float cosAngle = std::cos(angle);
|
const float cosAngle = std::cos(angle);
|
||||||
float sinAngle = std::sin(angle);
|
const float sinAngle = std::sin(angle);
|
||||||
b.xc_vel.x() += x150_scatterVel * (b.xc_vel.y() * sinAngle + b.xc_vel.x() * cosAngle);
|
b.xc_vel.x() += x150_scatterVel * (b.xc_vel.y() * sinAngle + b.xc_vel.x() * cosAngle);
|
||||||
b.xc_vel.y() += x150_scatterVel * (b.xc_vel.y() * cosAngle + b.xc_vel.x() * sinAngle);
|
b.xc_vel.y() += x150_scatterVel * (b.xc_vel.y() * cosAngle + b.xc_vel.x() * sinAngle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::Think(float dt, CStateManager& mgr) {
|
void CFishCloud::Think(float dt, CStateManager& mgr) {
|
||||||
if (!GetActive())
|
if (!GetActive()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId);
|
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId);
|
||||||
auto occState = area->IsPostConstructed() ? area->GetOcclusionState() : CGameArea::EOcclusionState::Occluded;
|
const auto occState = area->IsPostConstructed() ? area->GetOcclusionState() : CGameArea::EOcclusionState::Occluded;
|
||||||
if (occState == CGameArea::EOcclusionState::Visible) {
|
if (occState == CGameArea::EOcclusionState::Visible) {
|
||||||
x168_weaponRepelDamping = std::max(0.f, x168_weaponRepelDamping - x160_weaponRepelDampingSpeed * dt * 0.1f);
|
x168_weaponRepelDamping = std::max(0.f, x168_weaponRepelDamping - x160_weaponRepelDampingSpeed * dt * 0.1f);
|
||||||
if (x250_26_enableWeaponRepelDamping)
|
if (x250_26_enableWeaponRepelDamping) {
|
||||||
x168_weaponRepelDamping = std::min(x160_weaponRepelDampingSpeed * dt + x168_weaponRepelDamping,
|
x168_weaponRepelDamping =
|
||||||
x148_weaponRepelMagnitude);
|
std::min(x160_weaponRepelDampingSpeed * dt + x168_weaponRepelDamping, x148_weaponRepelMagnitude);
|
||||||
|
}
|
||||||
|
|
||||||
x164_playerRepelDamping = std::max(0.f, x164_playerRepelDamping - x15c_playerRepelDampingSpeed * dt * 0.1f);
|
x164_playerRepelDamping = std::max(0.f, x164_playerRepelDamping - x15c_playerRepelDampingSpeed * dt * 0.1f);
|
||||||
if (x250_30_enablePlayerRepelDamping)
|
if (x250_30_enablePlayerRepelDamping) {
|
||||||
x164_playerRepelDamping = std::min(x15c_playerRepelDampingSpeed * dt + x164_playerRepelDamping,
|
x164_playerRepelDamping =
|
||||||
x14c_playerRepelMagnitude);
|
std::min(x15c_playerRepelDampingSpeed * dt + x164_playerRepelDamping, x14c_playerRepelMagnitude);
|
||||||
|
}
|
||||||
|
|
||||||
x250_26_enableWeaponRepelDamping = false;
|
x250_26_enableWeaponRepelDamping = false;
|
||||||
x250_30_enablePlayerRepelDamping = false;
|
x250_30_enablePlayerRepelDamping = false;
|
||||||
++x118_thinkCounter;
|
++x118_thinkCounter;
|
||||||
|
|
||||||
UpdateParticles(dt);
|
UpdateParticles(dt);
|
||||||
UpdatePartitionList();
|
UpdatePartitionList();
|
||||||
zeus::CAABox aabb = GetBoundingBox();
|
|
||||||
|
const zeus::CAABox aabb = GetBoundingBox();
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (auto& b : xe8_boids) {
|
for (auto& b : xe8_boids) {
|
||||||
if (b.x20_active && (idx & x11c_updateMask) == (x118_thinkCounter & x11c_updateMask)) {
|
if (b.x20_active && (idx & x11c_updateMask) == (x118_thinkCounter & x11c_updateMask)) {
|
||||||
rstl::reserved_vector<CBoid*, 25> nearList;
|
rstl::reserved_vector<CBoid*, 25> nearList;
|
||||||
if (x250_31_updateWithoutPartitions)
|
if (x250_31_updateWithoutPartitions) {
|
||||||
BuildBoidNearList(b.x0_pos, x138_separationRadius, nearList);
|
BuildBoidNearList(b.x0_pos, x138_separationRadius, nearList);
|
||||||
else
|
} else {
|
||||||
BuildBoidNearPartitionList(b.x0_pos, x138_separationRadius, nearList);
|
BuildBoidNearPartitionList(b.x0_pos, x138_separationRadius, nearList);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 1:
|
case 1:
|
||||||
ApplySeparation(b, nearList);
|
ApplySeparation(b, nearList);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (!x250_24_randomMovement || mgr.GetActiveRandom()->Float() > x12c_randomMovementTimer)
|
if (!x250_24_randomMovement || mgr.GetActiveRandom()->Float() > x12c_randomMovementTimer) {
|
||||||
ApplyCohesion(b, nearList);
|
ApplyCohesion(b, nearList);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (!x250_24_randomMovement || mgr.GetActiveRandom()->Float() > x12c_randomMovementTimer)
|
if (!x250_24_randomMovement || mgr.GetActiveRandom()->Float() > x12c_randomMovementTimer) {
|
||||||
ApplyAlignment(b, nearList);
|
ApplyAlignment(b, nearList);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
ScatterBoid(mgr, b);
|
ScatterBoid(mgr, b);
|
||||||
|
@ -391,12 +451,14 @@ void CFishCloud::Think(float dt, CStateManager& mgr) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (b.xc_vel.magSquared() > 3.2f)
|
if (b.xc_vel.magSquared() > 3.2f) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!x250_24_randomMovement && b.xc_vel.magSquared() < 3.2f) {
|
if (!x250_24_randomMovement && b.xc_vel.magSquared() < 3.2f) {
|
||||||
for (auto& m : x108_modifierSources) {
|
for (const auto& m : x108_modifierSources) {
|
||||||
if (TCastToPtr<CActor> act = mgr.ObjectById(m.x0_source)) {
|
if (const TCastToConstPtr<CActor> act = mgr.ObjectById(m.x0_source)) {
|
||||||
if (m.xd_isSwirl) {
|
if (m.xd_isSwirl) {
|
||||||
ApplySwirl(b, act->GetTranslation(), m.xc_isRepulsor, m.x8_priority, m.x4_radius);
|
ApplySwirl(b, act->GetTranslation(), m.xc_isRepulsor, m.x8_priority, m.x4_radius);
|
||||||
} else if (m.xc_isRepulsor) {
|
} else if (m.xc_isRepulsor) {
|
||||||
|
@ -416,28 +478,34 @@ void CFishCloud::Think(float dt, CStateManager& mgr) {
|
||||||
}
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& b : xe8_boids) {
|
for (auto& b : xe8_boids) {
|
||||||
if (b.x20_active) {
|
if (b.x20_active) {
|
||||||
ApplyContainment(b, aabb);
|
ApplyContainment(b, aabb);
|
||||||
float velMag = b.xc_vel.magnitude();
|
const float velMag = b.xc_vel.magnitude();
|
||||||
if (!zeus::close_enough(velMag, 0.f))
|
if (!zeus::close_enough(velMag, 0.f)) {
|
||||||
b.xc_vel = b.xc_vel / velMag;
|
b.xc_vel = b.xc_vel / velMag;
|
||||||
|
}
|
||||||
b.xc_vel.z() *= 0.99f;
|
b.xc_vel.z() *= 0.99f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x12c_randomMovementTimer > 0.f) {
|
if (x12c_randomMovementTimer > 0.f) {
|
||||||
x12c_randomMovementTimer -= dt;
|
x12c_randomMovementTimer -= dt;
|
||||||
} else {
|
} else {
|
||||||
x12c_randomMovementTimer = 0.f;
|
x12c_randomMovementTimer = 0.f;
|
||||||
x250_24_randomMovement = false;
|
x250_24_randomMovement = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& b : xe8_boids) {
|
for (auto& b : xe8_boids) {
|
||||||
if (b.x20_active) {
|
if (b.x20_active) {
|
||||||
b.x0_pos += b.xc_vel * dt * x130_speed;
|
b.x0_pos += b.xc_vel * dt * x130_speed;
|
||||||
if (!PointInBox(aabb, b.x0_pos))
|
if (!PointInBox(aabb, b.x0_pos)) {
|
||||||
PlaceBoid(mgr, b, aabb);
|
PlaceBoid(mgr, b, aabb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (x250_27_validModel) {
|
if (x250_27_validModel) {
|
||||||
for (auto& m : x1b0_models) {
|
for (auto& m : x1b0_models) {
|
||||||
m->GetAnimationData()->SetPlaybackRate(1.f);
|
m->GetAnimationData()->SetPlaybackRate(1.f);
|
||||||
|
@ -455,8 +523,8 @@ void CFishCloud::AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichMod
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (auto& m : x1b0_models) {
|
for (auto& m : x1b0_models) {
|
||||||
m->EnableLooping(true);
|
m->EnableLooping(true);
|
||||||
m->AdvanceAnimation(
|
m->AdvanceAnimation(m->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * 0.25f * float(idx), mgr,
|
||||||
m->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * 0.25f * idx, mgr, x4_areaId, true);
|
x4_areaId, true);
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
x230_whichModel = which;
|
x230_whichModel = which;
|
||||||
|
@ -467,10 +535,10 @@ void CFishCloud::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case EScriptObjectMessage::Registered: {
|
case EScriptObjectMessage::Registered: {
|
||||||
xe8_boids.reserve(x134_numBoids);
|
xe8_boids.reserve(x134_numBoids);
|
||||||
zeus::CAABox aabb = GetUntransformedBoundingBox();
|
const zeus::CAABox aabb = GetUntransformedBoundingBox();
|
||||||
zeus::CVector3f extent = aabb.max - aabb.min;
|
const zeus::CVector3f extent = aabb.max - aabb.min;
|
||||||
zeus::CVector3f randPoint;
|
zeus::CVector3f randPoint;
|
||||||
for (int i = 0; i < x134_numBoids; ++i) {
|
for (u32 i = 0; i < x134_numBoids; ++i) {
|
||||||
randPoint.z() = mgr.GetActiveRandom()->Float() * extent.z() + aabb.min.z();
|
randPoint.z() = mgr.GetActiveRandom()->Float() * extent.z() + aabb.min.z();
|
||||||
randPoint.y() = mgr.GetActiveRandom()->Float() * extent.y() + aabb.min.y();
|
randPoint.y() = mgr.GetActiveRandom()->Float() * extent.y() + aabb.min.y();
|
||||||
randPoint.x() = mgr.GetActiveRandom()->Float() * extent.x() + aabb.min.x();
|
randPoint.x() = mgr.GetActiveRandom()->Float() * extent.x() + aabb.min.x();
|
||||||
|
@ -481,8 +549,9 @@ void CFishCloud::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt
|
||||||
0.2f * std::pow(mgr.GetActiveRandom()->Float(), 7.f) + 0.9f);
|
0.2f * std::pow(mgr.GetActiveRandom()->Float(), 7.f) + 0.9f);
|
||||||
}
|
}
|
||||||
CreatePartitionList();
|
CreatePartitionList();
|
||||||
if (x250_27_validModel)
|
if (x250_27_validModel) {
|
||||||
AllocateSkinnedModels(mgr, CModelData::EWhichModel::Normal);
|
AllocateSkinnedModels(mgr, CModelData::EWhichModel::Normal);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -501,22 +570,26 @@ void CFishCloud::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::AddParticlesToRenderer() const {
|
void CFishCloud::AddParticlesToRenderer() const {
|
||||||
for (const auto& p : x1f8_particleGens)
|
for (const auto& p : x1f8_particleGens) {
|
||||||
g_Renderer->AddParticleGen(*p);
|
g_Renderer->AddParticleGen(*p);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CFishCloud::RenderBoid(int idx, const CBoid& boid, u32& drawMask,
|
void CFishCloud::RenderBoid(int idx, const CBoid& boid, u32& drawMask,
|
||||||
bool thermalHot, const CModelFlags& flags) const {
|
bool thermalHot, const CModelFlags& flags) const {
|
||||||
u32 modelIndex = idx & 0x3;
|
const u32 modelIndex = idx & 0x3;
|
||||||
CModelData& mData = *x1b0_models[modelIndex];
|
CModelData& mData = *x1b0_models[modelIndex];
|
||||||
CSkinnedModel& model = mData.PickAnimatedModel(CModelData::EWhichModel::Normal);
|
CSkinnedModel& model = mData.PickAnimatedModel(CModelData::EWhichModel::Normal);
|
||||||
if (!model.GetModelInst()->TryLockTextures())
|
if (!model.GetModelInst()->TryLockTextures()) {
|
||||||
return;
|
return;
|
||||||
u32 thisDrawMask = 1u << modelIndex;
|
}
|
||||||
if (drawMask & thisDrawMask) {
|
|
||||||
|
const u32 thisDrawMask = 1u << modelIndex;
|
||||||
|
if ((drawMask & thisDrawMask) != 0) {
|
||||||
drawMask &= ~thisDrawMask;
|
drawMask &= ~thisDrawMask;
|
||||||
mData.GetAnimationData()->BuildPose();
|
mData.GetAnimationData()->BuildPose();
|
||||||
}
|
}
|
||||||
|
|
||||||
model.GetModelInst()->SetAmbientColor(zeus::skWhite);
|
model.GetModelInst()->SetAmbientColor(zeus::skWhite);
|
||||||
CGraphics::SetModelMatrix(zeus::lookAt(boid.x0_pos, boid.x0_pos + boid.xc_vel));
|
CGraphics::SetModelMatrix(zeus::lookAt(boid.x0_pos, boid.x0_pos + boid.xc_vel));
|
||||||
if (thermalHot) {
|
if (thermalHot) {
|
||||||
|
@ -528,24 +601,31 @@ void CFishCloud::RenderBoid(int idx, const CBoid& boid, u32& drawMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::Render(CStateManager& mgr) {
|
void CFishCloud::Render(CStateManager& mgr) {
|
||||||
if (!GetActive())
|
if (!GetActive()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CFishCloud::Render {} {} {}"),
|
SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CFishCloud::Render {} {} {}"),
|
||||||
x8_uid, xc_editorId, x10_name).c_str(), zeus::skOrange);
|
x8_uid, xc_editorId, x10_name).c_str(), zeus::skOrange);
|
||||||
bool thermalHot = mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot;
|
|
||||||
|
const bool thermalHot = mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot;
|
||||||
CModelFlags flags(0, 0, 3, zeus::skWhite);
|
CModelFlags flags(0, 0, 3, zeus::skWhite);
|
||||||
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay)
|
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) {
|
||||||
flags = CModelFlags(5, 0, 3, x16c_color);
|
flags = CModelFlags(5, 0, 3, x16c_color);
|
||||||
else
|
} else {
|
||||||
flags = CModelFlags(1, 0, 3, x16c_color);
|
flags = CModelFlags(1, 0, 3, x16c_color);
|
||||||
|
}
|
||||||
|
|
||||||
AddParticlesToRenderer();
|
AddParticlesToRenderer();
|
||||||
|
|
||||||
if (x250_27_validModel) {
|
if (x250_27_validModel) {
|
||||||
// Ambient white
|
// Ambient white
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
u32 drawMask = 0xffffffff;
|
u32 drawMask = 0xffffffff;
|
||||||
for (const auto& b : xe8_boids) {
|
for (const auto& b : xe8_boids) {
|
||||||
if (b.x20_active)
|
if (b.x20_active) {
|
||||||
RenderBoid(idx, b, drawMask, thermalHot, flags);
|
RenderBoid(idx, b, drawMask, thermalHot, flags);
|
||||||
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -595,35 +675,41 @@ void CFishCloud::KillBoid(CBoid& b) const {
|
||||||
|
|
||||||
void CFishCloud::Touch(CActor& other, CStateManager& mgr) {
|
void CFishCloud::Touch(CActor& other, CStateManager& mgr) {
|
||||||
CActor::Touch(other, mgr);
|
CActor::Touch(other, mgr);
|
||||||
if (TCastToPtr<CWeapon> weap = other) {
|
|
||||||
|
if (const TCastToConstPtr<CWeapon> weap = other) {
|
||||||
if (!x250_26_enableWeaponRepelDamping && x250_29_repelFromThreats) {
|
if (!x250_26_enableWeaponRepelDamping && x250_29_repelFromThreats) {
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (auto& b : xe8_boids) {
|
for (auto& b : xe8_boids) {
|
||||||
if ((idx & 0x3) == (x118_thinkCounter & 0x3))
|
if ((idx & 0x3) == (x118_thinkCounter & 0x3)) {
|
||||||
ApplyRepulsion(b, weap->GetTranslation(), 8.f, x148_weaponRepelMagnitude - x168_weaponRepelDamping);
|
ApplyRepulsion(b, weap->GetTranslation(), 8.f, x148_weaponRepelMagnitude - x168_weaponRepelDamping);
|
||||||
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x250_26_enableWeaponRepelDamping = true;
|
x250_26_enableWeaponRepelDamping = true;
|
||||||
|
|
||||||
if (x250_28_killable) {
|
if (x250_28_killable) {
|
||||||
if (auto tb = weap->GetTouchBounds()) {
|
if (const auto tb = weap->GetTouchBounds()) {
|
||||||
for (auto& b : xe8_boids) {
|
for (auto& b : xe8_boids) {
|
||||||
if (b.x20_active &&
|
if (b.x20_active && tb->intersects(zeus::CAABox(weap->GetTranslation() - x170_weaponKillRadius,
|
||||||
tb->intersects(zeus::CAABox(weap->GetTranslation() - x170_weaponKillRadius,
|
weap->GetTranslation() + x170_weaponKillRadius))) {
|
||||||
weap->GetTranslation() + x170_weaponKillRadius)))
|
|
||||||
KillBoid(b);
|
KillBoid(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (x250_29_repelFromThreats) {
|
if (x250_29_repelFromThreats) {
|
||||||
if (TCastToPtr<CPlayer> player = other) {
|
if (const TCastToConstPtr<CPlayer> player = other) {
|
||||||
zeus::CVector3f playerPos = player->GetTranslation();
|
const zeus::CVector3f playerPos = player->GetTranslation();
|
||||||
for (auto& b : xe8_boids) {
|
for (auto& b : xe8_boids) {
|
||||||
zeus::CVector3f adjPlayerPos = playerPos;
|
zeus::CVector3f adjPlayerPos = playerPos;
|
||||||
float zDelta = b.x0_pos.z() - adjPlayerPos.z();
|
const float zDelta = b.x0_pos.z() - adjPlayerPos.z();
|
||||||
if (zDelta > 0.f && zDelta < 2.3f)
|
if (zDelta > 0.f && zDelta < 2.3f) {
|
||||||
adjPlayerPos.z() = float(b.x0_pos.z());
|
adjPlayerPos.z() = float(b.x0_pos.z());
|
||||||
|
}
|
||||||
adjPlayerPos.x() += mgr.GetActiveRandom()->Float() * 0.2f - 0.1f;
|
adjPlayerPos.x() += mgr.GetActiveRandom()->Float() * 0.2f - 0.1f;
|
||||||
adjPlayerPos.y() += mgr.GetActiveRandom()->Float() * 0.2f - 0.1f;
|
adjPlayerPos.y() += mgr.GetActiveRandom()->Float() * 0.2f - 0.1f;
|
||||||
ApplyRepulsion(b, adjPlayerPos, 8.f, x14c_playerRepelMagnitude - x164_playerRepelDamping);
|
ApplyRepulsion(b, adjPlayerPos, 8.f, x14c_playerRepelMagnitude - x164_playerRepelDamping);
|
||||||
|
@ -634,7 +720,7 @@ void CFishCloud::Touch(CActor& other, CStateManager& mgr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CAABox CFishCloud::GetUntransformedBoundingBox() const {
|
zeus::CAABox CFishCloud::GetUntransformedBoundingBox() const {
|
||||||
zeus::CVector3f extent = x120_scale * 0.75f;
|
const zeus::CVector3f extent = x120_scale * 0.75f;
|
||||||
return zeus::CAABox(-extent, extent);
|
return zeus::CAABox(-extent, extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,46 +729,62 @@ zeus::CAABox CFishCloud::GetBoundingBox() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::RemoveRepulsor(TUniqueId sourceId) {
|
void CFishCloud::RemoveRepulsor(TUniqueId sourceId) {
|
||||||
CModifierSource source(sourceId, true, false, 0.f, 0.f);
|
const CModifierSource source(sourceId, true, false, 0.f, 0.f);
|
||||||
auto it = rstl::binary_find(x108_modifierSources.begin(), x108_modifierSources.end(), source);
|
const auto it = rstl::binary_find(x108_modifierSources.begin(), x108_modifierSources.end(), source);
|
||||||
if (it != x108_modifierSources.end())
|
|
||||||
|
if (it == x108_modifierSources.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
x108_modifierSources.erase(it);
|
x108_modifierSources.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFishCloud::RemoveAttractor(TUniqueId sourceId) {
|
void CFishCloud::RemoveAttractor(TUniqueId sourceId) {
|
||||||
CModifierSource source(sourceId, false, false, 0.f, 0.f);
|
const CModifierSource source(sourceId, false, false, 0.f, 0.f);
|
||||||
auto it = rstl::binary_find(x108_modifierSources.begin(), x108_modifierSources.end(), source);
|
const auto it = rstl::binary_find(x108_modifierSources.begin(), x108_modifierSources.end(), source);
|
||||||
if (it != x108_modifierSources.end())
|
|
||||||
|
if (it == x108_modifierSources.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
x108_modifierSources.erase(it);
|
x108_modifierSources.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFishCloud::AddRepulsor(TUniqueId sourceId, bool swirl, float radius, float priority) {
|
bool CFishCloud::AddRepulsor(TUniqueId sourceId, bool swirl, float radius, float priority) {
|
||||||
CModifierSource source(sourceId, true, swirl, radius, priority);
|
const CModifierSource source(sourceId, true, swirl, radius, priority);
|
||||||
auto it = rstl::binary_find(x108_modifierSources.begin(), x108_modifierSources.end(), source);
|
const auto it = rstl::binary_find(x108_modifierSources.begin(), x108_modifierSources.end(), source);
|
||||||
|
|
||||||
if (it != x108_modifierSources.end()) {
|
if (it != x108_modifierSources.end()) {
|
||||||
it->x4_radius = radius;
|
it->x4_radius = radius;
|
||||||
it->x8_priority = priority;
|
it->x8_priority = priority;
|
||||||
return true;
|
return true;
|
||||||
} else if (x108_modifierSources.size() < x108_modifierSources.capacity()) {
|
}
|
||||||
x108_modifierSources.insert(std::lower_bound(
|
|
||||||
x108_modifierSources.begin(), x108_modifierSources.end(), source), source);
|
if (x108_modifierSources.size() < x108_modifierSources.capacity()) {
|
||||||
|
x108_modifierSources.insert(std::lower_bound(x108_modifierSources.begin(), x108_modifierSources.end(), source),
|
||||||
|
source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFishCloud::AddAttractor(TUniqueId sourceId, bool swirl, float radius, float priority) {
|
bool CFishCloud::AddAttractor(TUniqueId sourceId, bool swirl, float radius, float priority) {
|
||||||
CModifierSource source(sourceId, false, swirl, radius, priority);
|
const CModifierSource source(sourceId, false, swirl, radius, priority);
|
||||||
auto it = rstl::binary_find(x108_modifierSources.begin(), x108_modifierSources.end(), source);
|
const auto it = rstl::binary_find(x108_modifierSources.begin(), x108_modifierSources.end(), source);
|
||||||
|
|
||||||
if (it != x108_modifierSources.end()) {
|
if (it != x108_modifierSources.end()) {
|
||||||
it->x4_radius = radius;
|
it->x4_radius = radius;
|
||||||
it->x8_priority = priority;
|
it->x8_priority = priority;
|
||||||
return true;
|
return true;
|
||||||
} else if (x108_modifierSources.size() < x108_modifierSources.capacity()) {
|
}
|
||||||
x108_modifierSources.insert(std::lower_bound(
|
|
||||||
x108_modifierSources.begin(), x108_modifierSources.end(), source), source);
|
if (x108_modifierSources.size() < x108_modifierSources.capacity()) {
|
||||||
|
x108_modifierSources.insert(std::lower_bound(x108_modifierSources.begin(), x108_modifierSources.end(), source),
|
||||||
|
source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue