diff --git a/modules/generator/src/main/kotlin/org/lwjgl/generator/Modules.kt b/modules/generator/src/main/kotlin/org/lwjgl/generator/Modules.kt
index f7a1b9bdb4..2aa9d00d37 100644
--- a/modules/generator/src/main/kotlin/org/lwjgl/generator/Modules.kt
+++ b/modules/generator/src/main/kotlin/org/lwjgl/generator/Modules.kt
@@ -665,24 +665,6 @@ git branch -D @{-1}""")}"""}()}
}"""
)
),
- TOOTLE(
- "tootle",
- "org.lwjgl.util.tootle",
- """
- Contains bindings to ${url("https://gpuopen.com/archived/tootle/", "AMD Tootle")}.
-
- AMD Tootle (Triangle Order Optimization Tool) is a 3D triangle mesh optimization library that improves on existing mesh preprocessing techniques. By
- using AMD Tootle, developers can optimize their models for pixel overdraw as well as vertex cache performance. This can provide significant performance
- improvements in pixel limited situations, with no penalty in vertex-limited scenarios, and no runtime cost.
-
- Resources
- ${ul(
- url("https://github.com/GPUOpen-Archive/amd_tootle", "Source Repository")
- )}
- """,
- library = JNILibrary.simple(),
- arrayOverloads = false
- ),
VMA(
"vma",
"org.lwjgl.util.vma",
diff --git a/modules/lwjgl/tootle/src/generated/c/org_lwjgl_util_tootle_Tootle.cpp b/modules/lwjgl/tootle/src/generated/c/org_lwjgl_util_tootle_Tootle.cpp
deleted file mode 100644
index e0b2174497..0000000000
--- a/modules/lwjgl/tootle/src/generated/c/org_lwjgl_util_tootle_Tootle.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright LWJGL. All rights reserved.
- * License terms: https://www.lwjgl.org/license
- * MACHINE GENERATED FILE, DO NOT EDIT
- */
-#include "common_tools.h"
-#include "tootlelib.h"
-
-EXTERN_C_ENTER
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_TootleInit(JNIEnv *__env, jclass clazz) {
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleInit();
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleOptimizeVCache(JNIEnv *__env, jclass clazz, jlong pnIBAddress, jint nFaces, jint nVertices, jint nCacheSize, jlong pnIBOutAddress, jlong pnFaceRemapOutAddress, jint eVCacheOptimizer) {
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- unsigned int *pnIBOut = (unsigned int *)(uintptr_t)pnIBOutAddress;
- unsigned int *pnFaceRemapOut = (unsigned int *)(uintptr_t)pnFaceRemapOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleOptimizeVCache(pnIB, (unsigned int)nFaces, (unsigned int)nVertices, (unsigned int)nCacheSize, pnIBOut, pnFaceRemapOut, (TootleVCacheOptimizer)eVCacheOptimizer);
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleClusterMesh(JNIEnv *__env, jclass clazz, jlong pVBAddress, jlong pnIBAddress, jint nVertices, jint nFaces, jint nVBStride, jint nTargetClusters, jlong pnClusteredIBOutAddress, jlong pnFaceClustersOutAddress, jlong pnFaceRemapOutAddress) {
- void const *pVB = (void const *)(uintptr_t)pVBAddress;
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- unsigned int *pnClusteredIBOut = (unsigned int *)(uintptr_t)pnClusteredIBOutAddress;
- unsigned int *pnFaceClustersOut = (unsigned int *)(uintptr_t)pnFaceClustersOutAddress;
- unsigned int *pnFaceRemapOut = (unsigned int *)(uintptr_t)pnFaceRemapOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleClusterMesh(pVB, pnIB, (unsigned int)nVertices, (unsigned int)nFaces, (unsigned int)nVBStride, (unsigned int)nTargetClusters, pnClusteredIBOut, pnFaceClustersOut, pnFaceRemapOut);
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleFastOptimizeVCacheAndClusterMesh(JNIEnv *__env, jclass clazz, jlong pnIBAddress, jint nFaces, jint nVertices, jint nCacheSize, jlong pnIBOutAddress, jlong pnClustersOutAddress, jlong pnNumClustersOutAddress, jfloat fAlpha) {
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- unsigned int *pnIBOut = (unsigned int *)(uintptr_t)pnIBOutAddress;
- unsigned int *pnClustersOut = (unsigned int *)(uintptr_t)pnClustersOutAddress;
- unsigned int *pnNumClustersOut = (unsigned int *)(uintptr_t)pnNumClustersOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleFastOptimizeVCacheAndClusterMesh(pnIB, (unsigned int)nFaces, (unsigned int)nVertices, (unsigned int)nCacheSize, pnIBOut, pnClustersOut, pnNumClustersOut, fAlpha);
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleOptimizeOverdraw(JNIEnv *__env, jclass clazz, jlong pVBAddress, jlong pnIBAddress, jint nVertices, jint nFaces, jint nVBStride, jlong pfViewpointAddress, jint nViewpoints, jint eFrontWinding, jlong pnFaceClustersAddress, jlong pnIBOutAddress, jlong pnClusterRemapOutAddress, jint eOverdrawOptimizer) {
- void const *pVB = (void const *)(uintptr_t)pVBAddress;
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- float const *pfViewpoint = (float const *)(uintptr_t)pfViewpointAddress;
- unsigned int const *pnFaceClusters = (unsigned int const *)(uintptr_t)pnFaceClustersAddress;
- unsigned int *pnIBOut = (unsigned int *)(uintptr_t)pnIBOutAddress;
- unsigned int *pnClusterRemapOut = (unsigned int *)(uintptr_t)pnClusterRemapOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleOptimizeOverdraw(pVB, pnIB, (unsigned int)nVertices, (unsigned int)nFaces, (unsigned int)nVBStride, pfViewpoint, (unsigned int)nViewpoints, (TootleFaceWinding)eFrontWinding, pnFaceClusters, pnIBOut, pnClusterRemapOut, (TootleOverdrawOptimizer)eOverdrawOptimizer);
-}
-
-JNIEXPORT void JNICALL Java_org_lwjgl_util_tootle_Tootle_TootleCleanup(JNIEnv *__env, jclass clazz) {
- UNUSED_PARAMS(__env, clazz)
- TootleCleanup();
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleOptimize(JNIEnv *__env, jclass clazz, jlong pVBAddress, jlong pnIBAddress, jint nVertices, jint nFaces, jint nVBStride, jint nCacheSize, jlong pViewpointsAddress, jint nViewpoints, jint eFrontWinding, jlong pnIBOutAddress, jlong pnNumClustersOutAddress, jint eVCacheOptimizer, jint eOverdrawOptimizer) {
- void const *pVB = (void const *)(uintptr_t)pVBAddress;
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- float const *pViewpoints = (float const *)(uintptr_t)pViewpointsAddress;
- unsigned int *pnIBOut = (unsigned int *)(uintptr_t)pnIBOutAddress;
- unsigned int *pnNumClustersOut = (unsigned int *)(uintptr_t)pnNumClustersOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleOptimize(pVB, pnIB, (unsigned int)nVertices, (unsigned int)nFaces, (unsigned int)nVBStride, (unsigned int)nCacheSize, pViewpoints, (unsigned int)nViewpoints, (TootleFaceWinding)eFrontWinding, pnIBOut, pnNumClustersOut, (TootleVCacheOptimizer)eVCacheOptimizer, (TootleOverdrawOptimizer)eOverdrawOptimizer);
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleFastOptimize(JNIEnv *__env, jclass clazz, jlong pVBAddress, jlong pnIBAddress, jint nVertices, jint nFaces, jint nVBStride, jint nCacheSize, jint eFrontWinding, jlong pnIBOutAddress, jlong pnNumClustersOutAddress, jfloat fAlpha) {
- void const *pVB = (void const *)(uintptr_t)pVBAddress;
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- unsigned int *pnIBOut = (unsigned int *)(uintptr_t)pnIBOutAddress;
- unsigned int *pnNumClustersOut = (unsigned int *)(uintptr_t)pnNumClustersOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleFastOptimize(pVB, pnIB, (unsigned int)nVertices, (unsigned int)nFaces, (unsigned int)nVBStride, (unsigned int)nCacheSize, (TootleFaceWinding)eFrontWinding, pnIBOut, pnNumClustersOut, fAlpha);
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleVCacheClusters(JNIEnv *__env, jclass clazz, jlong pnIBAddress, jint nFaces, jint nVertices, jint nCacheSize, jlong pnFaceClustersAddress, jlong pnIBOutAddress, jlong pnFaceRemapOutAddress, jint eVCacheOptimizer) {
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- unsigned int const *pnFaceClusters = (unsigned int const *)(uintptr_t)pnFaceClustersAddress;
- unsigned int *pnIBOut = (unsigned int *)(uintptr_t)pnIBOutAddress;
- unsigned int *pnFaceRemapOut = (unsigned int *)(uintptr_t)pnFaceRemapOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleVCacheClusters(pnIB, (unsigned int)nFaces, (unsigned int)nVertices, (unsigned int)nCacheSize, pnFaceClusters, pnIBOut, pnFaceRemapOut, (TootleVCacheOptimizer)eVCacheOptimizer);
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleMeasureCacheEfficiency(JNIEnv *__env, jclass clazz, jlong pnIBAddress, jint nFaces, jint nCacheSize, jlong pfEfficiencyOutAddress) {
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- float *pfEfficiencyOut = (float *)(uintptr_t)pfEfficiencyOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleMeasureCacheEfficiency(pnIB, (unsigned int)nFaces, (unsigned int)nCacheSize, pfEfficiencyOut);
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleMeasureOverdraw(JNIEnv *__env, jclass clazz, jlong pVBAddress, jlong pnIBAddress, jint nVertices, jint nFaces, jint nVBStride, jlong pfViewpointAddress, jint nViewpoints, jint eFrontWinding, jlong pfAvgODOutAddress, jlong pfMaxODOutAddress, jint eOverdrawOptimizer) {
- void const *pVB = (void const *)(uintptr_t)pVBAddress;
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- float const *pfViewpoint = (float const *)(uintptr_t)pfViewpointAddress;
- float *pfAvgODOut = (float *)(uintptr_t)pfAvgODOutAddress;
- float *pfMaxODOut = (float *)(uintptr_t)pfMaxODOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleMeasureOverdraw(pVB, pnIB, (unsigned int)nVertices, (unsigned int)nFaces, (unsigned int)nVBStride, pfViewpoint, (unsigned int)nViewpoints, (TootleFaceWinding)eFrontWinding, pfAvgODOut, pfMaxODOut, (TootleOverdrawOptimizer)eOverdrawOptimizer);
-}
-
-JNIEXPORT jint JNICALL Java_org_lwjgl_util_tootle_Tootle_nTootleOptimizeVertexMemory(JNIEnv *__env, jclass clazz, jlong pVBAddress, jlong pnIBAddress, jint nVertices, jint nFaces, jint nVBStride, jlong pVBOutAddress, jlong pnIBOutAddress, jlong pnVertexRemapOutAddress) {
- void const *pVB = (void const *)(uintptr_t)pVBAddress;
- unsigned int const *pnIB = (unsigned int const *)(uintptr_t)pnIBAddress;
- void *pVBOut = (void *)(uintptr_t)pVBOutAddress;
- unsigned int *pnIBOut = (unsigned int *)(uintptr_t)pnIBOutAddress;
- unsigned int *pnVertexRemapOut = (unsigned int *)(uintptr_t)pnVertexRemapOutAddress;
- UNUSED_PARAMS(__env, clazz)
- return (jint)TootleOptimizeVertexMemory(pVB, pnIB, (unsigned int)nVertices, (unsigned int)nFaces, (unsigned int)nVBStride, pVBOut, pnIBOut, pnVertexRemapOut);
-}
-
-EXTERN_C_EXIT
diff --git a/modules/lwjgl/tootle/src/generated/java/org/lwjgl/util/tootle/Tootle.java b/modules/lwjgl/tootle/src/generated/java/org/lwjgl/util/tootle/Tootle.java
deleted file mode 100644
index 72d11d1168..0000000000
--- a/modules/lwjgl/tootle/src/generated/java/org/lwjgl/util/tootle/Tootle.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright LWJGL. All rights reserved.
- * License terms: https://www.lwjgl.org/license
- * MACHINE GENERATED FILE, DO NOT EDIT
- */
-package org.lwjgl.util.tootle;
-
-import org.jspecify.annotations.*;
-
-import java.nio.*;
-
-import org.lwjgl.system.*;
-
-import static org.lwjgl.system.Checks.*;
-import static org.lwjgl.system.MemoryUtil.*;
-
-public class Tootle {
-
- static { Library.loadSystem(System::load, System::loadLibrary, Tootle.class, "org.lwjgl.tootle", Platform.mapLibraryNameBundled("lwjgl_tootle")); }
-
- public static final int TOOTLE_DEFAULT_VCACHE_SIZE = 16;
-
- public static final int TOOTLE_MAX_FACES = 0x7FFFFFFF;
-
- public static final int TOOTLE_MAX_VERTICES = 0x7FFFFFFF;
-
- public static final float TOOTLE_DEFAULT_ALPHA = 0.75f;
-
- public static final int
- TOOTLE_OK = 1,
- TOOTLE_INVALID_ARGS = 2,
- TOOTLE_OUT_OF_MEMORY = 3,
- TOOTLE_3D_API_ERROR = 4,
- TOOTLE_INTERNAL_ERROR = 5,
- TOOTLE_NOT_INITIALIZED = 6;
-
- public static final int
- TOOTLE_CCW = 1,
- TOOTLE_CW = 2;
-
- public static final int
- TOOTLE_VCACHE_AUTO = 1,
- TOOTLE_VCACHE_DIRECT3D = 2,
- TOOTLE_VCACHE_LSTRIPS = 3,
- TOOTLE_VCACHE_TIPSY = 4;
-
- public static final int
- TOOTLE_OVERDRAW_AUTO = 1,
- TOOTLE_OVERDRAW_DIRECT3D = 2,
- TOOTLE_OVERDRAW_RAYTRACE = 3,
- TOOTLE_OVERDRAW_FAST = 4;
-
- protected Tootle() {
- throw new UnsupportedOperationException();
- }
-
- // --- [ TootleInit ] ---
-
- /** {@code TootleResult TootleInit(void)} */
- @NativeType("TootleResult")
- public static native int TootleInit();
-
- // --- [ TootleOptimizeVCache ] ---
-
- /** {@code TootleResult TootleOptimizeVCache(unsigned int const * pnIB, unsigned int nFaces, unsigned int nVertices, unsigned int nCacheSize, unsigned int * pnIBOut, unsigned int * pnFaceRemapOut, TootleVCacheOptimizer eVCacheOptimizer)} */
- public static native int nTootleOptimizeVCache(long pnIB, int nFaces, int nVertices, int nCacheSize, long pnIBOut, long pnFaceRemapOut, int eVCacheOptimizer);
-
- /** {@code TootleResult TootleOptimizeVCache(unsigned int const * pnIB, unsigned int nFaces, unsigned int nVertices, unsigned int nCacheSize, unsigned int * pnIBOut, unsigned int * pnFaceRemapOut, TootleVCacheOptimizer eVCacheOptimizer)} */
- @NativeType("TootleResult")
- public static int TootleOptimizeVCache(@NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVertices, @NativeType("unsigned int") int nCacheSize, @NativeType("unsigned int *") @Nullable IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnFaceRemapOut, @NativeType("TootleVCacheOptimizer") int eVCacheOptimizer) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- checkSafe(pnIBOut, pnIB.remaining());
- checkSafe(pnFaceRemapOut, nFaces);
- }
- return nTootleOptimizeVCache(memAddress(pnIB), nFaces, nVertices, nCacheSize, memAddressSafe(pnIBOut), memAddressSafe(pnFaceRemapOut), eVCacheOptimizer);
- }
-
- // --- [ TootleClusterMesh ] ---
-
- /** {@code TootleResult TootleClusterMesh(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nTargetClusters, unsigned int * pnClusteredIBOut, unsigned int * pnFaceClustersOut, unsigned int * pnFaceRemapOut)} */
- public static native int nTootleClusterMesh(long pVB, long pnIB, int nVertices, int nFaces, int nVBStride, int nTargetClusters, long pnClusteredIBOut, long pnFaceClustersOut, long pnFaceRemapOut);
-
- /** {@code TootleResult TootleClusterMesh(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nTargetClusters, unsigned int * pnClusteredIBOut, unsigned int * pnFaceClustersOut, unsigned int * pnFaceRemapOut)} */
- @NativeType("TootleResult")
- public static int TootleClusterMesh(@NativeType("void const *") ByteBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("unsigned int") int nTargetClusters, @NativeType("unsigned int *") IntBuffer pnClusteredIBOut, @NativeType("unsigned int *") IntBuffer pnFaceClustersOut, @NativeType("unsigned int *") @Nullable IntBuffer pnFaceRemapOut) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- check(pnClusteredIBOut, pnIB.remaining());
- check(pnFaceClustersOut, nFaces + 1);
- checkSafe(pnFaceRemapOut, nFaces);
- }
- return nTootleClusterMesh(memAddress(pVB), memAddress(pnIB), pVB.remaining() / nVBStride, nFaces, nVBStride, nTargetClusters, memAddress(pnClusteredIBOut), memAddress(pnFaceClustersOut), memAddressSafe(pnFaceRemapOut));
- }
-
- /** {@code TootleResult TootleClusterMesh(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nTargetClusters, unsigned int * pnClusteredIBOut, unsigned int * pnFaceClustersOut, unsigned int * pnFaceRemapOut)} */
- @NativeType("TootleResult")
- public static int TootleClusterMesh(@NativeType("void const *") FloatBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("unsigned int") int nTargetClusters, @NativeType("unsigned int *") IntBuffer pnClusteredIBOut, @NativeType("unsigned int *") IntBuffer pnFaceClustersOut, @NativeType("unsigned int *") @Nullable IntBuffer pnFaceRemapOut) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- check(pnClusteredIBOut, pnIB.remaining());
- check(pnFaceClustersOut, nFaces + 1);
- checkSafe(pnFaceRemapOut, nFaces);
- }
- return nTootleClusterMesh(memAddress(pVB), memAddress(pnIB), (int)(((long)pVB.remaining() << 2) / nVBStride), nFaces, nVBStride, nTargetClusters, memAddress(pnClusteredIBOut), memAddress(pnFaceClustersOut), memAddressSafe(pnFaceRemapOut));
- }
-
- // --- [ TootleFastOptimizeVCacheAndClusterMesh ] ---
-
- /** {@code TootleResult TootleFastOptimizeVCacheAndClusterMesh(unsigned int const * pnIB, unsigned int nFaces, unsigned int nVertices, unsigned int nCacheSize, unsigned int * pnIBOut, unsigned int * pnClustersOut, unsigned int * pnNumClustersOut, float fAlpha)} */
- public static native int nTootleFastOptimizeVCacheAndClusterMesh(long pnIB, int nFaces, int nVertices, int nCacheSize, long pnIBOut, long pnClustersOut, long pnNumClustersOut, float fAlpha);
-
- /** {@code TootleResult TootleFastOptimizeVCacheAndClusterMesh(unsigned int const * pnIB, unsigned int nFaces, unsigned int nVertices, unsigned int nCacheSize, unsigned int * pnIBOut, unsigned int * pnClustersOut, unsigned int * pnNumClustersOut, float fAlpha)} */
- @NativeType("TootleResult")
- public static int TootleFastOptimizeVCacheAndClusterMesh(@NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVertices, @NativeType("unsigned int") int nCacheSize, @NativeType("unsigned int *") IntBuffer pnIBOut, @NativeType("unsigned int *") IntBuffer pnClustersOut, @NativeType("unsigned int *") IntBuffer pnNumClustersOut, float fAlpha) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- check(pnIBOut, pnIB.remaining());
- check(pnClustersOut, nFaces + 1);
- check(pnNumClustersOut, 1);
- }
- return nTootleFastOptimizeVCacheAndClusterMesh(memAddress(pnIB), nFaces, nVertices, nCacheSize, memAddress(pnIBOut), memAddress(pnClustersOut), memAddress(pnNumClustersOut), fAlpha);
- }
-
- // --- [ TootleOptimizeOverdraw ] ---
-
- /** {@code TootleResult TootleOptimizeOverdraw(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, float const * pfViewpoint, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, unsigned int const * pnFaceClusters, unsigned int * pnIBOut, unsigned int * pnClusterRemapOut, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- public static native int nTootleOptimizeOverdraw(long pVB, long pnIB, int nVertices, int nFaces, int nVBStride, long pfViewpoint, int nViewpoints, int eFrontWinding, long pnFaceClusters, long pnIBOut, long pnClusterRemapOut, int eOverdrawOptimizer);
-
- /** {@code TootleResult TootleOptimizeOverdraw(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, float const * pfViewpoint, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, unsigned int const * pnFaceClusters, unsigned int * pnIBOut, unsigned int * pnClusterRemapOut, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- @NativeType("TootleResult")
- public static int TootleOptimizeOverdraw(@NativeType("void const *") ByteBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("float const *") @Nullable FloatBuffer pfViewpoint, @NativeType("TootleFaceWinding") int eFrontWinding, @NativeType("unsigned int const *") IntBuffer pnFaceClusters, @NativeType("unsigned int *") @Nullable IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnClusterRemapOut, @NativeType("TootleOverdrawOptimizer") int eOverdrawOptimizer) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- checkSafe(pnIBOut, pnIB.remaining());
- check(pnFaceClusters, nFaces + 1);
- checkSafe(pnClusterRemapOut, pnFaceClusters.get(nFaces));
- }
- return nTootleOptimizeOverdraw(memAddress(pVB), memAddress(pnIB), pVB.remaining() / nVBStride, nFaces, nVBStride, memAddressSafe(pfViewpoint), remainingSafe(pfViewpoint) / 3, eFrontWinding, memAddress(pnFaceClusters), memAddressSafe(pnIBOut), memAddressSafe(pnClusterRemapOut), eOverdrawOptimizer);
- }
-
- /** {@code TootleResult TootleOptimizeOverdraw(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, float const * pfViewpoint, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, unsigned int const * pnFaceClusters, unsigned int * pnIBOut, unsigned int * pnClusterRemapOut, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- @NativeType("TootleResult")
- public static int TootleOptimizeOverdraw(@NativeType("void const *") FloatBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("float const *") @Nullable FloatBuffer pfViewpoint, @NativeType("TootleFaceWinding") int eFrontWinding, @NativeType("unsigned int const *") IntBuffer pnFaceClusters, @NativeType("unsigned int *") @Nullable IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnClusterRemapOut, @NativeType("TootleOverdrawOptimizer") int eOverdrawOptimizer) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- checkSafe(pnIBOut, pnIB.remaining());
- check(pnFaceClusters, nFaces + 1);
- checkSafe(pnClusterRemapOut, pnFaceClusters.get(nFaces));
- }
- return nTootleOptimizeOverdraw(memAddress(pVB), memAddress(pnIB), (int)(((long)pVB.remaining() << 2) / nVBStride), nFaces, nVBStride, memAddressSafe(pfViewpoint), remainingSafe(pfViewpoint) / 3, eFrontWinding, memAddress(pnFaceClusters), memAddressSafe(pnIBOut), memAddressSafe(pnClusterRemapOut), eOverdrawOptimizer);
- }
-
- // --- [ TootleCleanup ] ---
-
- /** {@code void TootleCleanup(void)} */
- public static native void TootleCleanup();
-
- // --- [ TootleOptimize ] ---
-
- /** {@code TootleResult TootleOptimize(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nCacheSize, float const * pViewpoints, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, unsigned int * pnIBOut, unsigned int * pnNumClustersOut, TootleVCacheOptimizer eVCacheOptimizer, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- public static native int nTootleOptimize(long pVB, long pnIB, int nVertices, int nFaces, int nVBStride, int nCacheSize, long pViewpoints, int nViewpoints, int eFrontWinding, long pnIBOut, long pnNumClustersOut, int eVCacheOptimizer, int eOverdrawOptimizer);
-
- /** {@code TootleResult TootleOptimize(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nCacheSize, float const * pViewpoints, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, unsigned int * pnIBOut, unsigned int * pnNumClustersOut, TootleVCacheOptimizer eVCacheOptimizer, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- @NativeType("TootleResult")
- public static int TootleOptimize(@NativeType("void const *") ByteBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("unsigned int") int nCacheSize, @NativeType("float const *") @Nullable FloatBuffer pViewpoints, @NativeType("TootleFaceWinding") int eFrontWinding, @NativeType("unsigned int *") IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnNumClustersOut, @NativeType("TootleVCacheOptimizer") int eVCacheOptimizer, @NativeType("TootleOverdrawOptimizer") int eOverdrawOptimizer) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- check(pnIBOut, pnIB.remaining());
- checkSafe(pnNumClustersOut, 1);
- }
- return nTootleOptimize(memAddress(pVB), memAddress(pnIB), pVB.remaining() / nVBStride, nFaces, nVBStride, nCacheSize, memAddressSafe(pViewpoints), remainingSafe(pViewpoints) / 3, eFrontWinding, memAddress(pnIBOut), memAddressSafe(pnNumClustersOut), eVCacheOptimizer, eOverdrawOptimizer);
- }
-
- /** {@code TootleResult TootleOptimize(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nCacheSize, float const * pViewpoints, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, unsigned int * pnIBOut, unsigned int * pnNumClustersOut, TootleVCacheOptimizer eVCacheOptimizer, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- @NativeType("TootleResult")
- public static int TootleOptimize(@NativeType("void const *") FloatBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("unsigned int") int nCacheSize, @NativeType("float const *") @Nullable FloatBuffer pViewpoints, @NativeType("TootleFaceWinding") int eFrontWinding, @NativeType("unsigned int *") IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnNumClustersOut, @NativeType("TootleVCacheOptimizer") int eVCacheOptimizer, @NativeType("TootleOverdrawOptimizer") int eOverdrawOptimizer) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- check(pnIBOut, pnIB.remaining());
- checkSafe(pnNumClustersOut, 1);
- }
- return nTootleOptimize(memAddress(pVB), memAddress(pnIB), (int)(((long)pVB.remaining() << 2) / nVBStride), nFaces, nVBStride, nCacheSize, memAddressSafe(pViewpoints), remainingSafe(pViewpoints) / 3, eFrontWinding, memAddress(pnIBOut), memAddressSafe(pnNumClustersOut), eVCacheOptimizer, eOverdrawOptimizer);
- }
-
- // --- [ TootleFastOptimize ] ---
-
- /** {@code TootleResult TootleFastOptimize(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nCacheSize, TootleFaceWinding eFrontWinding, unsigned int * pnIBOut, unsigned int * pnNumClustersOut, float fAlpha)} */
- public static native int nTootleFastOptimize(long pVB, long pnIB, int nVertices, int nFaces, int nVBStride, int nCacheSize, int eFrontWinding, long pnIBOut, long pnNumClustersOut, float fAlpha);
-
- /** {@code TootleResult TootleFastOptimize(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nCacheSize, TootleFaceWinding eFrontWinding, unsigned int * pnIBOut, unsigned int * pnNumClustersOut, float fAlpha)} */
- @NativeType("TootleResult")
- public static int TootleFastOptimize(@NativeType("void const *") ByteBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("unsigned int") int nCacheSize, @NativeType("TootleFaceWinding") int eFrontWinding, @NativeType("unsigned int *") IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnNumClustersOut, float fAlpha) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- check(pnIBOut, pnIB.remaining());
- checkSafe(pnNumClustersOut, 1);
- }
- return nTootleFastOptimize(memAddress(pVB), memAddress(pnIB), pVB.remaining() / nVBStride, nFaces, nVBStride, nCacheSize, eFrontWinding, memAddress(pnIBOut), memAddressSafe(pnNumClustersOut), fAlpha);
- }
-
- /** {@code TootleResult TootleFastOptimize(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, unsigned int nCacheSize, TootleFaceWinding eFrontWinding, unsigned int * pnIBOut, unsigned int * pnNumClustersOut, float fAlpha)} */
- @NativeType("TootleResult")
- public static int TootleFastOptimize(@NativeType("void const *") FloatBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("unsigned int") int nCacheSize, @NativeType("TootleFaceWinding") int eFrontWinding, @NativeType("unsigned int *") IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnNumClustersOut, float fAlpha) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- check(pnIBOut, pnIB.remaining());
- checkSafe(pnNumClustersOut, 1);
- }
- return nTootleFastOptimize(memAddress(pVB), memAddress(pnIB), (int)(((long)pVB.remaining() << 2) / nVBStride), nFaces, nVBStride, nCacheSize, eFrontWinding, memAddress(pnIBOut), memAddressSafe(pnNumClustersOut), fAlpha);
- }
-
- // --- [ TootleVCacheClusters ] ---
-
- /** {@code TootleResult TootleVCacheClusters(unsigned int const * pnIB, unsigned int nFaces, unsigned int nVertices, unsigned int nCacheSize, unsigned int const * pnFaceClusters, unsigned int * pnIBOut, unsigned int * pnFaceRemapOut, TootleVCacheOptimizer eVCacheOptimizer)} */
- public static native int nTootleVCacheClusters(long pnIB, int nFaces, int nVertices, int nCacheSize, long pnFaceClusters, long pnIBOut, long pnFaceRemapOut, int eVCacheOptimizer);
-
- /** {@code TootleResult TootleVCacheClusters(unsigned int const * pnIB, unsigned int nFaces, unsigned int nVertices, unsigned int nCacheSize, unsigned int const * pnFaceClusters, unsigned int * pnIBOut, unsigned int * pnFaceRemapOut, TootleVCacheOptimizer eVCacheOptimizer)} */
- @NativeType("TootleResult")
- public static int TootleVCacheClusters(@NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVertices, @NativeType("unsigned int") int nCacheSize, @NativeType("unsigned int const *") IntBuffer pnFaceClusters, @NativeType("unsigned int *") @Nullable IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnFaceRemapOut, @NativeType("TootleVCacheOptimizer") int eVCacheOptimizer) {
- int nFaces = pnIB.remaining() / 3;
- if (CHECKS) {
- checkSafe(pnIBOut, pnIB.remaining());
- check(pnFaceClusters, nFaces + 1);
- checkSafe(pnFaceRemapOut, nFaces);
- }
- return nTootleVCacheClusters(memAddress(pnIB), nFaces, nVertices, nCacheSize, memAddress(pnFaceClusters), memAddressSafe(pnIBOut), memAddressSafe(pnFaceRemapOut), eVCacheOptimizer);
- }
-
- // --- [ TootleMeasureCacheEfficiency ] ---
-
- /** {@code TootleResult TootleMeasureCacheEfficiency(unsigned int const * pnIB, unsigned int nFaces, unsigned int nCacheSize, float * pfEfficiencyOut)} */
- public static native int nTootleMeasureCacheEfficiency(long pnIB, int nFaces, int nCacheSize, long pfEfficiencyOut);
-
- /** {@code TootleResult TootleMeasureCacheEfficiency(unsigned int const * pnIB, unsigned int nFaces, unsigned int nCacheSize, float * pfEfficiencyOut)} */
- @NativeType("TootleResult")
- public static int TootleMeasureCacheEfficiency(@NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nCacheSize, @NativeType("float *") FloatBuffer pfEfficiencyOut) {
- if (CHECKS) {
- check(pfEfficiencyOut, 1);
- }
- return nTootleMeasureCacheEfficiency(memAddress(pnIB), pnIB.remaining() / 3, nCacheSize, memAddress(pfEfficiencyOut));
- }
-
- // --- [ TootleMeasureOverdraw ] ---
-
- /** {@code TootleResult TootleMeasureOverdraw(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, float const * pfViewpoint, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, float * pfAvgODOut, float * pfMaxODOut, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- public static native int nTootleMeasureOverdraw(long pVB, long pnIB, int nVertices, int nFaces, int nVBStride, long pfViewpoint, int nViewpoints, int eFrontWinding, long pfAvgODOut, long pfMaxODOut, int eOverdrawOptimizer);
-
- /** {@code TootleResult TootleMeasureOverdraw(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, float const * pfViewpoint, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, float * pfAvgODOut, float * pfMaxODOut, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- @NativeType("TootleResult")
- public static int TootleMeasureOverdraw(@NativeType("void const *") ByteBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("float const *") @Nullable FloatBuffer pfViewpoint, @NativeType("TootleFaceWinding") int eFrontWinding, @NativeType("float *") @Nullable FloatBuffer pfAvgODOut, @NativeType("float *") @Nullable FloatBuffer pfMaxODOut, @NativeType("TootleOverdrawOptimizer") int eOverdrawOptimizer) {
- if (CHECKS) {
- checkSafe(pfAvgODOut, 1);
- checkSafe(pfMaxODOut, 1);
- }
- return nTootleMeasureOverdraw(memAddress(pVB), memAddress(pnIB), pVB.remaining() / nVBStride, pnIB.remaining() / 3, nVBStride, memAddressSafe(pfViewpoint), remainingSafe(pfViewpoint) / 3, eFrontWinding, memAddressSafe(pfAvgODOut), memAddressSafe(pfMaxODOut), eOverdrawOptimizer);
- }
-
- /** {@code TootleResult TootleMeasureOverdraw(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, float const * pfViewpoint, unsigned int nViewpoints, TootleFaceWinding eFrontWinding, float * pfAvgODOut, float * pfMaxODOut, TootleOverdrawOptimizer eOverdrawOptimizer)} */
- @NativeType("TootleResult")
- public static int TootleMeasureOverdraw(@NativeType("void const *") FloatBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("float const *") @Nullable FloatBuffer pfViewpoint, @NativeType("TootleFaceWinding") int eFrontWinding, @NativeType("float *") @Nullable FloatBuffer pfAvgODOut, @NativeType("float *") @Nullable FloatBuffer pfMaxODOut, @NativeType("TootleOverdrawOptimizer") int eOverdrawOptimizer) {
- if (CHECKS) {
- checkSafe(pfAvgODOut, 1);
- checkSafe(pfMaxODOut, 1);
- }
- return nTootleMeasureOverdraw(memAddress(pVB), memAddress(pnIB), (int)(((long)pVB.remaining() << 2) / nVBStride), pnIB.remaining() / 3, nVBStride, memAddressSafe(pfViewpoint), remainingSafe(pfViewpoint) / 3, eFrontWinding, memAddressSafe(pfAvgODOut), memAddressSafe(pfMaxODOut), eOverdrawOptimizer);
- }
-
- // --- [ TootleOptimizeVertexMemory ] ---
-
- /** {@code TootleResult TootleOptimizeVertexMemory(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, void * pVBOut, unsigned int * pnIBOut, unsigned int * pnVertexRemapOut)} */
- public static native int nTootleOptimizeVertexMemory(long pVB, long pnIB, int nVertices, int nFaces, int nVBStride, long pVBOut, long pnIBOut, long pnVertexRemapOut);
-
- /** {@code TootleResult TootleOptimizeVertexMemory(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, void * pVBOut, unsigned int * pnIBOut, unsigned int * pnVertexRemapOut)} */
- @NativeType("TootleResult")
- public static int TootleOptimizeVertexMemory(@NativeType("void const *") ByteBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("void *") ByteBuffer pVBOut, @NativeType("unsigned int *") IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnVertexRemapOut) {
- int nVertices = pVB.remaining() / nVBStride;
- if (CHECKS) {
- check(pVBOut, pVB.remaining());
- check(pnIBOut, pnIB.remaining());
- checkSafe(pnVertexRemapOut, nVertices);
- }
- return nTootleOptimizeVertexMemory(memAddress(pVB), memAddress(pnIB), nVertices, pnIB.remaining() / 3, nVBStride, memAddress(pVBOut), memAddress(pnIBOut), memAddressSafe(pnVertexRemapOut));
- }
-
- /** {@code TootleResult TootleOptimizeVertexMemory(void const * pVB, unsigned int const * pnIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, void * pVBOut, unsigned int * pnIBOut, unsigned int * pnVertexRemapOut)} */
- @NativeType("TootleResult")
- public static int TootleOptimizeVertexMemory(@NativeType("void const *") FloatBuffer pVB, @NativeType("unsigned int const *") IntBuffer pnIB, @NativeType("unsigned int") int nVBStride, @NativeType("void *") FloatBuffer pVBOut, @NativeType("unsigned int *") IntBuffer pnIBOut, @NativeType("unsigned int *") @Nullable IntBuffer pnVertexRemapOut) {
- int nVertices = (int)(((long)pVBOut.remaining() << 2) / nVBStride);
- if (CHECKS) {
- check(pVBOut, pVB.remaining());
- check(pnIBOut, pnIB.remaining());
- checkSafe(pnVertexRemapOut, nVertices);
- }
- return nTootleOptimizeVertexMemory(memAddress(pVB), memAddress(pnIB), nVertices, pnIB.remaining() / 3, nVBStride, memAddress(pVBOut), memAddress(pnIBOut), memAddressSafe(pnVertexRemapOut));
- }
-
-}
\ No newline at end of file
diff --git a/modules/lwjgl/tootle/src/generated/java/org/lwjgl/util/tootle/package-info.java b/modules/lwjgl/tootle/src/generated/java/org/lwjgl/util/tootle/package-info.java
deleted file mode 100644
index fb03e1f4b8..0000000000
--- a/modules/lwjgl/tootle/src/generated/java/org/lwjgl/util/tootle/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright LWJGL. All rights reserved.
- * License terms: https://www.lwjgl.org/license
- * MACHINE GENERATED FILE, DO NOT EDIT
- */
-
-/**
- * Contains bindings to AMD Tootle.
- *
- * AMD Tootle (Triangle Order Optimization Tool) is a 3D triangle mesh optimization library that improves on existing mesh preprocessing techniques. By
- * using AMD Tootle, developers can optimize their models for pixel overdraw as well as vertex cache performance. This can provide significant performance
- * improvements in pixel limited situations, with no penalty in vertex-limited scenarios, and no runtime cost.
- *
- * Resources
- *
- *
- */
-@org.jspecify.annotations.NullMarked
-package org.lwjgl.util.tootle;
-
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMesh.h b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMesh.h
deleted file mode 100644
index 6cfecde65e..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMesh.h
+++ /dev/null
@@ -1,650 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMesh.h
-//
-// DirectX Mesh Geometry Library
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#pragma once
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef _WIN32
-#if !defined(__d3d11_h__) && !defined(__d3d11_x_h__) && !defined(__d3d12_h__) && !defined(__d3d12_x_h__) && !defined(__XBOX_D3D12_X__)
-#ifdef _GAMING_XBOX_SCARLETT
-#include
-#elif defined(_GAMING_XBOX)
-#include
-#elif defined(_XBOX_ONE) && defined(_TITLE)
-#include
-#else
-#include
-#endif
-#endif
-#else // !WIN32
-#include
-#include
-#endif
-
-#include
-#include
-#include
-
-#define DIRECTX_MESH_VERSION 163
-
-
-namespace DirectX
-{
- //---------------------------------------------------------------------------------
- // DXGI Format Utilities
- bool __cdecl IsValidVB(_In_ DXGI_FORMAT fmt) noexcept;
- constexpr bool __cdecl IsValidIB(_In_ DXGI_FORMAT fmt) noexcept;
- size_t __cdecl BytesPerElement(_In_ DXGI_FORMAT fmt) noexcept;
-
-
- //---------------------------------------------------------------------------------
- // Input Layout Descriptor Utilities
-#if defined(__d3d11_h__) || defined(__d3d11_x_h__)
- bool __cdecl IsValid(_In_reads_(nDecl) const D3D11_INPUT_ELEMENT_DESC* vbDecl, _In_ size_t nDecl) noexcept;
- void __cdecl ComputeInputLayout(
- _In_reads_(nDecl) const D3D11_INPUT_ELEMENT_DESC* vbDecl, _In_ size_t nDecl,
- _Out_writes_opt_(nDecl) uint32_t* offsets,
- _Out_writes_opt_(D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT) uint32_t* strides) noexcept;
-#endif
-
-#if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__)
- bool __cdecl IsValid(const D3D12_INPUT_LAYOUT_DESC& vbDecl) noexcept;
- void __cdecl ComputeInputLayout(
- const D3D12_INPUT_LAYOUT_DESC& vbDecl,
- _Out_writes_opt_(vbDecl.NumElements) uint32_t* offsets,
- _Out_writes_opt_(D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT) uint32_t* strides) noexcept;
-#endif
-
- //---------------------------------------------------------------------------------
- // Attribute Utilities
- std::vector> __cdecl ComputeSubsets(_In_reads_opt_(nFaces) const uint32_t* attributes, _In_ size_t nFaces);
- // Returns a list of face offset,counts for attribute groups
-
- //---------------------------------------------------------------------------------
- // Mesh Optimization Utilities
- void __cdecl ComputeVertexCacheMissRate(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
- _In_ size_t cacheSize, _Out_ float& acmr, _Out_ float& atvr);
- void __cdecl ComputeVertexCacheMissRate(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
- _In_ size_t cacheSize, _Out_ float& acmr, _Out_ float& atvr);
- // Compute the average cache miss ratio and average triangle vertex reuse for the post-transform vertex cache
-
- //---------------------------------------------------------------------------------
- // Vertex Buffer Reader/Writer
-
- class VBReader
- {
- public:
- VBReader() noexcept(false);
- VBReader(VBReader&&) noexcept;
- VBReader& operator= (VBReader&&) noexcept;
-
- VBReader(VBReader const&) = delete;
- VBReader& operator= (VBReader const&) = delete;
-
- ~VBReader();
-
- #if defined(__d3d11_h__) || defined(__d3d11_x_h__)
- HRESULT __cdecl Initialize(_In_reads_(nDecl) const D3D11_INPUT_ELEMENT_DESC* vbDecl, _In_ size_t nDecl);
- // Does not support VB decls with D3D11_INPUT_PER_INSTANCE_DATA
- #endif
-
- #if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__)
- HRESULT __cdecl Initialize(const D3D12_INPUT_LAYOUT_DESC& vbDecl);
- // Does not support VB decls with D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA
- #endif
-
- HRESULT __cdecl AddStream(_In_reads_bytes_(stride*nVerts) const void* vb, _In_ size_t nVerts, _In_ size_t inputSlot, _In_ size_t stride = 0) noexcept;
- // Add vertex buffer to reader
-
- HRESULT __cdecl Read(_Out_writes_(count) XMVECTOR* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- // Extracts data elements from vertex buffer
-
- HRESULT __cdecl Read(_Out_writes_(count) float* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- HRESULT __cdecl Read(_Out_writes_(count) XMFLOAT2* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- HRESULT __cdecl Read(_Out_writes_(count) XMFLOAT3* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- HRESULT __cdecl Read(_Out_writes_(count) XMFLOAT4* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- // Helpers for data extraction
-
- void __cdecl Release() noexcept;
-
- #if defined(__d3d11_h__) || defined(__d3d11_x_h__)
- const D3D11_INPUT_ELEMENT_DESC* GetElement(_In_z_ const char* semanticName, _In_ unsigned int semanticIndex) const
- {
- return GetElement11(semanticName, semanticIndex);
- }
-
- const D3D11_INPUT_ELEMENT_DESC* __cdecl GetElement11(_In_z_ const char* semanticName, _In_ unsigned int semanticIndex) const;
- #endif
-
- #if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__)
- const D3D12_INPUT_ELEMENT_DESC* __cdecl GetElement12(_In_z_ const char* semanticName, _In_ unsigned int semanticIndex) const;
- #endif
-
- private:
- // Private implementation.
- class Impl;
-
- std::unique_ptr pImpl;
- };
-
- class VBWriter
- {
- public:
- VBWriter() noexcept(false);
- VBWriter(VBWriter&&) noexcept;
- VBWriter& operator= (VBWriter&&) noexcept;
-
- VBWriter(VBWriter const&) = delete;
- VBWriter& operator= (VBWriter const&) = delete;
-
- ~VBWriter();
-
- #if defined(__d3d11_h__) || defined(__d3d11_x_h__)
- HRESULT __cdecl Initialize(_In_reads_(nDecl) const D3D11_INPUT_ELEMENT_DESC* vbDecl, _In_ size_t nDecl);
- // Does not support VB decls with D3D11_INPUT_PER_INSTANCE_DATA
- #endif
-
- #if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__)
- HRESULT __cdecl Initialize(const D3D12_INPUT_LAYOUT_DESC& vbDecl);
- // Does not support VB decls with D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA
- #endif
-
- HRESULT __cdecl AddStream(_Out_writes_bytes_(stride*nVerts) void* vb, _In_ size_t nVerts, _In_ size_t inputSlot, _In_ size_t stride = 0) noexcept;
- // Add vertex buffer to writer
-
- HRESULT __cdecl Write(_In_reads_(count) const XMVECTOR* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- // Inserts data elements into vertex buffer
-
- HRESULT __cdecl Write(_In_reads_(count) const float* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- HRESULT __cdecl Write(_In_reads_(count) const XMFLOAT2* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- HRESULT __cdecl Write(_In_reads_(count) const XMFLOAT3* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- HRESULT __cdecl Write(_In_reads_(count) const XMFLOAT4* buffer, _In_z_ const char* semanticName, _In_ unsigned int semanticIndex, _In_ size_t count, bool x2bias = false) const;
- // Helpers for data insertion
-
- void __cdecl Release() noexcept;
-
- #if defined(__d3d11_h__) || defined(__d3d11_x_h__)
- const D3D11_INPUT_ELEMENT_DESC* __cdecl GetElement(_In_z_ const char* semanticName, _In_ unsigned int semanticIndex) const
- {
- return GetElement11(semanticName, semanticIndex);
- }
-
- const D3D11_INPUT_ELEMENT_DESC* __cdecl GetElement11(_In_z_ const char* semanticName, _In_ unsigned int semanticIndex) const;
- #endif
-
- #if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__)
- const D3D12_INPUT_ELEMENT_DESC* __cdecl GetElement12(_In_z_ const char* semanticName, _In_ unsigned int semanticIndex) const;
- #endif
-
- private:
- // Private implementation.
- class Impl;
-
- std::unique_ptr pImpl;
- };
-
- //---------------------------------------------------------------------------------
- // Adjacency Computation
-
- HRESULT __cdecl GenerateAdjacencyAndPointReps(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_ float epsilon,
- _Out_writes_opt_(nVerts) uint32_t* pointRep,
- _Out_writes_opt_(nFaces * 3) uint32_t* adjacency);
- HRESULT __cdecl GenerateAdjacencyAndPointReps(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_ float epsilon,
- _Out_writes_opt_(nVerts) uint32_t* pointRep,
- _Out_writes_opt_(nFaces * 3) uint32_t* adjacency);
- // If pointRep is null, it still generates them internally as they are needed for the final adjacency computation
-
- HRESULT __cdecl ConvertPointRepsToAdjacency(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_reads_opt_(nVerts) const uint32_t* pointRep,
- _Out_writes_(nFaces * 3) uint32_t* adjacency);
- HRESULT __cdecl ConvertPointRepsToAdjacency(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_reads_opt_(nVerts) const uint32_t* pointRep,
- _Out_writes_(nFaces * 3) uint32_t* adjacency);
- // If pointRep is null, assumes an identity
-
- HRESULT __cdecl GenerateGSAdjacency(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const uint32_t* pointRep,
- _In_reads_(nFaces * 3) const uint32_t* adjacency, _In_ size_t nVerts,
- _Out_writes_(nFaces * 6) uint16_t* indicesAdj) noexcept;
- HRESULT __cdecl GenerateGSAdjacency(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const uint32_t* pointRep,
- _In_reads_(nFaces * 3) const uint32_t* adjacency, _In_ size_t nVerts,
- _Out_writes_(nFaces * 6) uint32_t* indicesAdj) noexcept;
- // Generates an IB suitable for Geometry Shader using D3D1x_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ
-
- //---------------------------------------------------------------------------------
- // Normals, Tangents, and Bi-Tangents Computation
-
- enum CNORM_FLAGS : unsigned long
- {
- CNORM_DEFAULT = 0x0,
- // Default is to compute normals using weight-by-angle
-
- CNORM_WEIGHT_BY_AREA = 0x1,
- // Computes normals using weight-by-area
-
- CNORM_WEIGHT_EQUAL = 0x2,
- // Compute normals with equal weights
-
- CNORM_WIND_CW = 0x4,
- // Vertices are clock-wise (defaults to CCW)
- };
-
- HRESULT __cdecl ComputeNormals(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_ CNORM_FLAGS flags,
- _Out_writes_(nVerts) XMFLOAT3* normals) noexcept;
- HRESULT __cdecl ComputeNormals(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_ CNORM_FLAGS flags,
- _Out_writes_(nVerts) XMFLOAT3* normals) noexcept;
- // Computes vertex normals
-
- HRESULT __cdecl ComputeTangentFrame(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions,
- _In_reads_(nVerts) const XMFLOAT3* normals,
- _In_reads_(nVerts) const XMFLOAT2* texcoords, _In_ size_t nVerts,
- _Out_writes_opt_(nVerts) XMFLOAT3* tangents,
- _Out_writes_opt_(nVerts) XMFLOAT3* bitangents) noexcept;
- HRESULT __cdecl ComputeTangentFrame(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions,
- _In_reads_(nVerts) const XMFLOAT3* normals,
- _In_reads_(nVerts) const XMFLOAT2* texcoords, _In_ size_t nVerts,
- _Out_writes_opt_(nVerts) XMFLOAT3* tangents,
- _Out_writes_opt_(nVerts) XMFLOAT3* bitangents) noexcept;
- HRESULT __cdecl ComputeTangentFrame(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions,
- _In_reads_(nVerts) const XMFLOAT3* normals,
- _In_reads_(nVerts) const XMFLOAT2* texcoords, _In_ size_t nVerts,
- _Out_writes_opt_(nVerts) XMFLOAT4* tangents,
- _Out_writes_opt_(nVerts) XMFLOAT3* bitangents) noexcept;
- HRESULT __cdecl ComputeTangentFrame(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions,
- _In_reads_(nVerts) const XMFLOAT3* normals,
- _In_reads_(nVerts) const XMFLOAT2* texcoords, _In_ size_t nVerts,
- _Out_writes_opt_(nVerts) XMFLOAT4* tangents,
- _Out_writes_opt_(nVerts) XMFLOAT3* bitangents) noexcept;
- HRESULT __cdecl ComputeTangentFrame(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions,
- _In_reads_(nVerts) const XMFLOAT3* normals,
- _In_reads_(nVerts) const XMFLOAT2* texcoords, _In_ size_t nVerts,
- _Out_writes_(nVerts) XMFLOAT4* tangents) noexcept;
- HRESULT __cdecl ComputeTangentFrame(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions,
- _In_reads_(nVerts) const XMFLOAT3* normals,
- _In_reads_(nVerts) const XMFLOAT2* texcoords, _In_ size_t nVerts,
- _Out_writes_(nVerts) XMFLOAT4* tangents) noexcept;
- // Computes tangents and/or bi-tangents (optionally with handedness stored in .w)
-
- //---------------------------------------------------------------------------------
- // Mesh clean-up and validation
-
- enum VALIDATE_FLAGS : unsigned long
- {
- VALIDATE_DEFAULT = 0x0,
-
- VALIDATE_BACKFACING = 0x1,
- // Check for duplicate neighbor from triangle (requires adjacency)
-
- VALIDATE_BOWTIES = 0x2,
- // Check for two fans of triangles using the same vertex (requires adjacency)
-
- VALIDATE_DEGENERATE = 0x4,
- // Check for degenerate triangles
-
- VALIDATE_UNUSED = 0x8,
- // Check for issues with 'unused' triangles
-
- VALIDATE_ASYMMETRIC_ADJ = 0x10,
- // Checks that neighbors are symmetric (requires adjacency)
- };
-
- HRESULT __cdecl Validate(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_ size_t nVerts, _In_reads_opt_(nFaces * 3) const uint32_t* adjacency,
- _In_ VALIDATE_FLAGS flags, _In_opt_ std::wstring* msgs = nullptr);
- HRESULT __cdecl Validate(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_ size_t nVerts, _In_reads_opt_(nFaces * 3) const uint32_t* adjacency,
- _In_ VALIDATE_FLAGS flags, _In_opt_ std::wstring* msgs = nullptr);
- // Checks the mesh for common problems, return 'S_OK' if no problems were found
-
- HRESULT __cdecl Clean(
- _Inout_updates_all_(nFaces * 3) uint16_t* indices, _In_ size_t nFaces,
- _In_ size_t nVerts, _Inout_updates_all_opt_(nFaces * 3) uint32_t* adjacency,
- _In_reads_opt_(nFaces) const uint32_t* attributes,
- _Inout_ std::vector& dupVerts, _In_ bool breakBowties = false);
- HRESULT __cdecl Clean(
- _Inout_updates_all_(nFaces * 3) uint32_t* indices, _In_ size_t nFaces,
- _In_ size_t nVerts, _Inout_updates_all_opt_(nFaces * 3) uint32_t* adjacency,
- _In_reads_opt_(nFaces) const uint32_t* attributes,
- _Inout_ std::vector& dupVerts, _In_ bool breakBowties = false);
- // Cleans the mesh, splitting vertices if needed
-
- //---------------------------------------------------------------------------------
- // Mesh utilities
-
- HRESULT __cdecl WeldVertices(
- _Inout_updates_all_(nFaces * 3) uint16_t* indices, _In_ size_t nFaces,
- _In_ size_t nVerts, _In_reads_(nVerts) const uint32_t* pointRep,
- _Out_writes_opt_(nVerts) uint32_t* vertexRemap,
- _In_ std::function weldTest);
- HRESULT __cdecl WeldVertices(
- _Inout_updates_all_(nFaces * 3) uint32_t* indices, _In_ size_t nFaces,
- _In_ size_t nVerts, _In_reads_(nVerts) const uint32_t* pointRep,
- _Out_writes_opt_(nVerts) uint32_t* vertexRemap,
- _In_ std::function weldTest);
- // Welds vertices together based on a test function
-
- HRESULT __cdecl ConcatenateMesh(
- _In_ size_t nFaces,
- _In_ size_t nVerts,
- _Out_writes_(nFaces) uint32_t* faceDestMap,
- _Out_writes_(nVerts) uint32_t* vertexDestMap,
- _Inout_ size_t& totalFaces,
- _Inout_ size_t& totalVerts) noexcept;
- // Merge meshes together
-
- //---------------------------------------------------------------------------------
- // Mesh Optimization
-
- HRESULT __cdecl AttributeSort(
- _In_ size_t nFaces, _Inout_updates_all_(nFaces) uint32_t* attributes,
- _Out_writes_(nFaces) uint32_t* faceRemap);
- // Reorders faces by attribute id
-
- enum OPTFACES : uint32_t
- {
- OPTFACES_V_DEFAULT = 12,
- OPTFACES_R_DEFAULT = 7,
- // Default vertex cache size and restart threshold which is considered 'device independent'
-
- OPTFACES_LRU_DEFAULT = 32,
- // Default vertex cache size for the LRU algorithm
-
- OPTFACES_V_STRIPORDER = 0,
- // Indicates no vertex cache optimization, only reordering into strips
- };
-
- HRESULT __cdecl OptimizeFaces(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nFaces * 3) const uint32_t* adjacency,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- _In_ uint32_t vertexCache = OPTFACES_V_DEFAULT,
- _In_ uint32_t restart = OPTFACES_R_DEFAULT);
- HRESULT __cdecl OptimizeFaces(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nFaces * 3) const uint32_t* adjacency,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- _In_ uint32_t vertexCache = OPTFACES_V_DEFAULT,
- _In_ uint32_t restart = OPTFACES_R_DEFAULT);
- HRESULT __cdecl OptimizeFacesLRU(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- _In_ uint32_t lruCacheSize = OPTFACES_LRU_DEFAULT);
- HRESULT __cdecl OptimizeFacesLRU(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- _In_ uint32_t lruCacheSize = OPTFACES_LRU_DEFAULT);
- // Reorders faces to increase hit rate of vertex caches
-
- HRESULT __cdecl OptimizeFacesEx(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nFaces * 3) const uint32_t* adjacency,
- _In_reads_(nFaces) const uint32_t* attributes,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- _In_ uint32_t vertexCache = OPTFACES_V_DEFAULT,
- _In_ uint32_t restart = OPTFACES_R_DEFAULT);
- HRESULT __cdecl OptimizeFacesEx(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nFaces * 3) const uint32_t* adjacency,
- _In_reads_(nFaces) const uint32_t* attributes,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- _In_ uint32_t vertexCache = OPTFACES_V_DEFAULT,
- _In_ uint32_t restart = OPTFACES_R_DEFAULT);
- HRESULT __cdecl OptimizeFacesLRUEx(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nFaces) const uint32_t* attributes,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- _In_ uint32_t lruCacheSize = OPTFACES_LRU_DEFAULT);
- HRESULT __cdecl OptimizeFacesLRUEx(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nFaces) const uint32_t* attributes,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- _In_ uint32_t lruCacheSize = OPTFACES_LRU_DEFAULT);
- // Attribute group version of OptimizeFaces
-
- HRESULT __cdecl OptimizeVertices(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
- _Out_writes_(nVerts) uint32_t* vertexRemap, _Out_opt_ size_t* trailingUnused = nullptr) noexcept;
- HRESULT __cdecl OptimizeVertices(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
- _Out_writes_(nVerts) uint32_t* vertexRemap, _Out_opt_ size_t* trailingUnused = nullptr) noexcept;
- // Reorders vertices in order of use
-
- //---------------------------------------------------------------------------------
- // Remap functions
-
- HRESULT __cdecl ReorderIB(
- _In_reads_(nFaces * 3) const uint16_t* ibin, _In_ size_t nFaces,
- _In_reads_(nFaces) const uint32_t* faceRemap,
- _Out_writes_(nFaces * 3) uint16_t* ibout) noexcept;
- HRESULT __cdecl ReorderIB(
- _Inout_updates_all_(nFaces * 3) uint16_t* ib, _In_ size_t nFaces,
- _In_reads_(nFaces) const uint32_t* faceRemap) noexcept;
- HRESULT __cdecl ReorderIB(
- _In_reads_(nFaces * 3) const uint32_t* ibin, _In_ size_t nFaces,
- _In_reads_(nFaces) const uint32_t* faceRemap,
- _Out_writes_(nFaces * 3) uint32_t* ibout) noexcept;
- HRESULT __cdecl ReorderIB(
- _Inout_updates_all_(nFaces * 3) uint32_t* ib, _In_ size_t nFaces,
- _In_reads_(nFaces) const uint32_t* faceRemap) noexcept;
- // Applies a face remap reordering to an index buffer
-
- HRESULT __cdecl ReorderIBAndAdjacency(
- _In_reads_(nFaces * 3) const uint16_t* ibin, _In_ size_t nFaces, _In_reads_(nFaces * 3) const uint32_t* adjin,
- _In_reads_(nFaces) const uint32_t* faceRemap,
- _Out_writes_(nFaces * 3) uint16_t* ibout, _Out_writes_(nFaces * 3) uint32_t* adjout) noexcept;
- HRESULT __cdecl ReorderIBAndAdjacency(
- _Inout_updates_all_(nFaces * 3) uint16_t* ib, _In_ size_t nFaces, _Inout_updates_all_(nFaces * 3) uint32_t* adj,
- _In_reads_(nFaces) const uint32_t* faceRemap) noexcept;
- HRESULT __cdecl ReorderIBAndAdjacency(
- _In_reads_(nFaces * 3) const uint32_t* ibin, _In_ size_t nFaces, _In_reads_(nFaces * 3) const uint32_t* adjin,
- _In_reads_(nFaces) const uint32_t* faceRemap,
- _Out_writes_(nFaces * 3) uint32_t* ibout, _Out_writes_(nFaces * 3) uint32_t* adjout) noexcept;
- HRESULT __cdecl ReorderIBAndAdjacency(
- _Inout_updates_all_(nFaces * 3) uint32_t* ib, _In_ size_t nFaces, _Inout_updates_all_(nFaces * 3) uint32_t* adj,
- _In_reads_(nFaces) const uint32_t* faceRemap) noexcept;
- // Applies a face remap reordering to an index buffer and adjacency
-
- HRESULT __cdecl FinalizeIB(
- _In_reads_(nFaces * 3) const uint16_t* ibin, _In_ size_t nFaces,
- _In_reads_(nVerts) const uint32_t* vertexRemap, _In_ size_t nVerts,
- _Out_writes_(nFaces * 3) uint16_t* ibout) noexcept;
- HRESULT __cdecl FinalizeIB(
- _Inout_updates_all_(nFaces * 3) uint16_t* ib, _In_ size_t nFaces,
- _In_reads_(nVerts) const uint32_t* vertexRemap, _In_ size_t nVerts) noexcept;
- HRESULT __cdecl FinalizeIB(
- _In_reads_(nFaces * 3) const uint32_t* ibin, _In_ size_t nFaces,
- _In_reads_(nVerts) const uint32_t* vertexRemap, _In_ size_t nVerts,
- _Out_writes_(nFaces * 3) uint32_t* ibout) noexcept;
- HRESULT __cdecl FinalizeIB(
- _Inout_updates_all_(nFaces * 3) uint32_t* ib, _In_ size_t nFaces,
- _In_reads_(nVerts) const uint32_t* vertexRemap, _In_ size_t nVerts) noexcept;
- // Applies a vertex remap reordering to an index buffer
-
- HRESULT __cdecl FinalizeVB(
- _In_reads_bytes_(nVerts*stride) const void* vbin, _In_ size_t stride, _In_ size_t nVerts,
- _In_reads_opt_(nDupVerts) const uint32_t* dupVerts, _In_ size_t nDupVerts,
- _In_reads_opt_(nVerts + nDupVerts) const uint32_t* vertexRemap,
- _Out_writes_bytes_((nVerts + nDupVerts)*stride) void* vbout) noexcept;
- HRESULT __cdecl FinalizeVB(
- _Inout_updates_bytes_all_(nVerts*stride) void* vb, _In_ size_t stride, _In_ size_t nVerts,
- _In_reads_(nVerts) const uint32_t* vertexRemap) noexcept;
- // Applies a vertex remap and/or a vertex duplication set to a vertex buffer
-
- HRESULT __cdecl FinalizeVBAndPointReps(
- _In_reads_bytes_(nVerts*stride) const void* vbin, _In_ size_t stride, _In_ size_t nVerts,
- _In_reads_(nVerts) const uint32_t* prin,
- _In_reads_opt_(nDupVerts) const uint32_t* dupVerts, _In_ size_t nDupVerts,
- _In_reads_opt_(nVerts + nDupVerts) const uint32_t* vertexRemap,
- _Out_writes_bytes_((nVerts + nDupVerts)*stride) void* vbout,
- _Out_writes_(nVerts + nDupVerts) uint32_t* prout) noexcept;
- HRESULT __cdecl FinalizeVBAndPointReps(
- _Inout_updates_bytes_all_(nVerts*stride) void* vb, _In_ size_t stride, _In_ size_t nVerts,
- _Inout_updates_all_(nVerts) uint32_t* pointRep,
- _In_reads_(nVerts) const uint32_t* vertexRemap) noexcept;
- // Applies a vertex remap and/or a vertex duplication set to a vertex buffer and point representatives
-
- HRESULT __cdecl CompactVB(
- _In_reads_bytes_(nVerts*stride) const void* vbin, _In_ size_t stride, _In_ size_t nVerts,
- _In_ size_t trailingUnused,
- _In_reads_opt_(nVerts) const uint32_t* vertexRemap,
- _Out_writes_bytes_((nVerts - trailingUnused)*stride) void* vbout) noexcept;
- // Applies a vertex remap which contains a known number of unused entries at the end
-
- //---------------------------------------------------------------------------------
- // Meshlet Generation
-
- constexpr size_t MESHLET_DEFAULT_MAX_VERTS = 128u;
- constexpr size_t MESHLET_DEFAULT_MAX_PRIMS = 128u;
-
- constexpr size_t MESHLET_MINIMUM_SIZE = 32u;
- constexpr size_t MESHLET_MAXIMUM_SIZE = 256u;
-
- enum MESHLET_FLAGS : unsigned long
- {
- MESHLET_DEFAULT = 0x0,
-
- MESHLET_WIND_CW = 0x1,
- // Vertices are clock-wise (defaults to CCW)
- };
-
- struct Meshlet
- {
- uint32_t VertCount;
- uint32_t VertOffset;
- uint32_t PrimCount;
- uint32_t PrimOffset;
- };
-
- struct MeshletTriangle
- {
- uint32_t i0 : 10;
- uint32_t i1 : 10;
- uint32_t i2 : 10;
- };
-
- struct CullData
- {
- DirectX::BoundingSphere BoundingSphere; // xyz = center, w = radius
- DirectX::PackedVector::XMUBYTEN4 NormalCone; // xyz = axis, w = -cos(a + 90)
- float ApexOffset; // apex = center - axis * offset
- };
-
- HRESULT __cdecl ComputeMeshlets(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_reads_opt_(nFaces * 3) const uint32_t* adjacency,
- _Inout_ std::vector& meshlets,
- _Inout_ std::vector& uniqueVertexIB,
- _Inout_ std::vector& primitiveIndices,
- _In_ size_t maxVerts = MESHLET_DEFAULT_MAX_VERTS, _In_ size_t maxPrims = MESHLET_DEFAULT_MAX_PRIMS);
- HRESULT __cdecl ComputeMeshlets(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_reads_opt_(nFaces * 3) const uint32_t* adjacency,
- _Inout_ std::vector& meshlets,
- _Inout_ std::vector& uniqueVertexIB,
- _Inout_ std::vector& primitiveIndices,
- _In_ size_t maxVerts = MESHLET_DEFAULT_MAX_VERTS, _In_ size_t maxPrims = MESHLET_DEFAULT_MAX_PRIMS);
- // Generates meshlets for a single subset mesh
-
- HRESULT __cdecl ComputeMeshlets(
- _In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_reads_(nSubsets) const std::pair* subsets, _In_ size_t nSubsets,
- _In_reads_opt_(nFaces * 3) const uint32_t* adjacency,
- _Inout_ std::vector& meshlets,
- _Inout_ std::vector& uniqueVertexIB,
- _Inout_ std::vector& primitiveIndices,
- _Out_writes_(nSubsets) std::pair* meshletSubsets,
- _In_ size_t maxVerts = MESHLET_DEFAULT_MAX_VERTS, _In_ size_t maxPrims = MESHLET_DEFAULT_MAX_PRIMS);
- HRESULT __cdecl ComputeMeshlets(
- _In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_reads_(nSubsets) const std::pair* subsets, _In_ size_t nSubsets,
- _In_reads_opt_(nFaces * 3) const uint32_t* adjacency,
- _Inout_ std::vector& meshlets,
- _Inout_ std::vector& uniqueVertexIB,
- _Inout_ std::vector& primitiveIndices,
- _Out_writes_(nSubsets) std::pair* meshletSubsets,
- _In_ size_t maxVerts = MESHLET_DEFAULT_MAX_VERTS, _In_ size_t maxPrims = MESHLET_DEFAULT_MAX_PRIMS);
- // Generates meshlets for a mesh with several face subsets
-
- HRESULT __cdecl ComputeCullData(
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_reads_(nMeshlets) const Meshlet* meshlets, _In_ size_t nMeshlets,
- _In_reads_(nVertIndices) const uint16_t* uniqueVertexIndices, _In_ size_t nVertIndices,
- _In_reads_(nPrimIndices) const MeshletTriangle* primitiveIndices, _In_ size_t nPrimIndices,
- _Out_writes_(nMeshlets) CullData* cullData,
- _In_ MESHLET_FLAGS flags = MESHLET_DEFAULT) noexcept;
- HRESULT __cdecl ComputeCullData(
- _In_reads_(nVerts) const XMFLOAT3* positions, _In_ size_t nVerts,
- _In_reads_(nMeshlets) const Meshlet* meshlets, _In_ size_t nMeshlets,
- _In_reads_(nVertIndices) const uint32_t* uniqueVertexIndices, _In_ size_t nVertIndices,
- _In_reads_(nPrimIndices) const MeshletTriangle* primitiveIndices, _In_ size_t nPrimIndices,
- _Out_writes_(nMeshlets) CullData* cullData,
- _In_ MESHLET_FLAGS flags = MESHLET_DEFAULT) noexcept;
- // Computes culling data for each input meshlet
-
- //---------------------------------------------------------------------------------
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec"
-#endif
-
-#include "DirectXMesh.inl"
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-} // namespace
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMesh.inl b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMesh.inl
deleted file mode 100644
index 7f9cbb37e5..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMesh.inl
+++ /dev/null
@@ -1,35 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMesh.inl
-//
-// DirectX Mesh Geometry Library
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#pragma once
-
-//=====================================================================================
-// Bitmask flags enumerator operators
-//=====================================================================================
-DEFINE_ENUM_FLAG_OPERATORS(CNORM_FLAGS);
-DEFINE_ENUM_FLAG_OPERATORS(VALIDATE_FLAGS);
-DEFINE_ENUM_FLAG_OPERATORS(MESHLET_FLAGS);
-
-
-//=====================================================================================
-// DXGI Format Utilities
-//=====================================================================================
-_Use_decl_annotations_
-inline bool __cdecl IsValidVB(DXGI_FORMAT fmt) noexcept
-{
- return BytesPerElement(fmt) != 0;
-}
-
-_Use_decl_annotations_
-constexpr bool __cdecl IsValidIB(DXGI_FORMAT fmt) noexcept
-{
- return (fmt == DXGI_FORMAT_R32_UINT || fmt == DXGI_FORMAT_R16_UINT) != 0;
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshAdjacency.cpp b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshAdjacency.cpp
deleted file mode 100644
index 9ab953d111..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshAdjacency.cpp
+++ /dev/null
@@ -1,784 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshAdjacency.cpp
-//
-// DirectX Mesh Geometry Library - Adjacency computation
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#include "DirectXMeshP.h"
-
-using namespace DirectX;
-
-namespace
-{
- //---------------------------------------------------------------------------------
- // Utilities
- //---------------------------------------------------------------------------------
- struct vertexHashEntry
- {
- XMFLOAT3 v;
- uint32_t index;
- vertexHashEntry * next;
- };
-
- struct edgeHashEntry
- {
- uint32_t v1;
- uint32_t v2;
- uint32_t vOther;
- uint32_t face;
- edgeHashEntry * next;
- };
-
- // std::make_heap doesn't match D3DX10 so we use the same algorithm here
- void MakeXHeap(
- _Out_writes_(nVerts) uint32_t *index,
- _In_reads_(nVerts) const XMFLOAT3* positions, size_t nVerts) noexcept
- {
- for (uint32_t vert = 0; vert < nVerts; ++vert)
- {
- index[vert] = vert;
- }
-
- if (nVerts > 1)
- {
- // Create the heap
- uint32_t iulLim = uint32_t(nVerts);
-
- for (uint32_t vert = uint32_t(nVerts >> 1); --vert != uint32_t(-1); )
- {
- // Percolate down
- uint32_t iulI = vert;
- uint32_t iulJ = vert + vert + 1;
- const uint32_t ulT = index[iulI];
-
- while (iulJ < iulLim)
- {
- uint32_t ulJ = index[iulJ];
-
- if (iulJ + 1 < iulLim)
- {
- const uint32_t ulJ1 = index[iulJ + 1];
- if (positions[ulJ1].x <= positions[ulJ].x)
- {
- iulJ++;
- ulJ = ulJ1;
- }
- }
-
- if (positions[ulJ].x > positions[ulT].x)
- break;
-
- index[iulI] = index[iulJ];
- iulI = iulJ;
- iulJ += iulJ + 1;
- }
-
- index[iulI] = ulT;
- }
-
- // Sort the heap
- while (--iulLim != uint32_t(-1))
- {
- const uint32_t ulT = index[iulLim];
- index[iulLim] = index[0];
-
- // Percolate down
- uint32_t iulI = 0;
- uint32_t iulJ = 1;
-
- while (iulJ < iulLim)
- {
- _Analysis_assume_(iulJ < nVerts);
- uint32_t ulJ = index[iulJ];
-
- if (iulJ + 1 < iulLim)
- {
- const uint32_t ulJ1 = index[iulJ + 1];
- if (positions[ulJ1].x <= positions[ulJ].x)
- {
- iulJ++;
- ulJ = ulJ1;
- }
- }
-
- if (positions[ulJ].x > positions[ulT].x)
- break;
-
- index[iulI] = index[iulJ];
- iulI = iulJ;
- iulJ += iulJ + 1;
- }
-
- assert(iulI < nVerts);
- _Analysis_assume_(iulI < nVerts);
- index[iulI] = ulT;
- }
- }
- }
-
-
- //---------------------------------------------------------------------------------
- // PointRep computation
- //---------------------------------------------------------------------------------
- template
- HRESULT GeneratePointReps(
- _In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, size_t nVerts,
- float epsilon,
- _Out_writes_(nVerts) uint32_t* pointRep) noexcept
- {
- std::unique_ptr temp(new (std::nothrow) uint32_t[nVerts + nFaces * 3]);
- if (!temp)
- return E_OUTOFMEMORY;
-
- uint32_t* vertexToCorner = temp.get();
- uint32_t* vertexCornerList = temp.get() + nVerts;
-
- memset(vertexToCorner, 0xff, sizeof(uint32_t) * nVerts);
- memset(vertexCornerList, 0xff, sizeof(uint32_t) * nFaces * 3);
-
- // build initial lists and validate indices
- for (size_t j = 0; j < (nFaces * 3); ++j)
- {
- index_t k = indices[j];
- if (k == index_t(-1))
- continue;
-
- if (k >= nVerts)
- return E_UNEXPECTED;
-
- vertexCornerList[j] = vertexToCorner[k];
- vertexToCorner[k] = uint32_t(j);
- }
-
- if (epsilon == 0.f)
- {
- auto hashSize = std::max(nVerts / 3, 1);
-
- std::unique_ptr hashTable(new (std::nothrow) vertexHashEntry*[hashSize]);
- if (!hashTable)
- return E_OUTOFMEMORY;
-
- memset(hashTable.get(), 0, sizeof(vertexHashEntry*) * hashSize);
-
- std::unique_ptr hashEntries(new (std::nothrow) vertexHashEntry[nVerts]);
- if (!hashEntries)
- return E_OUTOFMEMORY;
-
- uint32_t freeEntry = 0;
-
- for (size_t vert = 0; vert < nVerts; ++vert)
- {
- auto px = reinterpret_cast(&positions[vert].x);
- auto py = reinterpret_cast(&positions[vert].y);
- auto pz = reinterpret_cast(&positions[vert].z);
- const uint32_t hashKey = (*px + *py + *pz) % uint32_t(hashSize);
-
- uint32_t found = UNUSED32;
-
- for (auto current = hashTable[hashKey]; current != nullptr; current = current->next)
- {
- if (current->v.x == positions[vert].x
- && current->v.y == positions[vert].y
- && current->v.z == positions[vert].z)
- {
- uint32_t head = vertexToCorner[vert];
-
- bool ispresent = false;
-
- while (head != UNUSED32)
- {
- const uint32_t face = head / 3;
- assert(face < nFaces);
- _Analysis_assume_(face < nFaces);
-
- assert((indices[face * 3] == vert) || (indices[face * 3 + 1] == vert) || (indices[face * 3 + 2] == vert));
-
- if ((indices[face * 3] == current->index) || (indices[face * 3 + 1] == current->index) || (indices[face * 3 + 2] == current->index))
- {
- ispresent = true;
- break;
- }
-
- head = vertexCornerList[head];
- }
-
- if (!ispresent)
- {
- found = current->index;
- break;
- }
- }
- }
-
- if (found != UNUSED32)
- {
- pointRep[vert] = found;
- }
- else
- {
- assert(freeEntry < nVerts);
- _Analysis_assume_(freeEntry < nVerts);
-
- auto newEntry = &hashEntries[freeEntry];
- ++freeEntry;
-
- newEntry->v = positions[vert];
- newEntry->index = uint32_t(vert);
- newEntry->next = hashTable[hashKey];
- hashTable[hashKey] = newEntry;
-
- pointRep[vert] = uint32_t(vert);
- }
- }
-
- assert(freeEntry <= nVerts);
-
- return S_OK;
- }
- else
- {
- std::unique_ptr xorder(new (std::nothrow) uint32_t[nVerts]);
- if (!xorder)
- return E_OUTOFMEMORY;
-
- // order in descending order
- MakeXHeap(xorder.get(), positions, nVerts);
-
- memset(pointRep, 0xff, sizeof(uint32_t) * nVerts);
-
- const XMVECTOR vepsilon = XMVectorReplicate(epsilon * epsilon);
-
- uint32_t head = 0;
- uint32_t tail = 0;
-
- while (tail < nVerts)
- {
- // move head until just out of epsilon
- while ((head < nVerts)
- && ((positions[tail].x - positions[head].x) <= epsilon))
- {
- ++head;
- }
-
- // check new tail against all points up to the head
- uint32_t tailIndex = xorder[tail];
- assert(tailIndex < nVerts);
- _Analysis_assume_(tailIndex < nVerts);
- if (pointRep[tailIndex] == UNUSED32)
- {
- pointRep[tailIndex] = tailIndex;
-
- const XMVECTOR outer = XMLoadFloat3(&positions[tailIndex]);
-
- for (uint32_t current = tail + 1; current < head; ++current)
- {
- uint32_t curIndex = xorder[current];
- assert(curIndex < nVerts);
- _Analysis_assume_(curIndex < nVerts);
-
- // if the point is already assigned, ignore it
- if (pointRep[curIndex] == UNUSED32)
- {
- const XMVECTOR inner = XMLoadFloat3(&positions[curIndex]);
-
- const XMVECTOR diff = XMVector3LengthSq(XMVectorSubtract(inner, outer));
-
- if (XMVector2Less(diff, vepsilon))
- {
- uint32_t headvc = vertexToCorner[tailIndex];
-
- bool ispresent = false;
-
- while (headvc != UNUSED32)
- {
- const uint32_t face = headvc / 3;
- assert(face < nFaces);
- _Analysis_assume_(face < nFaces);
-
- assert((indices[face * 3] == tailIndex) || (indices[face * 3 + 1] == tailIndex) || (indices[face * 3 + 2] == tailIndex));
-
- if ((indices[face * 3] == curIndex) || (indices[face * 3 + 1] == curIndex) || (indices[face * 3 + 2] == curIndex))
- {
- ispresent = true;
- break;
- }
-
- headvc = vertexCornerList[headvc];
- }
-
- if (!ispresent)
- {
- pointRep[curIndex] = tailIndex;
- }
- }
- }
- }
- }
-
- ++tail;
- }
-
- return S_OK;
- }
- }
-
-
- //---------------------------------------------------------------------------------
- // Convert PointRep to Adjacency
- //---------------------------------------------------------------------------------
- template
- HRESULT ConvertPointRepsToAdjacencyImpl(
- _In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, size_t nVerts,
- _In_reads_(nVerts) const uint32_t* pointRep,
- _Out_writes_(nFaces * 3) uint32_t* adjacency) noexcept
- {
- auto hashSize = std::max(nVerts / 3, 1);
-
- std::unique_ptr hashTable(new (std::nothrow) edgeHashEntry*[hashSize]);
- if (!hashTable)
- return E_OUTOFMEMORY;
-
- memset(hashTable.get(), 0, sizeof(edgeHashEntry*) * hashSize);
-
- std::unique_ptr hashEntries(new (std::nothrow) edgeHashEntry[3 * nFaces]);
- if (!hashEntries)
- return E_OUTOFMEMORY;
-
- uint32_t freeEntry = 0;
-
- // add face edges to hash table and validate indices
- for (size_t face = 0; face < nFaces; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- continue;
-
- if (i0 >= nVerts
- || i1 >= nVerts
- || i2 >= nVerts)
- return E_UNEXPECTED;
-
- const uint32_t v1 = pointRep[i0];
- const uint32_t v2 = pointRep[i1];
- const uint32_t v3 = pointRep[i2];
-
- // filter out degenerate triangles
- if (v1 == v2 || v1 == v3 || v2 == v3)
- continue;
-
- for (uint32_t point = 0; point < 3; ++point)
- {
- const uint32_t va = pointRep[indices[face * 3 + point]];
- const uint32_t vb = pointRep[indices[face * 3 + ((point + 1) % 3)]];
- const uint32_t vOther = pointRep[indices[face * 3 + ((point + 2) % 3)]];
-
- const uint32_t hashKey = va % hashSize;
-
- assert(freeEntry < (3 * nFaces));
- _Analysis_assume_(freeEntry < (3 * nFaces));
-
- auto newEntry = &hashEntries[freeEntry];
- ++freeEntry;
-
- newEntry->v1 = va;
- newEntry->v2 = vb;
- newEntry->vOther = vOther;
- newEntry->face = uint32_t(face);
- newEntry->next = hashTable[hashKey];
- hashTable[hashKey] = newEntry;
- }
- }
-
- assert(freeEntry <= (3 * nFaces));
-
- memset(adjacency, 0xff, sizeof(uint32_t) * nFaces * 3);
-
- for (size_t face = 0; face < nFaces; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- // filter out unused triangles
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- continue;
-
- assert(i0 < nVerts);
- assert(i1 < nVerts);
- assert(i2 < nVerts);
-
- _Analysis_assume_(i0 < nVerts);
- _Analysis_assume_(i1 < nVerts);
- _Analysis_assume_(i2 < nVerts);
-
- const uint32_t v1 = pointRep[i0];
- const uint32_t v2 = pointRep[i1];
- const uint32_t v3 = pointRep[i2];
-
- // filter out degenerate triangles
- if (v1 == v2 || v1 == v3 || v2 == v3)
- continue;
-
- for (uint32_t point = 0; point < 3; ++point)
- {
- if (adjacency[face * 3 + point] != UNUSED32)
- continue;
-
- // see if edge already entered, if not then enter it
- const uint32_t va = pointRep[indices[face * 3 + ((point + 1) % 3)]];
- const uint32_t vb = pointRep[indices[face * 3 + point]];
- const uint32_t vOther = pointRep[indices[face * 3 + ((point + 2) % 3)]];
-
- const uint32_t hashKey = va % hashSize;
-
- edgeHashEntry* current = hashTable[hashKey];
- edgeHashEntry* prev = nullptr;
-
- uint32_t foundFace = UNUSED32;
-
- while (current != nullptr)
- {
- if ((current->v2 == vb) && (current->v1 == va))
- {
- foundFace = current->face;
- break;
- }
-
- prev = current;
- current = current->next;
- }
-
- edgeHashEntry* found = current;
- edgeHashEntry* foundPrev = prev;
-
- float bestDiff = -2.f;
-
- // Scan for additional matches
- if (current)
- {
- prev = current;
- current = current->next;
-
- // find 'better' match
- while (current != nullptr)
- {
- if ((current->v2 == vb) && (current->v1 == va))
- {
- const XMVECTOR pB1 = XMLoadFloat3(&positions[vb]);
- const XMVECTOR pB2 = XMLoadFloat3(&positions[va]);
- const XMVECTOR pB3 = XMLoadFloat3(&positions[vOther]);
-
- XMVECTOR v12 = XMVectorSubtract(pB1, pB2);
- XMVECTOR v13 = XMVectorSubtract(pB1, pB3);
-
- const XMVECTOR bnormal = XMVector3Normalize(XMVector3Cross(v12, v13));
-
- if (bestDiff == -2.f)
- {
- const XMVECTOR pA1 = XMLoadFloat3(&positions[found->v1]);
- const XMVECTOR pA2 = XMLoadFloat3(&positions[found->v2]);
- const XMVECTOR pA3 = XMLoadFloat3(&positions[found->vOther]);
-
- v12 = XMVectorSubtract(pA1, pA2);
- v13 = XMVectorSubtract(pA1, pA3);
-
- const XMVECTOR anormal = XMVector3Normalize(XMVector3Cross(v12, v13));
-
- bestDiff = XMVectorGetX(XMVector3Dot(anormal, bnormal));
- }
-
- const XMVECTOR pA1 = XMLoadFloat3(&positions[current->v1]);
- const XMVECTOR pA2 = XMLoadFloat3(&positions[current->v2]);
- const XMVECTOR pA3 = XMLoadFloat3(&positions[current->vOther]);
-
- v12 = XMVectorSubtract(pA1, pA2);
- v13 = XMVectorSubtract(pA1, pA3);
-
- const XMVECTOR anormal = XMVector3Normalize(XMVector3Cross(v12, v13));
-
- const float diff = XMVectorGetX(XMVector3Dot(anormal, bnormal));
-
- // if face normals are closer, use new match
- if (diff > bestDiff)
- {
- found = current;
- foundPrev = prev;
- foundFace = current->face;
- bestDiff = diff;
- }
- }
-
- prev = current;
- current = current->next;
- }
- }
-
- if (foundFace != UNUSED32)
- {
- assert(found != nullptr);
-
- // remove found face from hash table
- if (foundPrev != nullptr)
- {
- foundPrev->next = found->next;
- }
- else
- {
- hashTable[hashKey] = found->next;
- }
-
- assert(adjacency[face * 3 + point] == UNUSED32);
- adjacency[face * 3 + point] = foundFace;
-
- // Check for other edge
- const uint32_t hashKey2 = vb % hashSize;
-
- current = hashTable[hashKey2];
- prev = nullptr;
-
- while (current != nullptr)
- {
- if ((current->face == uint32_t(face)) && (current->v2 == va) && (current->v1 == vb))
- {
- // trim edge from hash table
- if (prev != nullptr)
- {
- prev->next = current->next;
- }
- else
- {
- hashTable[hashKey2] = current->next;
- }
- break;
- }
-
- prev = current;
- current = current->next;
- }
-
- // mark neighbor to point back
- bool linked = false;
-
- for (uint32_t point2 = 0; point2 < point; ++point2)
- {
- if (foundFace == adjacency[face * 3 + point2])
- {
- linked = true;
- adjacency[face * 3 + point] = UNUSED32;
- break;
- }
- }
-
- if (!linked)
- {
- uint32_t point2 = 0;
- for (; point2 < 3; ++point2)
- {
- index_t k = indices[foundFace * 3 + point2];
- if (k == index_t(-1))
- continue;
-
- assert(k < nVerts);
- _Analysis_assume_(k < nVerts);
-
- if (pointRep[k] == va)
- break;
- }
-
- if (point2 < 3)
- {
- #ifndef NDEBUG
- uint32_t testPoint = indices[foundFace * 3 + ((point2 + 1) % 3)];
- testPoint = pointRep[testPoint];
- assert(testPoint == vb);
- #endif
- assert(adjacency[foundFace * 3 + point2] == UNUSED32);
-
- // update neighbor to point back to this face match edge
- adjacency[foundFace * 3 + point2] = uint32_t(face);
- }
- }
- }
- }
- }
-
- return S_OK;
- }
-}
-
-//=====================================================================================
-// Entry-points
-//=====================================================================================
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::GenerateAdjacencyAndPointReps(
- const uint16_t* indices,
- size_t nFaces,
- const XMFLOAT3* positions,
- size_t nVerts,
- float epsilon,
- uint32_t* pointRep,
- uint32_t* adjacency)
-{
- if (!indices || !nFaces || !positions || !nVerts)
- return E_INVALIDARG;
-
- if (!pointRep && !adjacency)
- return E_INVALIDARG;
-
- if (nVerts >= UINT16_MAX)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- std::unique_ptr temp;
- if (!pointRep)
- {
- temp.reset(new (std::nothrow) uint32_t[nVerts]);
- if (!temp)
- return E_OUTOFMEMORY;
-
- pointRep = temp.get();
- }
-
- HRESULT hr = GeneratePointReps(indices, nFaces, positions, nVerts, epsilon, pointRep);
- if (FAILED(hr))
- return hr;
-
- if (!adjacency)
- return S_OK;
-
- return ConvertPointRepsToAdjacencyImpl(indices, nFaces, positions, nVerts, pointRep, adjacency);
-}
-
-_Use_decl_annotations_
-HRESULT DirectX::GenerateAdjacencyAndPointReps(
- const uint32_t* indices,
- size_t nFaces,
- const XMFLOAT3* positions,
- size_t nVerts,
- float epsilon,
- uint32_t* pointRep,
- uint32_t* adjacency)
-{
- if (!indices || !nFaces || !positions || !nVerts)
- return E_INVALIDARG;
-
- if (!pointRep && !adjacency)
- return E_INVALIDARG;
-
- if (nVerts >= UINT32_MAX)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- std::unique_ptr temp;
- if (!pointRep)
- {
- temp.reset(new (std::nothrow) uint32_t[nVerts]);
- if (!temp)
- return E_OUTOFMEMORY;
-
- pointRep = temp.get();
- }
-
- HRESULT hr = GeneratePointReps(indices, nFaces, positions, nVerts, epsilon, pointRep);
- if (FAILED(hr))
- return hr;
-
- if (!adjacency)
- return S_OK;
-
- return ConvertPointRepsToAdjacencyImpl(indices, nFaces, positions, nVerts, pointRep, adjacency);
-}
-
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::ConvertPointRepsToAdjacency(
- const uint16_t* indices,
- size_t nFaces,
- const XMFLOAT3* positions,
- size_t nVerts,
- const uint32_t* pointRep,
- uint32_t* adjacency)
-{
- if (!indices || !nFaces || !positions || !nVerts || !adjacency)
- return E_INVALIDARG;
-
- if (nVerts >= UINT16_MAX)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- std::unique_ptr temp;
- if (!pointRep)
- {
- temp.reset(new (std::nothrow) uint32_t[nVerts]);
- if (!temp)
- return E_OUTOFMEMORY;
-
- for (size_t j = 0; j < nVerts; ++j)
- {
- temp[j] = uint32_t(j);
- }
-
- pointRep = temp.get();
- }
-
- return ConvertPointRepsToAdjacencyImpl(indices, nFaces, positions, nVerts, pointRep, adjacency);
-}
-
-_Use_decl_annotations_
-HRESULT DirectX::ConvertPointRepsToAdjacency(
- const uint32_t* indices,
- size_t nFaces,
- const XMFLOAT3* positions,
- size_t nVerts,
- const uint32_t* pointRep,
- uint32_t* adjacency)
-{
- if (!indices || !nFaces || !positions || !nVerts || !adjacency)
- return E_INVALIDARG;
-
- if (nVerts >= UINT32_MAX)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- std::unique_ptr temp;
- if (!pointRep)
- {
- temp.reset(new (std::nothrow) uint32_t[nVerts]);
- if (!temp)
- return E_OUTOFMEMORY;
-
- for (size_t j = 0; j < nVerts; ++j)
- {
- temp[j] = uint32_t(j);
- }
-
- pointRep = temp.get();
- }
-
- return ConvertPointRepsToAdjacencyImpl(indices, nFaces, positions, nVerts, pointRep, adjacency);
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshClean.cpp b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshClean.cpp
deleted file mode 100644
index 80e16eabf2..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshClean.cpp
+++ /dev/null
@@ -1,443 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshClean.cpp
-//
-// DirectX Mesh Geometry Library - Mesh clean-up
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#include "DirectXMeshP.h"
-
-using namespace DirectX;
-
-namespace
-{
- template
- HRESULT CleanImpl(
- _Inout_updates_all_(nFaces * 3) index_t* indices,
- size_t nFaces, size_t nVerts,
- _Inout_updates_all_opt_(nFaces * 3) uint32_t* adjacency,
- _In_reads_opt_(nFaces) const uint32_t* attributes,
- _Inout_ std::vector& dupVerts, bool breakBowties)
- {
- if (!adjacency && !attributes)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- dupVerts.clear();
- size_t curNewVert = nVerts;
-
- const size_t tsize = (sizeof(bool) * nFaces * 3) + (sizeof(uint32_t) * nVerts) + (sizeof(index_t) * nFaces * 3);
- std::unique_ptr temp(new (std::nothrow) uint8_t[tsize]);
- if (!temp)
- return E_OUTOFMEMORY;
-
- auto faceSeen = reinterpret_cast(temp.get());
- auto ids = reinterpret_cast(temp.get() + sizeof(bool) * nFaces * 3);
-
- // UNUSED/DEGENERATE cleanup
- for (uint32_t face = 0; face < nFaces; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- {
- // ensure all index entries in the unused face are 'unused'
- indices[face * 3] =
- indices[face * 3 + 1] =
- indices[face * 3 + 2] = index_t(-1);
-
- // ensure no neighbor references the unused face
- if (adjacency)
- {
- for (uint32_t point = 0; point < 3; ++point)
- {
- uint32_t k = adjacency[face * 3 + point];
- if (k != UNUSED32)
- {
- assert(k < nFaces);
- _Analysis_assume_(k < nFaces);
-
- if (adjacency[k * 3] == face)
- adjacency[k * 3] = UNUSED32;
-
- if (adjacency[k * 3 + 1] == face)
- adjacency[k * 3 + 1] = UNUSED32;
-
- if (adjacency[k * 3 + 2] == face)
- adjacency[k * 3 + 2] = UNUSED32;
-
- adjacency[face * 3 + point] = UNUSED32;
- }
- }
- }
- }
- else if (i0 == i1
- || i0 == i2
- || i1 == i2)
- {
- // Clean doesn't trim out degenerates as most other functions ignore them
-
- // ensure no neighbor references the degenerate face
- if (adjacency)
- {
- for (uint32_t point = 0; point < 3; ++point)
- {
- uint32_t k = adjacency[face * 3 + point];
- if (k != UNUSED32)
- {
- assert(k < nFaces);
- _Analysis_assume_(k < nFaces);
-
- if (adjacency[k * 3] == face)
- adjacency[k * 3] = UNUSED32;
-
- if (adjacency[k * 3 + 1] == face)
- adjacency[k * 3 + 1] = UNUSED32;
-
- if (adjacency[k * 3 + 2] == face)
- adjacency[k * 3 + 2] = UNUSED32;
-
- adjacency[face * 3 + point] = UNUSED32;
- }
- }
- }
- }
- }
-
- // ASYMMETRIC ADJ cleanup
- if (adjacency)
- {
- for (;;)
- {
- bool unlinked = false;
-
- for (uint32_t face = 0; face < nFaces; ++face)
- {
- for (uint32_t point = 0; point < 3; ++point)
- {
- const uint32_t k = adjacency[face * 3 + point];
- if (k != UNUSED32)
- {
- assert(k < nFaces);
- _Analysis_assume_(k < nFaces);
-
- const uint32_t edge = find_edge(&adjacency[k * 3], face);
- if (edge >= 3)
- {
- unlinked = true;
- adjacency[face * 3 + point] = UNUSED32;
- }
- }
- }
- }
-
- if (!unlinked)
- break;
- }
- }
-
- // BACKFACING cleanup
- if (adjacency)
- {
- for (size_t face = 0; face < nFaces; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- {
- // ignore unused faces
- continue;
- }
-
- assert(i0 < nVerts);
- assert(i1 < nVerts);
- assert(i2 < nVerts);
-
- if (i0 == i1
- || i0 == i2
- || i1 == i2)
- {
- // ignore degenerate faces
- continue;
- }
-
- const uint32_t j0 = adjacency[face * 3];
- const uint32_t j1 = adjacency[face * 3 + 1];
- const uint32_t j2 = adjacency[face * 3 + 2];
-
- if ((j0 == j1 && j0 != UNUSED32)
- || (j0 == j2 && j0 != UNUSED32)
- || (j1 == j2 && j1 != UNUSED32))
- {
- uint32_t neighbor = (j0 == j1 || j0 == j2) ? j0 : j1;
-
- // remove links then break bowties will clean up any remaining issues
- for (uint32_t edge = 0; edge < 3; ++edge)
- {
- if (adjacency[face * 3 + edge] == neighbor)
- {
- adjacency[face * 3 + edge] = UNUSED32;
- }
-
- if (adjacency[neighbor * 3 + edge] == face)
- {
- adjacency[neighbor * 3 + edge] = UNUSED32;
- }
- }
- }
- }
- }
-
- auto indicesNew = reinterpret_cast(reinterpret_cast(ids) + sizeof(uint32_t) * nVerts);
- memcpy(indicesNew, indices, sizeof(index_t) * nFaces * 3);
-
- // BOWTIES cleanup
- if (adjacency && breakBowties)
- {
- memset(faceSeen, 0, sizeof(bool) * nFaces * 3);
- memset(ids, 0xFF, sizeof(uint32_t) * nVerts);
-
- orbit_iterator ovi(adjacency, indices, nFaces);
-
- for (uint32_t face = 0; face < nFaces; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- {
- // ignore unused faces
- faceSeen[face * 3] = true;
- faceSeen[face * 3 + 1] = true;
- faceSeen[face * 3 + 2] = true;
- continue;
- }
-
- assert(i0 < nVerts);
- assert(i1 < nVerts);
- assert(i2 < nVerts);
-
- if (i0 == i1
- || i0 == i2
- || i1 == i2)
- {
- // ignore degenerate faces
- faceSeen[face * 3] = true;
- faceSeen[face * 3 + 1] = true;
- faceSeen[face * 3 + 2] = true;
- continue;
- }
-
- for (uint32_t point = 0; point < 3; ++point)
- {
- if (faceSeen[face * 3 + point])
- continue;
-
- faceSeen[face * 3 + point] = true;
-
- index_t i = indices[face * 3 + point];
- if (i == index_t(-1))
- continue;
-
- assert(i < nVerts);
-
- ovi.initialize(face, i, orbit_iterator::ALL);
- ovi.moveToCCW();
-
- index_t replaceVertex = index_t(-1);
- index_t replaceValue = index_t(-1);
-
- while (!ovi.done())
- {
- uint32_t curFace = ovi.nextFace();
- if (curFace >= nFaces)
- return E_FAIL;
-
- uint32_t curPoint = ovi.getpoint();
- if (curPoint > 2)
- return E_FAIL;
-
- faceSeen[curFace * 3 + curPoint] = true;
-
- index_t j = indices[curFace * 3 + curPoint];
- if (j == index_t(-1))
- continue;
-
- assert(j < nVerts);
-
- if (j == replaceVertex)
- {
- indicesNew[curFace * 3 + curPoint] = replaceValue;
- }
- else if (ids[j] == UNUSED32)
- {
- ids[j] = face;
- }
- else if (ids[j] != face)
- {
- // We found a bowtie, duplicate a vert
- replaceVertex = j;
- replaceValue = index_t(curNewVert);
- indicesNew[curFace * 3 + curPoint] = replaceValue;
- ++curNewVert;
-
- dupVerts.push_back(j);
- }
- }
- }
- }
-
- assert((nVerts + dupVerts.size()) == curNewVert);
- }
-
- // Ensure no vertex is used by more than one attribute
- if (attributes)
- {
- memset(ids, 0xFF, sizeof(uint32_t) * nVerts);
-
- std::vector dupAttr;
- dupAttr.reserve(dupVerts.size());
- for (size_t j = 0; j < dupVerts.size(); ++j)
- {
- dupAttr.push_back(UNUSED32);
- }
-
- std::unordered_multimap dups;
-
- for (size_t face = 0; face < nFaces; ++face)
- {
- uint32_t a = attributes[face];
-
- for (size_t point = 0; point < 3; ++point)
- {
- uint32_t j = indicesNew[face * 3 + point];
-
- const uint32_t k = (j >= nVerts) ? dupAttr[j - nVerts] : ids[j];
-
- if (k == UNUSED32)
- {
- if (j >= nVerts)
- dupAttr[j - nVerts] = a;
- else
- ids[j] = a;
- }
- else if (k != a)
- {
- // Look for a dup with the correct attribute
- auto range = dups.equal_range(j);
- auto it = range.first;
- for (; it != range.second; ++it)
- {
- const uint32_t m = (it->second >= nVerts) ? dupAttr[it->second - nVerts] : ids[it->second];
- if (m == a)
- {
- indicesNew[face * 3 + point] = index_t(it->second);
- break;
- }
- }
-
- if (it == range.second)
- {
- // Duplicate the vert
- auto dv = std::pair(j, curNewVert);
- dups.insert(dv);
-
- indicesNew[face * 3 + point] = index_t(curNewVert);
- ++curNewVert;
-
- if (j >= nVerts)
- {
- dupVerts.push_back(dupVerts[j - nVerts]);
- }
- else
- {
- dupVerts.push_back(j);
- }
-
- dupAttr.push_back(a);
-
- assert(dupVerts.size() == dupAttr.size());
- }
- }
- }
- }
-
- assert((nVerts + dupVerts.size()) == curNewVert);
-
- #ifndef NDEBUG
- for (const auto it : dupVerts)
- {
- assert(it < nVerts);
- }
- #endif
- }
-
- if ((uint64_t(nVerts) + uint64_t(dupVerts.size())) >= index_t(-1))
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- if (!dupVerts.empty())
- {
- memcpy(indices, indicesNew, sizeof(index_t) * nFaces * 3);
- }
-
- return S_OK;
- }
-}
-
-//=====================================================================================
-// Entry-points
-//=====================================================================================
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::Clean(
- uint16_t* indices,
- size_t nFaces,
- size_t nVerts,
- uint32_t* adjacency,
- const uint32_t* attributes,
- std::vector& dupVerts,
- bool breakBowties)
-{
- HRESULT hr = Validate(indices, nFaces, nVerts, adjacency, VALIDATE_DEFAULT);
- if (FAILED(hr))
- return hr;
-
- return CleanImpl(indices, nFaces, nVerts, adjacency, attributes, dupVerts, breakBowties);
-}
-
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::Clean(
- uint32_t* indices,
- size_t nFaces,
- size_t nVerts,
- uint32_t* adjacency,
- const uint32_t* attributes,
- std::vector& dupVerts,
- bool breakBowties)
-{
- HRESULT hr = Validate(indices, nFaces, nVerts, adjacency, VALIDATE_DEFAULT);
- if (FAILED(hr))
- return hr;
-
- return CleanImpl(indices, nFaces, nVerts, adjacency, attributes, dupVerts, breakBowties);
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshConcat.cpp b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshConcat.cpp
deleted file mode 100644
index 55cc4a2bb6..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshConcat.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshConcat.cpp
-//
-// DirectX Mesh Geometry Library - Concatenate mesh
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#include "DirectXMeshP.h"
-
-using namespace DirectX;
-
-//=====================================================================================
-// Entry-points
-//=====================================================================================
-
-_Use_decl_annotations_
-HRESULT __cdecl DirectX::ConcatenateMesh(
- size_t nFaces,
- size_t nVerts,
- uint32_t* faceDestMap,
- uint32_t* vertexDestMap,
- size_t& totalFaces,
- size_t& totalVerts) noexcept
-{
- if (!nFaces || !nVerts || !faceDestMap || !vertexDestMap)
- return E_INVALIDARG;
-
- if (nVerts >= UINT32_MAX)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- uint64_t newFaceCount = uint64_t(totalFaces) + nFaces;
- uint64_t newVertCount = uint64_t(totalVerts) + nVerts;
-
- if (newFaceCount >= UINT32_MAX || newVertCount >= UINT32_MAX)
- return E_FAIL;
-
- auto const baseFace = static_cast(totalFaces);
- for (uint32_t j = 0; j < nFaces; ++j)
- {
- faceDestMap[j] = baseFace + j;
- }
-
- auto const baseVert = static_cast(totalVerts);
- for (uint32_t j = 0; j < nVerts; ++j)
- {
- vertexDestMap[j] = baseVert + j;
- }
-
- totalFaces = static_cast(newFaceCount);
- totalVerts = static_cast(newVertCount);
-
- return S_OK;
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshGSAdjacency.cpp b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshGSAdjacency.cpp
deleted file mode 100644
index 84bf50494b..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshGSAdjacency.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshGSAdjacency.cpp
-//
-// DirectX Mesh Geometry Library - Geometry Shader adjacency computation
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#include "DirectXMeshP.h"
-
-using namespace DirectX;
-
-//
-// Generates an IB triangle list with adjacency (D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ)
-// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124.aspx
-//
-
-namespace
-{
- template
- HRESULT GenerateGSAdjacencyImpl(
- _In_reads_(nFaces * 3) const index_t* indices, _In_ size_t nFaces,
- _In_reads_(nVerts) const uint32_t* pointRep,
- _In_reads_(nFaces * 3) const uint32_t* adjacency, _In_ size_t nVerts,
- _Out_writes_(nFaces * 6) index_t* indicesAdj) noexcept
- {
- if (!indices || !nFaces || !pointRep || !adjacency || !nVerts || !indicesAdj)
- return E_INVALIDARG;
-
- if (nVerts >= index_t(-1))
- return E_INVALIDARG;
-
- if (indices == indicesAdj)
- {
- // Does not support in-place conversion of the index buffer
- return HRESULT_E_NOT_SUPPORTED;
- }
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- size_t inputi = 0;
- size_t outputi = 0;
-
- for (size_t face = 0; face < nFaces; ++face)
- {
- for (uint32_t point = 0; point < 3; ++point)
- {
- assert(outputi < (nFaces * 6));
- _Analysis_assume_(outputi < (nFaces * 6));
-
- indicesAdj[outputi] = indices[inputi];
- ++outputi;
- ++inputi;
-
- assert(outputi < (nFaces * 6));
- _Analysis_assume_(outputi < (nFaces * 6));
-
- const uint32_t a = adjacency[face * 3 + point];
- if (a == UNUSED32)
- {
- indicesAdj[outputi] = indices[face * 3 + ((point + 2) % 3)];
- }
- else
- {
- uint32_t v1 = indices[face * 3 + point];
- uint32_t v2 = indices[face * 3 + ((point + 1) % 3)];
-
- if (v1 == index_t(-1) || v2 == index_t(-1))
- {
- indicesAdj[outputi] = index_t(-1);
- }
- else
- {
- if (v1 >= nVerts
- || v2 >= nVerts)
- return E_UNEXPECTED;
-
- v1 = pointRep[v1];
- v2 = pointRep[v2];
-
- uint32_t vOther = UNUSED32;
-
- // find other vertex
- for (uint32_t k = 0; k < 3; ++k)
- {
- assert(a < nFaces);
- _Analysis_assume_(a < nFaces);
- const uint32_t ak = indices[a * 3 + k];
- if (ak == index_t(-1))
- break;
-
- if (ak >= nVerts)
- return E_UNEXPECTED;
-
- if (pointRep[ak] == v1)
- continue;
-
- if (pointRep[ak] == v2)
- continue;
-
- vOther = ak;
- }
-
- if (vOther == UNUSED32)
- {
- indicesAdj[outputi] = indices[face * 3 + ((point + 2) % 3)];
-
- }
- else
- {
- indicesAdj[outputi] = index_t(vOther);
- }
- }
- }
- ++outputi;
- }
- }
-
- assert(inputi == (nFaces * 3));
- assert(outputi == (nFaces * 6));
-
- return S_OK;
- }
-}
-
-//=====================================================================================
-// Entry-points
-//=====================================================================================
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::GenerateGSAdjacency(
- const uint16_t* indices,
- size_t nFaces,
- const uint32_t* pointRep,
- const uint32_t* adjacency,
- size_t nVerts,
- uint16_t* indicesAdj) noexcept
-{
- return GenerateGSAdjacencyImpl(indices, nFaces, pointRep, adjacency, nVerts, indicesAdj);
-}
-
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::GenerateGSAdjacency(
- const uint32_t* indices,
- size_t nFaces,
- const uint32_t* pointRep,
- const uint32_t* adjacency,
- size_t nVerts,
- uint32_t* indicesAdj) noexcept
-{
- return GenerateGSAdjacencyImpl(indices, nFaces, pointRep, adjacency, nVerts, indicesAdj);
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshNormals.cpp b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshNormals.cpp
deleted file mode 100644
index 31c8a9acd1..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshNormals.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshNormals.cpp
-//
-// DirectX Mesh Geometry Library - Normal computation
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#include "DirectXMeshP.h"
-
-using namespace DirectX;
-
-namespace
-{
- //---------------------------------------------------------------------------------
- // Compute normals with equal weighting
- //---------------------------------------------------------------------------------
- template
- HRESULT ComputeNormalsEqualWeight(
- _In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, size_t nVerts,
- bool cw, _Out_writes_(nVerts) XMFLOAT3* normals) noexcept
- {
- auto temp = make_AlignedArrayXMVECTOR(nVerts);
- if (!temp)
- return E_OUTOFMEMORY;
-
- XMVECTOR* vertNormals = temp.get();
- memset(vertNormals, 0, sizeof(XMVECTOR) * nVerts);
-
- for (size_t face = 0; face < nFaces; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- continue;
-
- if (i0 >= nVerts
- || i1 >= nVerts
- || i2 >= nVerts)
- return E_UNEXPECTED;
-
- const XMVECTOR p1 = XMLoadFloat3(&positions[i0]);
- const XMVECTOR p2 = XMLoadFloat3(&positions[i1]);
- const XMVECTOR p3 = XMLoadFloat3(&positions[i2]);
-
- const XMVECTOR u = XMVectorSubtract(p2, p1);
- const XMVECTOR v = XMVectorSubtract(p3, p1);
-
- const XMVECTOR faceNormal = XMVector3Normalize(XMVector3Cross(u, v));
-
- vertNormals[i0] = XMVectorAdd(vertNormals[i0], faceNormal);
- vertNormals[i1] = XMVectorAdd(vertNormals[i1], faceNormal);
- vertNormals[i2] = XMVectorAdd(vertNormals[i2], faceNormal);
- }
-
- // Store results
- if (cw)
- {
- for (size_t vert = 0; vert < nVerts; ++vert)
- {
- XMVECTOR n = XMVector3Normalize(vertNormals[vert]);
- n = XMVectorNegate(n);
- XMStoreFloat3(&normals[vert], n);
- }
- }
- else
- {
- for (size_t vert = 0; vert < nVerts; ++vert)
- {
- const XMVECTOR n = XMVector3Normalize(vertNormals[vert]);
- XMStoreFloat3(&normals[vert], n);
- }
- }
-
- return S_OK;
- }
-
-
- //---------------------------------------------------------------------------------
- // Compute normals with weighting by angle
- //---------------------------------------------------------------------------------
- template
- HRESULT ComputeNormalsWeightedByAngle(
- _In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, size_t nVerts,
- bool cw, _Out_writes_(nVerts) XMFLOAT3* normals) noexcept
- {
- auto temp = make_AlignedArrayXMVECTOR(nVerts);
- if (!temp)
- return E_OUTOFMEMORY;
-
- XMVECTOR* vertNormals = temp.get();
- memset(vertNormals, 0, sizeof(XMVECTOR) * nVerts);
-
- for (size_t face = 0; face < nFaces; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- continue;
-
- if (i0 >= nVerts
- || i1 >= nVerts
- || i2 >= nVerts)
- return E_UNEXPECTED;
-
- const XMVECTOR p0 = XMLoadFloat3(&positions[i0]);
- const XMVECTOR p1 = XMLoadFloat3(&positions[i1]);
- const XMVECTOR p2 = XMLoadFloat3(&positions[i2]);
-
- const XMVECTOR u = XMVectorSubtract(p1, p0);
- const XMVECTOR v = XMVectorSubtract(p2, p0);
-
- const XMVECTOR faceNormal = XMVector3Normalize(XMVector3Cross(u, v));
-
- // Corner 0 -> 1 - 0, 2 - 0
- const XMVECTOR a = XMVector3Normalize(u);
- const XMVECTOR b = XMVector3Normalize(v);
- XMVECTOR w0 = XMVector3Dot(a, b);
- w0 = XMVectorClamp(w0, g_XMNegativeOne, g_XMOne);
- w0 = XMVectorACos(w0);
-
- // Corner 1 -> 2 - 1, 0 - 1
- const XMVECTOR c = XMVector3Normalize(XMVectorSubtract(p2, p1));
- const XMVECTOR d = XMVector3Normalize(XMVectorSubtract(p0, p1));
- XMVECTOR w1 = XMVector3Dot(c, d);
- w1 = XMVectorClamp(w1, g_XMNegativeOne, g_XMOne);
- w1 = XMVectorACos(w1);
-
- // Corner 2 -> 0 - 2, 1 - 2
- const XMVECTOR e = XMVector3Normalize(XMVectorSubtract(p0, p2));
- const XMVECTOR f = XMVector3Normalize(XMVectorSubtract(p1, p2));
- XMVECTOR w2 = XMVector3Dot(e, f);
- w2 = XMVectorClamp(w2, g_XMNegativeOne, g_XMOne);
- w2 = XMVectorACos(w2);
-
- vertNormals[i0] = XMVectorMultiplyAdd(faceNormal, w0, vertNormals[i0]);
- vertNormals[i1] = XMVectorMultiplyAdd(faceNormal, w1, vertNormals[i1]);
- vertNormals[i2] = XMVectorMultiplyAdd(faceNormal, w2, vertNormals[i2]);
- }
-
- // Store results
- if (cw)
- {
- for (size_t vert = 0; vert < nVerts; ++vert)
- {
- XMVECTOR n = XMVector3Normalize(vertNormals[vert]);
- n = XMVectorNegate(n);
- XMStoreFloat3(&normals[vert], n);
- }
- }
- else
- {
- for (size_t vert = 0; vert < nVerts; ++vert)
- {
- const XMVECTOR n = XMVector3Normalize(vertNormals[vert]);
- XMStoreFloat3(&normals[vert], n);
- }
- }
-
- return S_OK;
- }
-
-
- //---------------------------------------------------------------------------------
- // Compute normals with weighting by face area
- //---------------------------------------------------------------------------------
- template
- HRESULT ComputeNormalsWeightedByArea(
- _In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
- _In_reads_(nVerts) const XMFLOAT3* positions, size_t nVerts,
- bool cw, _Out_writes_(nVerts) XMFLOAT3* normals) noexcept
- {
- auto temp = make_AlignedArrayXMVECTOR(nVerts);
- if (!temp)
- return E_OUTOFMEMORY;
-
- XMVECTOR* vertNormals = temp.get();
- memset(vertNormals, 0, sizeof(XMVECTOR) * nVerts);
-
- for (size_t face = 0; face < nFaces; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- continue;
-
- if (i0 >= nVerts
- || i1 >= nVerts
- || i2 >= nVerts)
- return E_UNEXPECTED;
-
- const XMVECTOR p0 = XMLoadFloat3(&positions[i0]);
- const XMVECTOR p1 = XMLoadFloat3(&positions[i1]);
- const XMVECTOR p2 = XMLoadFloat3(&positions[i2]);
-
- const XMVECTOR u = XMVectorSubtract(p1, p0);
- const XMVECTOR v = XMVectorSubtract(p2, p0);
-
- const XMVECTOR faceNormal = XMVector3Normalize(XMVector3Cross(u, v));
-
- // Corner 0 -> 1 - 0, 2 - 0
- XMVECTOR w0 = XMVector3Cross(u, v);
- w0 = XMVector3Length(w0);
-
- // Corner 1 -> 2 - 1, 0 - 1
- const XMVECTOR c = XMVectorSubtract(p2, p1);
- const XMVECTOR d = XMVectorSubtract(p0, p1);
- XMVECTOR w1 = XMVector3Cross(c, d);
- w1 = XMVector3Length(w1);
-
- // Corner 2 -> 0 - 2, 1 - 2
- const XMVECTOR e = XMVectorSubtract(p0, p2);
- const XMVECTOR f = XMVectorSubtract(p1, p2);
- XMVECTOR w2 = XMVector3Cross(e, f);
- w2 = XMVector3Length(w2);
-
- vertNormals[i0] = XMVectorMultiplyAdd(faceNormal, w0, vertNormals[i0]);
- vertNormals[i1] = XMVectorMultiplyAdd(faceNormal, w1, vertNormals[i1]);
- vertNormals[i2] = XMVectorMultiplyAdd(faceNormal, w2, vertNormals[i2]);
- }
-
- // Store results
- if (cw)
- {
- for (size_t vert = 0; vert < nVerts; ++vert)
- {
- XMVECTOR n = XMVector3Normalize(vertNormals[vert]);
- n = XMVectorNegate(n);
- XMStoreFloat3(&normals[vert], n);
- }
- }
- else
- {
- for (size_t vert = 0; vert < nVerts; ++vert)
- {
- const XMVECTOR n = XMVector3Normalize(vertNormals[vert]);
- XMStoreFloat3(&normals[vert], n);
- }
- }
-
- return S_OK;
- }
-}
-
-//=====================================================================================
-// Entry-points
-//=====================================================================================
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::ComputeNormals(
- const uint16_t* indices,
- size_t nFaces,
- const XMFLOAT3* positions,
- size_t nVerts,
- CNORM_FLAGS flags,
- XMFLOAT3* normals) noexcept
-{
- if (!indices || !positions || !nFaces || !nVerts || !normals)
- return E_INVALIDARG;
-
- if (nVerts >= UINT16_MAX)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- const bool cw = (flags & CNORM_WIND_CW) ? true : false;
-
- if (flags & CNORM_WEIGHT_BY_AREA)
- {
- return ComputeNormalsWeightedByArea(indices, nFaces, positions, nVerts, cw, normals);
- }
- else if (flags & CNORM_WEIGHT_EQUAL)
- {
- return ComputeNormalsEqualWeight(indices, nFaces, positions, nVerts, cw, normals);
- }
- else
- {
- return ComputeNormalsWeightedByAngle(indices, nFaces, positions, nVerts, cw, normals);
- }
-}
-
-_Use_decl_annotations_
-HRESULT DirectX::ComputeNormals(
- const uint32_t* indices,
- size_t nFaces,
- const XMFLOAT3* positions,
- size_t nVerts,
- CNORM_FLAGS flags,
- XMFLOAT3* normals) noexcept
-{
- if (!indices || !positions || !nFaces || !nVerts || !normals)
- return E_INVALIDARG;
-
- if (nVerts >= UINT32_MAX)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- const bool cw = (flags & CNORM_WIND_CW) ? true : false;
-
- if (flags & CNORM_WEIGHT_BY_AREA)
- {
- return ComputeNormalsWeightedByArea(indices, nFaces, positions, nVerts, cw, normals);
- }
- else if (flags & CNORM_WEIGHT_EQUAL)
- {
- return ComputeNormalsEqualWeight(indices, nFaces, positions, nVerts, cw, normals);
- }
- else
- {
- return ComputeNormalsWeightedByAngle(indices, nFaces, positions, nVerts, cw, normals);
- }
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimize.cpp b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimize.cpp
deleted file mode 100644
index fddbb2cd64..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimize.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshOptimize.cpp
-//
-// DirectX Mesh Geometry Library - Mesh optimization
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#include "DirectXMeshP.h"
-
-using namespace DirectX;
-
-namespace
-{
- template
- HRESULT OptimizeVerticesImpl(
- _In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
- size_t nVerts, _Out_writes_(nVerts) uint32_t* vertexRemap,
- _Out_opt_ size_t* trailingUnused) noexcept
- {
- if (!indices || !nFaces || !nVerts || !vertexRemap)
- return E_INVALIDARG;
-
- if (nVerts >= index_t(-1))
- return E_INVALIDARG;
-
- if (trailingUnused)
- {
- *trailingUnused = 0;
- }
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- std::unique_ptr tempRemap(new (std::nothrow) uint32_t[nVerts]);
- if (!tempRemap)
- return E_OUTOFMEMORY;
-
- memset(tempRemap.get(), 0xff, sizeof(uint32_t) * nVerts);
-
- uint32_t curvertex = 0;
- for (size_t j = 0; j < (nFaces * 3); ++j)
- {
- index_t curindex = indices[j];
- if (curindex == index_t(-1))
- continue;
-
- if (curindex >= nVerts)
- return E_UNEXPECTED;
-
- if (tempRemap[curindex] == UNUSED32)
- {
- tempRemap[curindex] = curvertex;
- ++curvertex;
- }
- }
-
- // inverse lookup
- memset(vertexRemap, 0xff, sizeof(uint32_t) * nVerts);
-
- size_t unused = 0;
-
- for (uint32_t j = 0; j < nVerts; ++j)
- {
- uint32_t vertindex = tempRemap[j];
- if (vertindex == UNUSED32)
- {
- ++unused;
- }
- else
- {
- if (vertindex >= nVerts)
- return E_UNEXPECTED;
-
- vertexRemap[vertindex] = j;
- }
- }
-
- if (trailingUnused)
- {
- *trailingUnused = unused;
- }
-
- return S_OK;
- }
-}
-
-//=====================================================================================
-// Entry-points
-//=====================================================================================
-
-_Use_decl_annotations_
-HRESULT DirectX::AttributeSort(
- size_t nFaces,
- uint32_t* attributes,
- uint32_t* faceRemap)
-{
- if (!nFaces || !attributes || !faceRemap)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- using intpair_t = std::pair;
-
- std::vector list;
- list.reserve(nFaces);
- for (uint32_t j = 0; j < nFaces; ++j)
- {
- list.emplace_back(intpair_t(attributes[j], j));
- }
-
- std::stable_sort(list.begin(), list.end(), [](const intpair_t& a, const intpair_t& b) noexcept -> bool
- {
- return (a.first < b.first);
- });
-
- auto it = list.begin();
- for (uint32_t j = 0; j < nFaces; ++j, ++it)
- {
- attributes[j] = it->first;
- faceRemap[j] = it->second;
- }
-
- return S_OK;
-}
-
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeVertices(
- const uint16_t* indices,
- size_t nFaces,
- size_t nVerts,
- uint32_t* vertexRemap,
- size_t* trailingUnused) noexcept
-{
- return OptimizeVerticesImpl(indices, nFaces, nVerts, vertexRemap, trailingUnused);
-}
-
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeVertices(
- const uint32_t* indices,
- size_t nFaces,
- size_t nVerts,
- uint32_t* vertexRemap,
- size_t* trailingUnused) noexcept
-{
- return OptimizeVerticesImpl(indices, nFaces, nVerts, vertexRemap, trailingUnused);
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimizeLRU.cpp b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimizeLRU.cpp
deleted file mode 100644
index 62fd683035..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimizeLRU.cpp
+++ /dev/null
@@ -1,661 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshOptimizeLRU.cpp
-//
-// DirectX Mesh Geometry Library - Mesh optimization
-//
-// Forsyth "Linear-Speed Vertex Cache Optimisation"
-// https://tomforsyth1000.github.io/papers/fast_vert_cache_opt.html
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#include "DirectXMeshP.h"
-
-using namespace DirectX;
-
-namespace
-{
- // This code was authored and released into the public domain by Adrian Stone (stone@gameangst.com).
-
- // code for computing vertex score was taken, as much as possible
- // directly from the original publication.
- float ComputeVertexCacheScore(uint32_t cachePosition, uint32_t vertexCacheSize) noexcept
- {
- constexpr float FindVertexScore_CacheDecayPower = 1.5f;
- constexpr float FindVertexScore_LastTriScore = 0.75f;
-
- float score = 0.0f;
- if (cachePosition >= vertexCacheSize)
- {
- // Vertex is not in FIFO cache - no score.
- }
- else
- {
- if (cachePosition < 3)
- {
- // This vertex was used in the last triangle,
- // so it has a fixed score, whichever of the three
- // it's in. Otherwise, you can get very different
- // answers depending on whether you add
- // the triangle 1,2,3 or 3,1,2 - which is silly.
-
- score = FindVertexScore_LastTriScore;
- }
- else
- {
- // Points for being high in the cache.
- const float scaler = 1.0f / float(vertexCacheSize - 3u);
- score = 1.0f - float(cachePosition - 3u) * scaler;
- score = powf(score, FindVertexScore_CacheDecayPower);
- }
- }
-
- return score;
- }
-
- float ComputeVertexValenceScore(uint32_t numActiveFaces) noexcept
- {
- constexpr float FindVertexScore_ValenceBoostScale = 2.0f;
- constexpr float FindVertexScore_ValenceBoostPower = 0.5f;
-
- float score = 0.f;
-
- // Bonus points for having a low number of tris still to
- // use the vert, so we get rid of lone verts quickly.
- const float valenceBoost = powf(static_cast(numActiveFaces),
- -FindVertexScore_ValenceBoostPower);
-
- score += FindVertexScore_ValenceBoostScale * valenceBoost;
- return score;
- }
-
- enum { kMaxVertexCacheSize = 64 };
- enum { kMaxPrecomputedVertexValenceScores = 64 };
-
- float s_vertexCacheScores[kMaxVertexCacheSize + 1][kMaxVertexCacheSize];
- float s_vertexValenceScores[kMaxPrecomputedVertexValenceScores];
-
-#ifdef _WIN32
- static INIT_ONCE s_initOnce = INIT_ONCE_STATIC_INIT;
-
- BOOL WINAPI ComputeVertexScores(PINIT_ONCE, PVOID, PVOID*) noexcept
- #else
- std::once_flag s_initOnce;
-
- void ComputeVertexScores() noexcept
- #endif
- {
- for (uint32_t cacheSize = 0; cacheSize <= kMaxVertexCacheSize; ++cacheSize)
- {
- for (uint32_t cachePos = 0; cachePos < cacheSize; ++cachePos)
- {
- s_vertexCacheScores[cacheSize][cachePos] = ComputeVertexCacheScore(cachePos, cacheSize);
- }
- }
-
- for (uint32_t valence = 0; valence < kMaxPrecomputedVertexValenceScores; ++valence)
- {
- s_vertexValenceScores[valence] = ComputeVertexValenceScore(valence);
- }
-
- #ifdef _WIN32
- return TRUE;
- #endif
- }
-
- float FindVertexScore(uint32_t numActiveFaces, uint32_t cachePosition, uint32_t vertexCacheSize) noexcept
- {
- if (numActiveFaces == 0)
- {
- // No tri needs this vertex!
-
- return -1.0f;
- }
-
- float score = 0.f;
-
- if (cachePosition < vertexCacheSize)
- {
- score += s_vertexCacheScores[vertexCacheSize][cachePosition];
- }
-
- if (numActiveFaces < kMaxPrecomputedVertexValenceScores)
- {
- score += s_vertexValenceScores[numActiveFaces];
- }
- else
- {
- score += ComputeVertexValenceScore(numActiveFaces);
- }
-
- return score;
- }
-
- template
- struct OptimizeVertexData
- {
- float score;
- uint32_t activeFaceListStart;
- uint32_t activeFaceListSize;
- IndexType cachePos0;
- IndexType cachePos1;
-
- OptimizeVertexData() noexcept : score(0.f), activeFaceListStart(0), activeFaceListSize(0), cachePos0(0), cachePos1(0) {}
- };
-
- template
-
- struct IndexSortCompareIndexed
- {
- const IndexType *_indexData;
-
- IndexSortCompareIndexed(const IndexType *indexData) noexcept : _indexData(indexData) {}
-
- bool operator()(T a, T b) const noexcept
- {
- IndexType indexA = _indexData[a];
- IndexType indexB = _indexData[b];
-
- if (indexA < indexB)
- return true;
-
- return false;
- }
- };
-
- template
- struct FaceValenceSort
- {
- const OptimizeVertexData *_vertexData;
-
- FaceValenceSort(const OptimizeVertexData *vertexData) noexcept : _vertexData(vertexData) {}
-
- bool operator()(T a, T b) const noexcept
- {
- const OptimizeVertexData *vA = _vertexData + size_t(a) * 3;
- const OptimizeVertexData *vB = _vertexData + size_t(b) * 3;
-
- const uint32_t aValence = vA[0].activeFaceListSize + vA[1].activeFaceListSize + vA[2].activeFaceListSize;
- const uint32_t bValence = vB[0].activeFaceListSize + vB[1].activeFaceListSize + vB[2].activeFaceListSize;
-
- // higher scoring faces are those with lower valence totals
-
- // reverse sort (reverse of reverse)
-
- if (aValence < bValence)
- return true;
-
- return false;
- }
- };
-
- template
- HRESULT OptimizeFacesImpl(
- _In_reads_(indexCount) const IndexType* indexList, uint32_t indexCount,
- _Out_writes_(indexCount / 3) uint32_t* faceRemap, uint32_t lruCacheSize, uint32_t offset)
- {
- std::unique_ptr[]> vertexDataList(new (std::nothrow) OptimizeVertexData[indexCount]);
- if (!vertexDataList)
- return E_OUTOFMEMORY;
-
- std::unique_ptr vertexRemap(new (std::nothrow) uint32_t[indexCount]);
- std::unique_ptr activeFaceList(new (std::nothrow) uint32_t[indexCount]);
- if (!vertexRemap || !activeFaceList)
- return E_OUTOFMEMORY;
-
- const uint32_t faceCount = indexCount / 3;
-
- std::unique_ptr processedFaceList(new (std::nothrow) uint8_t[faceCount]);
- std::unique_ptr faceSorted(new (std::nothrow) uint32_t[faceCount]);
- std::unique_ptr faceReverseLookup(new (std::nothrow) uint32_t[faceCount]);
- if (!processedFaceList || !faceSorted || !faceReverseLookup)
- return E_OUTOFMEMORY;
-
- memset(processedFaceList.get(), 0, sizeof(uint8_t) * faceCount);
-
- // build the vertex remap table
- uint32_t uniqueVertexCount = 0;
- uint32_t unused = 0;
- {
- using indexSorter = IndexSortCompareIndexed;
-
- std::unique_ptr indexSorted(new (std::nothrow) uint32_t[indexCount]);
- if (!indexSorted)
- return E_OUTOFMEMORY;
-
- for (uint32_t i = 0; i < indexCount; i++)
- {
- indexSorted[i] = i;
- }
-
- const indexSorter sortFunc(indexList);
- std::sort(indexSorted.get(), indexSorted.get() + indexCount, sortFunc);
-
- bool first = false;
- for (uint32_t i = 0; i < indexCount; i++)
- {
- const uint32_t idx = indexSorted[i];
- if (indexList[idx] == IndexType(-1))
- {
- unused++;
- vertexRemap[idx] = UNUSED32;
- continue;
- }
-
- if (!i || first || sortFunc(indexSorted[i - 1], idx))
- {
- // it's not a duplicate
- vertexRemap[idx] = uniqueVertexCount;
- uniqueVertexCount++;
- first = false;
- }
- else
- {
- vertexRemap[indexSorted[i]] = vertexRemap[indexSorted[i - 1]];
- }
- }
- }
-
- // compute face count per vertex
- for (uint32_t i = 0; i < indexCount; ++i)
- {
- if (vertexRemap[i] == UNUSED32)
- continue;
-
- OptimizeVertexData& vertexData = vertexDataList[vertexRemap[i]];
- vertexData.activeFaceListSize++;
- }
-
- constexpr IndexType kEvictedCacheIndex = std::numeric_limits::max();
- {
- // allocate face list per vertex
- uint32_t curActiveFaceListPos = 0;
- for (uint32_t i = 0; i < uniqueVertexCount; ++i)
- {
- OptimizeVertexData& vertexData = vertexDataList[i];
- vertexData.cachePos0 = kEvictedCacheIndex;
- vertexData.cachePos1 = kEvictedCacheIndex;
- vertexData.activeFaceListStart = curActiveFaceListPos;
- curActiveFaceListPos += vertexData.activeFaceListSize;
- vertexData.score = FindVertexScore(vertexData.activeFaceListSize, vertexData.cachePos0, lruCacheSize);
-
- vertexData.activeFaceListSize = 0;
- }
-
- assert(curActiveFaceListPos == (indexCount - unused));
- }
-
- // sort unprocessed faces by highest score
- for (uint32_t f = 0; f < faceCount; f++)
- {
- faceSorted[f] = f;
- }
-
- const FaceValenceSort faceValenceSort(vertexDataList.get());
- std::sort(faceSorted.get(), faceSorted.get() + faceCount, faceValenceSort);
-
- for (uint32_t f = 0; f < faceCount; f++)
- {
- faceReverseLookup[faceSorted[f]] = f;
- }
-
- // fill out face list per vertex
- for (uint32_t i = 0; i < indexCount; i += 3)
- {
- for (uint32_t j = 0; j < 3; ++j)
- {
- const uint32_t v = vertexRemap[size_t(i) + size_t(j)];
- if (v == UNUSED32)
- continue;
-
- OptimizeVertexData& vertexData = vertexDataList[v];
- activeFaceList[size_t(vertexData.activeFaceListStart) + vertexData.activeFaceListSize] = i;
- vertexData.activeFaceListSize++;
- }
- }
-
- uint32_t vertexCacheBuffer[(kMaxVertexCacheSize + 3) * 2] = {};
- uint32_t *cache0 = vertexCacheBuffer;
- uint32_t *cache1 = vertexCacheBuffer + (kMaxVertexCacheSize + 3);
- uint32_t entriesInCache0 = 0;
-
- uint32_t bestFace = 0;
- for (size_t i = 0; i < indexCount; i += 3)
- {
- if (vertexRemap[i] == UNUSED32
- || vertexRemap[i + 1] == UNUSED32
- || vertexRemap[i + 2] == UNUSED32)
- {
- ++bestFace;
- continue;
- }
- else
- break;
- }
-
- float bestScore = -1.f;
-
- uint32_t nextBestFace = 0;
-
- uint32_t curFace = 0;
- for (size_t i = 0; i < indexCount; i += 3)
- {
- if (vertexRemap[i] == UNUSED32
- || vertexRemap[i + 1] == UNUSED32
- || vertexRemap[i + 2] == UNUSED32)
- {
- continue;
- }
-
- if (bestScore < 0.f)
- {
- // no verts in the cache are used by any unprocessed faces so
- // search all unprocessed faces for a new starting point
- while (nextBestFace < faceCount)
- {
- const uint32_t faceIndex = faceSorted[nextBestFace++];
- if (processedFaceList[faceIndex] == 0)
- {
- const uint32_t face = faceIndex * 3;
- const uint32_t i0 = vertexRemap[face];
- const uint32_t i1 = vertexRemap[size_t(face) + 1];
- const uint32_t i2 = vertexRemap[size_t(face) + 2];
- if (i0 != UNUSED32 && i1 != UNUSED32 && i2 != UNUSED32)
- {
- // we're searching a pre-sorted list, first one we find will be the best
- bestFace = face;
- bestScore = vertexDataList[i0].score
- + vertexDataList[i1].score
- + vertexDataList[i2].score;
- break;
- }
- }
- }
- assert(bestScore >= 0.f);
- }
-
- processedFaceList[bestFace / 3] = 1;
- uint16_t entriesInCache1 = 0;
-
- faceRemap[curFace] = (bestFace / 3) + offset;
- curFace++;
-
- // add bestFace to LRU cache
- assert(vertexRemap[bestFace] != UNUSED32);
- assert(vertexRemap[size_t(bestFace) + 1] != UNUSED32);
- assert(vertexRemap[size_t(bestFace) + 2] != UNUSED32);
-
- for (size_t v = 0; v < 3; ++v)
- {
- OptimizeVertexData& vertexData = vertexDataList[vertexRemap[bestFace + v]];
-
- if (vertexData.cachePos1 >= entriesInCache1)
- {
- vertexData.cachePos1 = entriesInCache1;
- cache1[entriesInCache1++] = vertexRemap[bestFace + v];
-
- if (vertexData.activeFaceListSize == 1)
- {
- --vertexData.activeFaceListSize;
- continue;
- }
- }
-
- assert(vertexData.activeFaceListSize > 0);
- uint32_t* begin = activeFaceList.get() + vertexData.activeFaceListStart;
- uint32_t* end = activeFaceList.get() + (size_t(vertexData.activeFaceListStart) + vertexData.activeFaceListSize);
- uint32_t* it = std::find(begin, end, bestFace);
-
- assert(it != end);
-
- std::swap(*it, *(end - 1));
-
- --vertexData.activeFaceListSize;
- vertexData.score = FindVertexScore(vertexData.activeFaceListSize, vertexData.cachePos1, lruCacheSize);
-
- // need to re-sort the faces that use this vertex, as their score will change due to activeFaceListSize shrinking
- for (const uint32_t *fi = begin; fi != end - 1; ++fi)
- {
- const uint32_t faceIndex = *fi / 3;
- uint32_t n = faceReverseLookup[faceIndex];
- assert(faceSorted[n] == faceIndex);
-
- // found it, now move it up
- while (n > 0)
- {
- if (faceValenceSort(n, n - 1))
- {
- faceReverseLookup[faceSorted[n]] = n - 1;
- faceReverseLookup[faceSorted[n - 1]] = n;
- std::swap(faceSorted[n], faceSorted[n - 1]);
- n--;
- }
- else
- {
- break;
- }
- }
- }
- }
-
- // move the rest of the old verts in the cache down and compute their new scores
- for (uint32_t c0 = 0; c0 < entriesInCache0; ++c0)
- {
- OptimizeVertexData& vertexData = vertexDataList[cache0[c0]];
-
- if (vertexData.cachePos1 >= entriesInCache1)
- {
- vertexData.cachePos1 = entriesInCache1;
- cache1[entriesInCache1++] = cache0[c0];
- vertexData.score = FindVertexScore(vertexData.activeFaceListSize, vertexData.cachePos1, lruCacheSize);
-
- // don't need to re-sort this vertex... once it gets out of the cache, it'll have its original score
- }
- }
-
- // find the best scoring triangle in the current cache (including up to 3 that were just evicted)
- bestScore = -1.f;
-
- for (uint32_t c1 = 0; c1 < entriesInCache1; ++c1)
- {
- OptimizeVertexData& vertexData = vertexDataList[cache1[c1]];
- vertexData.cachePos0 = vertexData.cachePos1;
- vertexData.cachePos1 = kEvictedCacheIndex;
-
- for (uint32_t j = 0; j < vertexData.activeFaceListSize; ++j)
- {
- const uint32_t face = activeFaceList[size_t(vertexData.activeFaceListStart) + j];
- float faceScore = 0.f;
-
- for (uint32_t v = 0; v < 3; v++)
- {
- const OptimizeVertexData& faceVertexData = vertexDataList[vertexRemap[size_t(face) + v]];
- faceScore += faceVertexData.score;
- }
-
- if (faceScore > bestScore)
- {
- bestScore = faceScore;
- bestFace = face;
- }
- }
- }
-
- std::swap(cache0, cache1);
-
- entriesInCache0 = std::min(entriesInCache1, lruCacheSize);
- }
-
- for (; curFace < faceCount; ++curFace)
- {
- faceRemap[curFace] = UNUSED32;
- }
-
- return S_OK;
- }
-}
-
-//=====================================================================================
-// Entry-points
-//=====================================================================================
-
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeFacesLRU(
- const uint16_t* indices,
- size_t nFaces,
- uint32_t* faceRemap,
- uint32_t lruCacheSize)
-{
- if (!indices || !nFaces || !faceRemap)
- return E_INVALIDARG;
-
- if (!lruCacheSize || lruCacheSize > kMaxVertexCacheSize)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
-#ifdef _WIN32
- InitOnceExecuteOnce(&s_initOnce, ComputeVertexScores, nullptr, nullptr);
-#else
- std::call_once(s_initOnce, ComputeVertexScores);
-#endif
-
- return OptimizeFacesImpl(indices, static_cast(nFaces * 3), faceRemap, lruCacheSize, 0);
-}
-
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeFacesLRU(
- const uint32_t* indices,
- size_t nFaces,
- uint32_t* faceRemap,
- uint32_t lruCacheSize)
-{
- if (!indices || !nFaces || !faceRemap)
- return E_INVALIDARG;
-
- if (!lruCacheSize || lruCacheSize > kMaxVertexCacheSize)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
-#ifdef _WIN32
- InitOnceExecuteOnce(&s_initOnce, ComputeVertexScores, nullptr, nullptr);
-#else
- std::call_once(s_initOnce, ComputeVertexScores);
-#endif
-
- return OptimizeFacesImpl(indices, static_cast(nFaces * 3), faceRemap, lruCacheSize, 0);
-}
-
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeFacesLRUEx(
- const uint16_t* indices,
- size_t nFaces,
- const uint32_t* attributes,
- uint32_t* faceRemap,
- uint32_t lruCacheSize)
-{
- if (!indices || !nFaces || !attributes || !faceRemap)
- return E_INVALIDARG;
-
- if (!lruCacheSize || lruCacheSize > kMaxVertexCacheSize)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
-#ifdef _WIN32
- InitOnceExecuteOnce(&s_initOnce, ComputeVertexScores, nullptr, nullptr);
-#else
- std::call_once(s_initOnce, ComputeVertexScores);
-#endif
-
- auto subsets = ComputeSubsets(attributes, nFaces);
-
- if (subsets.empty())
- return E_UNEXPECTED;
-
- memset(faceRemap, 0, sizeof(uint32_t) * nFaces);
-
- for (const auto& it : subsets)
- {
- if (it.first >= nFaces)
- return E_UNEXPECTED;
-
- if ((uint64_t(it.first) + uint64_t(it.second)) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- const uint32_t faceMax = uint32_t(it.first + it.second);
-
- if (faceMax > nFaces)
- return E_UNEXPECTED;
-
- HRESULT hr = OptimizeFacesImpl(
- &indices[it.first * 3], static_cast(it.second * 3),
- &faceRemap[it.first], lruCacheSize, uint32_t(it.first));
- if (FAILED(hr))
- return hr;
- }
-
- return S_OK;
-}
-
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeFacesLRUEx(
- const uint32_t* indices,
- size_t nFaces,
- const uint32_t* attributes,
- uint32_t* faceRemap,
- uint32_t lruCacheSize)
-{
- if (!indices || !nFaces || !attributes || !faceRemap)
- return E_INVALIDARG;
-
- if (!lruCacheSize || lruCacheSize > kMaxVertexCacheSize)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
-#ifdef _WIN32
- InitOnceExecuteOnce(&s_initOnce, ComputeVertexScores, nullptr, nullptr);
-#else
- std::call_once(s_initOnce, ComputeVertexScores);
-#endif
-
- auto subsets = ComputeSubsets(attributes, nFaces);
-
- if (subsets.empty())
- return E_UNEXPECTED;
-
- memset(faceRemap, 0, sizeof(uint32_t) * nFaces);
-
- for (const auto& it : subsets)
- {
- if (it.first >= nFaces)
- return E_UNEXPECTED;
-
- if ((uint64_t(it.first) + uint64_t(it.second)) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- const uint32_t faceMax = uint32_t(it.first + it.second);
-
- if (faceMax > nFaces)
- return E_UNEXPECTED;
-
- HRESULT hr = OptimizeFacesImpl(
- &indices[it.first * 3], static_cast(it.second * 3),
- &faceRemap[it.first], lruCacheSize, uint32_t(it.first));
- if (FAILED(hr))
- return hr;
- }
-
- return S_OK;
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimizeTVC.cpp b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimizeTVC.cpp
deleted file mode 100644
index 02a741457c..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshOptimizeTVC.cpp
+++ /dev/null
@@ -1,885 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshOptimizeTVC.cpp
-//
-// DirectX Mesh Geometry Library - Mesh optimization
-//
-// Hoppe "Optimization of mesh locality for transparent vertex caching"
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#include "DirectXMeshP.h"
-
-using namespace DirectX;
-
-namespace
-{
- //---------------------------------------------------------------------------------
- template
- class mesh_status
- {
- public:
- mesh_status() noexcept :
- mUnprocessed{},
- mFaceOffset(0),
- mFaceCount(0),
- mMaxSubset(0),
- mTotalFaces(0)
- {
- }
-
- HRESULT initialize(
- _In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
- _In_reads_(nFaces * 3) const uint32_t* adjacency,
- const std::vector>& subsets)
- {
- if (!indices || !nFaces || !adjacency || subsets.empty())
- return E_INVALIDARG;
-
- // Convert adjacency to 'physical' adjacency
- mPhysicalNeighbors.reset(new (std::nothrow) neighborInfo[nFaces]);
- if (!mPhysicalNeighbors)
- return E_OUTOFMEMORY;
-
- #ifdef _DEBUG
- memset(mPhysicalNeighbors.get(), 0xcd, sizeof(neighborInfo) * nFaces);
- #endif
-
- mFaceOffset = 0;
- mFaceCount = 0;
- mMaxSubset = 0;
- mTotalFaces = nFaces;
-
- for (const auto& it : subsets)
- {
- if ((uint64_t(it.first) + uint64_t(it.second)) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- if (it.second > mMaxSubset)
- {
- mMaxSubset = it.second;
- }
-
- const uint32_t faceOffset = uint32_t(it.first);
- const uint32_t faceMax = uint32_t(it.first + it.second);
-
- for (uint32_t face = faceOffset; face < faceMax; ++face)
- {
- if (face >= nFaces)
- return E_UNEXPECTED;
-
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1)
- || i0 == i1
- || i0 == i2
- || i1 == i2)
- {
- // unused and degenerate faces should not have neighbors
- for (uint32_t point = 0; point < 3; ++point)
- {
- const uint32_t k = adjacency[face * 3 + point];
-
- if (k != UNUSED32)
- {
- if (k >= nFaces)
- return E_UNEXPECTED;
-
- if (adjacency[k * 3] == face)
- mPhysicalNeighbors[k].neighbors[0] = UNUSED32;
-
- if (adjacency[k * 3 + 1] == face)
- mPhysicalNeighbors[k].neighbors[1] = UNUSED32;
-
- if (adjacency[k * 3 + 2] == face)
- mPhysicalNeighbors[k].neighbors[2] = UNUSED32;
- }
-
- mPhysicalNeighbors[face].neighbors[point] = UNUSED32;
- }
- }
- else
- {
- for (uint32_t n = 0; n < 3; ++n)
- {
- uint32_t neighbor = adjacency[face * 3 + n];
-
- if (neighbor != UNUSED32)
- {
- if ((neighbor < faceOffset) || (neighbor >= faceMax)
- || (neighbor == adjacency[face * 3 + ((n + 1) % 3)])
- || (neighbor == adjacency[face * 3 + ((n + 2) % 3)]))
- {
- // Break links for any neighbors outside of our attribute set, and remove duplicate neighbors
- neighbor = UNUSED32;
- }
- else
- {
- const uint32_t edgeBack = find_edge(&adjacency[neighbor * 3], face);
- if (edgeBack < 3)
- {
- index_t p1 = indices[face * 3 + n];
- index_t p2 = indices[face * 3 + ((n + 1) % 3)];
-
- index_t pn1 = indices[neighbor * 3 + edgeBack];
- index_t pn2 = indices[neighbor * 3 + ((edgeBack + 1) % 3)];
-
- // if wedge not identical on shared edge, drop link
- if ((p1 != pn2) || (p2 != pn1))
- {
- neighbor = UNUSED32;
- }
- }
- else
- {
- neighbor = UNUSED32;
- }
- }
- }
-
- mPhysicalNeighbors[face].neighbors[n] = neighbor;
- }
- }
- }
- }
-
- if (!mMaxSubset)
- return E_FAIL;
-
- mListElements.reset(new (std::nothrow) listElement[mMaxSubset]);
- if (!mListElements)
- return E_OUTOFMEMORY;
-
- return S_OK;
- }
-
- HRESULT setSubset(
- _In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
- size_t faceOffset, size_t faceCount) noexcept
- {
- if (!faceCount || !indices || !nFaces)
- return E_INVALIDARG;
-
- if (faceCount > mMaxSubset)
- return E_UNEXPECTED;
-
- if (!mListElements)
- return E_POINTER;
-
- if ((uint64_t(faceOffset) + uint64_t(faceCount)) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- const uint32_t faceMax = uint32_t(faceOffset + faceCount);
-
- if (faceMax > nFaces)
- return E_UNEXPECTED;
-
- mFaceOffset = faceOffset;
- mFaceCount = faceCount;
-
- mUnprocessed[0] = UNUSED32;
- mUnprocessed[1] = UNUSED32;
- mUnprocessed[2] = UNUSED32;
- mUnprocessed[3] = UNUSED32;
-
- for (uint32_t face = uint32_t(faceOffset); face < faceMax; ++face)
- {
- index_t i0 = indices[face * 3];
- index_t i1 = indices[face * 3 + 1];
- index_t i2 = indices[face * 3 + 2];
-
- if (i0 == index_t(-1)
- || i1 == index_t(-1)
- || i2 == index_t(-1))
- {
- // filter out unused triangles
- continue;
- }
-
- uint32_t unprocessed = 0;
-
- for (uint32_t n = 0; n < 3; ++n)
- {
- if (mPhysicalNeighbors[face].neighbors[n] != UNUSED32)
- {
- unprocessed += 1;
-
- assert(mPhysicalNeighbors[face].neighbors[n] >= mFaceOffset);
- assert(mPhysicalNeighbors[face].neighbors[n] < faceMax);
- }
- }
-
- const uint32_t faceIndex = uint32_t(face - faceOffset);
- mListElements[faceIndex].processed = false;
- mListElements[faceIndex].unprocessed = unprocessed;
-
- push_front(faceIndex);
- }
-
- return S_OK;
- }
-
- bool isprocessed(uint32_t face) const noexcept
- {
- assert(face < mTotalFaces);
- assert((face >= mFaceOffset) || (face < (mFaceOffset + mFaceCount)));
- return mListElements[face - mFaceOffset].processed;
- }
-
- uint32_t unprocessed_count(uint32_t face) const noexcept
- {
- assert(face < mTotalFaces);
- assert((face >= mFaceOffset) || (face < (mFaceOffset + mFaceCount)));
- return mListElements[face - mFaceOffset].unprocessed;
- }
-
- uint32_t find_initial() const noexcept
- {
- for (size_t j = 0; j < 4; ++j)
- {
- if (mUnprocessed[j] != UNUSED32)
- return uint32_t(mUnprocessed[j] + mFaceOffset);
- }
-
- return UNUSED32;
- }
-
- void mark(uint32_t face) noexcept
- {
- assert(face < mTotalFaces);
- assert((face >= mFaceOffset) || (face < (mFaceOffset + mFaceCount)));
-
- const uint32_t faceIndex = uint32_t(face - mFaceOffset);
-
- assert(!mListElements[faceIndex].processed);
- mListElements[faceIndex].processed = true;
-
- remove(faceIndex);
-
- for (uint32_t n = 0; n < 3; ++n)
- {
- const uint32_t neighbor = mPhysicalNeighbors[face].neighbors[n];
- if ((neighbor != UNUSED32) && !isprocessed(neighbor))
- {
- decrement(neighbor);
- }
- }
- }
-
- uint32_t find_next(uint32_t face) const noexcept
- {
- assert(face < mTotalFaces);
- assert((face >= mFaceOffset) || (face < (mFaceOffset + mFaceCount)));
-
- uint32_t iret = 3;
- uint32_t minNeighbor = UNUSED32;
- uint32_t minNextNeighbor = 0;
-
- for (uint32_t n = 0; n < 3; ++n)
- {
- const uint32_t neighbor = mPhysicalNeighbors[face].neighbors[n];
-
- if ((neighbor == UNUSED32) || isprocessed(neighbor))
- continue;
-
- const uint32_t unprocessed = unprocessed_count(neighbor);
- assert(unprocessed < 3);
-
- uint32_t mintemp = UNUSED32;
-
- for (uint32_t nt = 0; nt < 3; ++nt)
- {
- const uint32_t neighborTemp = mPhysicalNeighbors[neighbor].neighbors[nt];
-
- if ((neighborTemp == UNUSED32) || isprocessed(neighborTemp))
- continue;
-
- const uint32_t next_count = unprocessed_count(neighborTemp);
- if (next_count < mintemp)
- mintemp = next_count;
- }
-
- if (mintemp == UNUSED32)
- mintemp = 0;
-
- if (unprocessed < minNeighbor)
- {
- iret = n;
- minNeighbor = unprocessed;
- minNextNeighbor = mintemp;
- }
- else if ((unprocessed == minNeighbor) && (mintemp < minNextNeighbor))
- {
- iret = n;
- minNextNeighbor = mintemp;
- }
- }
-
- return iret;
- }
-
- uint32_t get_neighbors(uint32_t face, uint32_t n) const noexcept
- {
- assert(face < mTotalFaces);
- assert(n < 3);
- _Analysis_assume_(face < mTotalFaces);
- _Analysis_assume_(n < 3);
- return mPhysicalNeighbors[face].neighbors[n];
- }
-
- const uint32_t* get_neighborsPtr(uint32_t face) const noexcept
- {
- assert(face < mTotalFaces);
- return &mPhysicalNeighbors[face].neighbors[0];
- }
-
- private:
- void push_front(uint32_t faceIndex) noexcept
- {
- assert(faceIndex < mFaceCount);
-
- uint32_t unprocessed = mListElements[faceIndex].unprocessed;
-
- const uint32_t head = mUnprocessed[unprocessed];
- mListElements[faceIndex].next = head;
-
- if (head != UNUSED32)
- mListElements[head].prev = faceIndex;
-
- mUnprocessed[unprocessed] = faceIndex;
-
- mListElements[faceIndex].prev = UNUSED32;
- }
-
- void remove(uint32_t faceIndex) noexcept
- {
- assert(faceIndex < mFaceCount);
-
- if (mListElements[faceIndex].prev != UNUSED32)
- {
- assert(mUnprocessed[mListElements[faceIndex].unprocessed] != faceIndex);
-
- const uint32_t prev = mListElements[faceIndex].prev;
- const uint32_t next = mListElements[faceIndex].next;
-
- mListElements[prev].next = next;
-
- if (next != UNUSED32)
- {
- mListElements[next].prev = prev;
- }
- }
- else
- {
- // remove head of the list
- assert(mUnprocessed[mListElements[faceIndex].unprocessed] == faceIndex);
-
- uint32_t unprocessed = mListElements[faceIndex].unprocessed;
-
- mUnprocessed[unprocessed] = mListElements[faceIndex].next;
-
- if (mUnprocessed[unprocessed] != UNUSED32)
- {
- mListElements[mUnprocessed[unprocessed]].prev = UNUSED32;
- }
- }
-
- mListElements[faceIndex].prev =
- mListElements[faceIndex].next = UNUSED32;
- }
-
- void decrement(uint32_t face) noexcept
- {
- assert(face < mTotalFaces);
- assert((face >= mFaceOffset) || (face < (mFaceOffset + mFaceCount)));
- assert(!isprocessed(face));
-
- const uint32_t faceIndex = uint32_t(face - mFaceOffset);
-
- assert((mListElements[faceIndex].unprocessed >= 1) && (mListElements[faceIndex].unprocessed <= 3));
-
- remove(faceIndex);
-
- mListElements[faceIndex].unprocessed -= 1;
-
- push_front(faceIndex);
- }
-
- struct neighborInfo
- {
- uint32_t neighbors[3];
- };
-
- struct listElement
- {
- bool processed;
- uint32_t unprocessed;
- uint32_t prev;
- uint32_t next;
- };
-
- uint32_t mUnprocessed[4];
- size_t mFaceOffset;
- size_t mFaceCount;
- size_t mMaxSubset;
- size_t mTotalFaces;
- std::unique_ptr mListElements;
- std::unique_ptr mPhysicalNeighbors;
- };
-
-
- //---------------------------------------------------------------------------------
- using facecorner_t = std::pair;
-
- template
- inline facecorner_t counterclockwise_corner(facecorner_t corner, const mesh_status& status) noexcept
- {
- assert(corner.second != UNUSED32);
- const uint32_t edge = (corner.second + 2) % 3;
- uint32_t neighbor = status.get_neighbors(corner.first, edge);
- uint32_t point = (neighbor == UNUSED32) ? UNUSED32 : find_edge(status.get_neighborsPtr(neighbor), corner.first);
- return facecorner_t(neighbor, point);
- }
-
-
- //---------------------------------------------------------------------------------
- class sim_vcache
- {
- public:
- sim_vcache() noexcept : mTail(0), mCacheSize(0) {}
-
- HRESULT initialize(uint32_t cacheSize) noexcept
- {
- if (!cacheSize)
- return E_INVALIDARG;
-
- mFIFO.reset(new (std::nothrow) uint32_t[cacheSize]);
- if (!mFIFO)
- return E_OUTOFMEMORY;
-
- mCacheSize = cacheSize;
-
- clear();
-
- return S_OK;
- }
-
- void clear() noexcept
- {
- assert(mFIFO != nullptr);
- mTail = 0;
- memset(mFIFO.get(), 0xff, sizeof(uint32_t) * mCacheSize);
- }
-
- bool access(uint32_t vertex) noexcept
- {
- assert(vertex != UNUSED32);
- assert(mFIFO != nullptr);
-
- for (size_t ptr = 0; ptr < mCacheSize; ++ptr)
- {
- if (mFIFO[ptr] == vertex)
- {
- return true;
- }
- }
-
- mFIFO[mTail] = vertex;
- mTail += 1;
- if (mTail == mCacheSize)
- mTail = 0;
-
- return false;
- }
-
- private:
- uint32_t mTail;
- uint32_t mCacheSize;
- std::unique_ptr mFIFO;
- };
-
-
- //---------------------------------------------------------------------------------
- template
- HRESULT StripReorderImpl(
- _In_reads_(nFaces * 3) const index_t* indices, _In_ size_t nFaces,
- _In_reads_(nFaces * 3) const uint32_t* adjacency,
- _In_reads_opt_(nFaces) const uint32_t* attributes,
- _Out_writes_(nFaces) uint32_t* faceRemap)
- {
- auto subsets = ComputeSubsets(attributes, nFaces);
-
- assert(!subsets.empty());
-
- mesh_status status;
- HRESULT hr = status.initialize(indices, nFaces, adjacency, subsets);
- if (FAILED(hr))
- return hr;
-
- std::unique_ptr faceRemapInverse(new (std::nothrow) uint32_t[nFaces]);
- if (!faceRemapInverse)
- return E_OUTOFMEMORY;
-
- memset(faceRemapInverse.get(), 0xff, sizeof(uint32_t) * nFaces);
-
- for (const auto& it : subsets)
- {
- hr = status.setSubset(indices, nFaces, it.first, it.second);
- if (FAILED(hr))
- return hr;
-
- uint32_t curface = 0;
-
- for (;;)
- {
- uint32_t face = status.find_initial();
- if (face == UNUSED32)
- break;
-
- status.mark(face);
-
- uint32_t next = status.find_next(face);
-
- for (;;)
- {
- assert(face != UNUSED32);
- faceRemapInverse[face] = uint32_t(curface + it.first);
- curface += 1;
-
- // if at end of strip, break out
- if (next >= 3)
- break;
-
- face = status.get_neighbors(face, next);
- assert(face != UNUSED32);
-
- status.mark(face);
-
- next = status.find_next(face);
- }
- }
- }
-
- // inverse remap
- memset(faceRemap, 0xff, sizeof(uint32_t) * nFaces);
-
- for (uint32_t j = 0; j < nFaces; ++j)
- {
- uint32_t f = faceRemapInverse[j];
- if (f < nFaces)
- {
- faceRemap[f] = j;
- }
- }
-
- return S_OK;
- }
-
-
- //---------------------------------------------------------------------------------
- template
- HRESULT VertexCacheStripReorderImpl(
- _In_reads_(nFaces * 3) const index_t* indices, _In_ size_t nFaces,
- _In_reads_(nFaces * 3) const uint32_t* adjacency,
- _In_reads_opt_(nFaces) const uint32_t* attributes,
- _Out_writes_(nFaces) uint32_t* faceRemap,
- uint32_t vertexCache, uint32_t restart)
- {
- auto subsets = ComputeSubsets(attributes, nFaces);
-
- assert(!subsets.empty());
-
- mesh_status status;
- HRESULT hr = status.initialize(indices, nFaces, adjacency, subsets);
- if (FAILED(hr))
- return hr;
-
- sim_vcache vcache;
- hr = vcache.initialize(vertexCache);
- if (FAILED(hr))
- return hr;
-
- std::unique_ptr faceRemapInverse(new (std::nothrow) uint32_t[nFaces]);
- if (!faceRemapInverse)
- return E_OUTOFMEMORY;
-
- memset(faceRemapInverse.get(), 0xff, sizeof(uint32_t) * nFaces);
-
- assert(vertexCache >= restart);
- const uint32_t desired = vertexCache - restart;
-
- for (const auto& it : subsets)
- {
- hr = status.setSubset(indices, nFaces, it.first, it.second);
- if (FAILED(hr))
- return hr;
-
- vcache.clear();
-
- uint32_t locnext = 0;
- facecorner_t nextCorner(UNUSED32, UNUSED32);
- facecorner_t curCorner(UNUSED32, UNUSED32);
-
- uint32_t curface = 0;
-
- for (;;)
- {
- assert(nextCorner.first == UNUSED32);
-
- curCorner.first = status.find_initial();
- if (curCorner.first == UNUSED32)
- break;
-
- const uint32_t n0 = status.get_neighbors(curCorner.first, 0);
- if ((n0 != UNUSED32) && !status.isprocessed(n0))
- {
- curCorner.second = 1;
- }
- else
- {
- const uint32_t n1 = status.get_neighbors(curCorner.first, 1);
- if ((n1 != UNUSED32) && !status.isprocessed(n1))
- {
- curCorner.second = 2;
- }
- else
- {
- curCorner.second = 0;
- }
- }
-
- bool striprestart = false;
- for (;;)
- {
- assert(curCorner.first != UNUSED32);
- assert(!status.isprocessed(curCorner.first));
-
- // Decision: either add a ring of faces or restart strip
- if (nextCorner.first != UNUSED32)
- {
- uint32_t nf = 0;
- for (facecorner_t temp = curCorner; ; )
- {
- const facecorner_t next = counterclockwise_corner(temp, status);
- if ((next.first == UNUSED32) || status.isprocessed(next.first))
- break;
- ++nf;
- temp = next;
- }
-
- if (locnext + nf > desired)
- {
- // restart
- if (!status.isprocessed(nextCorner.first))
- {
- curCorner = nextCorner;
- }
-
- nextCorner.first = UNUSED32;
- }
- }
-
- for (;;)
- {
- assert(curCorner.first != UNUSED32);
- status.mark(curCorner.first);
-
- faceRemapInverse[curCorner.first] = uint32_t(curface + it.first);
- curface += 1;
-
- assert(indices[curCorner.first * 3] != index_t(-1));
- if (!vcache.access(indices[curCorner.first * 3]))
- locnext += 1;
-
- assert(indices[curCorner.first * 3 + 1] != index_t(-1));
- if (!vcache.access(indices[curCorner.first * 3 + 1]))
- locnext += 1;
-
- assert(indices[curCorner.first * 3 + 2] != index_t(-1));
- if (!vcache.access(indices[curCorner.first * 3 + 2]))
- locnext += 1;
-
- const facecorner_t intCorner = counterclockwise_corner(curCorner, status);
- const bool interiornei = (intCorner.first != UNUSED32) && !status.isprocessed(intCorner.first);
-
- const facecorner_t extCorner = counterclockwise_corner(facecorner_t(curCorner.first, (curCorner.second + 2) % 3), status);
- const bool exteriornei = (extCorner.first != UNUSED32) && !status.isprocessed(extCorner.first);
-
- if (interiornei)
- {
- if (exteriornei)
- {
- if (nextCorner.first == UNUSED32)
- {
- nextCorner = extCorner;
- locnext = 0;
- }
- }
- curCorner = intCorner;
- }
- else if (exteriornei)
- {
- curCorner = extCorner;
- break;
- }
- else
- {
- curCorner = nextCorner;
- nextCorner.first = UNUSED32;
-
- if ((curCorner.first == UNUSED32) || status.isprocessed(curCorner.first))
- {
- striprestart = true;
- break;
- }
- }
- }
-
- if (striprestart)
- break;
- }
- }
- }
-
- // inverse remap
- memset(faceRemap, 0xff, sizeof(uint32_t) * nFaces);
-
- for (uint32_t j = 0; j < nFaces; ++j)
- {
- uint32_t f = faceRemapInverse[j];
- if (f < nFaces)
- {
- faceRemap[f] = j;
- }
- }
-
- return S_OK;
- }
-}
-
-//=====================================================================================
-// Entry-points
-//=====================================================================================
-
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeFaces(
- const uint16_t* indices,
- size_t nFaces,
- const uint32_t* adjacency,
- uint32_t* faceRemap,
- uint32_t vertexCache,
- uint32_t restart)
-{
- if (!indices || !nFaces || !adjacency || !faceRemap)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- if (vertexCache == OPTFACES_V_STRIPORDER)
- {
- return StripReorderImpl(indices, nFaces, adjacency, nullptr, faceRemap);
- }
- else
- {
- if (restart > vertexCache)
- return E_INVALIDARG;
-
- return VertexCacheStripReorderImpl(indices, nFaces, adjacency, nullptr, faceRemap, vertexCache, restart);
- }
-}
-
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeFaces(
- const uint32_t* indices,
- size_t nFaces,
- const uint32_t* adjacency,
- uint32_t* faceRemap,
- uint32_t vertexCache,
- uint32_t restart)
-{
- if (!indices || !nFaces || !adjacency || !faceRemap)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- if (vertexCache == OPTFACES_V_STRIPORDER)
- {
- return StripReorderImpl(indices, nFaces, adjacency, nullptr, faceRemap);
- }
- else
- {
- if (restart > vertexCache)
- return E_INVALIDARG;
-
- return VertexCacheStripReorderImpl(indices, nFaces, adjacency, nullptr, faceRemap, vertexCache, restart);
- }
-}
-
-
-//-------------------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeFacesEx(
- const uint16_t* indices,
- size_t nFaces,
- const uint32_t* adjacency,
- const uint32_t* attributes,
- uint32_t* faceRemap,
- uint32_t vertexCache,
- uint32_t restart)
-{
- if (!indices || !nFaces || !adjacency || !attributes || !faceRemap)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- if (vertexCache == OPTFACES_V_STRIPORDER)
- {
- return StripReorderImpl(indices, nFaces, adjacency, attributes, faceRemap);
- }
- else
- {
- if (restart > vertexCache)
- return E_INVALIDARG;
-
- return VertexCacheStripReorderImpl(indices, nFaces, adjacency, attributes, faceRemap, vertexCache, restart);
- }
-}
-
-_Use_decl_annotations_
-HRESULT DirectX::OptimizeFacesEx(
- const uint32_t* indices,
- size_t nFaces,
- const uint32_t* adjacency,
- const uint32_t* attributes,
- uint32_t* faceRemap,
- uint32_t vertexCache,
- uint32_t restart)
-{
- if (!indices || !nFaces || !adjacency || !attributes || !faceRemap)
- return E_INVALIDARG;
-
- if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
- return HRESULT_E_ARITHMETIC_OVERFLOW;
-
- if (vertexCache == OPTFACES_V_STRIPORDER)
- {
- return StripReorderImpl(indices, nFaces, adjacency, attributes, faceRemap);
- }
- else
- {
- if (restart > vertexCache)
- return E_INVALIDARG;
-
- return VertexCacheStripReorderImpl(indices, nFaces, adjacency, attributes, faceRemap, vertexCache, restart);
- }
-}
diff --git a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshP.h b/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshP.h
deleted file mode 100644
index cc1e114d27..0000000000
--- a/modules/lwjgl/tootle/src/main/c/DirectXMesh/DirectXMeshP.h
+++ /dev/null
@@ -1,410 +0,0 @@
-//-------------------------------------------------------------------------------------
-// DirectXMeshP.h
-//
-// DirectX Mesh Geometry Library
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//-------------------------------------------------------------------------------------
-
-#pragma once
-
-// Off by default warnings
-#pragma warning(disable : 4619 4616 4061 4365 4514 4571 4623 4625 4626 4628 4668 4710 4711 4746 4774 4820 4987 5026 5027 5031 5032 5039 5045 5219 5246 26812)
-// C4619/4616 #pragma warning warnings
-// C4061 enumerator 'X' in switch of enum 'X' is not explicitly handled by a case label
-// C4365 signed/unsigned mismatch
-// C4514 unreferenced inline function has been removed
-// C4571 behavior change
-// C4623 default constructor was implicitly defined as deleted
-// C4625 copy constructor was implicitly defined as deleted
-// C4626 assignment operator was implicitly defined as deleted
-// C4628 digraphs not supported
-// C4668 not defined as a preprocessor macro
-// C4710 function not inlined
-// C4711 selected for automatic inline expansion
-// C4746 volatile access of '' is subject to /volatile: setting
-// C4774 format string expected in argument 3 is not a string literal
-// C4820 padding added after data member
-// C4987 nonstandard extension used
-// C5026 move constructor was implicitly defined as deleted
-// C5027 move assignment operator was implicitly defined as deleted
-// C5031/5032 push/pop mismatches in windows headers
-// C5039 pointer or reference to potentially throwing function passed to extern C function under - EHc
-// C5045 Spectre mitigation warning
-// C5219 implicit conversion from 'int' to 'float', possible loss of data
-// C5246 the initialization of a subobject should be wrapped in braces
-// 26812: The enum type 'x' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
-
-// Windows 8.1 SDK related Off by default warnings
-#pragma warning(disable : 4471 4917 4986 5029)
-// C4471 forward declaration of an unscoped enumeration must have an underlying type
-// C4917 a GUID can only be associated with a class, interface or namespace
-// C4986 exception specification does not match previous declaration
-// C5029 nonstandard extension used
-
-// Xbox One XDK related Off by default warnings
-#pragma warning(disable : 4643)
-// C4643 Forward declaring in namespace std is not permitted by the C++ Standard
-
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wc++98-compat"
-#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
-#pragma clang diagnostic ignored "-Wc++98-compat-local-type-template-args"
-#pragma clang diagnostic ignored "-Wcovered-switch-default"
-#pragma clang diagnostic ignored "-Wfloat-equal"
-#pragma clang diagnostic ignored "-Wreserved-id-macro"
-#endif
-
-#ifdef _WIN32
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-#pragma warning(push)
-#pragma warning(disable : 4005)
-#define NOMINMAX 1
-#define NODRAWTEXT
-#define NOGDI
-#define NOBITMAP
-#define NOMCX
-#define NOSERVICE
-#define NOHELP
-#pragma warning(pop)
-
-#include
-
-#ifdef __MINGW32__
-#include
-#endif
-
-#ifndef _WIN32_WINNT_WIN10
-#define _WIN32_WINNT_WIN10 0x0A00
-#endif
-
-#ifdef _GAMING_XBOX_SCARLETT
-#pragma warning(push)
-#pragma warning(disable: 5204 5249)
-#include
-#pragma warning(pop)
-#elif defined(_GAMING_XBOX)
-#pragma warning(push)
-#pragma warning(disable: 5204)
-#include
-#pragma warning(pop)
-#elif defined(_XBOX_ONE) && defined(_TITLE)
-#include
-#include
-#elif (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
-#ifdef USING_DIRECTX_HEADERS
-#include
-#include
-#else
-#include
-#endif
-#include
-#else
-#include
-#endif
-#else // !WIN32
-#include
-#include
-#include
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include