diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4bb615d6f..7a8a02626 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,3 +32,7 @@ jobs: Binaries/Tests/Linux/x64/Development/FlaxTests mono Source/Platforms/DotNet/NUnit/nunit3-console.exe Binaries/Tools/FlaxEngine.Tests.dll --framework=mono-4.0 mono Source/Platforms/DotNet/NUnit/nunit3-console.exe Binaries/Tools/Flax.Build.Tests.dll --framework=mono-4.0 + - name: Test UseLargeWorlds + run: | + ./Development/Scripts/Linux/CallBuildTool.sh -build -log -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true + Binaries/Tests/Linux/x64/Development/FlaxTests diff --git a/Flax.flaxproj b/Flax.flaxproj index d3c343532..79711dbe4 100644 --- a/Flax.flaxproj +++ b/Flax.flaxproj @@ -8,5 +8,8 @@ "Company": "Flax", "Copyright": "Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.", "GameTarget": "FlaxGame", - "EditorTarget": "FlaxEditor" + "EditorTarget": "FlaxEditor", + "Configuration": { + "UseLargeWorlds": false + } } \ No newline at end of file diff --git a/Source/Engine/Core/Math/Vector2.h b/Source/Engine/Core/Math/Vector2.h index a78c05643..e7201d80b 100644 --- a/Source/Engine/Core/Math/Vector2.h +++ b/Source/Engine/Core/Math/Vector2.h @@ -665,3 +665,30 @@ struct TIsPODType }; DEFINE_DEFAULT_FORMATTING(Int2, "X:{0} Y:{1}", v.X, v.Y); + +#if !defined(_MSC_VER) || defined(__clang__) +// Forward specializations for Clang +template<> FLAXENGINE_API const Float2 Float2::Zero; +template<> FLAXENGINE_API const Float2 Float2::One; +template<> FLAXENGINE_API const Float2 Float2::UnitX; +template<> FLAXENGINE_API const Float2 Float2::UnitY; +template<> FLAXENGINE_API const Float2 Float2::Minimum; +template<> FLAXENGINE_API const Float2 Float2::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Float2::TypeInitializer; + +template<> FLAXENGINE_API const Double2 Double2::Zero; +template<> FLAXENGINE_API const Double2 Double2::One; +template<> FLAXENGINE_API const Double2 Double2::UnitX; +template<> FLAXENGINE_API const Double2 Double2::UnitY; +template<> FLAXENGINE_API const Double2 Double2::Minimum; +template<> FLAXENGINE_API const Double2 Double2::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Double2::TypeInitializer; + +template<> FLAXENGINE_API const Int2 Int2::Zero; +template<> FLAXENGINE_API const Int2 Int2::One; +template<> FLAXENGINE_API const Int2 Int2::UnitX; +template<> FLAXENGINE_API const Int2 Int2::UnitY; +template<> FLAXENGINE_API const Int2 Int2::Minimum; +template<> FLAXENGINE_API const Int2 Int2::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Int2::TypeInitializer; +#endif diff --git a/Source/Engine/Core/Math/Vector3.h b/Source/Engine/Core/Math/Vector3.h index 205a3dcb1..b87552133 100644 --- a/Source/Engine/Core/Math/Vector3.h +++ b/Source/Engine/Core/Math/Vector3.h @@ -932,3 +932,54 @@ struct TIsPODType }; DEFINE_DEFAULT_FORMATTING(Int3, "X:{0} Y:{1} Z:{2}", v.X, v.Y, v.Z); + +#if !defined(_MSC_VER) || defined(__clang__) +// Forward specializations for Clang +template<> FLAXENGINE_API const Float3 Float3::Zero; +template<> FLAXENGINE_API const Float3 Float3::One; +template<> FLAXENGINE_API const Float3 Float3::Half; +template<> FLAXENGINE_API const Float3 Float3::UnitX; +template<> FLAXENGINE_API const Float3 Float3::UnitY; +template<> FLAXENGINE_API const Float3 Float3::UnitZ; +template<> FLAXENGINE_API const Float3 Float3::Up; +template<> FLAXENGINE_API const Float3 Float3::Down; +template<> FLAXENGINE_API const Float3 Float3::Left; +template<> FLAXENGINE_API const Float3 Float3::Right; +template<> FLAXENGINE_API const Float3 Float3::Forward; +template<> FLAXENGINE_API const Float3 Float3::Backward; +template<> FLAXENGINE_API const Float3 Float3::Minimum; +template<> FLAXENGINE_API const Float3 Float3::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Float3::TypeInitializer; + +template<> FLAXENGINE_API const Double3 Double3::Zero; +template<> FLAXENGINE_API const Double3 Double3::One; +template<> FLAXENGINE_API const Double3 Double3::Half; +template<> FLAXENGINE_API const Double3 Double3::UnitX; +template<> FLAXENGINE_API const Double3 Double3::UnitY; +template<> FLAXENGINE_API const Double3 Double3::UnitZ; +template<> FLAXENGINE_API const Double3 Double3::Up; +template<> FLAXENGINE_API const Double3 Double3::Down; +template<> FLAXENGINE_API const Double3 Double3::Left; +template<> FLAXENGINE_API const Double3 Double3::Right; +template<> FLAXENGINE_API const Double3 Double3::Forward; +template<> FLAXENGINE_API const Double3 Double3::Backward; +template<> FLAXENGINE_API const Double3 Double3::Minimum; +template<> FLAXENGINE_API const Double3 Double3::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Double3::TypeInitializer; + +template<> FLAXENGINE_API const Int3 Int3::Zero; +template<> FLAXENGINE_API const Int3 Int3::One; +template<> FLAXENGINE_API const Int3 Int3::Half; +template<> FLAXENGINE_API const Int3 Int3::UnitX; +template<> FLAXENGINE_API const Int3 Int3::UnitY; +template<> FLAXENGINE_API const Int3 Int3::UnitZ; +template<> FLAXENGINE_API const Int3 Int3::Up; +template<> FLAXENGINE_API const Int3 Int3::Down; +template<> FLAXENGINE_API const Int3 Int3::Left; +template<> FLAXENGINE_API const Int3 Int3::Right; +template<> FLAXENGINE_API const Int3 Int3::Forward; +template<> FLAXENGINE_API const Int3 Int3::Backward; +template<> FLAXENGINE_API const Int3 Int3::Minimum; +template<> FLAXENGINE_API const Int3 Int3::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Int3::TypeInitializer; +#endif diff --git a/Source/Engine/Core/Math/Vector4.h b/Source/Engine/Core/Math/Vector4.h index 2de93466a..7c87b6d1a 100644 --- a/Source/Engine/Core/Math/Vector4.h +++ b/Source/Engine/Core/Math/Vector4.h @@ -581,3 +581,36 @@ struct TIsPODType }; DEFINE_DEFAULT_FORMATTING(Int4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W); + +#if !defined(_MSC_VER) || defined(__clang__) +// Forward specializations for Clang +template<> FLAXENGINE_API const Float4 Float4::Zero; +template<> FLAXENGINE_API const Float4 Float4::One; +template<> FLAXENGINE_API const Float4 Float4::UnitX; +template<> FLAXENGINE_API const Float4 Float4::UnitY; +template<> FLAXENGINE_API const Float4 Float4::UnitZ; +template<> FLAXENGINE_API const Float4 Float4::UnitW; +template<> FLAXENGINE_API const Float4 Float4::Minimum; +template<> FLAXENGINE_API const Float4 Float4::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Float4::TypeInitializer; + +template<> FLAXENGINE_API const Double4 Double4::Zero; +template<> FLAXENGINE_API const Double4 Double4::One; +template<> FLAXENGINE_API const Double4 Double4::UnitX; +template<> FLAXENGINE_API const Double4 Double4::UnitY; +template<> FLAXENGINE_API const Double4 Double4::UnitZ; +template<> FLAXENGINE_API const Double4 Double4::UnitW; +template<> FLAXENGINE_API const Double4 Double4::Minimum; +template<> FLAXENGINE_API const Double4 Double4::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Double4::TypeInitializer; + +template<> FLAXENGINE_API const Int4 Int4::Zero; +template<> FLAXENGINE_API const Int4 Int4::One; +template<> FLAXENGINE_API const Int4 Int4::UnitX; +template<> FLAXENGINE_API const Int4 Int4::UnitY; +template<> FLAXENGINE_API const Int4 Int4::UnitZ; +template<> FLAXENGINE_API const Int4 Int4::UnitW; +template<> FLAXENGINE_API const Int4 Int4::Minimum; +template<> FLAXENGINE_API const Int4 Int4::Maximum; +template<> FLAXENGINE_API ScriptingTypeInitializer Int4::TypeInitializer; +#endif diff --git a/Source/Engine/Core/Types/CommonValue.h b/Source/Engine/Core/Types/CommonValue.h index 790c1f210..1ceebce0b 100644 --- a/Source/Engine/Core/Types/CommonValue.h +++ b/Source/Engine/Core/Types/CommonValue.h @@ -632,7 +632,7 @@ public: /// Gets value as Vector4 (if can convert it) /// /// Value - FORCE_INLINE Vector4 GetVector4() const + FORCE_INLINE Float4 GetVector4() const { bool isValid; return GetVector4(isValid); diff --git a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp index b20f23df0..ce67c4405 100644 --- a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp +++ b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp @@ -1999,7 +1999,10 @@ bool PhysicsBackend::ComputeShapesPenetration(void* shapeA, void* shapeB, const auto shapeBPhysX = (PxShape*)shapeB; const PxTransform poseA(C2P(positionA), C2P(orientationA)); const PxTransform poseB(C2P(positionB), C2P(orientationB)); - return PxGeometryQuery::computePenetration(C2P(direction), distance, shapeAPhysX->getGeometry().any(), poseA, shapeBPhysX->getGeometry().any(), poseB); + PxVec3 dir = C2P(direction); + const bool result = PxGeometryQuery::computePenetration(dir, distance, shapeAPhysX->getGeometry().any(), poseA, shapeBPhysX->getGeometry().any(), poseB); + direction = P2C(dir); + return result; } float PhysicsBackend::ComputeShapeSqrDistanceToPoint(void* shape, const Vector3& position, const Quaternion& orientation, const Vector3& point, Vector3* closestPoint) @@ -2063,7 +2066,12 @@ void PhysicsBackend::GetJointForce(void* joint, Vector3& linear, Vector3& angula { auto jointPhysX = (PxJoint*)joint; if (jointPhysX->getConstraint()) - jointPhysX->getConstraint()->getForce(*(PxVec3*)&linear, *(PxVec3*)&angular); + { + PxVec3 linearPhysX = C2P(linear), angularPhysX = C2P(angular); + jointPhysX->getConstraint()->getForce(linearPhysX, angularPhysX); + linear = P2C(linearPhysX); + angular = P2C(angularPhysX); + } } void* PhysicsBackend::CreateFixedJoint(const PhysicsJointDesc& desc) diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index 45bac78f2..4eee9ee84 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -784,11 +784,11 @@ namespace { // Hack for Vector2/3/4 which alias with Float2/3/4 or Double2/3/4 (depending on USE_LARGE_WORLDS) const auto& stdTypes = *StdTypesContainer::Instance(); - if (monoClass == stdTypes.Vector2Class->GetNative() && type.Type == VariantType::Float2 || type.Type == VariantType::Double2) + if (monoClass == stdTypes.Vector2Class->GetNative() && (type.Type == VariantType::Float2 || type.Type == VariantType::Double2)) return true; - if (monoClass == stdTypes.Vector3Class->GetNative() && type.Type == VariantType::Float3 || type.Type == VariantType::Double3) + if (monoClass == stdTypes.Vector3Class->GetNative() && (type.Type == VariantType::Float3 || type.Type == VariantType::Double3)) return true; - if (monoClass == stdTypes.Vector4Class->GetNative() && type.Type == VariantType::Float4 || type.Type == VariantType::Double4) + if (monoClass == stdTypes.Vector4Class->GetNative() && (type.Type == VariantType::Float4 || type.Type == VariantType::Double4)) return true; return false; diff --git a/Source/Platforms/PS4 b/Source/Platforms/PS4 new file mode 160000 index 000000000..e32393633 --- /dev/null +++ b/Source/Platforms/PS4 @@ -0,0 +1 @@ +Subproject commit e32393633bb204803f177a197e3d5751919ce010 diff --git a/Source/Platforms/PS5 b/Source/Platforms/PS5 new file mode 160000 index 000000000..3cd9b6ec9 --- /dev/null +++ b/Source/Platforms/PS5 @@ -0,0 +1 @@ +Subproject commit 3cd9b6ec922a3fcc6b1e109a7c3c6369cdf301b7 diff --git a/Source/Platforms/Switch b/Source/Platforms/Switch new file mode 160000 index 000000000..48a35afd9 --- /dev/null +++ b/Source/Platforms/Switch @@ -0,0 +1 @@ +Subproject commit 48a35afd945f38e19bc7aa18412ad113f92dfdd3 diff --git a/Source/Shaders/GI/DDGI.hlsl b/Source/Shaders/GI/DDGI.hlsl index c40e414f3..a02ebff7d 100644 --- a/Source/Shaders/GI/DDGI.hlsl +++ b/Source/Shaders/GI/DDGI.hlsl @@ -146,7 +146,7 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D probesState, Textur float3 biasedWorldPosition = worldPosition + surfaceBias; // Get the grid coordinates of the probe nearest the biased world position - uint3 baseProbeCoords = clamp(uint3((worldPosition - probesOrigin + probesExtent) / probesSpacing), 0, data.ProbesCounts - 1); + uint3 baseProbeCoords = clamp(uint3((worldPosition - probesOrigin + probesExtent) / probesSpacing), uint3(0, 0, 0), data.ProbesCounts - uint3(1, 1, 1)); float3 baseProbeWorldPosition = GetDDGIProbeWorldPosition(data, cascadeIndex, baseProbeCoords); float3 biasAlpha = saturate((biasedWorldPosition - baseProbeWorldPosition) / probesSpacing); @@ -155,7 +155,7 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D probesState, Textur for (uint i = 0; i < 8; i++) { uint3 probeCoordsOffset = uint3(i, i >> 1, i >> 2) & 1; - uint3 probeCoords = clamp(baseProbeCoords + probeCoordsOffset, 0, data.ProbesCounts - 1); + uint3 probeCoords = clamp(baseProbeCoords + probeCoordsOffset, uint3(0, 0, 0), data.ProbesCounts - uint3(1, 1, 1)); uint probeIndex = GetDDGIScrollingProbeIndex(data, cascadeIndex, probeCoords); // Load probe position and state diff --git a/Source/Tools/Flax.Build/Bindings/ApiTypeInfo.cs b/Source/Tools/Flax.Build/Bindings/ApiTypeInfo.cs index e8c37b689..b09d63f09 100644 --- a/Source/Tools/Flax.Build/Bindings/ApiTypeInfo.cs +++ b/Source/Tools/Flax.Build/Bindings/ApiTypeInfo.cs @@ -22,6 +22,7 @@ namespace Flax.Build.Bindings public bool IsInBuild; public bool IsDeprecated; internal bool IsInited; + internal TypedefInfo Instigator; public virtual bool IsClass => false; public virtual bool IsStruct => false; diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 64a8ce9c2..2908695e0 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -75,6 +75,11 @@ namespace Flax.Build.Bindings "Rectangle", }; + private static bool GenerateCppIsTemplateInstantiationType(ApiTypeInfo typeInfo) + { + return typeInfo.Instigator != null && typeInfo.Instigator.TypeInfo is ClassStructInfo classStructInfo && classStructInfo.IsTemplate; + } + private static string GenerateCppWrapperNativeToVariantMethodName(TypeInfo typeInfo) { var sb = new StringBuilder(); @@ -1786,6 +1791,8 @@ namespace Flax.Build.Bindings var interfacesTable = GenerateCppInterfaceInheritanceTable(buildData, contents, moduleInfo, classInfo, classTypeNameNative); // Type initializer + if (GenerateCppIsTemplateInstantiationType(classInfo)) + contents.Append("template<> "); contents.Append($"ScriptingTypeInitializer {classTypeNameNative}::TypeInitializer((BinaryModule*)GetBinaryModule{moduleInfo.Name}(), "); contents.Append($"StringAnsiView(\"{classTypeNameManaged}\", {classTypeNameManaged.Length}), "); contents.Append($"sizeof({classTypeNameNative}), "); @@ -2010,6 +2017,8 @@ namespace Flax.Build.Bindings contents.Append('}').Append(';').AppendLine(); contents.AppendLine(); + if (GenerateCppIsTemplateInstantiationType(structureInfo)) + contents.Append("template<> "); contents.Append($"ScriptingTypeInitializer {structureTypeNameNative}::TypeInitializer((BinaryModule*)GetBinaryModule{moduleInfo.Name}(), "); contents.Append($"StringAnsiView(\"{structureTypeNameManaged}\", {structureTypeNameManaged.Length}), "); contents.Append($"sizeof({structureTypeNameNative}), "); diff --git a/Source/Tools/Flax.Build/Bindings/TypedefInfo.cs b/Source/Tools/Flax.Build/Bindings/TypedefInfo.cs index dffeec618..f664264c1 100644 --- a/Source/Tools/Flax.Build/Bindings/TypedefInfo.cs +++ b/Source/Tools/Flax.Build/Bindings/TypedefInfo.cs @@ -12,6 +12,7 @@ namespace Flax.Build.Bindings { public bool IsAlias; public TypeInfo Type; + public ApiTypeInfo TypeInfo; // Cached info of Type public ApiTypeInfo Typedef; // Guards to prevent looped initialization for typedefs that are recursive @@ -48,6 +49,7 @@ namespace Flax.Build.Bindings if (apiTypeInfo == null) throw new Exception(string.Format("Unknown type '{0}' for typedef '{1}'.", Type, Name)); apiTypeInfo.EnsureInited(buildData); + TypeInfo = apiTypeInfo; // Alias type without introducing any new type if (IsAlias || apiTypeInfo is LangType) @@ -60,6 +62,7 @@ namespace Flax.Build.Bindings { // Duplicate type var typedef = (ApiTypeInfo)apiTypeInfo.Clone(); + typedef.Instigator = this; typedef.NativeName = NativeName ?? Name; typedef.Name = Name; typedef.Namespace = Namespace; diff --git a/Source/Tools/Flax.Build/Build/EngineTarget.cs b/Source/Tools/Flax.Build/Build/EngineTarget.cs index a2c567c8e..55cc856ea 100644 --- a/Source/Tools/Flax.Build/Build/EngineTarget.cs +++ b/Source/Tools/Flax.Build/Build/EngineTarget.cs @@ -15,6 +15,11 @@ namespace Flax.Build { private static Version _engineVersion; + /// + /// Gets the engine project. + /// + public static ProjectInfo EngineProject => ProjectInfo.Load(Path.Combine(Globals.EngineRoot, "Flax.flaxproj")); + /// /// Gets the engine version. /// @@ -24,7 +29,7 @@ namespace Flax.Build { if (_engineVersion == null) { - _engineVersion = ProjectInfo.Load(Path.Combine(Globals.EngineRoot, "Flax.flaxproj")).Version; + _engineVersion = EngineProject.Version; Log.Verbose(string.Format("Engine build version: {0}", _engineVersion)); } return _engineVersion; diff --git a/Source/Tools/Flax.Build/CommandLine.cs b/Source/Tools/Flax.Build/CommandLine.cs index 69fc1d615..814d302e3 100644 --- a/Source/Tools/Flax.Build/CommandLine.cs +++ b/Source/Tools/Flax.Build/CommandLine.cs @@ -205,6 +205,26 @@ namespace Flax.Build return options; } + /// + /// Gets the options for the given configuration (key=value pairs). + /// + /// The configuration (key=value pairs). + /// The options. + public static Option[] GetOptions(Dictionary configuration) + { + var options = new Option[configuration.Count]; + int i = 0; + foreach (var e in configuration) + { + options[i] = new Option + { + Name = e.Key, + Value = e.Value, + }; + } + return options; + } + /// /// Parses the specified command line. /// @@ -347,14 +367,45 @@ namespace Flax.Build Configure(GetMembers(obj), obj, commandLine); } + /// + /// Configures the members of the specified object using the command line options. + /// + /// The type. + /// The configuration (key=value pairs). + public static void Configure(Type type, Dictionary configuration) + { + Configure(GetMembers(type), null, configuration); + } + + /// + /// Configures the members of the specified object using the command line options. + /// + /// The object. + /// The configuration (key=value pairs). + public static void Configure(object obj, Dictionary configuration) + { + Configure(GetMembers(obj), obj, configuration); + } + private static void Configure(Dictionary members, object instance, string commandLine) { if (commandLine == null) throw new ArgumentNullException(); - - // Process command line var options = GetOptions(commandLine); + Configure(members, instance, options); + } + + private static void Configure(Dictionary members, object instance, Dictionary configuration) + { + if (configuration == null) + throw new ArgumentNullException(); + var options = GetOptions(configuration); + Configure(members, instance, options); + } + + private static void Configure(Dictionary members, object instance, Option[] options) + { foreach (var e in members) { // Get option from command line diff --git a/Source/Tools/Flax.Build/Program.cs b/Source/Tools/Flax.Build/Program.cs index 7f3ff477e..be9d20470 100644 --- a/Source/Tools/Flax.Build/Program.cs +++ b/Source/Tools/Flax.Build/Program.cs @@ -38,7 +38,6 @@ namespace Flax.Build { // Setup CommandLine.Configure(typeof(Configuration)); - CommandLine.Configure(typeof(EngineConfiguration)); foreach (var option in CommandLine.GetOptions()) { if (option.Name.Length > 1 && option.Name[0] == 'D') @@ -78,6 +77,14 @@ namespace Flax.Build Log.Warning("Missing project file."); } + // Configure engine + { + var engineProject = EngineTarget.EngineProject; + if (engineProject != null && engineProject.Configuration != null && engineProject.Configuration.Count != 0) + CommandLine.Configure(typeof(EngineConfiguration), engineProject.Configuration); + CommandLine.Configure(typeof(EngineConfiguration)); + } + // Use mutex if required if (Configuration.Mutex) { diff --git a/Source/Tools/Flax.Build/ProjectInfo.cs b/Source/Tools/Flax.Build/ProjectInfo.cs index b6941da1e..803f8b5dd 100644 --- a/Source/Tools/Flax.Build/ProjectInfo.cs +++ b/Source/Tools/Flax.Build/ProjectInfo.cs @@ -95,6 +95,11 @@ namespace Flax.Build /// public string EngineNickname; + /// + /// The custom build configuration entries loaded from project file. + /// + public Dictionary Configuration; + /// /// True if project is using C#-only and no native toolsets is required to build and use scripts. ///