void VoxelExplosionGenerator::spawn() {
    // spawn explosionSpawnCount voxels with color and scale at position within a sphere with radius with a speed of ~force in all directions modified by ~impactVector
    Transform transform;

    for (int i = 0; i < m_count; i++) {
        glm::vec3 directionalSpeed = createDirectionalSpeed();

        transform.setScale(createScale());
        transform.setPosition(m_position + (m_radius * safeNormalize(directionalSpeed, glm::vec3(0.0f))));

        Visuals visuals(m_color, m_emissiveness);
        Speed speed(directionalSpeed, createAngularSpeed());

        VoxelParticleSetup particleSetup(
            transform,
            visuals,
            speed,
            createLifetime()
        );

        World::instance()->particleEngine().addParticle(particleSetup, m_creator);
    }
}
void ApplicationEngine::Render() const
{
    vector<Visual> visuals(SurfaceCount);
    
    visuals[0].Color = vec3(255.0f, 1.0f, 1.0f);
    visuals[0].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[0].Orientation = m_orientation;
    visuals[0].RenderMode = GL_TRIANGLES;
    
    visuals[1].Color = vec3(0.0f, 0.0f, 128.0f);
    visuals[1].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[1].Orientation = m_orientation;
    visuals[1].RenderMode = GL_LINES; // must be the same as in Initialize
    
    visuals[2].Color = vec3(0.0f, 128.0f, 0.0f);
    visuals[2].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[2].Orientation = m_orientation;
    visuals[2].RenderMode = GL_TRIANGLES; // must be the same as in Initialize
    
    visuals[3].Color = vec3(0.0f, 128.0f, 0.0f);
    visuals[3].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[3].Orientation = m_orientation;
    visuals[3].RenderMode = GL_TRIANGLES; // must be the same as in Initialize
    
    visuals[4].Color = vec3(0.0f, 128.0f, 0.0f);
    visuals[4].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[4].Orientation = m_orientation;
    visuals[4].RenderMode = GL_TRIANGLES; // must be the same as in Initialize
    
    visuals[5].Color = vec3(0.0f, 128.0f, 0.0f);
    visuals[5].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[5].Orientation = m_orientation;
    visuals[5].RenderMode = GL_TRIANGLES; // must be the same as in Initialize
    
    
    m_renderingEngine->Render(visuals);
}
void ApplicationEngine::Render() const
{
    vector<Visual> visuals(SurfaceCount);
    
    if (!m_animation.Active) {
        PopulateVisuals(&visuals[0]);
    } else {
        float t = m_animation.Elapsed / m_animation.Duration;
        
        for (int i = 0; i < SurfaceCount; i++) {
            
            const Visual& start = m_animation.StartingVisuals[i];
            const Visual& end = m_animation.EndingVisuals[i];
            Visual& tweened = visuals[i];
            
            tweened.Color = start.Color.Lerp(t, end.Color);
            tweened.LowerLeft = start.LowerLeft.Lerp(t, end.LowerLeft);
            tweened.ViewportSize = start.ViewportSize.Lerp(t, end.ViewportSize);
            tweened.Orientation = start.Orientation.Slerp(t, end.Orientation);
        }
    }
    
    m_renderingEngine->Render(visuals);
}