Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9172d95
Adding font awesome at tag 7.2.0 as a submodule
CCPNobody Jun 24, 2026
e13d78f
Merge branch 'main' of https://github.com/carbonengine/mesh
CCPNobody Jun 25, 2026
0cd1e43
Downgrading font-awesome submodule to 6.7.2
CCPNobody Jun 25, 2026
0a23102
Fontawesome integration
CCPNobody Jun 25, 2026
bebe959
Added better sizing of fontawesome buttons
CCPNobody Jun 26, 2026
4731820
Disabling items when no model is loaded
CCPNobody Jun 26, 2026
68f1df9
Add camera focus state and dynamic focus menu options
CCPNobody Jun 29, 2026
f925004
Merge branch 'main' into PLAT-11506-misc-improvements
CCPNobody Jun 29, 2026
8324001
Adding a changed to chaderCacheCreator that somehow got forgotten in …
CCPNobody Jun 29, 2026
acedf4d
Refactor polygon mode to be per-mesh, update UI and effects
CCPNobody Jun 29, 2026
ecf03cb
Refactor camera near/far plane calculation logic
CCPNobody Jun 30, 2026
3f1a380
Moving all ui rendering to a ui folder
CCPNobody Jun 30, 2026
c956dc0
Refactor UI into modular components
CCPNobody Jul 3, 2026
03ef3f3
Refactor UI and font handling; update icon size types
CCPNobody Jul 3, 2026
2459eef
Fixing a mac build error
CCPNobody Jul 3, 2026
bbdc583
Fixing linter errors
CCPNobody Jul 3, 2026
937ce39
Merge branch 'main' into PLAT-11506-misc-improvements
CCPNobody Jul 3, 2026
8605f73
Fixing more clang errors
CCPNobody Jul 3, 2026
8baef40
Merge branch 'PLAT-11506-misc-improvements' of https://github.com/car…
CCPNobody Jul 3, 2026
18c936f
hopefully fixing a mac compile error
CCPNobody Jul 3, 2026
5e35305
removing an unused file
CCPNobody Jul 3, 2026
0fb644a
Fixing some code review comments
CCPNobody Jul 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "vendor/github.com/carbonengine/vcpkg-registry"]
path = vendor/github.com/carbonengine/vcpkg-registry
url = git@github.com:carbonengine/vcpkg-registry.git
[submodule "vendor/github.com/FortAwesome/Font-Awesome"]
path = vendor/github.com/FortAwesome/Font-Awesome
url = https://github.com/FortAwesome/Font-Awesome
18 changes: 18 additions & 0 deletions src/viewer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ set( SHADER_BINARY_TO_SHADER_CACHE ${CMAKE_CURRENT_SOURCE_DIR}/scripts/shaderCac
set( SOURCE_SHADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/assets/shaders/)
set( GENERATED_SHADER_DIR ${CMAKE_CURRENT_BINARY_DIR}/GeneratedShaders)
set( GLSLC_EXECUTABLE "${VCPKG_INSTALLED_PATH}/tools/shaderc/glslc.exe")
set( FONT_AWESOME_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/scripts/fontAwesomeCreator.py)
set( GENERATED_FONTAWESOME_DIR ${CMAKE_CURRENT_BINARY_DIR}/GeneratedFontAwesome)
set( ENV{VK_LAYER_PATH} "${VCPKG_INSTALLED_PATH}/bin")
set( ENV{VULKAN_SDK} "${VCPKG_INSTALLED_PATH}")

Expand Down Expand Up @@ -80,6 +82,7 @@ ccp_enable_vs_analizers(CarbonMeshViewer)

set(COMPILED_SHADERS "")

# Compile shaders to SPIR-V and generate header files
foreach( SHADER_PATH ${SHADERS} )
file( RELATIVE_PATH SHADER_RELATIVE_PATH ${SOURCE_SHADER_DIR} ${SHADER_PATH} )

Expand All @@ -100,6 +103,7 @@ foreach( SHADER_PATH ${SHADERS} )
endif()
endforeach()

# shader cache generation
add_custom_command(
OUTPUT "${GENERATED_SHADER_DIR}/generatedShaderCache.h"
DEPENDS ${SHADERS} ${COMPILED_SHADERS} ${SHADER_BINARY_TO_SHADER_CACHE}
Expand All @@ -114,9 +118,23 @@ message(STATUS "generated files: ${COMPILED_SHADERS}")
add_custom_target(CompileShaders DEPENDS ${COMPILED_SHADERS})
add_dependencies(CarbonMeshViewer CompileShaders)

# font awesome generation
get_filename_component(FONT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../vendor/github.com/FortAwesome/Font-Awesome" ABSOLUTE)

add_custom_command(
OUTPUT "${GENERATED_FONTAWESOME_DIR}/faBinary.h" "${GENERATED_FONTAWESOME_DIR}/faLookup.h"
DEPENDS ${FONT_AWESOME_GENERATOR} "${FONT_DIR}/webfonts/fa-solid-900.ttf" "${FONT_DIR}/metadata/icons.json"

COMMAND ${Python3_EXECUTABLE} ${FONT_AWESOME_GENERATOR} "${FONT_DIR}/webfonts/fa-solid-900.ttf" "${FONT_DIR}/metadata/icons.json" "${GENERATED_FONTAWESOME_DIR}/faBinary.h" "${GENERATED_FONTAWESOME_DIR}/faLookup.h"
COMMENT "Generating Font Awesome header ${GENERATED_FONTAWESOME_DIR}/faBinary.h and ${GENERATED_FONTAWESOME_DIR}/faLookup.h from ${CMAKE_CURRENT_SOURCE_DIR} and ${FONT_DIR}."
)
add_custom_target(CompileFontAwesome DEPENDS "${GENERATED_FONTAWESOME_DIR}/faBinary.h" "${GENERATED_FONTAWESOME_DIR}/faLookup.h")
add_dependencies(CarbonMeshViewer CompileFontAwesome)

target_link_libraries(CarbonMeshViewer PUBLIC CarbonMesh CcpMath glfw Vulkan::Vulkan imgui::imgui tinyfiledialogs::tinyfiledialogs)
target_precompile_headers(CarbonMeshViewer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h)
target_include_directories(CarbonMeshViewer PRIVATE ${GENERATED_SHADER_DIR})
target_include_directories(CarbonMeshViewer PRIVATE ${GENERATED_FONTAWESOME_DIR})

target_compile_options(CarbonMeshViewer PRIVATE $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-fms-extensions>)
target_compile_features(CarbonMeshViewer PRIVATE cxx_std_17)
Expand Down
3 changes: 3 additions & 0 deletions src/viewer/appState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ void AppState::CallStateCallbacks()
windowSize.CallCallbacks( *this );
mouseState.CallCallbacks( *this );
cameraTrigger.CallCallbacks( *this );
cameraFocus.CallCallbacks( *this );

cmfContent.CallCallbacks( *this );
cmfPath.CallCallbacks( *this );
cmfLoadRequest.CallCallbacks( *this );
exitRequested.CallCallbacks( *this );
showUi.CallCallbacks( *this );

modelState.CallCallbacks( *this );
}
Expand Down
6 changes: 4 additions & 2 deletions src/viewer/appState.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ struct ModelState
State<std::pair<std::string, GraphicsEffectTypes::ShaderInputDeclaration>> activeShader{ {} };
State<std::vector<std::pair<std::string, GraphicsEffectTypes::ShaderInputDeclaration>>> availableShaders{ {} };

State<VkPolygonMode> polygonMode{ VK_POLYGON_MODE_FILL };
State<std::string> currentAnimation{ "" };
State<float> currentAnimationTime{ 0.0f };

Expand All @@ -166,7 +165,6 @@ struct ModelState
meshes.CallCallbacks( appState );
activeShader.CallCallbacks( appState );
availableShaders.CallCallbacks( appState );
polygonMode.CallCallbacks( appState );
currentAnimation.CallCallbacks( appState );
currentAnimationTime.CallCallbacks( appState );
boneDebug.CallCallbacks( appState );
Expand All @@ -189,12 +187,16 @@ struct AppState

// camera
State<CameraTrigger> cameraTrigger{ CameraTrigger::CAMERA_TRIGGER_NONE };
State<CcpMath::Sphere> cameraFocus{ {} };

// cmf
State<std::shared_ptr<CmfContent>> cmfContent{ nullptr };
State<std::string> cmfPath{ "" };
// requests from ui to load cmf data
State<std::string> cmfLoadRequest{ "" };

State<bool> exitRequested{ false };
State<bool> showUi{ true };

// model
ModelState modelState{};
Expand Down
12 changes: 11 additions & 1 deletion src/viewer/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ void Application::Initialize()
m_renderer->Resize( width, height );
} );

m_appState.cmfLoadRequest.RegisterCallback( [this]( std::string path, AppState& ) {
if( !path.empty() )
{
LoadCmfFile( path );
m_appState.cmfLoadRequest.SetValueNoCallback( "" );
}
} );

m_valid = true;
}

Expand All @@ -163,6 +171,7 @@ void Application::Run()

while( !glfwWindowShouldClose( m_window ) && !m_appState.exitRequested.GetValue() )
{

m_appState.CallStateCallbacks();

// Poll for and process events
Expand Down Expand Up @@ -199,6 +208,7 @@ void Application::Run()
m_orientationGizmoRenderer->Render( m_appState, m_camera );

m_uiRenderer->Update( m_appState );

m_uiRenderer->Render( m_appState );

if( m_renderer->EndRender() != VK_SUCCESS )
Expand Down Expand Up @@ -241,10 +251,10 @@ void Application::LoadCmfFile( const std::string& path )
else
{
Log::Info( "Applying model file %s", path.c_str() );
// load the cmf content from the path and set it in the app state
m_appState.cmfPath.SetValue( path );
m_appState.modelState.activeAnimationOwner.SetValue( data );
m_appState.cmfContent.ForceSetValue( data );
m_sceneRenderer->SetData( data, m_appState );
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/viewer/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "rendering/orientationGizmoRenderer.h"
#include "rendering/sceneRenderer.h"
#include "rendering/renderer.h"
#include "rendering/uiRenderer.h"
#include "rendering/ui/uiRenderer.h"

class Application
{
Expand Down
6 changes: 5 additions & 1 deletion src/viewer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ int main( int argc, char** argv )
app.Initialize();
if( argc > 1 )
{
app.LoadCmfFile( argv[1] );
for( int i = 1; i < argc; ++i )
{
Log::Info( "Loading file: %s", argv[i] );
app.LoadCmfFile( argv[i] );
}
}
app.Run();

Expand Down
27 changes: 19 additions & 8 deletions src/viewer/rendering/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ void Camera::Initialize( AppState& state )
SetScreenSize( width, height );
} );

state.cameraTrigger.RegisterCallback( [this]( CameraTrigger trigger, AppState& ) {
HandleCameraTriggerChange( trigger );
state.cameraTrigger.RegisterCallback( [this]( CameraTrigger trigger, AppState& state ) {
CcpMath::Sphere focusSphere = state.cameraFocus.GetValue();
HandleCameraTriggerChange( trigger, focusSphere );
} );

state.mouseState.RegisterCallback( [this]( MouseState newMouseState, AppState& ) {
Expand All @@ -30,17 +31,25 @@ void Camera::Initialize( AppState& state )
SetScreenSize( width, height );
}

void Camera::HandleCameraTriggerChange( CameraTrigger& trigger )
void Camera::HandleCameraTriggerChange( CameraTrigger& trigger, const CcpMath::Sphere& focusSphere )
{
if( trigger == CameraTrigger::CAMERA_TRIGGER_NONE )
{
return;
}

CcpMath::Sphere boundingSphere = m_boundingSphere;
if( focusSphere.radius > 0.0f )
{
boundingSphere = focusSphere;
}
this->LookAt( boundingSphere.center );


switch( trigger )
{
case CameraTrigger::CAMERA_TRIGGER_FOCUS:
this->LookAt( this->m_boundingSphere.center );
m_targetZoom = this->m_boundingSphere.radius * DEFAULT_ZOOM_MULTIPLIER;
m_targetZoom = boundingSphere.radius * DEFAULT_ZOOM_MULTIPLIER;
break;
case CameraTrigger::CAMERA_TRIGGER_LOOK_UP:
this->m_targetRotation = RotationQuaternion( 0.0f, -PI / 2.0f, 0.0f );
Expand Down Expand Up @@ -101,11 +110,13 @@ void Camera::HandleMouseStateChanged( MouseState& mouseState )

Matrix Camera::GetProjection() const
{
const float ABSOLUTE_MIN_NEAR_PLANE = 0.01f;
const float ABSOLUTE_MIN_FAR_PLANE = 1.0f;
const float boundingDepth = m_boundingSphere.radius * 2.0f;
const float centerDepth = -TransformCoord( m_boundingSphere.center, GetView() ).z;
const float nearPlane = std::max( ABSOLUTE_MIN_NEAR_PLANE, centerDepth - boundingDepth );
const float farPlane = std::max( nearPlane + ABSOLUTE_MIN_NEAR_PLANE, centerDepth + boundingDepth );
const float calculatedFar = centerDepth + boundingDepth;
const float farPlane = std::max( ABSOLUTE_MIN_FAR_PLANE, calculatedFar );

const float nearPlane = std::max( farPlane / 100.0f, centerDepth - boundingDepth );

return PerspectiveFovMatrix(
m_fov,
Expand Down
2 changes: 1 addition & 1 deletion src/viewer/rendering/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Camera

void Initialize( AppState& state );

void HandleCameraTriggerChange( CameraTrigger& trigger );
void HandleCameraTriggerChange( CameraTrigger& trigger, const CcpMath::Sphere& focusSphere );

void HandleMouseStateChanged( MouseState& newMouseState );

Expand Down
6 changes: 2 additions & 4 deletions src/viewer/rendering/models/primitiveEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ GraphicsEffect PrimitiveEffects::CreateFlatColorEffect( std::shared_ptr<const Re
effect.RegisterStorageBuffer<uint32_t>( VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT, 2, vertexToBoneMapping.data(), vertexToBoneMapping.size() ); // vertex to bone mapping
effect.RegisterStorageBuffer<uint32_t>( VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT, 3, 0xFF ); // selected bones
effect.RegisterUniformData<ColorInfo>( VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT, 4, colorInfo );
effect.SetConfig( config );
effect.SetShaderName( "flatcolor" );
effect.Reset( "flatcolor", config );
return effect;
}

Expand All @@ -120,8 +119,7 @@ GraphicsEffect PrimitiveEffects::CreateOrientationEffect( std::shared_ptr<const
auto effect = GraphicsEffect( renderer );
effect.RegisterUniformData<PrimitiveEffects::VertexUBO>( VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT, 0 );
effect.RegisterStorageBuffer<Matrix>( VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT, 1, 0xFF );
effect.SetConfig( config );
effect.SetShaderName( "orientationgizmo" );
effect.Reset( "orientationgizmo", config );
return effect;
}

Expand Down
27 changes: 11 additions & 16 deletions src/viewer/rendering/renderable/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,19 @@ MeshRenderable::MeshRenderable( std::shared_ptr<CmfContent> data, const cmf::Mes
}
}
}

m_polygonMode = m_cmfMesh.topology == cmf::MeshTopology::TriangleList ? VK_POLYGON_MODE_FILL : VK_POLYGON_MODE_POINT;
m_topology = m_cmfMesh.topology == cmf::MeshTopology::TriangleList ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST : VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
}

void MeshRenderable::Initialize( AppState& appState )
{
m_prepass.Initialize( appState );

appState.modelState.polygonMode.RegisterCallback( [this]( VkPolygonMode mode, AppState& appState ) {
auto [name, declaration] = appState.modelState.activeShader.GetValue();
SetRenderingMode( name, declaration, mode );
} );

appState.modelState.activeShader.RegisterCallback( [this]( std::pair<std::string, GraphicsEffectTypes::ShaderInputDeclaration> shaderInputDeclaration, AppState& appState ) {
auto [name, declaration] = shaderInputDeclaration;

SetRenderingMode( name, declaration, appState.modelState.polygonMode.GetValue() );
SetRenderingMode( name, declaration );
} );

m_meshIndex = appState.modelState.meshes.AddState( [this]( MeshState& meshState ) {
Expand Down Expand Up @@ -400,24 +398,23 @@ void MeshRenderable::DrawIndexed( GraphicsCommandBuffer& commandBuffer )
}
}

VkResult MeshRenderable::SetRenderingMode( std::string shaderName, GraphicsEffectTypes::ShaderInputDeclaration shaderInputDeclaration, VkPolygonMode polygonMode )
VkResult MeshRenderable::SetRenderingMode( std::string shaderName, GraphicsEffectTypes::ShaderInputDeclaration shaderInputDeclaration )
{
auto logicalDevice = m_renderer->GetDevice()->GetLogicalDevice();

m_polygonMode = polygonMode;
m_shaderName = shaderName;

CR_RETURN( vkDeviceWaitIdle( logicalDevice ) );

auto config = GraphicsEffectTypes::Config();
config.topology = m_topology;
config.polygonMode = polygonMode;
config.cullMode = ( polygonMode == VK_POLYGON_MODE_FILL ) ? VK_CULL_MODE_BACK_BIT : VK_CULL_MODE_NONE;
config.polygonMode = m_polygonMode;
config.cullMode = ( m_polygonMode == VK_POLYGON_MODE_FILL ) ? VK_CULL_MODE_BACK_BIT : VK_CULL_MODE_NONE;
config.inputDeclaration.vertexDeclarations = shaderInputDeclaration.vertexDeclarations;
config.inputDeclaration.stride = m_stride;

m_modelEffect.SetShaderName( m_shaderName );
m_modelEffect.SetConfig( config );
m_modelEffect.Reset( m_shaderName, config );

if( !m_modelEffect.IsInitialized() )
{
m_modelEffect.RegisterUniformData<GraphicsEffect::VertexUboData>( VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT, 0 );
Expand All @@ -443,8 +440,7 @@ VkResult MeshRenderable::SetRenderingMode( std::string shaderName, GraphicsEffec
3,
0 } };

m_wireframeEffect.SetShaderName( "wireframeoverlay" );
m_wireframeEffect.SetConfig( wireframeConfig );
m_wireframeEffect.Reset( "wireframeoverlay", wireframeConfig );
m_wireframeEffect.RegisterUniformData<GraphicsEffect::VertexUboData>( VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT, 0 );
m_wireframeEffect.Initialize();
}
Expand All @@ -469,8 +465,7 @@ GraphicsEffect MeshRenderable::GetAudioOcclusionEffect( std::shared_ptr<const Re
};

GraphicsEffect effect( renderer );
effect.SetShaderName( "Face Normal" );
effect.SetConfig( config );
effect.Reset( "Face Normal", config );
effect.RegisterUniformData<GraphicsEffect::VertexUboData>( VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT, 0 );
return effect;
}
Expand Down
2 changes: 1 addition & 1 deletion src/viewer/rendering/renderable/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MeshRenderable
void Render( GraphicsCommandBuffer& commandBuffer, const AppState& appState, const Camera& camera );
void RenderDebug( GraphicsCommandBuffer& commandBuffer, const AppState& appState, const Camera& camera );
void PrepareMesh( ComputeCommandBuffer& computeCommandBuffer );
VkResult SetRenderingMode( std::string shaderName, GraphicsEffectTypes::ShaderInputDeclaration shaderInputDeclaration, VkPolygonMode polygonMode );
VkResult SetRenderingMode( std::string shaderName, GraphicsEffectTypes::ShaderInputDeclaration shaderInputDeclaration );

void SetAnimation( const cmf::Animation* animation );
void UpdateMeshCurves( float animationTime, const cmf::Animation* animation, AppState& appState );
Expand Down
4 changes: 0 additions & 4 deletions src/viewer/rendering/sceneRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ SceneRenderer::~SceneRenderer()

VkResult SceneRenderer::Initialize( AppState& state )
{
state.cmfContent.RegisterCallback( [this]( std::shared_ptr<CmfContent> content, AppState& appState ) {
this->SetData( content, appState );
} );

state.windowSize.RegisterCallback( [this]( std::pair<uint32_t, uint32_t> size, AppState& appState ) {
auto [width, height] = size;
this->m_graphicsCommandBuffer.SetRenderSize( width, height );
Expand Down
Loading