Skip to content

Commit

Permalink
Make final polishing (challenge end)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikgoe committed Jan 24, 2021
1 parent e66f691 commit 594138c
Showing 1 changed file with 16 additions and 11 deletions.
27 changes: 16 additions & 11 deletions terminalDonut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct Vector3 {
Vector3 operator*( const float &factor ) const { return Vector3{ x * factor, y * factor, z * factor }; }

float dot_product( const Vector3 &other ) const { return x * other.x + y * other.y + z * other.z; }
float length() const { return std::sqrt( this->dot_product( *this ) ); }
};

struct Matrix3 {
Expand Down Expand Up @@ -46,16 +47,16 @@ struct Matrix3 {

int main() {
// Create a simple ring in the xy-plane
const size_t RING_SECTIONS = 32;
const size_t RING_SECTIONS = 64;
Vector3 basic_ring[RING_SECTIONS];
for ( size_t i = 0; i < RING_SECTIONS; i++ )
basic_ring[i] = Vector3::in_xy_circle( i * M_PI * 2 / RING_SECTIONS );

// Create the torus
const size_t TORUS_SECTIONS = 128;
const size_t TORUS_SECTIONS = 256;
Vector3 torus[RING_SECTIONS * TORUS_SECTIONS];
Vector3 normals[RING_SECTIONS * TORUS_SECTIONS];
Vector3 index = Vector3{ 2.5f, 0.f, 0.f };
Vector3 index = Vector3{ 2.f, 0.f, 0.f };
for ( size_t i = 0; i < TORUS_SECTIONS; i++ ) {
auto rotation = Matrix3::rotationAroundY( i * M_PI * 2 / TORUS_SECTIONS );
for ( size_t j = 0; j < RING_SECTIONS; j++ ) {
Expand All @@ -71,13 +72,15 @@ int main() {
float render_buffer[BUFFER_SIZE_X][BUFFER_SIZE_Y];
float z_buffer[BUFFER_SIZE_X][BUFFER_SIZE_Y];
Vector3 center = Vector3{ 32.f, 32.f, 32.f };
Vector3 light_dir = Vector3::in_xy_circle( -M_PI / 2.f );
Vector3 light_dir = Vector3{ -0.4f, -1.f, 0.4f };
light_dir = light_dir * ( 1.f / light_dir.length() );
float time = 0.f;

// Main loop
while ( running ) {
auto x_rotation = Matrix3::rotationAroundX( M_PI / 2.f * std::sin( time * 1.2 ) );
auto y_rotation = Matrix3::rotationAroundY( M_PI / 2.f * std::sin( time + 1.2 ) );
auto x_rotation = Matrix3::rotationAroundX( M_PI / 2.f * std::sin( time * 1.5 ) );
auto y_rotation = Matrix3::rotationAroundY( M_PI / 2.f * std::sin( time * 1.5 + 1.5 ) );
auto z_rotation = Matrix3::rotationAroundZ( M_PI / 2.f * std::sin( time + 1.5 ) );
// Clear buffer
for ( size_t y = 0; y < BUFFER_SIZE_Y; y++ ) {
for ( size_t x = 0; x < BUFFER_SIZE_X; x++ ) {
Expand All @@ -88,15 +91,17 @@ int main() {

// Rotate and project the torus
for ( size_t i = 0; i < TORUS_SECTIONS * RING_SECTIONS; i++ ) {
auto final_position = y_rotation * ( x_rotation * torus[i] );
auto final_normal = y_rotation * ( x_rotation * normals[i] );
final_position = final_position * 6.f + center; // adjust position into viewport
auto final_position = z_rotation * ( y_rotation * ( x_rotation * torus[i] ) );
auto final_normal = z_rotation * ( y_rotation * ( x_rotation * normals[i] ) );
final_position = final_position * 8.f + center; // adjust position into viewport
int x = static_cast<int>( std::round( final_position.x ) );
int y = static_cast<int>( std::round( final_position.y * character_ratio ) );
int z = static_cast<int>( std::round( final_position.z ) );
if ( z_buffer[x][y] + 0.1 < z ) {
if ( z_buffer[x][y] + 0.1f < z ) {
render_buffer[x][y] = final_normal.dot_product( light_dir );
z_buffer[x][y] = final_position.z;
} else if ( std::abs( z_buffer[x][y] - z ) < 0.1f ) {
render_buffer[x][y] = ( render_buffer[x][y] + final_normal.dot_product( light_dir ) ) / 2.f;
}
}

Expand All @@ -117,7 +122,7 @@ int main() {

// Ensure ~60 FPS
std::this_thread::sleep_for( std::chrono::milliseconds( 16 ) );
time += 0.01;
time += 0.015;
}

return 0;
Expand Down

0 comments on commit 594138c

Please sign in to comment.