Ship CultMath 0.2.0 to Unity with a UnityEngine conversion bridge
- Bump GameCult.Math and org.gamecult.cultmath to 0.2.0; the CultCache Unity tools package now depends on cultmath 0.2.0. - Rebuild the tracked netstandard2.1 CultMath.dll/pdb with the builder's deterministic command; build-unity-package.ps1 verifies it byte-for-byte. - Add Runtime/UnityBridge (CultMath.UnityBridge asmdef) with ToCultMath / ToUnity / ToColor extension methods for Vector2/3/4, Vector2Int/3Int, Quaternion and Color. C# only admits conversion operators on the source or target type, and the core DLL stays engine-free. - The builder admits exactly that one bridge assembly: it must reference UnityEngine and CultMath.dll, and no core source may be compiled in the package. - Sync the Unity copy of CultMath.hlsl and the third-party notice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
d514efebba
commit
23cc86c4e9
15 changed files with 179 additions and 29 deletions
|
|
@ -1,9 +1,9 @@
|
|||
# Third-Party Notices
|
||||
|
||||
## 2D Simplex Noise
|
||||
## 2D and 3D Simplex Noise
|
||||
|
||||
`math.simplex_noise` and `cultmath_simplex_noise` port the textureless 2D
|
||||
simplex-noise function by Ian McEwan and Ashima Arts, as distributed by Stefan
|
||||
`math.snoise` and `cultmath_snoise` port the textureless 2D and 3D
|
||||
simplex-noise functions by Ian McEwan and Ashima Arts, as distributed by Stefan
|
||||
Gustavson's `webgl-noise` project and Unity Mathematics.
|
||||
|
||||
- Copyright 2011 Ashima Arts.
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ $requiredTemplateFiles = @(
|
|||
"Runtime\Plugins\CultMath.dll.meta",
|
||||
"Runtime\Plugins\CultMath.pdb",
|
||||
"Runtime\Plugins\CultMath.pdb.meta",
|
||||
"Runtime\UnityBridge\CultMath.UnityBridge.asmdef",
|
||||
"Runtime\UnityBridge\CultMath.UnityBridge.asmdef.meta",
|
||||
"Runtime\UnityBridge\UnityConversions.cs",
|
||||
"Runtime\UnityBridge\UnityConversions.cs.meta",
|
||||
"Shaders\CultMath.hlsl",
|
||||
"Shaders\CultMath.hlsl.meta"
|
||||
)
|
||||
|
|
@ -62,7 +66,7 @@ foreach ($relativePath in $requiredTemplateFiles) {
|
|||
}
|
||||
|
||||
$unityAssetFiles = @(Get-ChildItem -LiteralPath $templateRoot -Recurse -File | Where-Object {
|
||||
$_.Extension -in @(".asmdef", ".dll", ".pdb", ".hlsl")
|
||||
$_.Extension -in @(".asmdef", ".cs", ".dll", ".pdb", ".hlsl")
|
||||
})
|
||||
$missingAssetMetas = @($unityAssetFiles | Where-Object { -not (Test-Path -LiteralPath ($_.FullName + ".meta")) })
|
||||
$missingDirectoryMetas = @(Get-ChildItem -LiteralPath $templateRoot -Recurse -Directory | Where-Object {
|
||||
|
|
@ -78,9 +82,18 @@ $pluginMeta = Get-Content -LiteralPath ($trackedAssembly + ".meta") -Raw
|
|||
if ($pluginMeta -notmatch '(?m)^\s*isExplicitlyReferenced:\s*0\s*$') {
|
||||
throw "CultMath.dll must be auto-referenced; explicit-only plugins do not reach dependent Unity asmdefs"
|
||||
}
|
||||
$facadeDefinitions = @(Get-ChildItem -LiteralPath $templateRoot -Recurse -File -Filter "*.asmdef")
|
||||
if ($facadeDefinitions.Count -ne 0) {
|
||||
throw "CultMath's precompiled DLL is the Unity assembly authority; empty asmdef facades are forbidden"
|
||||
# The precompiled DLL is the only authority for CultMath's numeric types. The one
|
||||
# compiled assembly allowed beside it is the UnityEngine conversion bridge, which
|
||||
# references that DLL and must not re-declare core sources.
|
||||
$bridgeRoot = Join-Path $templateRoot "Runtime\UnityBridge"
|
||||
$bridgeDefinition = Join-Path $bridgeRoot "CultMath.UnityBridge.asmdef"
|
||||
$definitions = @(Get-ChildItem -LiteralPath $templateRoot -Recurse -File -Filter "*.asmdef")
|
||||
if ($definitions.Count -ne 1 -or $definitions[0].FullName -ne $bridgeDefinition) {
|
||||
throw "CultMath's Unity package may define only the Runtime\UnityBridge assembly; found: $($definitions.FullName -join ', ')"
|
||||
}
|
||||
$bridge = Get-Content -LiteralPath $bridgeDefinition -Raw | ConvertFrom-Json
|
||||
if ($bridge.noEngineReferences -or -not $bridge.overrideReferences -or @($bridge.precompiledReferences) -notcontains "CultMath.dll") {
|
||||
throw "CultMath.UnityBridge must reference UnityEngine and the precompiled CultMath.dll"
|
||||
}
|
||||
$expectedFileVersion = "$($manifest.version).0"
|
||||
$trackedFileVersion = [Diagnostics.FileVersionInfo]::GetVersionInfo($trackedAssembly).FileVersion
|
||||
|
|
@ -97,23 +110,29 @@ foreach ($pair in @(@($freshAssembly, $trackedAssembly), @($freshSymbols, $track
|
|||
}
|
||||
}
|
||||
|
||||
$coreSourceNames = @(Get-ChildItem -LiteralPath (Join-Path $repoRoot "src\CultMath") -File -Filter "*.cs" | ForEach-Object Name)
|
||||
$trackedSourceFiles = @(Get-ChildItem -LiteralPath $templateRoot -Recurse -File -Filter "*.cs")
|
||||
if ($trackedSourceFiles.Count -ne 0) {
|
||||
throw "CultMath Unity package must not compile repository C# sources: $($trackedSourceFiles.FullName -join ', ')"
|
||||
$strayOrCoreSources = @($trackedSourceFiles | Where-Object {
|
||||
$_.DirectoryName -ne $bridgeRoot -or $coreSourceNames -contains $_.Name
|
||||
})
|
||||
if ($trackedSourceFiles.Count -eq 0 -or $strayOrCoreSources.Count -ne 0) {
|
||||
throw "CultMath Unity package may compile only bridge sources under Runtime\UnityBridge, never core sources: $($strayOrCoreSources.FullName -join ', ')"
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $outputRoot | Out-Null
|
||||
Copy-Item -Path (Join-Path $templateRoot "*") -Destination $outputRoot -Recurse -Force
|
||||
|
||||
$stagedAssemblies = @(Get-ChildItem -LiteralPath (Join-Path $outputRoot "Runtime\Plugins") -Filter "*.dll")
|
||||
$stagedBridgeRoot = Join-Path $outputRoot "Runtime\UnityBridge"
|
||||
$stagedSources = @(Get-ChildItem -LiteralPath $outputRoot -Recurse -File -Filter "*.cs")
|
||||
$stagedFacades = @(Get-ChildItem -LiteralPath $outputRoot -Recurse -File -Filter "*.asmdef")
|
||||
if ($stagedAssemblies.Count -ne 1 -or $stagedAssemblies[0].Name -ne "CultMath.dll" -or $stagedSources.Count -ne 0 -or $stagedFacades.Count -ne 0) {
|
||||
throw "CultMath package must contain one owned auto-referenced DLL, no C# source files, and no asmdef facade"
|
||||
$stagedDefinitions = @(Get-ChildItem -LiteralPath $outputRoot -Recurse -File -Filter "*.asmdef")
|
||||
$stagedStraySources = @($stagedSources | Where-Object { $_.DirectoryName -ne $stagedBridgeRoot })
|
||||
if ($stagedAssemblies.Count -ne 1 -or $stagedAssemblies[0].Name -ne "CultMath.dll" -or $stagedStraySources.Count -ne 0 -or $stagedDefinitions.Count -ne 1) {
|
||||
throw "CultMath package must contain one owned auto-referenced DLL and only the UnityBridge assembly as source"
|
||||
}
|
||||
|
||||
Write-Host "CultMath Unity package: $outputRoot"
|
||||
Write-Host "Package: $($manifest.name)@$($manifest.version)"
|
||||
Write-Host "Managed assemblies: $($stagedAssemblies.Count)"
|
||||
Write-Host "C# source files: $($stagedSources.Count)"
|
||||
Write-Host "Asmdef facades: $($stagedFacades.Count)"
|
||||
Write-Host "Bridge C# source files: $($stagedSources.Count)"
|
||||
Write-Host "Asmdef definitions: $($stagedDefinitions.Count)"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;netstandard2.1</TargetFrameworks>
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
<RootNamespace>CultMath</RootNamespace>
|
||||
<AssemblyName>CultMath</AssemblyName>
|
||||
<PackageId>GameCult.Math</PackageId>
|
||||
<Version>0.1.2</Version>
|
||||
<Version>0.2.0</Version>
|
||||
<Description>Clean-room C# math shaped for HLSL-style renderer code.</Description>
|
||||
<Authors>GameCult</Authors>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
# CultMath for Unity
|
||||
|
||||
This is CultMath's Unity 2021.3-compatible Git-UPM surface. It contains the
|
||||
precompiled `CultMath.dll`, portable symbols, and the numeric
|
||||
`Shaders/CultMath.hlsl` mirror.
|
||||
precompiled `CultMath.dll`, portable symbols, the numeric
|
||||
`Shaders/CultMath.hlsl` mirror, and the `CultMath.UnityBridge` assembly.
|
||||
|
||||
`CultMath.UnityBridge` is the only C# source Unity compiles here. It holds the
|
||||
UnityEngine conversions the engine-free core cannot declare: `ToCultMath()` on
|
||||
`Vector2/3/4`, `Vector2Int/3Int`, `Quaternion`, and `Color`; `ToUnity()` on
|
||||
`float2/3/4`, `int2/3`, and `quaternion`; `ToColor()` on `float4`. C# only
|
||||
admits conversion operators on the source or target type, so these are
|
||||
extension methods rather than implicit casts. Import `CultMath.UnityBridge` to
|
||||
use them.
|
||||
|
||||
Unity does not compile CultMath's repository source tree. That source uses the
|
||||
current C# language and remains owned by the normal .NET project. The package
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 01f9f472b0a645b1ab392567aa38911a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "CultMath.UnityBridge",
|
||||
"rootNamespace": "CultMath.UnityBridge",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"CultMath.dll"
|
||||
],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 77e50a05974842bc99d285ef6d5d04f7
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace CultMath.UnityBridge
|
||||
{
|
||||
/// <summary>
|
||||
/// Explicit conversions between UnityEngine and CultMath value types.
|
||||
/// C# only admits user-defined conversion operators declared on the source or target
|
||||
/// type, and CultMath's core types stay engine-free, so the bridge is extension methods.
|
||||
/// </summary>
|
||||
public static class UnityConversions
|
||||
{
|
||||
public static float2 ToCultMath(this Vector2 value) => new float2(value.x, value.y);
|
||||
public static float3 ToCultMath(this Vector3 value) => new float3(value.x, value.y, value.z);
|
||||
public static float4 ToCultMath(this Vector4 value) => new float4(value.x, value.y, value.z, value.w);
|
||||
public static float4 ToCultMath(this Color value) => new float4(value.r, value.g, value.b, value.a);
|
||||
public static quaternion ToCultMath(this Quaternion value) => new quaternion(value.x, value.y, value.z, value.w);
|
||||
public static int2 ToCultMath(this Vector2Int value) => new int2(value.x, value.y);
|
||||
public static int3 ToCultMath(this Vector3Int value) => new int3(value.x, value.y, value.z);
|
||||
|
||||
public static Vector2 ToUnity(this float2 value) => new Vector2(value.x, value.y);
|
||||
public static Vector3 ToUnity(this float3 value) => new Vector3(value.x, value.y, value.z);
|
||||
public static Vector4 ToUnity(this float4 value) => new Vector4(value.x, value.y, value.z, value.w);
|
||||
public static Quaternion ToUnity(this quaternion value) => new Quaternion(value.x, value.y, value.z, value.w);
|
||||
public static Vector2Int ToUnity(this int2 value) => new Vector2Int(value.x, value.y);
|
||||
public static Vector3Int ToUnity(this int3 value) => new Vector3Int(value.x, value.y, value.z);
|
||||
public static Color ToColor(this float4 value) => new Color(value.x, value.y, value.z, value.w);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8fc742177b3f4715b204afe0e69a400c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -73,11 +73,64 @@ float cultmath_smootherstep(float value)
|
|||
return value * value * value * (value * (value * 6.0 - 15.0) + 10.0);
|
||||
}
|
||||
|
||||
float2 cultmath_simplex_mod289(float2 value) { return value - floor(value * (1.0 / 289.0)) * 289.0; }
|
||||
float3 cultmath_simplex_mod289(float3 value) { return value - floor(value * (1.0 / 289.0)) * 289.0; }
|
||||
float3 cultmath_simplex_permute(float3 value) { return cultmath_simplex_mod289(((value * 34.0) + 1.0) * value); }
|
||||
float2 cultmath_snoise_mod289(float2 value) { return value - floor(value * (1.0 / 289.0)) * 289.0; }
|
||||
float3 cultmath_snoise_mod289(float3 value) { return value - floor(value * (1.0 / 289.0)) * 289.0; }
|
||||
float4 cultmath_snoise_mod289(float4 value) { return value - floor(value * (1.0 / 289.0)) * 289.0; }
|
||||
float3 cultmath_snoise_permute(float3 value) { return cultmath_snoise_mod289(((value * 34.0) + 1.0) * value); }
|
||||
float4 cultmath_snoise_permute(float4 value) { return cultmath_snoise_mod289(((value * 34.0) + 1.0) * value); }
|
||||
|
||||
float cultmath_simplex_noise(float2 value)
|
||||
// Ashima Arts / Ian McEwan 3D simplex noise (MIT), same float32 evaluation
|
||||
// order as the C# math.snoise(float3) mirror.
|
||||
float cultmath_snoise(float3 value)
|
||||
{
|
||||
const float2 c = float2(1.0 / 6.0, 1.0 / 3.0);
|
||||
float3 i = floor(value + dot(value, c.yyy));
|
||||
float3 x0 = value - i + dot(i, c.xxx);
|
||||
float3 g = step(x0.yzx, x0.xyz);
|
||||
float3 l = 1.0 - g;
|
||||
float3 i1 = min(g.xyz, l.zxy);
|
||||
float3 i2 = max(g.xyz, l.zxy);
|
||||
float3 x1 = x0 - i1 + c.xxx;
|
||||
float3 x2 = x0 - i2 + c.yyy;
|
||||
float3 x3 = x0 - 0.5;
|
||||
|
||||
i = cultmath_snoise_mod289(i);
|
||||
float4 p = cultmath_snoise_permute(cultmath_snoise_permute(cultmath_snoise_permute(
|
||||
i.z + float4(0.0, i1.z, i2.z, 1.0)) + i.y + float4(0.0, i1.y, i2.y, 1.0)) + i.x + float4(0.0, i1.x, i2.x, 1.0));
|
||||
|
||||
const float n_ = 0.142857142857;
|
||||
float3 ns = float3(2.0 * n_, 0.5 * n_ - 1.0, n_);
|
||||
float4 j = p - 49.0 * floor(p * ns.z * ns.z);
|
||||
float4 x_ = floor(j * ns.z);
|
||||
float4 y_ = floor(j - 7.0 * x_);
|
||||
float4 x = x_ * ns.x + ns.yyyy;
|
||||
float4 y = y_ * ns.x + ns.yyyy;
|
||||
float4 h = 1.0 - abs(x) - abs(y);
|
||||
|
||||
float4 b0 = float4(x.xy, y.xy);
|
||||
float4 b1 = float4(x.zw, y.zw);
|
||||
float4 s0 = floor(b0) * 2.0 + 1.0;
|
||||
float4 s1 = floor(b1) * 2.0 + 1.0;
|
||||
float4 sh = -step(h, 0.0);
|
||||
float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
|
||||
float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
|
||||
|
||||
float3 p0 = float3(a0.xy, h.x);
|
||||
float3 p1 = float3(a0.zw, h.y);
|
||||
float3 p2 = float3(a1.xy, h.z);
|
||||
float3 p3 = float3(a1.zw, h.w);
|
||||
float4 norm = 1.79284291400159 - 0.85373472095314 * float4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3));
|
||||
p0 *= norm.x;
|
||||
p1 *= norm.y;
|
||||
p2 *= norm.z;
|
||||
p3 *= norm.w;
|
||||
|
||||
float4 m = max(0.6 - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
|
||||
m = m * m;
|
||||
return 42.0 * dot(m * m, float4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
|
||||
}
|
||||
|
||||
float cultmath_snoise(float2 value)
|
||||
{
|
||||
const float4 c = float4(
|
||||
0.211324865405187,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Third-Party Notices
|
||||
|
||||
## 2D Simplex Noise
|
||||
## 2D and 3D Simplex Noise
|
||||
|
||||
`math.simplex_noise` and `cultmath_simplex_noise` port the textureless 2D
|
||||
simplex-noise function by Ian McEwan and Ashima Arts, as distributed by Stefan
|
||||
`math.snoise` and `cultmath_snoise` port the textureless 2D and 3D
|
||||
simplex-noise functions by Ian McEwan and Ashima Arts, as distributed by Stefan
|
||||
Gustavson's `webgl-noise` project and Unity Mathematics.
|
||||
|
||||
- Copyright 2011 Ashima Arts.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
{
|
||||
"name": "org.gamecult.cultmath",
|
||||
"displayName": "CultMath",
|
||||
"version": "0.1.2",
|
||||
"version": "0.2.0",
|
||||
"unity": "2021.3",
|
||||
"description": "Precompiled CultMath numeric primitives and matching HLSL semantics for GameCult Unity runtimes.",
|
||||
"license": "MPL-2.0",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"name": "org.gamecult.caching.unity",
|
||||
"displayName": "GameCult CultCache Unity Tools",
|
||||
"version": "1.1.0",
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.57",
|
||||
"org.gamecult.cultmath": "0.1.2"
|
||||
"org.gamecult.cultmath": "0.2.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"category": "Scripting"
|
||||
|
|
|
|||
Loading…
Reference in a new issue