Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into experiments/moonsharp
Browse files Browse the repository at this point in the history
  • Loading branch information
andybak committed Apr 27, 2024
2 parents c673df0 + 2fef407 commit 4597a97
Show file tree
Hide file tree
Showing 147 changed files with 2,919 additions and 1,525 deletions.
19 changes: 17 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,12 @@ jobs:
name: Android Pico
path: build_android_pico

- name: Download Build Artifacts (Linux)
uses: actions/download-artifact@v4
with:
name: Linux
path: build_linux

- name: Download Build Artifacts (Mac)
uses: actions/download-artifact@v4
with:
Expand All @@ -795,11 +801,13 @@ jobs:
mv build_windows_openxr/StandaloneWindows64/ releases/OpenBrush_Desktop_$VERSION/
mv build_windows_rift/StandaloneWindows64/ releases/OpenBrush_Rift_$VERSION/
mv build_macos/*.dmg releases/OpenBrush_Mac_$VERSION.dmg
mv build_linux/StandaloneLinux64/ releases/OpenBrush_Linux_$VERSION/
cd releases
zip -r OpenBrush_Desktop_$VERSION.zip OpenBrush_Desktop_$VERSION/
zip -r OpenBrush_Rift_$VERSION.zip OpenBrush_Rift_$VERSION/
rm -rf OpenBrush_Desktop_$VERSION
zip -r OpenBrush_Rift_$VERSION.zip OpenBrush_Rift_$VERSION/
rm -rf OpenBrush_Rift_$VERSION
zip -r OpenBrush_Linux_$VERSION.zip OpenBrush_Linux_$VERSION/
- name: Publish
uses: softprops/action-gh-release@v2
Expand Down Expand Up @@ -917,6 +925,11 @@ jobs:
with:
name: MacOS (signed)
path: build_macos
- name: Download Build Artifacts (Linux)
uses: actions/download-artifact@v4
with:
name: Linux
path: build_linux
- name: Upload Build
run: |
cd build_macos
Expand All @@ -926,6 +939,7 @@ jobs:
jinjanate Support/steam/app.vdf.j2 > app.vdf
jinjanate Support/steam/main_depot.win.vdf.j2 > build_windows_openxr/main_depot.vdf
jinjanate Support/steam/main_depot.mac.vdf.j2 > build_macos/main_depot.vdf
jinjanate Support/steam/main_depot.linux.vdf.j2 > build_linux/main_depot.vdf
jinjanate Support/steam/installscript_win.vdf.j2 > build_windows_openxr/installscript_win.vdf
steamcmd +login $STEAM_USERNAME +run_app_build $(pwd)/app.vdf +quit
env:
Expand All @@ -935,7 +949,8 @@ jobs:
OPEN_BRUSH_APP_ID: ${{ vars.STEAM_APP_ID }}
OPEN_BRUSH_WINDOWS_DEPOT_ID: ${{ vars.STEAM_WINDOWS_DEPOT_ID }}
OPEN_BRUSH_MAC_DEPOT_ID: ${{ vars.STEAM_MAC_DEPOT_ID }}
OPEN_BRUSH_EXECUTABLE: ${{ needs.configuration.outputs.basename}}.exe
OPEN_BRUSH_LINUX_DEPOT_ID: ${{ vars.STEAM_LINUX_DEPOT_ID }}
OPEN_BRUSH_WINDOWS_EXECUTABLE: ${{ needs.configuration.outputs.basename}}.exe
CHANNEL: beta
- name: Update steam login secret
run: |
Expand Down
263 changes: 140 additions & 123 deletions Assets/Editor/Tests/TestExport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,138 +16,155 @@
using System;
using System.Collections.Generic;
using System.IO;

using Autodesk.Fbx;
using NUnit.Framework;
using UnityEngine;
using UnityEditor;

namespace TiltBrush {

internal class TestExport {
[Test]
public void TestFbxQuaternion() {
var uq = new Quaternion(1, 2, 3, 4);
var fq = uq.ToFbxQuaternion();

// Basic round-tripping
var uq2 = fq.ToUQuaternion();
MathTestUtils.AssertAlmostEqual(uq, uq2);

// Check that [3] is w, the real part (docs don't say anything about this)
var fqc = new FbxQuaternion(fq);
fqc.Conjugate();
// [3] is the real part
MathTestUtils.AssertAlmostEqual((float)fq.GetAt(3), (float)fqc.GetAt(3));
// and 0-2 are the imaginary part
MathTestUtils.AssertAlmostEqual((float)fq.GetAt(1), -(float)fqc.GetAt(1));
}

[Test]
public void TestPositionAndVectorSemanticsHaveAtLeast3Elements() {
foreach (var guid in AssetDatabase.FindAssets("t:BrushDescriptor")) {
var path = AssetDatabase.GUIDToAssetPath(guid);
var desc = AssetDatabase.LoadAssetAtPath<BrushDescriptor>(path);
GeometryPool.VertexLayout layout;
try {
layout = desc.VertexLayout;
} catch (Exception e) {
throw new Exception("Bad descriptor " + path, e);
}
for (int channel = 0; channel < GeometryPool.kNumTexcoords; ++channel) {
var info = layout.GetTexcoordInfo(channel);
if (( info.semantic == GeometryPool.Semantic.Position
|| info.semantic == GeometryPool.Semantic.Vector)
&& info.size < 3) {
throw new Exception(
string.Format("{0} channel {1} is {2} and size {3} != 3",
desc.m_DurableName, channel, info.semantic, info.size));
namespace TiltBrush
{

internal class TestExport
{
[Test]
public void TestFbxQuaternion()
{
var uq = new Quaternion(1, 2, 3, 4);
var fq = uq.ToFbxQuaternion();

// Basic round-tripping
var uq2 = fq.ToUQuaternion();
MathTestUtils.AssertAlmostEqual(uq, uq2);

// Check that [3] is w, the real part (docs don't say anything about this)
var fqc = new FbxQuaternion(fq);
fqc.Conjugate();
// [3] is the real part
MathTestUtils.AssertAlmostEqual((float)fq.GetAt(3), (float)fqc.GetAt(3));
// and 0-2 are the imaginary part
MathTestUtils.AssertAlmostEqual((float)fq.GetAt(1), -(float)fqc.GetAt(1));
}
}
}
}

[Test]
public void TestAxisConvention() {
AxisConvention[] acs = {
AxisConvention.kUnity,
AxisConvention.kGltf2,
AxisConvention.kUsd,
AxisConvention.kStl,
AxisConvention.kUnreal
};

foreach (var ac1 in acs)
foreach (var ac2 in acs) {
Matrix4x4 ac1FromAc2 = AxisConvention.GetToDstFromSrc(ac1, ac2);
Assert.AreEqual(ac1.forward, ac1FromAc2.MultiplyVector(ac2.forward));
Assert.AreEqual(ac1.right, ac1FromAc2.MultiplyVector(ac2.right ));
Assert.AreEqual(ac1.up, ac1FromAc2.MultiplyVector(ac2.up ));
}

foreach (var ac in acs) {
Matrix4x4 fromUnity = AxisConvention.GetFromUnity(ac);
Assert.AreEqual(ac.forward, fromUnity.MultiplyVector(Vector3.forward));
Assert.AreEqual(ac.right, fromUnity.MultiplyVector(Vector3.right ));
Assert.AreEqual(ac.up, fromUnity.MultiplyVector(Vector3.up ));
[Test]
public void TestPositionAndVectorSemanticsHaveAtLeast3Elements()
{
foreach (var guid in AssetDatabase.FindAssets("t:BrushDescriptor"))
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var desc = AssetDatabase.LoadAssetAtPath<BrushDescriptor>(path);
GeometryPool.VertexLayout layout;
try
{
layout = desc.VertexLayout;
}
catch (Exception e)
{
throw new Exception("Bad descriptor " + path, e);
}
for (int channel = 0; channel < GeometryPool.kNumTexcoords; ++channel)
{
var info = layout.GetTexcoordInfo(channel);
if ((info.semantic == GeometryPool.Semantic.Position
|| info.semantic == GeometryPool.Semantic.Vector)
&& info.size < 3)
{
throw new Exception(
string.Format("{0} channel {1} is {2} and size {3} != 3",
desc.m_DurableName, channel, info.semantic, info.size));
}
}
}
}

Matrix4x4 toUnity = AxisConvention.GetToUnity(ac);
Assert.AreEqual(Vector3.forward, toUnity.MultiplyVector(ac.forward));
Assert.AreEqual(Vector3.right, toUnity.MultiplyVector(ac.right ));
Assert.AreEqual(Vector3.up, toUnity.MultiplyVector(ac.up ));
}
}

[Test]
public void TestGltfDispose() {
string tempDir = Path.Combine(Application.dataPath, "..", "Temp", "TiltBrushUnitTests");
using (var globals = new GlTF_Globals(tempDir, gltfVersion: 1)) {
globals.binary = true;
globals.OpenFiles(Path.Combine(tempDir, "foo.glb1"));
globals.CloseFiles();
[Test]
public void TestAxisConvention()
{
AxisConvention[] acs =
{
AxisConvention.kUnity,
AxisConvention.kGltf2,
AxisConvention.kUsd,
AxisConvention.kStl,
AxisConvention.kUnreal
};

foreach (var ac1 in acs)
foreach (var ac2 in acs)
{
Matrix4x4 ac1FromAc2 = AxisConvention.GetToDstFromSrc(ac1, ac2);
Assert.AreEqual(ac1.forward, ac1FromAc2.MultiplyVector(ac2.forward));
Assert.AreEqual(ac1.right, ac1FromAc2.MultiplyVector(ac2.right));
Assert.AreEqual(ac1.up, ac1FromAc2.MultiplyVector(ac2.up));
}

foreach (var ac in acs)
{
Matrix4x4 fromUnity = AxisConvention.GetFromUnity(ac);
Assert.AreEqual(ac.forward, fromUnity.MultiplyVector(Vector3.forward));
Assert.AreEqual(ac.right, fromUnity.MultiplyVector(Vector3.right));
Assert.AreEqual(ac.up, fromUnity.MultiplyVector(Vector3.up));

Matrix4x4 toUnity = AxisConvention.GetToUnity(ac);
Assert.AreEqual(Vector3.forward, toUnity.MultiplyVector(ac.forward));
Assert.AreEqual(Vector3.right, toUnity.MultiplyVector(ac.right));
Assert.AreEqual(Vector3.up, toUnity.MultiplyVector(ac.up));
}
}

[Test]
public void TestGltfDispose()
{
string tempDir = Path.Combine(Application.dataPath, "..", "Temp", "TiltBrushUnitTests");
using (var globals = new GlTF_Globals(tempDir, gltfVersion: 1))
{
globals.binary = true;
globals.OpenFiles(Path.Combine(tempDir, "foo.glb1"));
globals.CloseFiles();
}
}

[Test]
public void TestGetOrCreateSafeLocal()
{
var dp = Application.dataPath;
var ctx = new ExportFileReference.DisambiguationContext();
var paper = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper");
var paper2 = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper");
Assert.AreEqual(paper, paper2); // reference equality
Assert.AreEqual("main.png", paper.m_uri);
Assert.AreEqual("main.png", paper2.m_uri);

var ductTape = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main.png", dp + @"\Resources\Brushes\Basic\DuctTape");
Assert.AreNotEqual(paper, ductTape);
Assert.AreEqual("main_1.png", ductTape.m_uri);

var peverse = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main_1.png", dp + @"\Editor\Tests\TestData");
Assert.AreEqual("main_1_1.png", peverse.m_uri);

var withNamespace = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main.png", dp + @"\Resources\Brushes\Basic\Hypercolor",
@"subdirectory\brush_main.png");
Assert.AreEqual("brush_main.png", withNamespace.m_uri);
}

[Test]
public void TestCreateUniqueName()
{
HashSet<string> names = new HashSet<string>();
string Create(string name) => ExportUtils.CreateUniqueName(name, names);
Assert.AreEqual("main.png", Create("main.png"));
Assert.AreEqual("main_1.png", Create("main.png"));
Assert.AreEqual("main_1_1.png", Create("main_1.png")); // perverse
Assert.AreEqual("main_2.png", Create("main.png"));

Assert.AreEqual("initialShadingGroup", Create("initialShadingGroup"));
Assert.AreEqual("initialShadingGroup_1", Create("initialShadingGroup"));
}
}
}

[Test]
public void TestGetOrCreateSafeLocal() {
var dp = Application.dataPath;
var ctx = new ExportFileReference.DisambiguationContext();
var paper = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper");
var paper2 = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper");
Assert.AreEqual(paper, paper2); // reference equality
Assert.AreEqual("main.png", paper.m_uri);
Assert.AreEqual("main.png", paper2.m_uri);

var ductTape = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main.png", dp + @"\Resources\Brushes\Basic\DuctTape");
Assert.AreNotEqual(paper, ductTape);
Assert.AreEqual("main_1.png", ductTape.m_uri);

var peverse = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main_1.png", dp + @"\Editor\Tests\TestData");
Assert.AreEqual("main_1_1.png", peverse.m_uri);

var withNamespace = ExportFileReference.GetOrCreateSafeLocal(
ctx, "main.png", dp + @"\Resources\Brushes\Basic\Hypercolor",
@"subdirectory\brush_main.png");
Assert.AreEqual("brush_main.png", withNamespace.m_uri);
}

[Test]
public void TestCreateUniqueName() {
HashSet<string> names = new HashSet<string>();
string Create(string name) => ExportUtils.CreateUniqueName(name, names);
Assert.AreEqual("main.png", Create("main.png"));
Assert.AreEqual("main_1.png", Create("main.png"));
Assert.AreEqual("main_1_1.png", Create("main_1.png")); // perverse
Assert.AreEqual("main_2.png", Create("main.png"));

Assert.AreEqual("initialShadingGroup", Create("initialShadingGroup"));
Assert.AreEqual("initialShadingGroup_1", Create("initialShadingGroup"));
}
}

}
#endif
34 changes: 18 additions & 16 deletions Assets/Editor/ToolkitUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,22 +186,24 @@ private static bool ExportBrushStrokesFbx_Enabled()
}

#if FBX_SUPPORTED
[MenuItem("Open Brush/Toolkit/Export FBX")]
private static void ExportBrushStrokesFbx() {
var current = SaveLoadScript.m_Instance.SceneFile;
string basename = (current.Valid)
? Path.GetFileNameWithoutExtension(current.FullPath).Replace(" ", "_")
: "Untitled";

string directoryName = FileUtils.GenerateNonexistentFilename(
App.UserExportPath(), basename, "");
if (!FileUtils.InitializeDirectoryWithUserError(directoryName,
"Failed to export")) {
return;
}
string fbxName = Path.Combine(directoryName, basename + ".fbx");
ExportFbx.Export(fbxName, ExportFbx.kFbxAscii);
}
[MenuItem("Open Brush/Toolkit/Export FBX")]
private static void ExportBrushStrokesFbx()
{
var current = SaveLoadScript.m_Instance.SceneFile;
string basename = (current.Valid)
? Path.GetFileNameWithoutExtension(current.FullPath).Replace(" ", "_")
: "Untitled";

string directoryName = FileUtils.GenerateNonexistentFilename(
App.UserExportPath(), basename, "");
if (!FileUtils.InitializeDirectoryWithUserError(directoryName,
"Failed to export"))
{
return;
}
string fbxName = Path.Combine(directoryName, basename + ".fbx");
ExportFbx.Export(fbxName, ExportFbx.kFbxAscii);
}
#endif

// Collects all brushes and their assets, and exports them into a folder that can be copied into into Tilt Brush Toolkit's Unity SDK
Expand Down
Loading

0 comments on commit 4597a97

Please sign in to comment.