Skip to content

Commit

Permalink
Fixed bugs.
Browse files Browse the repository at this point in the history
Fixed so now s_VertexPosition starts at the top left corner instead of bottom left
Fixed UB in the C++ implementation
Quick changes in Entry.cpp so i can throw frames into ffmpeg directly.
  • Loading branch information
rafa-br34 committed Apr 7, 2024
1 parent ea8d3d6 commit aa625c2
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 29 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Example:
`-a P(500,500)D(0,-1)M(RL)`: Creates a single ant with the state machine `RL`
`-a P(500,500)D(0,-1)M(0)S(10)F(W);P(500,500)D(0,1)M(1)`: Creates two ants using state machine 0 and 1, ant 0 wraps and has a step size of 10
#### `-i`:
Defines how many iterations should be evaluated, by default it will run until all ants run out of bounds or (if wrap is enabled) will run indefinitely. Alternatively it can be specified as time to signal that it should run based on time instead of iterations.
Defines how many iterations should be evaluated, by default it will run until all ants run out of bounds or (if wrap is enabled) will run indefinitely. Alternatively `t` can be added before the number to make it time based.
Example:
`-i i50b`: Run for 50 billion iterations
`-i t100s`: Run a maximum of 100 seconds
Expand All @@ -47,7 +47,13 @@ Defines when a canvas snapshot should be taken. Can be chained using `;`
- `i<interval?>`: Snapshots every `interval` iterations (if not specified 1 is assumed)
- `f`: Snapshots the final state
#### `-o`:
For now `-o` just defines which folder to output the images, in the near future proper arguments and output formatting will be added.

Defines how to output images.
- `f:<format>:<name>`: Write image files. `%d` can be used for the image index and `%i` for the current iteration.
- `s:<format>:<stdout|stderr|stream>:<stream_name?>`: Write images to a pipe/stream.
Supported formats:
- `idx`/`u8`: Outputs the raw buffer.
- `rgb24`: Outputs the raw buffer as RGB24.
- `png`: Outputs the raw buffer as PNG.
- `idx-gzip`/`u8-gzip`: Outputs a compressed version of the buffer.
#### `-t`:
Defines how many threads should be used, for now this argument only changes the amount of threads used when encoding images, *eventually* multithreading for the ants will also be added.
35 changes: 22 additions & 13 deletions SOURCE/Entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ int main(int ArgCount, const char* ArgValues[]) {
}
*/


int main(int ArgCount, const char* ArgValues[]) {
using enum DirectionEnum;
std::vector<DirectionEnum> StateMachine = {
Expand All @@ -129,9 +128,9 @@ int main(int ArgCount, const char* ArgValues[]) {

};

std::cout << "State machine: " << StateMachineToString(StateMachine, "") << '\n';
//std::cout << "State machine: " << StateMachineToString(StateMachine, "") << '\n';

Vector2<int> CanvasSize(1000, 1000);//{ 30720, 17280 };
Vector2<int> CanvasSize(1920, 1920);//{ 30720, 17280 };

SimulationState<uint8_t, int> Simulation;
EncoderState Encoder;
Expand All @@ -147,34 +146,44 @@ int main(int ArgCount, const char* ArgValues[]) {
Ants.push_back(Ant<uint8_t>(Center - Vector2(10, 0), Vector2<int8_t>( 1, 0), StateMachine, StateMachineSize));
//*/
auto Center = CanvasSize / Vector2(2, 2);
Simulation.AddAnt(Ant<uint8_t>(Center, Vector2<int8_t>(0, -1), {R,L}, true));
//Simulation.AddAnt(Ant<uint8_t>(Center, Vector2<int8_t>(0, -1), {R,L}, true));

//Simulation.AddAnt(Ant<uint8_t>(Center, Vector2<int8_t>(0, -1), {C,C,C,C,C,C,U,C,C,C,C,C,R45,R,R45,L135,U,C,U,L,L,R135,L45,R45,R,R135,L45,R,R,R45}, true));

//Simulation.AddAnt(Ant<uint8_t>(Center, Vector2<int8_t>(0, -1), {R,L,R,R,L,R,R,L,R,R,L,R}, true));
//Simulation.AddAnt(Ant<uint8_t>(Center, Vector2<int8_t>(0, -1), {R,L,C}, true));
Simulation.AddAnt(Ant<uint8_t>(Center, Vector2<int8_t>(0, 1), {R,L,R,R,L,R,R,L,R,R,L,R}, true));
Simulation.AddAnt(Ant<uint8_t>(Center, Vector2<int8_t>(0, 1), {R,L,C}, true));

// ffmpeg -r 60 -i "Frames/%d.png" -b:v 5M -c:v libx264 -preset veryslow -qp 0 output.mp4
// ffmpeg -r 60 -i "Frames/%d.png" -b:v 5M -c:v libx264 -preset veryslow -qp 0 -s 1920x1920 output.mp4
// ffmpeg -r 60 -i "Frames/%d.png" -b:v 5M -c:v libx264 -preset veryslow -qp 0 -s 1920x1920 -sws_flags neighbor output.mp4
// ffmpeg -r 30 -i "Frames/%d.png" -c:v libx264 -preset veryslow -qp 0 -s 7680x4320 output.mp4
// ./LangtonsAnt | ~/ffmpeg/ffmpeg -y -f rawvideo -pix_fmt rgba -s 1920x1920 -r 30 -i - -c:v libx264 -preset veryslow output.h264
// ./LangtonsAnt | ~/ffmpeg/ffmpeg -y -f rawvideo -pix_fmt rgba -s 1920x1920 -r 30 -i - -c:v libx264 -preset veryslow -s 1920x1920 output.h264
// 1ull * 1000000000ull 1b
// 1ull * 1000000ull 1m

size_t Iterations = 1ull * 16000ull;
double FrameRate = 1.0; // Video frame rate
double Time = 1.0; // Video time
size_t Iterations = 1ull * 1000000000ull;
double FrameRate = 30.0; // Video frame rate
double Time = 240.0; // Video time
size_t Frames = size_t(Time * FrameRate);

size_t CaptureDelta = size_t(double(Iterations) / double(Frames));

size_t FrameSize = (size_t)CanvasSize.X * (size_t)CanvasSize.Y;
uint32_t* FrameBuffer = new uint32_t[FrameSize];

Simulation.Reset();
Encoder.Threads = 2;
Encoder.Threads = 75;
for (size_t i = 0; i < Frames; i++) {
std::cout << i << ' ' << Simulation.Simulate(CaptureDelta) << '/' << CaptureDelta << '\n';
Simulation.Simulate(CaptureDelta);//std::cout << "i:" << i << ' ' << Simulation.Simulate(CaptureDelta) << '/' << CaptureDelta << '\n';

//Encoder.EncodeSync(Simulation, std::string("Frames/") + std::to_string(i) +".png");
Encoder.EncodeAsync(Simulation, std::string("State_") + std::to_string(i) +".png");
for (size_t p = 0; p < FrameSize; p++) {
FrameBuffer[p] = Encoder.GetColor(Simulation.CanvasPointer[p]) & 0x00FFFFFF;
}
fwrite(FrameBuffer, 1, FrameSize * sizeof(uint32_t), stdout);
//Encoder.EncodeAsync(Simulation, std::string("Frames/") + std::to_string(i) +".png");
}

delete[] FrameBuffer;
Encoder.WaitJobs();
}
5 changes: 2 additions & 3 deletions SOURCE/Types/Ant.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class Ant {

CellType* Cell = Grid + FLATTEN_2D(Pos.X, Pos.Y, GridSize.X);

Rotate((int8_t)StateMachine[*Cell]);
Rotate((int8_t)StateMachine[*Cell % StateMachine.size()]);
Pos += Dir * StepSize;

*Cell = (*Cell + 1) % StateMachine.size();
Expand All @@ -118,8 +118,7 @@ class Ant {
auto& Dir = Direction;
auto& Pos = Position;

Rotate((int8_t)StateMachine[Grid[FLATTEN_2D(Pos.X, Pos.Y, GridSize.X)]]);

Rotate((int8_t)StateMachine[Grid[FLATTEN_2D(Pos.X, Pos.Y, GridSize.X)] % StateMachine.size()]);
Last = Pos;
Pos += Dir * StepSize;

Expand Down
9 changes: 7 additions & 2 deletions SOURCE/Types/EncoderState.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ typedef uint32_t(* ColorDescriptor)(size_t);
class EncoderState {
private:
std::vector<uint32_t> m_PaletteCache = {};
size_t m_PaletteSize = 0; // @todo Improve palette generation (add caching)

std::atomic<size_t> m_ThreadsActive = 0; // @todo std::atomic might not be required
std::condition_variable m_ThreadsSignal = {};
Expand Down Expand Up @@ -55,7 +54,7 @@ class EncoderState {

size_t CacheSize = m_PaletteCache.size();
if (StateCount <= CacheSize) {
if (m_PaletteCache.size() - CacheSize > CacheSize / 2)
if (CacheSize - StateCount > CacheSize * 2)
m_PaletteCache.resize(StateCount);

return;
Expand Down Expand Up @@ -123,6 +122,12 @@ class EncoderState {
ColorDescriptor Coloring = [](size_t Index) -> uint32_t { auto I = uint32_t(Index); XOR_SHIFT32(I); return I * 0x9E3779B9; };
size_t Threads = 1;

INLINE uint32_t GetColor(size_t Index) {
if (Index + 1 > m_PaletteCache.size())
m_UpdatePaletteCache(Index + 1);

return m_PaletteCache[Index];
}

template<typename CellType, typename SizeType>
unsigned int EncodeSync(const SimulationState<CellType, SizeType>& State, std::string Path) {
Expand Down
2 changes: 1 addition & 1 deletion SOURCE/Types/SimulationState.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ class SimulationState {
SimulationState() = default;
SimulationState(const Vector2<SizeType>& Size) { Resize(Size); }

~SimulationState() { m_Deallocate(); }
virtual ~SimulationState() { m_Deallocate(); }
};
3 changes: 2 additions & 1 deletion WEBSITE/Scripts/Ant.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,12 @@ class Ant {
let Last = this.LastPosition
let Pos = this.Position
let Dir = this.Direction

this.Rotate(this.StateMachine[Grid[GridSize.X * Pos.Y + Pos.X] % this.StateMachine.length])

Last.X = Pos.X
Last.Y = Pos.Y

this.Rotate(this.StateMachine[Grid[GridSize.X * Pos.Y + Pos.X] % this.StateMachine.length])
Pos.X += Dir.X * this.StepSize
Pos.Y += Dir.Y * this.StepSize

Expand Down
25 changes: 19 additions & 6 deletions WEBSITE/Scripts/Classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,38 @@ class SimulationState {
}
}

Update(Iterations=1) {
Update(Iterations = 1) {
let GridSize = this.GridSize
let Grid = this.Grid
let Ants = this.Ants

let Iterated = 0

if (Ants.length == 1) { // Use single step update (faster)
let AntObject = Ants[0]
for (let i = 0; i < Iterations; i++) {
if (!AntObject.Update(Grid, GridSize)) Ants.splice(0, 1)
for (; Iterated < Iterations; Iterated++) {
if (!AntObject.Update(Grid, GridSize)) {
Ants.splice(0, 1)
break
}
}
}
else { // Use double step update (slower)
for (let i = 0; i < Iterations; i++) {
for (; Iterated < Iterations; Iterated++) {
for (let AntObject of Ants) AntObject.UpdatePosition(Grid, GridSize)
for (let i = 0; i < Ants.length; i++) if (!Ants[i].UpdateCell(Grid, GridSize)) Ants.splice(i, 1)

for (let i = 0; i < Ants.length; i++) {
if (!Ants[i].UpdateCell(Grid, GridSize)) {
Ants.splice(i, 1)
break
}
}
}
}

this.TotalIterations += Iterations
this.TotalIterations += Iterated

return Iterated
}

ResizeGrid(X, Y) {
Expand Down
1 change: 1 addition & 0 deletions WEBSITE/Shaders/Vertex.vert
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ void main() {
gl_Position = Position * vec4(1.0, RY, 1.0, 1.0);

s_VertexPosition = (a_VertexPosition.xy + 1.0) / 2.0;
s_VertexPosition.x = 1.0 - s_VertexPosition.x;
}

0 comments on commit aa625c2

Please sign in to comment.