diff options
author | Aki <please@ignore.pl> | 2022-04-01 21:23:39 +0200 |
---|---|---|
committer | Aki <please@ignore.pl> | 2022-04-01 21:23:39 +0200 |
commit | 3c487c5cd69c53d6fea948643c0a76df03516605 (patch) | |
tree | 72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /StarsEx/DetailSet.cpp | |
parent | 8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff) | |
download | starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.zip starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.gz starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.bz2 |
Moved Stars45 to StarsEx
Diffstat (limited to 'StarsEx/DetailSet.cpp')
-rw-r--r-- | StarsEx/DetailSet.cpp | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/StarsEx/DetailSet.cpp b/StarsEx/DetailSet.cpp new file mode 100644 index 0000000..6edaec4 --- /dev/null +++ b/StarsEx/DetailSet.cpp @@ -0,0 +1,225 @@ +/* Starshatter: The Open Source Project + Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors + Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors + Copyright (c) 1997-2006, Destroyer Studios LLC. + + AUTHOR: John DiCamillo + + + OVERVIEW + ======== + Level of Detail manager class +*/ + +#include "DetailSet.h" +#include "Random.h" +#include "Video.h" + +// +--------------------------------------------------------------------+ + +SimRegion* DetailSet::ref_rgn = 0; +Point DetailSet::ref_loc; + +// +--------------------------------------------------------------------+ + +DetailSet::DetailSet() +{ + for (int i = 0; i < MAX_DETAIL; i++) + rad[i] = 0; + + index = -1; + levels = 0; + rgn = 0; +} + +DetailSet::~DetailSet() +{ + Destroy(); +} + +// +--------------------------------------------------------------------+ + +int +DetailSet::DefineLevel(double r, Graphic* g, Point* o, Point* spin_rate) +{ + if (levels < MAX_DETAIL && rep[levels].size() == 0) { + rad[levels] = r; + + if (g) + rep[levels].append(g); + + if (o) + off[levels].append(o); + + else if (g) + off[levels].append(new Point(0,0,0)); + + if (rate.size() == 0) { + if (spin_rate) { + rate.append(spin_rate); + + // randomize the initial orientation: + Point* initial_spin = new Point(); + if (spin_rate->x != 0) initial_spin->x = Random(-PI, PI); + if (spin_rate->y != 0) initial_spin->y = Random(-PI, PI); + if (spin_rate->z != 0) initial_spin->z = Random(-PI, PI); + + spin.append(initial_spin); + } + else { + rate.append(new Point()); + spin.append(new Point()); + } + } + else { + if (spin_rate) + rate[ rep[levels].size() - 1 ] = spin_rate; + } + + levels++; + } + + return levels-1; +} + +void +DetailSet::AddToLevel(int level, Graphic* g, Point* offset, Point* spin_rate) +{ + if (g && level >= 0 && level < levels) { + rep[level].append(g); + + if (!offset) + offset = new Point(0,0,0); + + off[level].append(offset); + + if (spin_rate) { + int nrep = rep[level].size(); + if (nrep > rate.size()) + rate.append(spin_rate); + else + rate[ nrep-1 ] = spin_rate; + } + + if (spin.size() < rep[level].size()) { + Point* initial_spin = new Point(); + + if (spin_rate) { + // randomize the initial orientation: + if (spin_rate->x != 0) initial_spin->x = Random(-PI, PI); + if (spin_rate->y != 0) initial_spin->y = Random(-PI, PI); + if (spin_rate->z != 0) initial_spin->z = Random(-PI, PI); + } + + spin.append(initial_spin); + } + } +} + +int +DetailSet::NumModels(int level) const +{ + if (level >= 0 && level < levels) + return rep[level].size(); + + return 0; +} + +// +--------------------------------------------------------------------+ + +void +DetailSet::ExecFrame(double seconds) +{ + for (int i = 0; i < spin.size() && i < rate.size(); i++) + (*spin[i]) += (*rate[i]) * seconds; +} + +// +--------------------------------------------------------------------+ + +void +DetailSet::SetLocation(SimRegion* r, const Point& p) +{ + rgn = r; + loc = p; +} + +// +--------------------------------------------------------------------+ + +void +DetailSet::SetReference(SimRegion* r, const Point& p) +{ + ref_rgn = r; + ref_loc = p; +} + +// +--------------------------------------------------------------------+ + +int +DetailSet::GetDetailLevel() +{ + index = 0; + + if (rgn == ref_rgn) { + double screen_width = Video::GetInstance()->Width(); + Point delta = loc - ref_loc; + double distance = delta.length(); + + for (int i = 1; i < levels && rad[i] > 0; i++) { + double apparent_feature_size = (rad[i] * screen_width) / distance; + + if (apparent_feature_size > 0.4) + index = i; + } + } + + return index; +} + +// +--------------------------------------------------------------------+ + +Graphic* +DetailSet::GetRep(int level, int n) +{ + if (level >= 0 && level < levels && n >= 0 && n < rep[level].size()) + return rep[level].at(n); + + return 0; +} + +Point +DetailSet::GetOffset(int level, int n) +{ + if (level >= 0 && level < levels && n >= 0 && n < off[level].size()) + return *(off[level].at(n)); + + return Point(); +} + +Point +DetailSet::GetSpin(int level, int n) +{ + if (n >= 0 && n < spin.size()) + return *(spin.at(n)); + + return Point(); +} + +// +--------------------------------------------------------------------+ + +void +DetailSet::Destroy() +{ + for (int i = 0; i < levels; i++) { + ListIter<Graphic> iter = rep[i]; + + while (++iter) { + Graphic* g = iter.removeItem(); + g->Destroy(); // this will delete the object (g) + } + + off[i].destroy(); + } + + rate.destroy(); + spin.destroy(); +} |