tests
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -17,3 +17,5 @@ Output/*
|
|||||||
Source/obj/
|
Source/obj/
|
||||||
.idea/*
|
.idea/*
|
||||||
*.DotSettings.user
|
*.DotSettings.user
|
||||||
|
Tests/bin/
|
||||||
|
Tests/obj/
|
||||||
|
|||||||
@@ -5,19 +5,31 @@
|
|||||||
"Data": {
|
"Data": {
|
||||||
"ProductName": "Goake",
|
"ProductName": "Goake",
|
||||||
"CompanyName": "GoaLitiuM",
|
"CompanyName": "GoaLitiuM",
|
||||||
|
"CopyrightNotice": "ddc",
|
||||||
|
"Icon": null,
|
||||||
"FirstScene": "194e05f445ece24ec5448d886e1334df",
|
"FirstScene": "194e05f445ece24ec5448d886e1334df",
|
||||||
"NoSplashScreen": true,
|
"NoSplashScreen": true,
|
||||||
|
"SplashScreen": null,
|
||||||
"Time": "a55dc3c04da4ea3744b7f1994565beac",
|
"Time": "a55dc3c04da4ea3744b7f1994565beac",
|
||||||
"Audio": "492a33824049ba25a8bdcdb148179e67",
|
"Audio": "492a33824049ba25a8bdcdb148179e67",
|
||||||
"LayersAndTags": "60078f6a489f7c57e47fce83afaada66",
|
"LayersAndTags": "60078f6a489f7c57e47fce83afaada66",
|
||||||
"Physics": "4bd8a4cc460399b5f1975fbe0a668e3f",
|
"Physics": "4bd8a4cc460399b5f1975fbe0a668e3f",
|
||||||
"Input": "8ec53dba4c238bfbea1d62922e612a4d",
|
"Input": "8ec53dba4c238bfbea1d62922e612a4d",
|
||||||
"Graphics": "f94d5aae457aeba67033a8a4ca753214",
|
"Graphics": "f94d5aae457aeba67033a8a4ca753214",
|
||||||
|
"Navigation": null,
|
||||||
|
"Localization": null,
|
||||||
"GameCooking": "af2e52554f7faed7b4937181dd22d166",
|
"GameCooking": "af2e52554f7faed7b4937181dd22d166",
|
||||||
"Streaming": "3a6ffc3a43e684f77cfed1a1f8f6bd0e",
|
"Streaming": "3a6ffc3a43e684f77cfed1a1f8f6bd0e",
|
||||||
"CustomSettings": {
|
"CustomSettings": {
|
||||||
"BrushMaterials": "29a0b0c54b40eb3e6857ffb4c9cab71e"
|
"BrushMaterials": "29a0b0c54b40eb3e6857ffb4c9cab71e"
|
||||||
},
|
},
|
||||||
"WindowsPlatform": "4a5eec97484253fed72934860ae62c40"
|
"WindowsPlatform": "4a5eec97484253fed72934860ae62c40",
|
||||||
|
"UWPPlatform": null,
|
||||||
|
"LinuxPlatform": null,
|
||||||
|
"PS4Platform": null,
|
||||||
|
"XboxOnePlatform": null,
|
||||||
|
"XboxScarlettPlatform": null,
|
||||||
|
"AndroidPlatform": null,
|
||||||
|
"SwitchPlatform": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"ID": "0c0af24c4fafa9c72af2c08723321976",
|
"ID": "0c0af24c4fafa9c72af2c08723321976",
|
||||||
"TypeName": "FlaxEngine.SceneAsset",
|
"TypeName": "FlaxEngine.SceneAsset",
|
||||||
"EngineBuild": 6219,
|
"EngineBuild": 6224,
|
||||||
"Data": [
|
"Data": [
|
||||||
{
|
{
|
||||||
"ID": "0c0af24c4fafa9c72af2c08723321976",
|
"ID": "0c0af24c4fafa9c72af2c08723321976",
|
||||||
@@ -25,103 +25,53 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "4ef1f38b4569142b55b0ff935525d47a",
|
"ID": "c28e12a74ac7d87cf078c6a52bf696e0",
|
||||||
"TypeName": "FlaxEngine.RigidBody",
|
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
|
||||||
"ParentID": "0c0af24c4fafa9c72af2c08723321976",
|
"PrefabObjectID": "999a202c47de967d2bdfd09abcc6df4e",
|
||||||
"Name": "PlayerPrefab",
|
"ParentID": "0c0af24c4fafa9c72af2c08723321976"
|
||||||
"Transform": {
|
|
||||||
"Translation": {
|
|
||||||
"X": -167.25045776367188,
|
|
||||||
"Y": -10.409317016601563,
|
|
||||||
"Z": 61.111427307128909
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"OverrideMass": true,
|
|
||||||
"Mass": 10.0,
|
|
||||||
"LinearDamping": 0.0,
|
|
||||||
"AngularDamping": 0.0,
|
|
||||||
"Constraints": 56,
|
|
||||||
"IsKinematic": true,
|
|
||||||
"EnableGravity": false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "e3bab01a4912873fc2e9ff855a214bf7",
|
"ID": "26ae32e2418882abc15d568692fdd97f",
|
||||||
"TypeName": "Game.PlayerMovement",
|
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
|
||||||
"ParentID": "4ef1f38b4569142b55b0ff935525d47a",
|
"PrefabObjectID": "b29a58f545071ca393afaab21faa83ad",
|
||||||
|
"ParentID": "c28e12a74ac7d87cf078c6a52bf696e0",
|
||||||
"V": {}
|
"V": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "08ed03be4d537814ba01edb88f6801e1",
|
"ID": "ddcf668e46d6c73d5d0d258822f24594",
|
||||||
"TypeName": "FlaxEngine.EmptyActor",
|
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
|
||||||
"ParentID": "4ef1f38b4569142b55b0ff935525d47a",
|
"PrefabObjectID": "a67383834fc3f6f1106e8099e5557e32",
|
||||||
"Name": "RootActor"
|
"ParentID": "c28e12a74ac7d87cf078c6a52bf696e0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "499cfa784579b58bba713daa0983d705",
|
"ID": "9b502ff34a9bee27cf23aabd9cf1da91",
|
||||||
"TypeName": "FlaxEngine.Camera",
|
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
|
||||||
"ParentID": "08ed03be4d537814ba01edb88f6801e1",
|
"PrefabObjectID": "b8fc420f4efe96fa2b4042bd98fd3e74",
|
||||||
"Name": "Camera",
|
"ParentID": "ddcf668e46d6c73d5d0d258822f24594"
|
||||||
"Transform": {
|
|
||||||
"Translation": {
|
|
||||||
"X": 0.0,
|
|
||||||
"Y": 28.7337646484375,
|
|
||||||
"Z": 0.0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Near": 1.0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "b59df4764594c5ee84a759b5e65bfc5a",
|
"ID": "7a0c2f7648daf4b52776858dd302d509",
|
||||||
"TypeName": "FlaxEngine.AudioListener",
|
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
|
||||||
"ParentID": "08ed03be4d537814ba01edb88f6801e1",
|
"PrefabObjectID": "226bdb004e72848777178a9d1f207cbf",
|
||||||
"Name": "AudioListener"
|
"ParentID": "9b502ff34a9bee27cf23aabd9cf1da91"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "fbaa6db24f0a2a9db36bc6a043fc2572",
|
"ID": "320c57c5499ef1692820f28954142720",
|
||||||
"TypeName": "FlaxEngine.CapsuleCollider",
|
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
|
||||||
"ParentID": "4ef1f38b4569142b55b0ff935525d47a",
|
"PrefabObjectID": "8bd80bca49ac35da66aabaa2e473851d",
|
||||||
"IsActive": false,
|
"ParentID": "c28e12a74ac7d87cf078c6a52bf696e0"
|
||||||
"Name": "CapsuleCollider",
|
|
||||||
"Transform": {
|
|
||||||
"Orientation": {
|
|
||||||
"X": 0.0,
|
|
||||||
"Y": 0.0,
|
|
||||||
"Z": 0.7071068286895752,
|
|
||||||
"W": 0.7071068286895752
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ContactOffset": 0.0,
|
|
||||||
"Material": "d99b8b6f40198beea4703dadd642150e",
|
|
||||||
"Radius": 16.0,
|
|
||||||
"Height": 52.0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "9677298d46e5d5d7021f7cb607bd3023",
|
"ID": "deef0a234d3a14fad95b50b822e9f096",
|
||||||
"TypeName": "FlaxEngine.BoxCollider",
|
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
|
||||||
"ParentID": "4ef1f38b4569142b55b0ff935525d47a",
|
"PrefabObjectID": "d9d61d314ad79d49ba08059cef50f802",
|
||||||
"Name": "BoxCollider",
|
"ParentID": "c28e12a74ac7d87cf078c6a52bf696e0"
|
||||||
"ContactOffset": 0.0,
|
|
||||||
"Material": "ffe0e84c49607480f67a3994a7fe11a8",
|
|
||||||
"Size": {
|
|
||||||
"X": 32.0,
|
|
||||||
"Y": 84.0,
|
|
||||||
"Z": 32.0
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "f472490345bbfe282aefa2aa027e0138",
|
"ID": "fc1310c843e3136b468f83947df3566d",
|
||||||
"TypeName": "FlaxEngine.MeshCollider",
|
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
|
||||||
"ParentID": "4ef1f38b4569142b55b0ff935525d47a",
|
"PrefabObjectID": "b377cc03418270d87e8a5b92cb5374ea",
|
||||||
"IsActive": false,
|
"ParentID": "c28e12a74ac7d87cf078c6a52bf696e0"
|
||||||
"Name": "CylinderCollider",
|
|
||||||
"Transform": {
|
|
||||||
"Scale": {
|
|
||||||
"X": 0.3199999928474426,
|
|
||||||
"Y": 0.8399999737739563,
|
|
||||||
"Z": 0.3199999928474426
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"CollisionData": "593d92914c4bd54679ddec9e539bba80"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "b5d566374477944e69bdc2b86249883b",
|
"ID": "b5d566374477944e69bdc2b86249883b",
|
||||||
@@ -168,13 +118,13 @@
|
|||||||
"Transform": {
|
"Transform": {
|
||||||
"Translation": {
|
"Translation": {
|
||||||
"X": 0.0,
|
"X": 0.0,
|
||||||
"Y": 733.0,
|
"Y": 735.0,
|
||||||
"Z": 0.0
|
"Z": 0.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Control": "FlaxEngine.GUI.Label",
|
"Control": "FlaxEngine.GUI.Label",
|
||||||
"Data": {
|
"Data": {
|
||||||
"Text": "uFPS: 120\nrFPS: 120\npFPS: 30\nCon: NaNms\nDirectX11\nGC memory: 15.30202MB",
|
"Text": "eFPS: 121\nuFPS: 120\nrFPS: 120\npFPS: 30\nCon: NaNms\nDirectX11\nGC memory: 9.235704MB",
|
||||||
"TextColor": {
|
"TextColor": {
|
||||||
"R": 1.0,
|
"R": 1.0,
|
||||||
"G": 1.0,
|
"G": 1.0,
|
||||||
@@ -194,6 +144,7 @@
|
|||||||
"Font": "4508d98f4aa1f0bd59362b81d47e38f4",
|
"Font": "4508d98f4aa1f0bd59362b81d47e38f4",
|
||||||
"Size": 10
|
"Size": 10
|
||||||
},
|
},
|
||||||
|
"Material": null,
|
||||||
"Margin": {
|
"Margin": {
|
||||||
"Left": 0.0,
|
"Left": 0.0,
|
||||||
"Right": 0.0,
|
"Right": 0.0,
|
||||||
@@ -222,7 +173,7 @@
|
|||||||
"Left": 0.0,
|
"Left": 0.0,
|
||||||
"Right": 143.0,
|
"Right": 143.0,
|
||||||
"Top": -80.0,
|
"Top": -80.0,
|
||||||
"Bottom": 96.0
|
"Bottom": 112.0
|
||||||
},
|
},
|
||||||
"Scale": {
|
"Scale": {
|
||||||
"X": 1.0,
|
"X": 1.0,
|
||||||
@@ -260,8 +211,8 @@
|
|||||||
"Name": "ContainerControl 0",
|
"Name": "ContainerControl 0",
|
||||||
"Transform": {
|
"Transform": {
|
||||||
"Translation": {
|
"Translation": {
|
||||||
"X": 45644.0,
|
"X": 44861.0,
|
||||||
"Y": 0.5,
|
"Y": 1.5,
|
||||||
"Z": 0.0
|
"Z": 0.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using FlaxEngine.Assertions;
|
|
||||||
|
|
||||||
namespace Cabrito
|
namespace Cabrito
|
||||||
{
|
{
|
||||||
@@ -32,13 +31,12 @@ namespace Cabrito
|
|||||||
instance = new ConsoleInstance();
|
instance = new ConsoleInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Destroy()
|
public static void Destroy()
|
||||||
{
|
{
|
||||||
if (instance != null)
|
if (instance != null)
|
||||||
{
|
{
|
||||||
instance.Dispose();
|
instance.Dispose();
|
||||||
instance = null;
|
instance = null;
|
||||||
FlaxEngine.Debug.Log("Console.Destroy");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +137,10 @@ namespace Cabrito
|
|||||||
assemblyName.StartsWith("Mono.") ||
|
assemblyName.StartsWith("Mono.") ||
|
||||||
assemblyName == "mscorlib" ||
|
assemblyName == "mscorlib" ||
|
||||||
assemblyName == "Newtonsoft.Json" ||
|
assemblyName == "Newtonsoft.Json" ||
|
||||||
assemblyName.StartsWith("FlaxEngine."))
|
assemblyName.StartsWith("FlaxEngine.") ||
|
||||||
|
assemblyName.StartsWith("JetBrains.") ||
|
||||||
|
assemblyName.StartsWith("Microsoft.") ||
|
||||||
|
assemblyName.StartsWith("nunit."))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using Cabrito;
|
using Cabrito;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Game
|
namespace Game
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -1082,6 +1083,16 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BrushGeometry
|
||||||
|
{
|
||||||
|
public MapBrush brush;
|
||||||
|
public Vector3[] vertices;
|
||||||
|
public uint[] indices;
|
||||||
|
public Vector2[] uvs;
|
||||||
|
public Vector3[] normals;
|
||||||
|
public Model model = null;
|
||||||
|
public MaterialBase brushMaterial = null; // FIXME: brush can have multiple textures
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class Q3MapImporter : Script
|
public class Q3MapImporter : Script
|
||||||
@@ -1103,7 +1114,7 @@ namespace Game
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void QuickHull(Vector3[] points, out Vector3[] outVertices)
|
static void QuickHull(Vector3[] points, out Vector3[] outVertices)
|
||||||
{
|
{
|
||||||
var verts = new List<Vector3>();
|
var verts = new List<Vector3>();
|
||||||
var tris = new List<int>();
|
var tris = new List<int>();
|
||||||
@@ -1424,7 +1435,7 @@ namespace Game
|
|||||||
return brushVertices.ToArray();
|
return brushVertices.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriangulateBrush3(MapBrush brush, out Vector3[] vertices)
|
static public void TriangulateBrush3(MapBrush brush, out Vector3[] vertices)
|
||||||
{
|
{
|
||||||
float cs = 3000f;
|
float cs = 3000f;
|
||||||
|
|
||||||
@@ -1638,13 +1649,13 @@ namespace Game
|
|||||||
//uniqPoints.Add(new Vector3((float)Math.Round(v.X, 3), (float)Math.Round(v.Y, 3), (float)Math.Round(v.Z, 3)));
|
//uniqPoints.Add(new Vector3((float)Math.Round(v.X, 3), (float)Math.Round(v.Y, 3), (float)Math.Round(v.Z, 3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
debugPoints = new List<Vector3>(uniqPoints);
|
//debugPoints = new List<Vector3>(uniqPoints);
|
||||||
|
|
||||||
|
|
||||||
Vector3[] hullPoints;
|
Vector3[] hullPoints;
|
||||||
QuickHull(uniqPoints.ToArray(), out hullPoints);
|
QuickHull(uniqPoints.ToArray(), out hullPoints);
|
||||||
|
|
||||||
var ms = new MeshSimplifier();
|
var ms = new MeshSimplifier(1f, 7f);
|
||||||
var optimizedVerts = ms.Simplify(hullPoints);
|
var optimizedVerts = ms.Simplify(hullPoints);
|
||||||
|
|
||||||
brushVertices.Clear();
|
brushVertices.Clear();
|
||||||
@@ -1652,7 +1663,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debugPoints = new List<Vector3>(faceVertices);
|
//debugPoints = new List<Vector3>(faceVertices);
|
||||||
|
|
||||||
var hullPoints = faceVertices;
|
var hullPoints = faceVertices;
|
||||||
|
|
||||||
@@ -1669,37 +1680,87 @@ namespace Game
|
|||||||
vertices = brushVertices.ToArray();
|
vertices = brushVertices.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Development (game)
|
||||||
|
cube3: 8.1ms + 123ms
|
||||||
|
aerowalk: 78ms + 1372ms
|
||||||
|
|
||||||
|
Development (editor)
|
||||||
|
cube3: 4.6ms + 77.3ms
|
||||||
|
aerowalk: 74ms + 1328ms
|
||||||
|
|
||||||
|
Release
|
||||||
|
cube3: 4.4ms + 61.4ms
|
||||||
|
aerowalk: 17ms + 511ms
|
||||||
|
|
||||||
|
UnitTest release:
|
||||||
|
aerowalk: 8ms + 267ms
|
||||||
|
|
||||||
|
aero unit:
|
||||||
|
.net6: 667 + 229
|
||||||
|
.net5: 704 + 237
|
||||||
|
.net5win7: 697 + 237
|
||||||
|
.net48 809 + 242
|
||||||
|
.net472 810 + 246
|
||||||
|
.net462 810 + 243
|
||||||
|
.net452 808 + 244
|
||||||
|
*/
|
||||||
|
|
||||||
public override void OnStart()
|
public override void OnStart()
|
||||||
{
|
{
|
||||||
byte[] mapChars = File.ReadAllBytes(mapPath);
|
byte[] mapChars = File.ReadAllBytes(mapPath);
|
||||||
|
|
||||||
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
root = MapParser.Parse(mapChars);
|
root = MapParser.Parse(mapChars);
|
||||||
|
sw.Stop();
|
||||||
|
|
||||||
|
Console.Print("Map parsing time: " + sw.Elapsed.TotalMilliseconds + "ms");
|
||||||
|
|
||||||
bool oneMesh = false;
|
bool oneMesh = false;
|
||||||
bool convexMesh = true;
|
bool convexMesh = true;
|
||||||
|
|
||||||
|
|
||||||
if (!oneMesh)
|
if (!oneMesh)
|
||||||
{
|
{
|
||||||
Dictionary<string, MaterialBase> materials = null;
|
Dictionary<string, MaterialBase> materials = null;
|
||||||
var mapRootActor = Actor.AddChild<Actor>();
|
var mapRootActor = Actor.AddChild<Actor>();
|
||||||
mapRootActor.Name = "MapRootActor";
|
mapRootActor.Name = "MapRootActor";
|
||||||
|
|
||||||
|
List<BrushGeometry> brushGeometries = new List<BrushGeometry>(root.entities[0].brushes.Count);
|
||||||
|
|
||||||
|
|
||||||
|
// pass 1: triangulation
|
||||||
|
sw.Restart();
|
||||||
int brushIndex = 0;
|
int brushIndex = 0;
|
||||||
foreach (var brush in root.entities[0].brushes)
|
foreach (var brush in root.entities[0].brushes)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<Vector3> vertices = new List<Vector3>();
|
BrushGeometry geom = new BrushGeometry();
|
||||||
List<Vector2> uvs = new List<Vector2>();
|
|
||||||
List<Vector3> normals = new List<Vector3>();
|
|
||||||
|
|
||||||
TriangulateBrush3(brush, out Vector3[] brushVertices);
|
TriangulateBrush3(brush, out geom.vertices);
|
||||||
|
geom.brush = brush;
|
||||||
|
|
||||||
|
brushGeometries.Add(geom);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.Print("Failed to triangulate brush " + brushIndex.ToString() + ": " + e.Message);
|
||||||
|
}
|
||||||
|
brushIndex++;
|
||||||
|
}
|
||||||
|
sw.Stop();
|
||||||
|
Console.Print("Pass 1: triangulation: " + sw.Elapsed.TotalMilliseconds + "ms");
|
||||||
|
|
||||||
|
// pass 2: texturing
|
||||||
|
sw.Restart();
|
||||||
|
foreach (var geom in brushGeometries)
|
||||||
|
{
|
||||||
|
var brushVertices = geom.vertices;
|
||||||
Vector2[] brushUvs = new Vector2[brushVertices.Length];
|
Vector2[] brushUvs = new Vector2[brushVertices.Length];
|
||||||
Vector3[] brushNormals = new Vector3[brushVertices.Length];
|
Vector3[] brushNormals = new Vector3[brushVertices.Length];
|
||||||
|
|
||||||
// FIXME: brush can have multiple textures
|
var textureName = geom.brush.planes[0].texture;
|
||||||
MaterialBase brushMaterial;
|
|
||||||
var textureName = brush.planes[0].texture;
|
|
||||||
|
|
||||||
if (materials == null)
|
if (materials == null)
|
||||||
{
|
{
|
||||||
@@ -1717,7 +1778,8 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!materials.TryGetValue(textureName, out brushMaterial))
|
// FIXME: brush can have multiple textures
|
||||||
|
if (!materials.TryGetValue(textureName, out geom.brushMaterial))
|
||||||
{
|
{
|
||||||
Console.Print("Material '" + textureName + "' not found for brush");
|
Console.Print("Material '" + textureName + "' not found for brush");
|
||||||
materials.Add(textureName, material);
|
materials.Add(textureName, material);
|
||||||
@@ -1736,7 +1798,7 @@ namespace Game
|
|||||||
float uvRotation = 0f;
|
float uvRotation = 0f;
|
||||||
Vector2 uvOffset = new Vector2(0f);
|
Vector2 uvOffset = new Vector2(0f);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach (var brushPlane in brush.planes)
|
foreach (var brushPlane in geom.brush.planes)
|
||||||
{
|
{
|
||||||
if ((brushPlane.plane.Normal - normal).Length < 0.01f)
|
if ((brushPlane.plane.Normal - normal).Length < 0.01f)
|
||||||
{
|
{
|
||||||
@@ -1760,6 +1822,7 @@ namespace Game
|
|||||||
|
|
||||||
// Attempt to workaround most rounding errors at 45-degree angles which causes bias towards one axis.
|
// Attempt to workaround most rounding errors at 45-degree angles which causes bias towards one axis.
|
||||||
// This behaviour is seemingly random in different engines and editors, so let's not bother.
|
// This behaviour is seemingly random in different engines and editors, so let's not bother.
|
||||||
|
|
||||||
Vector3 textureNormal = new Vector3((float)Math.Round(normal.X, 4),
|
Vector3 textureNormal = new Vector3((float)Math.Round(normal.X, 4),
|
||||||
(float)Math.Round(normal.Y, 4), (float)Math.Round(normal.Z, 4));
|
(float)Math.Round(normal.Y, 4), (float)Math.Round(normal.Z, 4));
|
||||||
|
|
||||||
@@ -1808,38 +1871,78 @@ namespace Game
|
|||||||
brushNormals[i + 2] = normal;
|
brushNormals[i + 2] = normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertices.AddRange(brushVertices);
|
geom.vertices = brushVertices;
|
||||||
uvs.AddRange(brushUvs);
|
geom.uvs = brushUvs;
|
||||||
normals.AddRange(brushNormals);
|
geom.normals = brushNormals;
|
||||||
|
geom.indices = new uint[geom.vertices.Length];
|
||||||
|
for (uint i = 0; i < geom.vertices.Length; i++)
|
||||||
|
geom.indices[i] = i;
|
||||||
|
|
||||||
if (vertices.Count > 0)
|
if (geom.vertices.Length > 0)
|
||||||
{
|
{
|
||||||
uint[] triangles = new uint[vertices.Count];
|
geom.model = Content.CreateVirtualAsset<Model>();
|
||||||
for (uint i = 0; i < vertices.Count; i++)
|
geom.model.SetupLODs(new int[] { 1 });
|
||||||
triangles[i] = i;
|
geom.model.LODs[0].Meshes[0].UpdateMesh(geom.vertices, geom.indices, geom.normals,
|
||||||
|
null, geom.uvs);
|
||||||
Model model = Content.CreateVirtualAsset<Model>();
|
|
||||||
model.SetupLODs(new int[] { 1 });
|
|
||||||
model.LODs[0].Meshes[0].UpdateMesh(vertices.ToArray(), (int[])(object)triangles, normals.ToArray(),
|
|
||||||
null, uvs.ToArray());
|
|
||||||
|
|
||||||
|
/*
|
||||||
StaticModel childModel = Actor.AddChild<StaticModel>();
|
StaticModel childModel = Actor.AddChild<StaticModel>();
|
||||||
childModel.Name = "Brush_" + brushIndex;
|
childModel.Name = "Brush_" + brushIndex;
|
||||||
childModel.Model = model;
|
childModel.Model = geom.model;
|
||||||
childModel.SetMaterial(0, brushMaterial);
|
childModel.SetMaterial(0, geom.brushMaterial);
|
||||||
childModel.Parent = mapRootActor;
|
childModel.Parent = mapRootActor;
|
||||||
|
|
||||||
CollisionData collisionData = Content.CreateVirtualAsset<CollisionData>();
|
CollisionData collisionData = Content.CreateVirtualAsset<CollisionData>();
|
||||||
if (collisionData.CookCollision(convexMesh ? CollisionDataType.ConvexMesh : CollisionDataType.TriangleMesh, vertices.ToArray(),
|
if (collisionData.CookCollision(convexMesh ? CollisionDataType.ConvexMesh : CollisionDataType.TriangleMesh, geom.vertices.ToArray(),
|
||||||
triangles.ToArray()))
|
geom.indices.ToArray()))
|
||||||
{
|
{
|
||||||
bool failed = true;
|
bool failed = true;
|
||||||
if (convexMesh)
|
if (convexMesh)
|
||||||
{
|
{
|
||||||
// fallback to triangle mesh
|
// fallback to triangle mesh
|
||||||
failed = collisionData.CookCollision(CollisionDataType.TriangleMesh,
|
failed = collisionData.CookCollision(CollisionDataType.TriangleMesh,
|
||||||
vertices.ToArray(),
|
geom.vertices.ToArray(),
|
||||||
triangles.ToArray());
|
geom.indices.ToArray());
|
||||||
|
if (!failed)
|
||||||
|
Console.PrintWarning("Hull brush " + brushIndex.ToString() + " is not convex");
|
||||||
|
}
|
||||||
|
if (failed)
|
||||||
|
throw new Exception("failed to cook final collision");
|
||||||
|
}
|
||||||
|
|
||||||
|
var meshCollider = childModel.AddChild<MeshCollider>();
|
||||||
|
meshCollider.CollisionData = collisionData;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//brushGeometries.Add(geom);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
sw.Stop();
|
||||||
|
Console.Print("Pass 2: texturing: " + sw.Elapsed.TotalMilliseconds + "ms");
|
||||||
|
|
||||||
|
// pass 3: collision
|
||||||
|
sw.Restart();
|
||||||
|
foreach (var geom in brushGeometries)
|
||||||
|
{
|
||||||
|
StaticModel childModel = Actor.AddChild<StaticModel>();
|
||||||
|
childModel.Name = "Brush_" + brushIndex;
|
||||||
|
childModel.Model = geom.model;
|
||||||
|
childModel.SetMaterial(0, geom.brushMaterial);
|
||||||
|
childModel.Parent = mapRootActor;
|
||||||
|
|
||||||
|
CollisionData collisionData = Content.CreateVirtualAsset<CollisionData>();
|
||||||
|
if (collisionData.CookCollision(convexMesh ? CollisionDataType.ConvexMesh : CollisionDataType.TriangleMesh, geom.vertices,
|
||||||
|
geom.indices))
|
||||||
|
{
|
||||||
|
bool failed = true;
|
||||||
|
if (convexMesh)
|
||||||
|
{
|
||||||
|
// fallback to triangle mesh
|
||||||
|
failed = collisionData.CookCollision(CollisionDataType.TriangleMesh,
|
||||||
|
geom.vertices,
|
||||||
|
geom.indices);
|
||||||
if (!failed)
|
if (!failed)
|
||||||
Console.PrintWarning("Hull brush " + brushIndex.ToString() + " is not convex");
|
Console.PrintWarning("Hull brush " + brushIndex.ToString() + " is not convex");
|
||||||
}
|
}
|
||||||
@@ -1850,14 +1953,8 @@ namespace Game
|
|||||||
var meshCollider = childModel.AddChild<MeshCollider>();
|
var meshCollider = childModel.AddChild<MeshCollider>();
|
||||||
meshCollider.CollisionData = collisionData;
|
meshCollider.CollisionData = collisionData;
|
||||||
}
|
}
|
||||||
}
|
sw.Stop();
|
||||||
catch (Exception e)
|
Console.Print("Pass 3: collision: " + sw.Elapsed.TotalMilliseconds + "ms");
|
||||||
{
|
|
||||||
Console.Print("Failed to hull brush " + brushIndex.ToString() + ": " + e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
brushIndex++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
32
Source/GoakeTestsTarget.Build.cs
Normal file
32
Source/GoakeTestsTarget.Build.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using Flax.Build;
|
||||||
|
|
||||||
|
public class GoakeTestsTarget : Target
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public GoakeTestsTarget()
|
||||||
|
{
|
||||||
|
Name = ProjectName = OutputName = "GoakeTests";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
base.Init();
|
||||||
|
|
||||||
|
IsPreBuilt = false;
|
||||||
|
Type = TargetType.DotNet;
|
||||||
|
OutputType = TargetOutputType.Library;
|
||||||
|
/*Platforms = new[]
|
||||||
|
{
|
||||||
|
Flax.Build.Platform.BuildPlatform.Target,
|
||||||
|
};
|
||||||
|
Configurations = new[]
|
||||||
|
{
|
||||||
|
TargetConfiguration.Debug,
|
||||||
|
TargetConfiguration.Release,
|
||||||
|
};*/
|
||||||
|
|
||||||
|
CustomExternalProjectFilePath = System.IO.Path.Combine("Tests/GoakeTests.csproj");
|
||||||
|
}
|
||||||
|
}
|
||||||
43
Tests/Cabrito/ConsoleTests.cs
Normal file
43
Tests/Cabrito/ConsoleTests.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
using Cabrito;
|
||||||
|
using Console = Cabrito.Console;
|
||||||
|
|
||||||
|
namespace GoakeTests.ConsoleTests
|
||||||
|
{
|
||||||
|
public class ConsoleTests
|
||||||
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
Console.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void CleanUp()
|
||||||
|
{
|
||||||
|
Console.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test1()
|
||||||
|
{
|
||||||
|
string testPrint = "Hello world!";
|
||||||
|
|
||||||
|
Console.OnPrint += delegate(string s) { Assert.True(s == testPrint); };
|
||||||
|
|
||||||
|
Console.Print(testPrint);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test2()
|
||||||
|
{
|
||||||
|
string testPrint = "Hello world2!";
|
||||||
|
|
||||||
|
Console.OnPrint += delegate(string s) { Assert.True(s == testPrint); };
|
||||||
|
|
||||||
|
Console.Print(testPrint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Tests/GoakeTests.csproj
Normal file
20
Tests/GoakeTests.csproj
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
|
||||||
|
<TargetFrameworks>net452;net462;net472;net48;net5.0;net5.0-windows;net6.0</TargetFrameworks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
|
||||||
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Source\Game.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
74
Tests/MapParser/MapParserTests.cs
Normal file
74
Tests/MapParser/MapParserTests.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Cabrito;
|
||||||
|
using FlaxEngine;
|
||||||
|
using Game;
|
||||||
|
|
||||||
|
namespace GoakeTests.MapParser
|
||||||
|
{
|
||||||
|
public class MapParserTests
|
||||||
|
{
|
||||||
|
private byte[] aerowalkBytes;
|
||||||
|
private MapEntity aerowalkRoot;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
aerowalkBytes = File.ReadAllBytes(@"C:\dev\Goake\maps\aerowalk\aerowalk.map");
|
||||||
|
aerowalkRoot = Game.MapParser.Parse(aerowalkBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void CleanUp()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Perf_LoadAerowalk()
|
||||||
|
{
|
||||||
|
List<Game.MapEntity> mapEntities = new List<Game.MapEntity>(100);
|
||||||
|
|
||||||
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
var root = Game.MapParser.Parse(aerowalkBytes);
|
||||||
|
mapEntities.Add(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
|
||||||
|
var elapsedMs = sw.Elapsed.TotalMilliseconds;
|
||||||
|
TestContext.Out.WriteLine("Map parsing time: " + elapsedMs/100 + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Perf_TriangulateAerowalk()
|
||||||
|
{
|
||||||
|
// warmup?
|
||||||
|
//var roott = Game.MapParser.Parse(aerowalkBytes);
|
||||||
|
|
||||||
|
List<Game.MapEntity> mapEntities = new List<Game.MapEntity>(100);
|
||||||
|
|
||||||
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
for (int i = 0; i < 1; i++)
|
||||||
|
{
|
||||||
|
foreach (var ent in aerowalkRoot.entities)
|
||||||
|
foreach (var brush in ent.brushes)
|
||||||
|
{
|
||||||
|
Q3MapImporter.TriangulateBrush3(brush, out Vector3[] verts);
|
||||||
|
Assert.IsTrue(verts.Length > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
|
||||||
|
var elapsedMs = sw.Elapsed.TotalMilliseconds;
|
||||||
|
TestContext.Out.WriteLine("Triangulation time: " + elapsedMs + "ms");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
lore.md
Normal file
19
lore.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
- overall tone should be fantasy-like (medieval) with hints of future/alien technology
|
||||||
|
- (year 4xxx in the future,) earth is dead, humankind is mostly dead, only ruins are left of the civilization
|
||||||
|
- previously technologically advanced civilization died thousands years ago
|
||||||
|
-
|
||||||
|
- goat-like humanoid creatures are waking up from deep sleep around the earth
|
||||||
|
|
||||||
|
- levels a mix of future and historical architecture (imagine ancients depicted artifacts but clearly technological in nature)
|
||||||
|
- old stone ruins mixed with a sparkle of futuristic tech
|
||||||
|
- crashed space ships with mostly futuristic texturing and materials
|
||||||
|
-
|
||||||
|
|
||||||
|
- weapons
|
||||||
|
- rocket launcher: technologically infused glove with engraved rune writing on it, basically a fireball thrower. possibly something everyone is carrying already but lacks power/ammo which can be found in the levels.
|
||||||
|
- nailgun: a homage to quake's super nailgun, looks like it was built in current day (early 2000) technology. has a heating element which can provide more punch to the nails making them more lethal (basic nailgun = starter weapon, ammo promotes it to super nailgun).
|
||||||
|
- crossbow: ancient looking crossbow capable of firing huge bolts that can be used to gain leverage around the levels, has a slot for a power crystal (battery) but is missing one or has a depleted one. adding power to this would increase the damage by tenfold, making it capable of instagibbing targets.
|
||||||
|
- shotgun: very powerful and inaccurate shotgun which shoots shrapnel that can ricochet from walls and still hit the target. possibly homage to flak cannon in unreal series. packs enough punch to even push the player backwards while in mid-air.
|
||||||
|
- lightning gun: ?
|
||||||
|
- melee weapon: can be almost anything from swords to hammers to laser sword and tasers. no pummel. can push back the player a bit when hitting floor or walls.
|
||||||
|
-
|
||||||
Reference in New Issue
Block a user