fix build errors on MSVC

- task-queue.hh: Use mutex fallback on MSVC (no GCC __atomic_* builtins)
- shape-to-mesh.hh: Use kPI/kPI_2 constants instead of M_PI/M_PI_2
- tinyexr_c_impl.c: Use Windows Interlocked functions for MSVC C mode
- unit-task-queue.cc: Fix lambda capture for MSVC

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Syoyo Fujita
2026-01-08 01:05:13 +09:00
parent 598839897a
commit ee72c871cd
4 changed files with 20 additions and 8 deletions

View File

@@ -36,6 +36,14 @@
#define ATOMIC_STORE(var, val) var.store(val)
#define ATOMIC_FETCH_ADD(var, val) var.fetch_add(val)
#define ATOMIC_FETCH_SUB(var, val) var.fetch_sub(val)
#elif defined(_MSC_VER)
/* MSVC C mode doesn't support C11 atomics, use Windows Interlocked functions */
#define ATOMIC_INT volatile long
#define ATOMIC_INIT(var, val) (var) = (val)
#define ATOMIC_LOAD(var) InterlockedCompareExchange(&(var), 0, 0)
#define ATOMIC_STORE(var, val) InterlockedExchange(&(var), (val))
#define ATOMIC_FETCH_ADD(var, val) InterlockedExchangeAdd(&(var), (val))
#define ATOMIC_FETCH_SUB(var, val) InterlockedExchangeAdd(&(var), -(val))
#else
#include <stdatomic.h>
#define ATOMIC_INT atomic_int

View File

@@ -12,10 +12,9 @@
#include <cstdint>
#include <cstddef>
// Detect compiler support for lock-free atomics
#if defined(__GNUC__) || defined(__clang__)
#define TINYUSDZ_TASK_QUEUE_HAS_BUILTIN_ATOMICS 1
#elif defined(_MSC_VER) && (_MSC_VER >= 1900)
// Detect compiler support for GCC-style lock-free atomics
// MSVC does not have __atomic_* builtins, so it uses the mutex fallback
#if (defined(__GNUC__) || defined(__clang__)) && !defined(_MSC_VER)
#define TINYUSDZ_TASK_QUEUE_HAS_BUILTIN_ATOMICS 1
#else
#define TINYUSDZ_TASK_QUEUE_HAS_BUILTIN_ATOMICS 0

View File

@@ -17,6 +17,11 @@
namespace tinyusdz {
namespace tydra {
namespace {
constexpr double kPI = 3.14159265358979323846;
constexpr double kPI_2 = 1.57079632679489661923; // PI / 2
}
///
/// Sphere tessellation modes
///
@@ -145,8 +150,8 @@ inline void GenerateUVSphereMesh(
for (int sector = 0; sector < sectors; sector++) {
float const ringF = static_cast<float>(ring);
float const sectorF = static_cast<float>(sector);
float const pi_f = static_cast<float>(M_PI);
float const pi_2_f = static_cast<float>(M_PI_2);
float const pi_f = static_cast<float>(kPI);
float const pi_2_f = static_cast<float>(kPI_2);
float const y = std::sin(-pi_2_f + pi_f * ringF * R);
float const x = std::cos(2.0f * pi_f * sectorF * S) * std::sin(pi_f * ringF * R);
float const z = std::sin(2.0f * pi_f * sectorF * S) * std::sin(pi_f * ringF * R);
@@ -322,7 +327,7 @@ inline void GenerateIcosphereMesh(
// UV coordinates (spherical projection)
for (int i = 0; i < 3; i++) {
const value::float3 &v = vertices[static_cast<size_t>(face[static_cast<size_t>(i)])];
float const pi_f = static_cast<float>(M_PI);
float const pi_f = static_cast<float>(kPI);
float u = 0.5f + std::atan2(v[2], v[0]) / (2.0f * pi_f);
float v_coord = 0.5f - std::asin(v[1]) / pi_f;
uvs.push_back({u, v_coord});

View File

@@ -158,7 +158,7 @@ void task_queue_multithreaded_test(void) {
// Producer threads
std::vector<std::thread> producers;
for (int i = 0; i < NUM_PRODUCERS; i++) {
producers.emplace_back([&queue, &counter]() {
producers.emplace_back([&queue, &counter, TASKS_PER_PRODUCER]() {
for (int j = 0; j < TASKS_PER_PRODUCER; j++) {
while (!queue.Push(simple_increment, &counter)) {
std::this_thread::yield();