Merge remote-tracking branch 'origin/master' into 1.1

# Conflicts:
#	Source/Engine/Navigation/NavMesh.cpp
#	Source/Engine/Navigation/NavMeshBuilder.cpp
This commit is contained in:
Wojtek Figat
2021-01-22 11:31:22 +01:00
178 changed files with 1163 additions and 864 deletions

View File

@@ -1489,11 +1489,11 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
case 2:
value = transitionsData.Position / transitionsData.Length;
break;
// Reaming Time
// Remaining Time
case 3:
value = transitionsData.Length - transitionsData.Position;
break;
// Reaming Normalized Time
// Remaining Normalized Time
case 4:
value = 1.0f - (transitionsData.Position / transitionsData.Length);
break;

View File

@@ -199,7 +199,7 @@ public:
/// Gets the current state of the audio playback (playing/paused/stopped).
/// </summary>
/// <returns>The value.</returns>
API_PROPERTY() FORCE_INLINE States GetState() const
API_PROPERTY() FORCE_INLINE AudioSource::States GetState() const
{
return _state;
}

View File

@@ -22,7 +22,7 @@ bool CSG::Mesh::Triangulate(RawData& data, Array<RawModelVertex>& cacheVB) const
Array<RawModelVertex> surfaceCacheVB(32);
// Cache submeshes by material to lay them down
// key- brush index, value- direcotry for surafecs (key: surface index, value: list with start vertex per triangle)
// key- brush index, value- direcotry for surfaces (key: surface index, value: list with start vertex per triangle)
Dictionary<int32, Dictionary<int32, Array<int32>>> polygonsPerBrush(64);
// Build index buffer
@@ -115,8 +115,8 @@ bool CSG::Mesh::Triangulate(RawData& data, Array<RawModelVertex>& cacheVB) const
tangent.Normalize();
// Gram-Schmidt orthogonalize
Vector3 newTangentUnormalized = tangent - normal * Vector3::Dot(normal, tangent);
const float length = newTangentUnormalized.Length();
Vector3 newTangentUnnormalized = tangent - normal * Vector3::Dot(normal, tangent);
const float length = newTangentUnnormalized.Length();
// Workaround to handle degenerated case
if (Math::IsZero(length))
@@ -129,7 +129,7 @@ bool CSG::Mesh::Triangulate(RawData& data, Array<RawModelVertex>& cacheVB) const
}
else
{
tangent = newTangentUnormalized / length;
tangent = newTangentUnnormalized / length;
bitangent.Normalize();
}
@@ -217,12 +217,12 @@ bool CSG::Mesh::Triangulate(RawData& data, Array<RawModelVertex>& cacheVB) const
auto& vertex = cacheVB[triangleStartVertex + k];
Vector3 projected = Vector3::Project(vertex.Position, 0, 0, 1000, 1000, 0, 1, vp);
Vector2 projectecXY = Vector2(projected);
Vector2 projectedXY = Vector2(projected);
min = Vector2::Min(projectecXY, min);
max = Vector2::Max(projectecXY, max);
min = Vector2::Min(projectedXY, min);
max = Vector2::Max(projectedXY, max);
pointsCache.Add(projectecXY);
pointsCache.Add(projectedXY);
}
}

View File

@@ -38,7 +38,7 @@ void CSG::Mesh::PerformOperation(Mesh* other)
{
case Mode::Additive:
{
// Check if both meshes do not intesect
// Check if both meshes do not intersect
if (AABB::IsOutside(_bounds, other->GetBounds())) // TODO: test every sub bounds not whole _bounds
{
// Add vertices to the mesh without any additional calculations
@@ -57,7 +57,7 @@ void CSG::Mesh::PerformOperation(Mesh* other)
case Mode::Subtractive:
{
// Check if both meshes do not intesect
// Check if both meshes do not intersect
if (AABB::IsOutside(_bounds, other->GetBounds())) // TODO: test every sub bounds not whole _bounds
{
// Do nothing
@@ -141,7 +141,7 @@ void CSG::Mesh::intersect(const Mesh* other, PolygonOperation insideOp, PolygonO
// insideOp - operation for polygons being inside the other brush
// outsideOp - operation for polygons being outside the other brush
// Prevent from redudant action
// Prevent from redundant action
if (insideOp == Keep && outsideOp == Keep)
return;
@@ -180,7 +180,7 @@ void CSG::Mesh::intersectSubMesh(const Mesh* other, int32 subMeshIndex, PolygonO
int32 startBrushSurface = brushMeta.StartSurfaceIndex;
int32 endBrushSurface = startBrushSurface + brushMeta.SurfacesCount;
// Check every polygon (itereate fron end since we can ass new polygons and we don't want to process them)
// Check every polygon (iterate from end since we can ass new polygons and we don't want to process them)
for (int32 i = _polygons.Count() - 1; i >= 0; i--)
{
auto& polygon = _polygons[i];

View File

@@ -53,7 +53,7 @@ public:
ScopeLock lock(Locker);
const int32 prevCount = MaterialSlots.Count();
MaterialSlots.Resize(slotsCount);
MaterialSlots.Resize(slotsCount, false);
// Initialize slot names
for (int32 i = prevCount; i < slotsCount; i++)

View File

@@ -208,7 +208,7 @@ void ContentLoadingManagerService::Dispose()
MainThread = nullptr;
ThisThread = nullptr;
// Cancel all reaming tasks (no chance to execute them)
// Cancel all remaining tasks (no chance to execute them)
Tasks.CancelAll();
}

View File

@@ -240,7 +240,7 @@ float IESLoader::ExtractInR16(Array<byte>& output)
float result = 0.0f;
for (uint32 i = 0; i < hAnglesCount; i++)
result += InterpolateBilinear(static_cast<float>(i), v);
*out++ = ConvertFloatToHalf(invMaxValue * result / (float)hAnglesCount);
*out++ = Float16Compressor::Compress(invMaxValue * result / (float)hAnglesCount);
}
}

View File

@@ -76,7 +76,7 @@ ExportAssetResult AssetExporters::ExportModel(ExportAssetContext& context)
for (uint32 i = 0; i < vertices; i++)
{
auto v = vb1[i].TexCoord;
output->WriteTextFormatted("vt {0} {1}\n", ConvertHalfToFloat(v.X), ConvertHalfToFloat(v.Y));
output->WriteTextFormatted("vt {0} {1}\n", Float16Compressor::Decompress(v.X), Float16Compressor::Decompress(v.Y));
}
output->WriteChar('\n');
@@ -181,7 +181,7 @@ ExportAssetResult AssetExporters::ExportSkinnedModel(ExportAssetContext& context
for (uint32 i = 0; i < vertices; i++)
{
auto v = vb0[i].TexCoord;
output->WriteTextFormatted("vt {0} {1}\n", ConvertHalfToFloat(v.X), ConvertHalfToFloat(v.Y));
output->WriteTextFormatted("vt {0} {1}\n", Float16Compressor::Decompress(v.X), Float16Compressor::Decompress(v.Y));
}
output->WriteChar('\n');

View File

@@ -51,18 +51,18 @@ bool Log::Logger::Init()
{
// Check if there are any files to delete
const int32 maxLogFiles = 20;
int32 reaming = oldLogs.Count() - maxLogFiles + 1;
if (reaming > 0)
int32 remaining = oldLogs.Count() - maxLogFiles + 1;
if (remaining > 0)
{
Sorting::QuickSort(oldLogs.Get(), oldLogs.Count());
// Delete the oldest logs
int32 i = 0;
while (reaming > 0)
while (remaining > 0)
{
FileSystem::DeleteFile(oldLogs[i++]);
filesDeleted++;
reaming--;
remaining--;
}
}
}

View File

@@ -8,7 +8,7 @@
/// <summary>
/// Integer axis aligned bounding box
/// </summary>
struct AABB
struct FLAXENGINE_API AABB
{
public:

View File

@@ -10,7 +10,7 @@
/// <summary>
/// Defines a frustum which can be used in frustum culling, zoom to Extents (zoom to fit) operations, (matrix, frustum, camera) interchange, and many kind of intersection testing.
/// </summary>
API_STRUCT(InBuild) struct BoundingFrustum
API_STRUCT(InBuild) struct FLAXENGINE_API BoundingFrustum
{
private:

View File

@@ -280,7 +280,7 @@ namespace FlaxEngine
/// </summary>
/// <param name="hexString">The hexadecimal string.</param>
/// <param name="value">Output value.</param>
/// <returns>True if value has benn parsed, otherwise false.</returns>
/// <returns>True if value has been parsed, otherwise false.</returns>
public static bool TryParseHex(string hexString, out Color value)
{
value = Black;

View File

@@ -18,81 +18,81 @@ Half4 Half4::Zero(0, 0, 0, 0);
Half2::Half2(const Vector2& v)
{
X = ConvertFloatToHalf(v.X);
Y = ConvertFloatToHalf(v.Y);
X = Float16Compressor::Compress(v.X);
Y = Float16Compressor::Compress(v.Y);
}
Vector2 Half2::ToVector2() const
{
return Vector2(
ConvertHalfToFloat(X),
ConvertHalfToFloat(Y)
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y)
);
}
Half3::Half3(const Vector3& v)
{
X = ConvertFloatToHalf(v.X);
Y = ConvertFloatToHalf(v.Y);
Z = ConvertFloatToHalf(v.Z);
X = Float16Compressor::Compress(v.X);
Y = Float16Compressor::Compress(v.Y);
Z = Float16Compressor::Compress(v.Z);
}
Vector3 Half3::ToVector3() const
{
return Vector3(
ConvertHalfToFloat(X),
ConvertHalfToFloat(Y),
ConvertHalfToFloat(Z)
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y),
Float16Compressor::Decompress(Z)
);
}
Half4::Half4(const Vector4& v)
{
X = ConvertFloatToHalf(v.X);
Y = ConvertFloatToHalf(v.Y);
Z = ConvertFloatToHalf(v.Z);
W = ConvertFloatToHalf(v.W);
X = Float16Compressor::Compress(v.X);
Y = Float16Compressor::Compress(v.Y);
Z = Float16Compressor::Compress(v.Z);
W = Float16Compressor::Compress(v.W);
}
Half4::Half4(const Color& c)
{
X = ConvertFloatToHalf(c.R);
Y = ConvertFloatToHalf(c.G);
Z = ConvertFloatToHalf(c.B);
W = ConvertFloatToHalf(c.A);
X = Float16Compressor::Compress(c.R);
Y = Float16Compressor::Compress(c.G);
Z = Float16Compressor::Compress(c.B);
W = Float16Compressor::Compress(c.A);
}
Half4::Half4(const Rectangle& rect)
{
X = ConvertFloatToHalf(rect.Location.X);
Y = ConvertFloatToHalf(rect.Location.Y);
Z = ConvertFloatToHalf(rect.Size.X);
W = ConvertFloatToHalf(rect.Size.Y);
X = Float16Compressor::Compress(rect.Location.X);
Y = Float16Compressor::Compress(rect.Location.Y);
Z = Float16Compressor::Compress(rect.Size.X);
W = Float16Compressor::Compress(rect.Size.Y);
}
Vector2 Half4::ToVector2() const
{
return Vector2(
ConvertHalfToFloat(X),
ConvertHalfToFloat(Y)
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y)
);
}
Vector3 Half4::ToVector3() const
{
return Vector3(
ConvertHalfToFloat(X),
ConvertHalfToFloat(Y),
ConvertHalfToFloat(Z)
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y),
Float16Compressor::Decompress(Z)
);
}
Vector4 Half4::ToVector4() const
{
return Vector4(
ConvertHalfToFloat(X),
ConvertHalfToFloat(Y),
ConvertHalfToFloat(Z),
ConvertHalfToFloat(W)
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y),
Float16Compressor::Decompress(Z),
Float16Compressor::Decompress(W)
);
}

View File

@@ -11,8 +11,14 @@ typedef uint16 Half;
#define USE_SSE_HALF_CONVERSION 0
class Float16Compressor
/// <summary>
/// Utility for packing/unpacking floating point value from single precision (32 bit) to half precision (16 bit).
/// </summary>
class FLAXENGINE_API Float16Compressor
{
// Reference:
// http://www.cs.cmu.edu/~jinlianw/third_party/float16_compressor.hpp
union Bits
{
float f;
@@ -22,24 +28,19 @@ class Float16Compressor
static const int shift = 13;
static const int shiftSign = 16;
static const int32 infN = 0x7F800000; // flt32 infinity
static const int32 maxN = 0x477FE000; // max flt16 normal as a flt32
static const int32 minN = 0x38800000; // min flt16 normal as a flt32
static const int32 signN = 0x80000000; // flt32 sign bit
static const int32 infC = infN >> shift;
static const int32 nanN = (infC + 1) << shift; // minimum flt16 nan as a flt32
static const int32 maxC = maxN >> shift;
static const int32 minC = minN >> shift;
static const int32 signC = signN >> shiftSign; // flt16 sign bit
static const int32 mulN = 0x52000000; // (1 << 23) / minN
static const int32 mulC = 0x33800000; // minN / (1 << (23 - shift))
static const int32 subC = 0x003FF; // max flt32 subnormal down shifted
static const int32 norC = 0x00400; // min flt32 normal down shifted
static const int32 maxD = infC - maxC - 1;
static const int32 minD = minC - subC - 1;
@@ -48,9 +49,9 @@ public:
static Half Compress(const float value)
{
#if USE_SSE_HALF_CONVERSION
__m128 V1 = _mm_set_ss(value);
__m128i V2 = _mm_cvtps_ph(V1, 0);
return static_cast<Half>(_mm_cvtsi128_si32(V2));
__m128 value1 = _mm_set_ss(value);
__m128i value2 = _mm_cvtps_ph(value1, 0);
return static_cast<Half>(_mm_cvtsi128_si32(value2));
#else
Bits v, s;
v.f = value;
@@ -72,9 +73,9 @@ public:
static float Decompress(const Half value)
{
#if USE_SSE_HALF_CONVERSION
__m128i V1 = _mm_cvtsi32_si128(static_cast<int>(value));
__m128 V2 = _mm_cvtph_ps(V1);
return _mm_cvtss_f32(V2);
__m128i value1 = _mm_cvtsi32_si128(static_cast<int>(value));
__m128 value2 = _mm_cvtph_ps(value1);
return _mm_cvtss_f32(value2);
#else
Bits v;
v.ui = value;
@@ -95,20 +96,10 @@ public:
}
};
inline float ConvertHalfToFloat(const Half value)
{
return Float16Compressor::Decompress(value);
}
inline Half ConvertFloatToHalf(const float value)
{
return Float16Compressor::Compress(value);
}
/// <summary>
/// Defines a two component vector, using half precision floating point coordinates.
/// </summary>
struct Half2
struct FLAXENGINE_API Half2
{
public:
@@ -145,8 +136,8 @@ public:
/// <param name="y">Y component</param>
Half2(float x, float y)
{
X = ConvertFloatToHalf(x);
Y = ConvertFloatToHalf(y);
X = Float16Compressor::Compress(x);
Y = Float16Compressor::Compress(y);
}
/// <summary>
@@ -167,7 +158,7 @@ public:
/// <summary>
/// Defines a three component vector, using half precision floating point coordinates.
/// </summary>
struct Half3
struct FLAXENGINE_API Half3
{
public:
@@ -201,9 +192,9 @@ public:
Half3(const float x, const float y, const float z)
{
X = ConvertFloatToHalf(x);
Y = ConvertFloatToHalf(y);
Z = ConvertFloatToHalf(z);
X = Float16Compressor::Compress(x);
Y = Float16Compressor::Compress(y);
Z = Float16Compressor::Compress(z);
}
Half3(const Vector3& v);
@@ -216,7 +207,7 @@ public:
/// <summary>
/// Defines a four component vector, using half precision floating point coordinates.
/// </summary>
struct Half4
struct FLAXENGINE_API Half4
{
public:
@@ -255,31 +246,27 @@ public:
Half4(const float x, const float y, const float z)
{
X = ConvertFloatToHalf(x);
Y = ConvertFloatToHalf(y);
Z = ConvertFloatToHalf(z);
X = Float16Compressor::Compress(x);
Y = Float16Compressor::Compress(y);
Z = Float16Compressor::Compress(z);
W = 0;
}
Half4(const float x, const float y, const float z, const float w)
{
X = ConvertFloatToHalf(x);
Y = ConvertFloatToHalf(y);
Z = ConvertFloatToHalf(z);
W = ConvertFloatToHalf(w);
X = Float16Compressor::Compress(x);
Y = Float16Compressor::Compress(y);
Z = Float16Compressor::Compress(z);
W = Float16Compressor::Compress(w);
}
explicit Half4(const Vector4& v);
explicit Half4(const Color& c);
explicit Half4(const Rectangle& rect);
public:
Vector2 ToVector2() const;
Vector3 ToVector3() const;
Vector4 ToVector4() const;
};

View File

@@ -0,0 +1,279 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Math.h"
#include "Engine/Core/Formatting.h"
#include "Engine/Core/Templates.h"
struct Vector2;
struct Vector3;
struct Vector4;
/// <summary>
/// Two-components vector (32 bit integer type).
/// </summary>
API_STRUCT(InBuild) struct FLAXENGINE_API Int2
{
public:
union
{
struct
{
// X component
int32 X;
// Y component
int32 Y;
};
// Raw values
int32 Raw[2];
};
public:
// Vector with all components equal 0
static const Int2 Zero;
// Vector with all components equal 1
static const Int2 One;
public:
/// <summary>
/// Empty constructor.
/// </summary>
Int2()
{
}
// Init
// @param xy Value to assign to the all components
Int2(int32 xy)
: X(xy)
, Y(xy)
{
}
// Init
// @param x X component value
// @param y Y component value
Int2(int32 x, int32 y)
: X(x)
, Y(y)
{
}
// Init
// @param v Vector to use X and Y components
explicit Int2(const Vector2& v);
public:
String ToString() const;
public:
// Arithmetic operators with Int2
Int2 operator+(const Int2& b) const
{
return Add(*this, b);
}
Int2 operator-(const Int2& b) const
{
return Subtract(*this, b);
}
Int2 operator*(const Int2& b) const
{
return Multiply(*this, b);
}
Int2 operator/(const Int2& b) const
{
return Divide(*this, b);
}
Int2 operator-() const
{
return Int2(-X, -Y);
}
// op= operators with Int2
Int2& operator+=(const Int2& b)
{
*this = Add(*this, b);
return *this;
}
Int2& operator-=(const Int2& b)
{
*this = Subtract(*this, b);
return *this;
}
Int2& operator*=(const Int2& b)
{
*this = Multiply(*this, b);
return *this;
}
Int2& operator/=(const Int2& b)
{
*this = Divide(*this, b);
return *this;
}
// Arithmetic operators with int32
Int2 operator+(int32 b) const
{
return Add(*this, b);
}
Int2 operator-(int32 b) const
{
return Subtract(*this, b);
}
Int2 operator*(int32 b) const
{
return Multiply(*this, b);
}
Int2 operator/(int32 b) const
{
return Divide(*this, b);
}
// op= operators with int32
Int2& operator+=(int32 b)
{
*this = Add(*this, b);
return *this;
}
Int2& operator-=(int32 b)
{
*this = Subtract(*this, b);
return *this;
}
Int2& operator*=(int32 b)
{
*this = Multiply(*this, b);
return *this;
}
Int2& operator/=(int32 b)
{
*this = Divide(*this, b);
return *this;
}
// Comparison operators
bool operator==(const Int2& b) const
{
return X == b.X && Y == b.Y;
}
bool operator!=(const Int2& b) const
{
return X != b.X || Y != b.Y;
}
bool operator>(const Int2& b) const
{
return X > b.X && Y > b.Y;
}
bool operator>=(const Int2& b) const
{
return X >= b.X && Y >= b.Y;
}
bool operator<(const Int2& b) const
{
return X < b.X && Y < b.Y;
}
bool operator<=(const Int2& b) const
{
return X <= b.X && Y <= b.Y;
}
public:
static void Add(const Int2& a, const Int2& b, Int2* result)
{
result->X = a.X + b.X;
result->Y = a.Y + b.Y;
}
static Int2 Add(const Int2& a, const Int2& b)
{
Int2 result;
Add(a, b, &result);
return result;
}
static void Subtract(const Int2& a, const Int2& b, Int2* result)
{
result->X = a.X - b.X;
result->Y = a.Y - b.Y;
}
static Int2 Subtract(const Int2& a, const Int2& b)
{
Int2 result;
Subtract(a, b, &result);
return result;
}
static Int2 Multiply(const Int2& a, const Int2& b)
{
return Int2(a.X * b.X, a.Y * b.Y);
}
static Int2 Multiply(const Int2& a, int32 b)
{
return Int2(a.X * b, a.Y * b);
}
static Int2 Divide(const Int2& a, const Int2& b)
{
return Int2(a.X / b.X, a.Y / b.Y);
}
static Int2 Divide(const Int2& a, int32 b)
{
return Int2(a.X / b, a.Y / b);
}
// Creates vector from minimum components of two vectors
static Int2 Min(const Int2& a, const Int2& b)
{
return Int2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
}
// Creates vector from maximum components of two vectors
static Int2 Max(const Int2& a, const Int2& b)
{
return Int2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
}
};
template<>
struct TIsPODType<Int2>
{
enum { Value = true };
};
DEFINE_DEFAULT_FORMATTING(Int2, "X:{0} Y:{1}", v.X, v.Y);

View File

@@ -0,0 +1,128 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Math.h"
#include "Engine/Core/Formatting.h"
#include "Engine/Core/Templates.h"
struct Vector2;
struct Vector3;
struct Vector4;
/// <summary>
/// Three-components vector (32 bit integer type).
/// </summary>
API_STRUCT(InBuild) struct FLAXENGINE_API Int3
{
public:
union
{
struct
{
// X component
int32 X;
// Y component
int32 Y;
// Y component
int32 Z;
};
// Raw values
int32 Raw[3];
};
public:
// Vector with all components equal 0
static const Int3 Zero;
// Vector with all components equal 1
static const Int3 One;
public:
/// <summary>
/// Empty constructor.
/// </summary>
Int3()
{
}
// Init
// @param xy Value to assign to the all components
Int3(int32 xyz)
: X(xyz)
, Y(xyz)
, Z(xyz)
{
}
// Init
// @param x X component value
// @param y Y component value
// @param z Z component value
Int3(int32 x, int32 y, int32 z)
: X(x)
, Y(y)
, Z(z)
{
}
// Init
// @param v Vector to use X, Y and Z components
explicit Int3(const Vector3& v);
public:
String ToString() const;
public:
// Returns a vector containing the largest components of the specified vectors
// @param a The first source vector
// @param b The second source vector
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
static Int3 Max(const Int3& a, const Int3& b)
{
return Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z);
}
// Returns a vector containing the smallest components of the specified vectors
// @param a The first source vector
// @param b The second source vector
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
static Int3 Min(const Int3& a, const Int3& b)
{
return Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z);
}
// Returns a vector containing the largest components of the specified vectors
// @param a The first source vector
// @param b The second source vector
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
static void Max(const Int3& a, const Int3& b, Int3* result)
{
*result = Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z);
}
// Returns a vector containing the smallest components of the specified vectors
// @param a The first source vector
// @param b The second source vector
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
static void Min(const Int3& a, const Int3& b, Int3* result)
{
*result = Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z);
}
};
template<>
struct TIsPODType<Int3>
{
enum { Value = true };
};
DEFINE_DEFAULT_FORMATTING(Int3, "X:{0} Y:{1} Z:{2}", v.X, v.Y, v.Z);

View File

@@ -0,0 +1,134 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Math.h"
#include "Engine/Core/Formatting.h"
#include "Engine/Core/Templates.h"
struct Vector2;
struct Vector3;
struct Vector4;
/// <summary>
/// Four-components vector (32 bit integer type).
/// </summary>
API_STRUCT(InBuild) struct FLAXENGINE_API Int4
{
public:
union
{
struct
{
// X component
int32 X;
// Y component
int32 Y;
// Z component
int32 Z;
// W component
int32 W;
};
// Raw values
int32 Raw[4];
};
public:
// Vector with all components equal 0
static const Int4 Zero;
// Vector with all components equal 1
static const Int4 One;
public:
/// <summary>
/// Empty constructor.
/// </summary>
Int4()
{
}
// Init
// @param xy Value to assign to the all components
Int4(int32 xyzw)
: X(xyzw)
, Y(xyzw)
, Z(xyzw)
, W(xyzw)
{
}
// Init
// @param x X component value
// @param y Y component value
// @param z Z component value
// @param w W component value
Int4(int32 x, int32 y, int32 z, int32 w)
: X(x)
, Y(y)
, Z(z)
, W(w)
{
}
// Init
// @param v Vector to use X, Y, Z and W components
explicit Int4(const Vector4& v);
public:
String ToString() const;
public:
/// <summary>
/// Returns average arithmetic of all the components
/// </summary>
/// <returns>Average arithmetic of all the components</returns>
float AverageArithmetic() const
{
return (X + Y + Z + W) * 0.25f;
}
/// <summary>
/// Gets sum of all vector components values
/// </summary>
/// <returns>Sum of X, Y, Z and W</returns>
int32 SumValues() const
{
return X + Y + Z + W;
}
/// <summary>
/// Returns minimum value of all the components
/// </summary>
/// <returns>Minimum value</returns>
int32 MinValue() const
{
return Math::Min(X, Y, Z, W);
}
/// <summary>
/// Returns maximum value of all the components
/// </summary>
/// <returns>Maximum value</returns>
int32 MaxValue() const
{
return Math::Max(X, Y, Z, W);
}
};
template<>
struct TIsPODType<Int4>
{
enum { Value = true };
};
DEFINE_DEFAULT_FORMATTING(Int4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W);

View File

@@ -36,6 +36,11 @@ namespace FlaxEngine
/// </summary>
public const float PiOverFour = (float)(Math.PI / 4);
/// <summary>
/// A value specifying the golden mean
/// </summary>
public const float GoldenRatio = 1.6180339887f;
/// <summary>
/// Returns the absolute value of f.
/// </summary>

View File

@@ -9,7 +9,7 @@
/// <summary>
/// Represents a 3x3 mathematical matrix.
/// </summary>
API_STRUCT(InBuild) struct Matrix3x3
API_STRUCT(InBuild) struct FLAXENGINE_API Matrix3x3
{
public:

View File

@@ -8,7 +8,7 @@
#include "CollisionsHelper.h"
// Oriented Bounding Box (OBB) is a rectangular block, much like an AABB (Bounding Box) but with an arbitrary orientation in 3D space.
API_STRUCT(InBuild) struct OrientedBoundingBox
API_STRUCT(InBuild) struct FLAXENGINE_API OrientedBoundingBox
{
public:

View File

@@ -13,7 +13,7 @@ typedef Half Float16;
/// <summary>
/// Packed vector, layout: R:10 bytes, G:10 bytes, B:10 bytes, A:2 bytes, all values are stored as floats in range [0;1].
/// </summary>
struct Float1010102
struct FLAXENGINE_API Float1010102
{
union
{
@@ -64,7 +64,7 @@ public:
};
// The 3D vector is packed into 32 bits with 11/11/10 bits per floating-point component.
struct FloatR11G11B10
struct FLAXENGINE_API FloatR11G11B10
{
union
{
@@ -118,7 +118,7 @@ public:
Vector3 ToVector3() const;
};
struct RG16UNorm
struct FLAXENGINE_API RG16UNorm
{
uint16 X, Y;
@@ -131,7 +131,7 @@ struct RG16UNorm
Vector2 ToVector2() const;
};
struct RGBA16UNorm
struct FLAXENGINE_API RGBA16UNorm
{
uint16 X, Y, Z, W;

View File

@@ -8,7 +8,7 @@
/// <summary>
/// Represents a plane in three dimensional space.
/// </summary>
API_STRUCT() struct Plane
API_STRUCT() struct FLAXENGINE_API Plane
{
DECLARE_SCRIPTING_TYPE_MINIMAL(Plane);
public:

View File

@@ -11,7 +11,7 @@ struct Viewport;
/// <summary>
/// Represents a three dimensional line based on a point in space and a direction.
/// </summary>
API_STRUCT() struct Ray
API_STRUCT() struct FLAXENGINE_API Ray
{
DECLARE_SCRIPTING_TYPE_MINIMAL(Ray);
public:

View File

@@ -10,7 +10,6 @@
API_STRUCT() struct FLAXENGINE_API Rectangle
{
DECLARE_SCRIPTING_TYPE_MINIMAL(Rectangle);
public:
/// <summary>
/// The empty rectangle.

View File

@@ -11,10 +11,9 @@ struct Matrix;
/// <summary>
/// Describes transformation in a 3D space.
/// </summary>
API_STRUCT() struct Transform
API_STRUCT() struct FLAXENGINE_API Transform
{
DECLARE_SCRIPTING_TYPE_MINIMAL(Transform);
public:
/// <summary>
/// The translation vector of the transform.

View File

@@ -8,7 +8,7 @@
/// <summary>
/// Represents a three dimensional triangle.
/// </summary>
struct Triangle
struct FLAXENGINE_API Triangle
{
public:

View File

@@ -4,8 +4,8 @@
#include "Vector3.h"
#include "Vector4.h"
#include "Color.h"
#include "Int2.h"
#include "../Types/String.h"
#include "VectorInt.h"
static_assert(sizeof(Vector2) == 8, "Invalid Vector2 type size.");

View File

@@ -6,7 +6,7 @@
#include "Color.h"
#include "Quaternion.h"
#include "Matrix.h"
#include "VectorInt.h"
#include "Int3.h"
#include "../Types/String.h"
static_assert(sizeof(Vector3) == 12, "Invalid Vector3 type size.");

View File

@@ -6,7 +6,7 @@
#include "Color.h"
#include "Matrix.h"
#include "Rectangle.h"
#include "VectorInt.h"
#include "Int4.h"
#include "../Types/String.h"
static_assert(sizeof(Vector4) == 16, "Invalid Vector4 type size.");

View File

@@ -2,518 +2,6 @@
#pragma once
#include "Math.h"
#include "Engine/Core/Formatting.h"
#include "Engine/Core/Templates.h"
struct Vector2;
struct Vector3;
struct Vector4;
/// <summary>
/// Two-components vector (32 bit integer type).
/// </summary>
API_STRUCT(InBuild) struct Int2
{
public:
union
{
struct
{
// X component
int32 X;
// Y component
int32 Y;
};
// Raw values
int32 Raw[2];
};
public:
// Vector with all components equal 0
static const Int2 Zero;
// Vector with all components equal 1
static const Int2 One;
public:
/// <summary>
/// Empty constructor.
/// </summary>
Int2()
{
}
// Init
// @param xy Value to assign to the all components
Int2(int32 xy)
: X(xy)
, Y(xy)
{
}
// Init
// @param x X component value
// @param y Y component value
Int2(int32 x, int32 y)
: X(x)
, Y(y)
{
}
// Init
// @param v Vector to use X and Y components
explicit Int2(const Vector2& v);
public:
String ToString() const;
public:
// Arithmetic operators with Int2
Int2 operator+(const Int2& b) const
{
return Add(*this, b);
}
Int2 operator-(const Int2& b) const
{
return Subtract(*this, b);
}
Int2 operator*(const Int2& b) const
{
return Multiply(*this, b);
}
Int2 operator/(const Int2& b) const
{
return Divide(*this, b);
}
Int2 operator-() const
{
return Int2(-X, -Y);
}
// op= operators with Int2
Int2& operator+=(const Int2& b)
{
*this = Add(*this, b);
return *this;
}
Int2& operator-=(const Int2& b)
{
*this = Subtract(*this, b);
return *this;
}
Int2& operator*=(const Int2& b)
{
*this = Multiply(*this, b);
return *this;
}
Int2& operator/=(const Int2& b)
{
*this = Divide(*this, b);
return *this;
}
// Arithmetic operators with int32
Int2 operator+(int32 b) const
{
return Add(*this, b);
}
Int2 operator-(int32 b) const
{
return Subtract(*this, b);
}
Int2 operator*(int32 b) const
{
return Multiply(*this, b);
}
Int2 operator/(int32 b) const
{
return Divide(*this, b);
}
// op= operators with int32
Int2& operator+=(int32 b)
{
*this = Add(*this, b);
return *this;
}
Int2& operator-=(int32 b)
{
*this = Subtract(*this, b);
return *this;
}
Int2& operator*=(int32 b)
{
*this = Multiply(*this, b);
return *this;
}
Int2& operator/=(int32 b)
{
*this = Divide(*this, b);
return *this;
}
// Comparison operators
bool operator==(const Int2& b) const
{
return X == b.X && Y == b.Y;
}
bool operator!=(const Int2& b) const
{
return X != b.X || Y != b.Y;
}
bool operator>(const Int2& b) const
{
return X > b.X && Y > b.Y;
}
bool operator>=(const Int2& b) const
{
return X >= b.X && Y >= b.Y;
}
bool operator<(const Int2& b) const
{
return X < b.X && Y < b.Y;
}
bool operator<=(const Int2& b) const
{
return X <= b.X && Y <= b.Y;
}
public:
static void Add(const Int2& a, const Int2& b, Int2* result)
{
result->X = a.X + b.X;
result->Y = a.Y + b.Y;
}
static Int2 Add(const Int2& a, const Int2& b)
{
Int2 result;
Add(a, b, &result);
return result;
}
static void Subtract(const Int2& a, const Int2& b, Int2* result)
{
result->X = a.X - b.X;
result->Y = a.Y - b.Y;
}
static Int2 Subtract(const Int2& a, const Int2& b)
{
Int2 result;
Subtract(a, b, &result);
return result;
}
static Int2 Multiply(const Int2& a, const Int2& b)
{
return Int2(a.X * b.X, a.Y * b.Y);
}
static Int2 Multiply(const Int2& a, int32 b)
{
return Int2(a.X * b, a.Y * b);
}
static Int2 Divide(const Int2& a, const Int2& b)
{
return Int2(a.X / b.X, a.Y / b.Y);
}
static Int2 Divide(const Int2& a, int32 b)
{
return Int2(a.X / b, a.Y / b);
}
// Creates vector from minimum components of two vectors
static Int2 Min(const Int2& a, const Int2& b)
{
return Int2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
}
// Creates vector from maximum components of two vectors
static Int2 Max(const Int2& a, const Int2& b)
{
return Int2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
}
};
/// <summary>
/// Three-components vector (32 bit integer type).
/// </summary>
API_STRUCT(InBuild) struct Int3
{
public:
union
{
struct
{
// X component
int32 X;
// Y component
int32 Y;
// Y component
int32 Z;
};
// Raw values
int32 Raw[3];
};
public:
// Vector with all components equal 0
static const Int3 Zero;
// Vector with all components equal 1
static const Int3 One;
public:
/// <summary>
/// Empty constructor.
/// </summary>
Int3()
{
}
// Init
// @param xy Value to assign to the all components
Int3(int32 xyz)
: X(xyz)
, Y(xyz)
, Z(xyz)
{
}
// Init
// @param x X component value
// @param y Y component value
// @param z Z component value
Int3(int32 x, int32 y, int32 z)
: X(x)
, Y(y)
, Z(z)
{
}
// Init
// @param v Vector to use X, Y and Z components
explicit Int3(const Vector3& v);
public:
String ToString() const;
public:
// Returns a vector containing the largest components of the specified vectors
// @param a The first source vector
// @param b The second source vector
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
static Int3 Max(const Int3& a, const Int3& b)
{
return Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z);
}
// Returns a vector containing the smallest components of the specified vectors
// @param a The first source vector
// @param b The second source vector
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
static Int3 Min(const Int3& a, const Int3& b)
{
return Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z);
}
// Returns a vector containing the largest components of the specified vectors
// @param a The first source vector
// @param b The second source vector
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
static void Max(const Int3& a, const Int3& b, Int3* result)
{
*result = Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z);
}
// Returns a vector containing the smallest components of the specified vectors
// @param a The first source vector
// @param b The second source vector
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
static void Min(const Int3& a, const Int3& b, Int3* result)
{
*result = Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z);
}
};
/// <summary>
/// Four-components vector (32 bit integer type).
/// </summary>
API_STRUCT(InBuild) struct Int4
{
public:
union
{
struct
{
// X component
int32 X;
// Y component
int32 Y;
// Z component
int32 Z;
// W component
int32 W;
};
// Raw values
int32 Raw[4];
};
public:
// Vector with all components equal 0
static const Int4 Zero;
// Vector with all components equal 1
static const Int4 One;
public:
/// <summary>
/// Empty constructor.
/// </summary>
Int4()
{
}
// Init
// @param xy Value to assign to the all components
Int4(int32 xyzw)
: X(xyzw)
, Y(xyzw)
, Z(xyzw)
, W(xyzw)
{
}
// Init
// @param x X component value
// @param y Y component value
// @param z Z component value
// @param w W component value
Int4(int32 x, int32 y, int32 z, int32 w)
: X(x)
, Y(y)
, Z(z)
, W(w)
{
}
// Init
// @param v Vector to use X, Y, Z and W components
explicit Int4(const Vector4& v);
public:
String ToString() const;
public:
/// <summary>
/// Returns average arithmetic of all the components
/// </summary>
/// <returns>Average arithmetic of all the components</returns>
float AverageArithmetic() const
{
return (X + Y + Z + W) * 0.25f;
}
/// <summary>
/// Gets sum of all vector components values
/// </summary>
/// <returns>Sum of X, Y, Z and W</returns>
int32 SumValues() const
{
return X + Y + Z + W;
}
/// <summary>
/// Returns minimum value of all the components
/// </summary>
/// <returns>Minimum value</returns>
int32 MinValue() const
{
return Math::Min(X, Y, Z, W);
}
/// <summary>
/// Returns maximum value of all the components
/// </summary>
/// <returns>Maximum value</returns>
int32 MaxValue() const
{
return Math::Max(X, Y, Z, W);
}
};
template<>
struct TIsPODType<Int2>
{
enum { Value = true };
};
template<>
struct TIsPODType<Int3>
{
enum { Value = true };
};
template<>
struct TIsPODType<Int4>
{
enum { Value = true };
};
DEFINE_DEFAULT_FORMATTING(Int2, "X:{0} Y:{1}", v.X, v.Y);
DEFINE_DEFAULT_FORMATTING(Int3, "X:{0} Y:{1} Z:{2}", v.X, v.Y, v.Z);
DEFINE_DEFAULT_FORMATTING(Int4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W);
#include "Int2.h"
#include "Int3.h"
#include "Int4.h"

View File

@@ -10,7 +10,7 @@ struct Matrix;
struct Rectangle;
// Describes the viewport dimensions.
API_STRUCT(InBuild) struct Viewport
API_STRUCT(InBuild) struct FLAXENGINE_API Viewport
{
public:

View File

@@ -193,7 +193,7 @@ void ObjectsRemovalServiceService::Dispose()
// Collect new objects
ObjectsRemovalService::Flush();
// Delete all reaming objects
// Delete all remaining objects
{
ScopeLock lock(PoolLocker);
for (auto i = Pool.Begin(); i.IsNotEnd(); ++i)

View File

@@ -2612,7 +2612,8 @@ Variant Variant::Lerp(const Variant& a, const Variant& b, float alpha)
void Variant::AllocStructure()
{
const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(StringAnsiView(Type.TypeName));
const StringAnsiView typeName(Type.TypeName);
const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeName);
if (typeHandle)
{
const ScriptingType& type = typeHandle.GetType();
@@ -2620,8 +2621,26 @@ void Variant::AllocStructure()
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
type.Struct.Ctor(AsBlob.Data);
}
else if (typeName == "System.Byte")
{
// Hack for byte
AsBlob.Length = 1;
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
*((byte*)AsBlob.Data) = 0;
}
else if (typeName == "System.Int16" || typeName == "System.UInt16")
{
// Hack for 16bit int
AsBlob.Length = 2;
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
*((int16*)AsBlob.Data) = 0;
}
else
{
if (typeName.Length() != 0)
{
LOG(Warning, "Missing scripting type \'{0}\'", String(typeName.Get()));
}
AsBlob.Data = nullptr;
AsBlob.Length = 0;
}
@@ -2637,6 +2656,10 @@ void Variant::CopyStructure(void* src)
auto& type = typeHandle.GetType();
type.Struct.Copy(AsBlob.Data, src);
}
else
{
Platform::MemoryCopy(AsBlob.Data, src, AsBlob.Length);
}
}
}

View File

@@ -36,7 +36,7 @@ namespace Log
/// </summary>
/// <param name="additionalInfo">Additional information that help describe error</param>
Exception(const String& additionalInfo)
: Exception(TEXT("An exception has occured."), additionalInfo)
: Exception(TEXT("An exception has occurred."), additionalInfo)
{
}

View File

@@ -468,7 +468,7 @@ void Engine::OnExit()
LOG_FLUSH();
// Kill all reaming threads
// Kill all remaining threads
ThreadRegistry::KillEmAll();
// Cleanup

View File

@@ -985,7 +985,7 @@ API_ENUM() enum class TessellationMethod
enum class ShaderFlags : uint32
{
/// <summary>
/// The default set fo flags.
/// The default set for flags.
/// </summary>
Default = 0,

View File

@@ -215,7 +215,7 @@ public:
/// Gets a CPU pointer to the resource by mapping its contents. Denies the GPU access to that resource.
/// </summary>
/// <param name="mode">The map operation mode.</param>
/// <returns>The pointer ot the mapped CPU buffer with resource data or null if failed.</returns>
/// <returns>The pointer of the mapped CPU buffer with resource data or null if failed.</returns>
API_FUNCTION() virtual void* Map(GPUResourceMapMode mode) = 0;
/// <summary>

View File

@@ -239,7 +239,7 @@ void GPUDevice::preDispose()
SAFE_DELETE_GPU_RESOURCE(_res->FullscreenTriangleVB);
// Release GPU resources memory and unlink from device
// Note: after that noe GPU resources should be used/created, only deleted
// Note: after that no GPU resources should be used/created, only deleted
Resources.OnDeviceDispose();
}

View File

@@ -174,10 +174,10 @@ API_ENUM(Attributes="Flags") enum class FormatSupport : int32
DECLARE_ENUM_OPERATORS(FormatSupport);
// Helper macro to check if given format does not support a given set of feature flags
#define FORMAT_FEATURES_ARE_NOT_SUPPORTED(formatSupport, formatSupportFlags) ((formatSupport & formatSupportFlags) != static_cast<int>(formatSupportFlags))
#define FORMAT_FEATURES_ARE_NOT_SUPPORTED(formatSupport, formatSupportFlags) ((formatSupport & (formatSupportFlags)) != static_cast<int>(formatSupportFlags))
// Helper macro to check if given format does support a given set of feature flags
#define FORMAT_FEATURES_ARE_SUPPORTED(formatSupport, formatSupportFlags) ((formatSupport & formatSupportFlags) == static_cast<int>(formatSupportFlags))
#define FORMAT_FEATURES_ARE_SUPPORTED(formatSupport, formatSupportFlags) ((formatSupport & (formatSupportFlags)) == static_cast<int>(formatSupportFlags))
/// <summary>
/// The features exposed for a particular format.

View File

@@ -39,7 +39,7 @@ Task* GPUSwapChain::DownloadDataAsync(TextureData& result)
{
if (_downloadTask)
{
LOG(Warning, "Can download window backuffer data ony once at the time.");
LOG(Warning, "Can download window backuffer data only once at the time.");
return nullptr;
}

View File

@@ -49,6 +49,9 @@ GraphicsService GraphicsServiceInstance;
void Graphics::DisposeDevice()
{
// Clean any danging pointer to last task (might stay if engine is disposing after crash)
GPUDevice::Instance->CurrentTask = nullptr;
if (GPUDevice::Instance)
{
GPUDevice::Instance->Dispose();

View File

@@ -108,7 +108,7 @@ public:
/// <summary>
/// Gets the mask of render passes supported by this material.
/// </summary>
/// <returns>The drw passes supported by this material.</returns>
/// <returns>The draw passes supported by this material.</returns>
virtual DrawPass GetDrawModes() const
{
return DrawPass::None;

View File

@@ -435,7 +435,7 @@ namespace FlaxEngine
/// Downloads the third vertex buffer that contains mesh vertices data. To download data from GPU set <paramref name="forceGpu"/> to true and call this method from the thread other than main thread (see <see cref="Platform.IsInMainThread"/>).
/// </summary>
/// <remarks>
/// If mesh has no vertex colors (stored in vertex buffer 2) the the returned value is null.
/// If mesh has no vertex colors (stored in vertex buffer 2) the returned value is null.
/// </remarks>
/// <param name="forceGpu">If set to <c>true</c> the data will be downloaded from the GPU, otherwise it can be loaded from the drive (source asset file) or from memory (if cached). Downloading mesh from GPU requires this call to be made from the other thread than main thread. Virtual assets are always downloaded from GPU memory due to lack of dedicated storage container for the asset data.</param>
/// <returns>The gathered data or null if mesh has no vertex colors.</returns>

View File

@@ -791,7 +791,7 @@ void MeshData::ImproveCacheLocality()
Allocator::Free(piCandidates);
const auto endTime = Platform::GetTimeSeconds();
LOG(Info, "Cache relevant optimzie for {0} vertices and {1} indices. Average output ACMR is {2}. Time: {3}s", vertexCount, indexCount, (float)iCacheMisses / indexCount / 3, Utilities::RoundTo2DecimalPlaces(endTime - startTime));
LOG(Info, "Cache relevant optimize for {0} vertices and {1} indices. Average output ACMR is {2}. Time: {3}s", vertexCount, indexCount, (float)iCacheMisses / indexCount / 3, Utilities::RoundTo2DecimalPlaces(endTime - startTime));
}
float MeshData::CalculateTrianglesArea() const

View File

@@ -5,7 +5,7 @@
#include "Engine/Core/Common.h"
#include "Engine/Core/Math/BoundingSphere.h"
#include "Engine/Core/Math/BoundingBox.h"
#include "Engine/Core/Math/VectorInt.h"
#include "Engine/Core/Math/Int4.h"
#include "Engine/Serialization/Stream.h"
#include "Engine/Graphics/Enums.h"
#include "Types.h"

View File

@@ -9,7 +9,7 @@
#include "Engine/Core/Math/Vector4.h"
#include "Engine/Core/Math/Color.h"
#include "Engine/Core/Math/Color32.h"
#include "Engine/Core/Math/VectorInt.h"
#include "Engine/Core/Math/Int4.h"
class Model;
class SkinnedModel;

View File

@@ -387,7 +387,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(ToneMappingSettings);
float WhiteTemperature = 6500.0f;
/// <summary>
/// Adjusts the white balance temperature tint for the scene by adjusting the cyan and magenta color ranges. Ideally, this setting should be used once you've adjusted the white balance temporature to get accurate colors. Under some light temperatures, the colors may appear to be more yellow or blue. This can be used to balance the resulting color to look more natural. The default value is `0`.
/// Adjusts the white balance temperature tint for the scene by adjusting the cyan and magenta color ranges. Ideally, this setting should be used once you've adjusted the white balance temperature to get accurate colors. Under some light temperatures, the colors may appear to be more yellow or blue. This can be used to balance the resulting color to look more natural. The default value is `0`.
/// </summary>
API_FIELD(Attributes="DefaultValue(0.0f), Limit(-1, 1, 0.001f), EditorOrder(1), PostProcessSetting((int)ToneMappingSettingsOverride.WhiteTint)")
float WhiteTint = 0.0f;

View File

@@ -108,5 +108,5 @@ void RenderTargetPool::Release(GPUTexture* rt)
}
}
LOG(Error, "Trying to release temporary render target which has not been registred in service!");
LOG(Error, "Trying to release temporary render target which has not been registered in service!");
}

View File

@@ -97,7 +97,7 @@ public:
/// <summary>
/// Gets the vertex shader.
/// </summary>
/// <param name="name">Thr shader program name.</param>
/// <param name="name">The shader program name.</param>
/// <param name="permutationIndex">The shader permutation index.</param>
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramVS* GetVS(const StringAnsiView& name, int32 permutationIndex = 0) const
@@ -108,7 +108,7 @@ public:
/// <summary>
/// Gets the hull shader.
/// </summary>
/// <param name="name">Thr shader program name.</param>
/// <param name="name">The shader program name.</param>
/// <param name="permutationIndex">The shader permutation index.</param>
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramHS* GetHS(const StringAnsiView& name, int32 permutationIndex = 0) const
@@ -119,7 +119,7 @@ public:
/// <summary>
/// Gets domain shader.
/// </summary>
/// <param name="name">Thr shader program name.</param>
/// <param name="name">The shader program name.</param>
/// <param name="permutationIndex">The shader permutation index.</param>
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramDS* GetDS(const StringAnsiView& name, int32 permutationIndex = 0) const
@@ -130,7 +130,7 @@ public:
/// <summary>
/// Gets the geometry shader.
/// </summary>
/// <param name="name">Thr shader program name.</param>
/// <param name="name">The shader program name.</param>
/// <param name="permutationIndex">The shader permutation index.</param>
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramGS* GetGS(const StringAnsiView& name, int32 permutationIndex = 0) const
@@ -141,7 +141,7 @@ public:
/// <summary>
/// Gets the pixel shader.
/// </summary>
/// <param name="name">Thr shader program name.</param>
/// <param name="name">The shader program name.</param>
/// <param name="permutationIndex">The shader permutation index.</param>
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramPS* GetPS(const StringAnsiView& name, int32 permutationIndex = 0) const
@@ -152,7 +152,7 @@ public:
/// <summary>
/// Gets the compute shader.
/// </summary>
/// <param name="name">Thr shader program name.</param>
/// <param name="name">The shader program name.</param>
/// <param name="permutationIndex">The shader permutation index.</param>
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramCS* GetCS(const StringAnsiView& name, int32 permutationIndex = 0) const
@@ -176,7 +176,7 @@ public:
/// <summary>
/// Determines whether the specified shader program is in the shader.
/// </summary>
/// <param name="name">Thr shader program name.</param>
/// <param name="name">The shader program name.</param>
/// <param name="permutationIndex">The shader permutation index.</param>
/// <returns><c>true</c> if the shader is valid; otherwise, <c>false</c>.</returns>
FORCE_INLINE bool HasShader(const StringAnsiView& name, int32 permutationIndex = 0) const

View File

@@ -483,7 +483,7 @@ public:
/// <summary>
/// Creates new staging readback texture with the same dimensions and properties as a source texture (but without a data transferred; warning: caller must delete object).
/// </summary>
/// <returns>Thr staging readback texture.</returns>
/// <returns>The staging readback texture.</returns>
GPUTexture* ToStagingReadback() const;
/// <summary>

View File

@@ -118,7 +118,7 @@ float GPUTimerQueryDX11::GetResult()
if (!SingleShotLog)
{
SingleShotLog = true;
LOG(Warning, "Unrealiable GPU timer query detected.");
LOG(Warning, "Unreliable GPU timer query detected.");
}
#endif
}

View File

@@ -216,7 +216,7 @@ uint64 GPUContextDX12::Execute(bool waitForCompletion)
ASSERT(_currentAllocator != nullptr);
auto queue = _device->GetCommandQueue();
// Flush reaming and buffered commands
// Flush remaining and buffered commands
FlushState();
_currentState = nullptr;

View File

@@ -391,7 +391,7 @@ bool GPUDeviceDX12::Init()
{
// Descriptor tables
D3D12_DESCRIPTOR_RANGE r[2];
// TODO: separate ranges for pixel/vertex visiblity and one shared for all?
// TODO: separate ranges for pixel/vertex visibility and one shared for all?
{
D3D12_DESCRIPTOR_RANGE& range = r[0];
range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;

View File

@@ -8,7 +8,7 @@
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
#include "Engine/Platform/Windows/ComPtr.h"
// Helper define to dispose the COM object with reaming references counter checking
// Helper define to dispose the COM object with remaining references counter checking
#define DX_SAFE_RELEASE_CHECK(x, refs) if(x) { auto res = (x)->Release(); (x) = nullptr; CHECK(res == refs); }
#endif

View File

@@ -44,7 +44,7 @@ void CmdBufferVulkan::End()
ASSERT(IsOutsideRenderPass());
#if GPU_ALLOW_PROFILE_EVENTS
// End reaming events
// End remaining events
while (_eventsBegin--)
vkCmdEndDebugUtilsLabelEXT(GetHandle());
#endif

View File

@@ -1155,7 +1155,7 @@ void GPUContextVulkan::FlushState()
void GPUContextVulkan::Flush()
{
// Flush reaming and buffered commands
// Flush remaining and buffered commands
FlushState();
_currentState = nullptr;

View File

@@ -1363,23 +1363,7 @@ PixelFormat GPUDeviceVulkan::GetClosestSupportedPixelFormat(PixelFormat format,
if (flags & GPUTextureFlags::UnorderedAccess)
wantedFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
// Check actual device for format support
const auto isSupported = [&](VkFormat vkFormat)
{
VkFormatProperties props;
vkGetPhysicalDeviceFormatProperties(Adapter->Gpu, vkFormat, &props);
const VkFormatFeatureFlags featureFlags = optimalTiling ? props.optimalTilingFeatures : props.linearTilingFeatures;
if ((featureFlags & wantedFeatureFlags) != wantedFeatureFlags)
return false;
//VkImageFormatProperties imageProps;
//vkGetPhysicalDeviceImageFormatProperties(Adapter->Gpu, vkFormat, , &imageProps);
return true;
};
VkFormat vkFormat = RenderToolsVulkan::ToVulkanFormat(format);
if (!isSupported(vkFormat))
if (!IsVkFormatSupported(RenderToolsVulkan::ToVulkanFormat(format), wantedFeatureFlags, optimalTiling))
{
// Special case for depth-stencil formats
if (flags & GPUTextureFlags::DepthStencil)
@@ -1389,7 +1373,7 @@ PixelFormat GPUDeviceVulkan::GetClosestSupportedPixelFormat(PixelFormat format,
// Spec guarantees at least one depth-only, and one depth-stencil format to be supported
if (hasStencil)
{
if (isSupported(VK_FORMAT_D32_SFLOAT_S8_UINT))
if (IsVkFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT, wantedFeatureFlags, optimalTiling))
format = PixelFormat::D32_Float;
else
format = PixelFormat::D24_UNorm_S8_UInt;
@@ -1493,6 +1477,20 @@ bool GPUDeviceVulkan::SaveValidationCache()
#endif
bool GPUDeviceVulkan::IsVkFormatSupported(VkFormat vkFormat, VkFormatFeatureFlags wantedFeatureFlags, bool optimalTiling) const
{
VkFormatProperties props;
vkGetPhysicalDeviceFormatProperties(Adapter->Gpu, vkFormat, &props);
const VkFormatFeatureFlags featureFlags = optimalTiling ? props.optimalTilingFeatures : props.linearTilingFeatures;
if ((featureFlags & wantedFeatureFlags) != wantedFeatureFlags)
return false;
//VkImageFormatProperties imageProps;
//vkGetPhysicalDeviceImageFormatProperties(Adapter->Gpu, vkFormat, , &imageProps);
return true;
}
GPUContext* GPUDeviceVulkan::GetMainContext()
{
return reinterpret_cast<GPUContext*>(MainContext);

View File

@@ -720,6 +720,10 @@ public:
#endif
private:
bool IsVkFormatSupported(VkFormat vkFormat, VkFormatFeatureFlags wantedFeatureFlags, bool optimalTiling) const;
public:
// [GPUDevice]

View File

@@ -232,10 +232,10 @@ public:
}
/// <summary>
/// Converts Flax comparision function to the Vulkan comparision operation.
/// Converts Flax comparison function to the Vulkan comparison operation.
/// </summary>
/// <param name="value">The Flax comparision function.</param>
/// <returns>The Vulkan comparision operation.</returns>
/// <param name="value">The Flax comparison function.</param>
/// <returns>The Vulkan comparison operation.</returns>
static FORCE_INLINE VkCompareOp ToVulkanCompareOp(const ComparisonFunc value)
{
return ComparisonFuncToVkCompareOp[(int32)value];

View File

@@ -8,7 +8,7 @@
#define MAX_GAMEPADS 8
/// <summary>
/// Hardware mouse cursor behaviour.
/// Hardware mouse cursor behavior.
/// </summary>
API_ENUM() enum class CursorLockMode
{

View File

@@ -124,7 +124,7 @@ public:
virtual void SetMousePosition(const Vector2& newPosition) = 0;
/// <summary>
/// Called when mouse cursor gets moved by the application. Invalidates the previous cached mouse position to prevent mouse jitter when locking the cursor programatically.
/// Called when mouse cursor gets moved by the application. Invalidates the previous cached mouse position to prevent mouse jitter when locking the cursor programmatically.
/// </summary>
/// <param name="newPosition">The new mouse position.</param>
void OnMouseMoved(const Vector2& newPosition)

View File

@@ -146,8 +146,32 @@ void AnimatedModel::GetNodeTransformation(const StringView& nodeName, Matrix& no
GetNodeTransformation(SkinnedModel ? SkinnedModel->FindNode(nodeName) : -1, nodeTransformation, worldSpace);
}
#define CHECK_ANIM_GRAPH_PARAM_ACCESS() \
if (!AnimationGraph) \
{ \
LOG(Warning, "Missing animation graph for animated model '{0}'", ToString()); \
return; \
} \
if (AnimationGraph->WaitForLoaded()) \
{ \
LOG(Warning, "Failed to load animation graph for animated model '{0}'", ToString()); \
return; \
}
#define CHECK_ANIM_GRAPH_PARAM_ACCESS_RESULT(result) \
if (!AnimationGraph) \
{ \
LOG(Warning, "Missing animation graph for animated model '{0}'", ToString()); \
return result; \
} \
if (AnimationGraph->WaitForLoaded()) \
{ \
LOG(Warning, "Failed to load animation graph for animated model '{0}'", ToString()); \
return result; \
}
AnimGraphParameter* AnimatedModel::GetParameter(const StringView& name)
{
CHECK_ANIM_GRAPH_PARAM_ACCESS_RESULT(nullptr);
for (auto& param : GraphInstance.Parameters)
{
if (param.Name == name)
@@ -159,6 +183,7 @@ AnimGraphParameter* AnimatedModel::GetParameter(const StringView& name)
Variant AnimatedModel::GetParameterValue(const StringView& name)
{
CHECK_ANIM_GRAPH_PARAM_ACCESS_RESULT(Variant::Null);
for (auto& param : GraphInstance.Parameters)
{
if (param.Name == name)
@@ -170,6 +195,7 @@ Variant AnimatedModel::GetParameterValue(const StringView& name)
void AnimatedModel::SetParameterValue(const StringView& name, const Variant& value)
{
CHECK_ANIM_GRAPH_PARAM_ACCESS();
for (auto& param : GraphInstance.Parameters)
{
if (param.Name == name)
@@ -183,6 +209,7 @@ void AnimatedModel::SetParameterValue(const StringView& name, const Variant& val
Variant AnimatedModel::GetParameterValue(const Guid& id)
{
CHECK_ANIM_GRAPH_PARAM_ACCESS_RESULT(Variant::Null);
for (auto& param : GraphInstance.Parameters)
{
if (param.Identifier == id)
@@ -194,6 +221,7 @@ Variant AnimatedModel::GetParameterValue(const Guid& id)
void AnimatedModel::SetParameterValue(const Guid& id, const Variant& value)
{
CHECK_ANIM_GRAPH_PARAM_ACCESS();
for (auto& param : GraphInstance.Parameters)
{
if (param.Identifier == id)

View File

@@ -98,7 +98,7 @@ void StaticModel::SetVertexColor(int32 lodIndex, int32 meshIndex, int32 vertexIn
{
if (!Model || Model->WaitForLoaded())
{
LOG(Warning, "Cannot set vertex color if model is missing or faied to load.");
LOG(Warning, "Cannot set vertex color if model is missing or failed to load.");
return;
}

View File

@@ -993,7 +993,7 @@ bool Level::loadScene(rapidjson_flax::Value& data, int32 engineBuild, bool autoI
}
// Synchronize prefab instances (prefab may have new objects added or some removed so deserialized instances need to synchronize with it)
// TODO: resave and force sync scenes durign game cooking so this step could be skipped in game
// TODO: resave and force sync scenes during game cooking so this step could be skipped in game
Scripting::ObjectsLookupIdMapping.Set(&modifier.Value->IdsMapping);
SceneObjectsFactory::SynchronizePrefabInstances(*sceneObjects.Value, actorToRemovedObjectsData, modifier.Value);
Scripting::ObjectsLookupIdMapping.Set(nullptr);
@@ -1005,7 +1005,7 @@ bool Level::loadScene(rapidjson_flax::Value& data, int32 engineBuild, bool autoI
if (obj && obj->GetParent() == nullptr)
{
sceneObjects->At(i) = nullptr;
LOG(Warning, "Scene object {0} {1} has missing parent objct after scene load. Removing it.", obj->GetID(), obj->ToString());
LOG(Warning, "Scene object {0} {1} has missing parent object after scene load. Removing it.", obj->GetID(), obj->ToString());
obj->DeleteObject();
}
}

View File

@@ -509,7 +509,7 @@ bool FindCyclicReferences(Actor* actor, const Guid& prefabRootId)
bool Prefab::ApplyAll(Actor* targetActor)
{
// TODO: use more cached dictionaries and other collections containers to prevent memory allocations during apply (optimize fo apply 10 times per second the same prefab on many changes in editor)
// TODO: use more cached dictionaries and other collections containers to prevent memory allocations during apply (optimize for apply 10 times per second the same prefab on many changes in editor)
PROFILE_CPU();
const auto startTime = DateTime::NowUTC();

View File

@@ -9,8 +9,9 @@
#include "NavLink.h"
#include "NavModifierVolume.h"
#include "NavMeshRuntime.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/Math/BoundingBox.h"
#include "Engine/Core/Math/VectorInt.h"
#include "Engine/Core/Math/Int3.h"
#include "Engine/Physics/Colliders/BoxCollider.h"
#include "Engine/Physics/Colliders/SphereCollider.h"
#include "Engine/Physics/Colliders/CapsuleCollider.h"
@@ -22,7 +23,6 @@
#include "Engine/Level/Scene/Scene.h"
#include "Engine/Level/Level.h"
#include "Engine/Level/SceneQuery.h"
#include "Engine/Core/Log.h"
#include <ThirdParty/recastnavigation/Recast.h>
#include <ThirdParty/recastnavigation/DetourNavMeshBuilder.h>
#include <ThirdParty/recastnavigation/DetourNavMesh.h>

View File

@@ -100,7 +100,7 @@ public:
public:
/// <summary>
/// Determinates whenever this emitter uses lights rendering.
/// Determines whenever this emitter uses lights rendering.
/// </summary>
/// <returns>True if emitter uses lights rendering, otherwise false.</returns>
FORCE_INLINE bool UsesLightRendering() const

View File

@@ -103,7 +103,7 @@ protected:
public:
/// <summary>
/// The Particle Emitter Graph data version number. Used to sync the Particle Emitter Graph data with the instances state. Handles graph reloads to enure data is valid.
/// The Particle Emitter Graph data version number. Used to sync the Particle Emitter Graph data with the instances state. Handles graph reloads to ensure data is valid.
/// </summary>
uint32 Version = 0;

View File

@@ -1172,7 +1172,7 @@ void ParticleManagerService::Update()
// Update bounds after first system update
updateBounds = true;
}
// TODO: if using fixed timestep quantize the dt and accumulate reaming part for the next update?
// TODO: if using fixed timestep quantize the dt and accumulate remaining part for the next update?
if (dt <= 1.0f / 240.0f)
continue;
dt *= effect->SimulationSpeed;

View File

@@ -115,7 +115,7 @@ int32 ParticleSystemInstance::GetParticlesCount() const
const auto desc = GPUBufferDescription::Buffer(Emitters.Count() * sizeof(uint32), GPUBufferFlags::None, PixelFormat::Unknown, nullptr, sizeof(uint32), GPUResourceUsage::StagingReadback);
if (GPUParticlesCountReadback->Init(desc))
{
LOG(Error, "Failed to create GPU particles coun readback buffer.");
LOG(Error, "Failed to create GPU particles count readback buffer.");
}
}

View File

@@ -175,7 +175,7 @@ public:
}
/// <summary>
/// Attaches collider to the the specified rigid body.
/// Attaches collider to the specified rigid body.
/// </summary>
/// <param name="rigidBody">The rigid body.</param>
void Attach(RigidBody* rigidBody);

View File

@@ -13,7 +13,7 @@
#define ENSURE_CAN_COOK \
if (Physics::GetCooking() == nullptr) \
{ \
LOG(Warning, "Physics collisions cooking is disabled at runtime. Enable Physics Settigns option SupportCookingAtRuntime to use terrain generation at runtime."); \
LOG(Warning, "Physics collisions cooking is disabled at runtime. Enable Physics Settings option SupportCookingAtRuntime to use terrain generation at runtime."); \
return true; \
}

View File

@@ -19,6 +19,7 @@
#include "Engine/Engine/CommandLine.h"
#include "Engine/Engine/Engine.h"
#include "Engine/Utilities/StringConverter.h"
#include "Engine/Platform/BatteryInfo.h"
#include <iostream>
// Check types sizes
@@ -381,6 +382,11 @@ void PlatformBase::SetHighDpiAwarenessEnabled(bool enable)
{
}
BatteryInfo PlatformBase::GetBatteryInfo()
{
return BatteryInfo();
}
int32 PlatformBase::GetDpi()
{
return 96;

View File

@@ -11,6 +11,7 @@ struct CPUInfo;
struct MemoryStats;
struct ProcessMemoryStats;
struct CreateWindowSettings;
struct BatteryInfo;
// ReSharper disable CppFunctionIsNotImplemented
@@ -548,6 +549,11 @@ public:
/// </summary>
static void SetHighDpiAwarenessEnabled(bool enable);
/// <summary>
/// Gets the battery information.
/// </summary>
API_PROPERTY() static BatteryInfo GetBatteryInfo();
/// <summary>
/// Gets the screen DPI setting.
/// </summary>

View File

@@ -77,7 +77,7 @@ void WindowsManagerService::Update()
void WindowsManagerService::Dispose()
{
// Close reaming windows
// Close remaining windows
WindowsManager::WindowsLocker.Lock();
auto windows = WindowsManager::Windows;
for (auto& win : windows)

View File

@@ -0,0 +1,49 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/BaseTypes.h"
/// <summary>
/// Contains information about power supply (battery).
/// </summary>
API_STRUCT() struct BatteryInfo
{
DECLARE_SCRIPTING_TYPE_MINIMAL(BatteryInfo);
/// <summary>
/// Power supply status.
/// </summary>
API_ENUM() enum class States
{
/// <summary>
/// Unknown status.
/// </summary>
Unknown,
/// <summary>
/// Power supply is connected and battery is charging.
/// </summary>
BatteryCharging,
/// <summary>
/// Device is running on a battery.
/// </summary>
BatteryDischarging,
/// <summary>
/// Device is connected to the stable power supply (AC).
/// </summary>
Connected,
};
/// <summary>
/// Power supply state.
/// </summary>
API_FIELD() BatteryInfo::States State = BatteryInfo::States::Unknown;
/// <summary>
/// Battery percentage left (normalized to 0-1 range).
/// </summary>
API_FIELD() float BatteryLifePercent = 1.0f;
};

View File

@@ -346,7 +346,7 @@ static int X11_MessageBoxCreateWindow(MessageBoxData* data)
{
windowdata = data->Parent;
windowdataWin = (X11::Window)windowdata->GetNativePtr();
// TODO: place popup on the the screen that parent window is
// TODO: place popup on the screen that parent window is
data->screen = X11_DefaultScreen(display);
}
else

View File

@@ -10,7 +10,7 @@
#include "Engine/Core/Log.h"
#include "Engine/Core/Math/Math.h"
#include "Engine/Core/Math/Color32.h"
#include "Engine/Core/Math/VectorInt.h"
#include "Engine/Core/Math/Int2.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Utilities/StringConverter.h"

View File

@@ -5,6 +5,7 @@
#include "Engine/Platform/Platform.h"
#include "Engine/Platform/MemoryStats.h"
#include "Engine/Platform/CPUInfo.h"
#include "Engine/Platform/BatteryInfo.h"
#include "Engine/Core/Types/Guid.h"
#include "Engine/Core/Types/String.h"
#include "Engine/Core/Math/Math.h"
@@ -15,6 +16,7 @@
#include <WinSock2.h>
#include <IPHlpApi.h>
#include <oleauto.h>
#include <WinBase.h>
#pragma comment(lib, "Iphlpapi.lib")
namespace
@@ -308,6 +310,21 @@ bool Win32Platform::Is64BitPlatform()
#endif
}
BatteryInfo Win32Platform::GetBatteryInfo()
{
BatteryInfo info;
SYSTEM_POWER_STATUS status;
GetSystemPowerStatus(&status);
info.BatteryLifePercent = (float)status.BatteryLifePercent / 255.0f;
if (status.BatteryFlag & 8)
info.State = BatteryInfo::States::BatteryCharging;
else if (status.BatteryFlag & 1 || status.BatteryFlag & 2 || status.BatteryFlag & 4)
info.State = BatteryInfo::States::BatteryDischarging;
else if (status.ACLineStatus == 1 || status.BatteryFlag & 128)
info.State = BatteryInfo::States::Connected;
return info;
}
CPUInfo Win32Platform::GetCPUInfo()
{
return CpuInfo;

View File

@@ -43,6 +43,7 @@ public:
_aligned_free(ptr);
}
static bool Is64BitPlatform();
static BatteryInfo GetBatteryInfo();
static CPUInfo GetCPUInfo();
static int32 GetCacheLineSize();
static MemoryStats GetMemoryStats();

View File

@@ -231,7 +231,9 @@ bool WindowsFileSystem::ShowOpenFileDialog(Window* parentWindow, const StringVie
while (*ptr)
{
filenames.Add(directory / ptr);
ptr += (lstrlenW(ptr) + 1);
ptr += lstrlenW(ptr);
if (multiSelect)
ptr++;
}
result = false;
@@ -276,7 +278,9 @@ bool WindowsFileSystem::ShowSaveFileDialog(Window* parentWindow, const StringVie
while (*ptr)
{
filenames.Add(directory / ptr);
ptr += (lstrlenW(ptr) + 1);
ptr += lstrlenW(ptr);
if (multiSelect)
ptr++;
}
result = false;

View File

@@ -33,7 +33,7 @@ Font::~Font()
void Font::GetCharacter(Char c, FontCharacterEntry& result)
{
// Try get character or cache it if cannot find
// Try to get the character or cache it if cannot be found
if (!_characters.TryGet(c, result))
{
// This thread race condition may happen in editor but in game we usually do all stuff with fonts on main thread (chars caching)

View File

@@ -55,7 +55,7 @@ void FontAsset::unload(bool isReloading)
// Ensure to cleanup child font objects
if (_fonts.HasItems())
{
LOG(Warning, "Font asset {0} is unloading but has {1} reaming font objects created", ToString(), _fonts.Count());
LOG(Warning, "Font asset {0} is unloading but has {1} remaining font objects created", ToString(), _fonts.Count());
for (auto font : _fonts)
{
font->_asset = nullptr;

View File

@@ -214,7 +214,7 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry)
return false;
}
// Copy glyph data after rasterize (row by row)
// Copy glyph data after rasterization (row by row)
for (int32 row = 0; row < glyphHeight; row++)
{
Platform::MemoryCopy(&GlyphImageData[row * glyphWidth], &bitmap->buffer[row * bitmap->pitch], glyphWidth);

View File

@@ -60,7 +60,7 @@ private:
float ShadowMultiplier; // [0.0, 5.0] Effect strength linear multiplier
float ShadowPower; // [0.5, 5.0] Effect strength pow modifier
float HorizonAngleThreshold; // [0.0, 0.2] Limits self-shadowing (makes the sampling area less of a hemisphere, more of a spherical cone, to avoid self-shadowing and various artifacts due to low tessellation and depth buffer imprecision, etc.)
float FadeOutFrom; // [0.0, ~ ] Distance to start start fading out the effect.
float FadeOutFrom; // [0.0, ~ ] Distance to start fading out the effect.
float FadeOutTo; // [0.0, ~ ] Distance at which the effect is faded out.
int QualityLevel; // [ 0, ] Effect quality; 0 - low, 1 - medium, 2 - high, 3 - very high; each quality level is roughly 2x more costly than the previous, except the q3 which is variable but, in general, above q2.
int BlurPassCount; // [ 0, 6] Number of edge-sensitive smart blur passes to apply. Quality 0 is an exception with only one 'dumb' blur pass used.

View File

@@ -2,6 +2,7 @@
#include "EyeAdaptationPass.h"
#include "RenderList.h"
#include "Engine/Core/Math/Int2.h"
#include "Engine/Content/Assets/Shader.h"
#include "Engine/Content/Content.h"
#include "Engine/Graphics/PostProcessBase.h"

View File

@@ -57,11 +57,11 @@ bool MotionBlurPass::Init()
// Prepare formats for the buffers
auto format = MOTION_VECTORS_PIXEL_FORMAT;
if (FORMAT_FEATURES_ARE_NOT_SUPPORTED(GPUDevice::Instance->GetFormatFeatures(format).Support, (FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D)))
if (FORMAT_FEATURES_ARE_NOT_SUPPORTED(GPUDevice::Instance->GetFormatFeatures(format).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
{
if (FORMAT_FEATURES_ARE_NOT_SUPPORTED(GPUDevice::Instance->GetFormatFeatures(PixelFormat::R32G32_Float).Support, (FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D)))
if (FORMAT_FEATURES_ARE_NOT_SUPPORTED(GPUDevice::Instance->GetFormatFeatures(PixelFormat::R32G32_Float).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
format = PixelFormat::R32G32_Float;
else if (FORMAT_FEATURES_ARE_NOT_SUPPORTED(GPUDevice::Instance->GetFormatFeatures(PixelFormat::R16G16B16A16_Float).Support, (FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D)))
else if (FORMAT_FEATURES_ARE_NOT_SUPPORTED(GPUDevice::Instance->GetFormatFeatures(PixelFormat::R16G16B16A16_Float).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
format = PixelFormat::R16G16B16A16_Float;
else
format = PixelFormat::R32G32B32A32_Float;
@@ -285,7 +285,7 @@ void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& input, GP
PROFILE_GPU_CPU("Motion Blur");
// Setup shader inputs
const int32 maxBlurSize = (int32)((float)motionVectorsHeight * 0.05f);
const int32 maxBlurSize = Math::Max((int32)((float)motionVectorsHeight * 0.05f), 1);
const int32 tileSize = Math::AlignUp(maxBlurSize, 8);
const float timeScale = renderContext.Task->View.IsOfflinePass ? 1.0f : 1.0f / Time::Draw.UnscaledDeltaTime.GetTotalSeconds() / 60.0f; // 60fps as a reference
Data data;

View File

@@ -6,6 +6,7 @@
#include "Engine/Graphics/Graphics.h"
#include "Engine/Graphics/RenderBuffers.h"
#include "Engine/Content/Content.h"
#include "Engine/Graphics/PixelFormatExtensions.h"
#if USE_EDITOR
#include "Engine/Renderer/Lightmaps.h"
#endif
@@ -77,6 +78,19 @@ bool ShadowsPass::Init()
_shader.Get()->OnReloading.Bind<ShadowsPass, &ShadowsPass::OnShaderReloading>(this);
#endif
// If GPU doesn't support linear sampling for the shadow map then fallback to the single sample on lowest quality
const auto formatTexture = PixelFormatExtensions::FindShaderResourceFormat(SHADOW_MAPS_FORMAT, false);
const auto formatFeaturesDepth = GPUDevice::Instance->GetFormatFeatures(SHADOW_MAPS_FORMAT);
const auto formatFeaturesTexture = GPUDevice::Instance->GetFormatFeatures(formatTexture);
_supportsShadows = FORMAT_FEATURES_ARE_SUPPORTED(formatFeaturesDepth.Support, FormatSupport::DepthStencil | FormatSupport::Texture2D)
&& FORMAT_FEATURES_ARE_SUPPORTED(formatFeaturesTexture.Support, FormatSupport::ShaderSample | FormatSupport::ShaderSampleComparison);
if (!_supportsShadows)
{
LOG(Warning, "GPU doesn't support shadows rendering");
LOG(Warning, "Format: {0} features support: {1}", (int32)SHADOW_MAPS_FORMAT, (uint32)formatFeaturesDepth.Support);
LOG(Warning, "Format: {0} features support: {1}", (int32)formatTexture, (uint32)formatFeaturesTexture.Support);
}
return false;
}
@@ -130,24 +144,27 @@ void ShadowsPass::updateShadowMapSize()
// Select new size
_currentShadowMapsQuality = Graphics::ShadowMapsQuality;
switch (_currentShadowMapsQuality)
if (_supportsShadows)
{
case Quality::Ultra:
newSizeCSM = 2048;
newSizeCube = 1024;
break;
case Quality::High:
newSizeCSM = 1024;
newSizeCube = 1024;
break;
case Quality::Medium:
newSizeCSM = 1024;
newSizeCube = 512;
break;
case Quality::Low:
newSizeCSM = 512;
newSizeCube = 256;
break;
switch (_currentShadowMapsQuality)
{
case Quality::Ultra:
newSizeCSM = 2048;
newSizeCube = 1024;
break;
case Quality::High:
newSizeCSM = 1024;
newSizeCube = 1024;
break;
case Quality::Medium:
newSizeCSM = 1024;
newSizeCube = 512;
break;
case Quality::Low:
newSizeCSM = 512;
newSizeCube = 256;
break;
}
}
// Check if size will change
@@ -194,7 +211,7 @@ bool ShadowsPass::CanRenderShadow(RenderContext& renderContext, const RendererPo
const float fadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
const float fade = 1 - Math::Saturate((dstLightToView - light.Radius - light.ShadowsDistance + fadeDistance) / fadeDistance);
return fade > ZeroTolerance;
return fade > ZeroTolerance && _supportsShadows;
}
bool ShadowsPass::CanRenderShadow(RenderContext& renderContext, const RendererSpotLightData& light)
@@ -206,12 +223,12 @@ bool ShadowsPass::CanRenderShadow(RenderContext& renderContext, const RendererSp
const float fadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
const float fade = 1 - Math::Saturate((dstLightToView - light.Radius - light.ShadowsDistance + fadeDistance) / fadeDistance);
return fade > ZeroTolerance;
return fade > ZeroTolerance && _supportsShadows;
}
bool ShadowsPass::CanRenderShadow(RenderContext& renderContext, const RendererDirectionalLightData& light)
{
return true;
return _supportsShadows;
}
void ShadowsPass::Prepare(RenderContext& renderContext, GPUContext* context)

View File

@@ -25,6 +25,7 @@ private:
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2 * 2> _psShadowDir;
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowPoint;
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowSpot;
bool _supportsShadows;
// Shadow maps stuff
int32 _shadowMapsSizeCSM;

View File

@@ -27,7 +27,7 @@ namespace FlaxEngine
/// <remarks>
/// Current order is resolved runtime, and can change if custom editor class has changed.
/// </remarks>
/// <param name="order">The order order.</param>
/// <param name="order">The order.</param>
public EditorOrderAttribute(int order)
{
Order = order;

View File

@@ -5,7 +5,7 @@ using System;
namespace FlaxEngine
{
/// <summary>
/// Indicates that a field or a property of a serializable class should be be serialized. This class cannot be inherited.
/// Indicates that a field or a property of a serializable class should be serialized. This class cannot be inherited.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public sealed class SerializeAttribute : Attribute

View File

@@ -302,7 +302,7 @@ bool MAssembly::LoadWithImage(const String& assemblyPath)
const auto assembly = mono_assembly_load_from_full(assemblyImage, name.Substring(0, name.Length() - 3).Get(), &status, false);
if (status != MONO_IMAGE_OK || assembly == nullptr)
{
// Close image if error occured
// Close image if error occurred
mono_image_close(assemblyImage);
Log::CLRInnerException(TEXT("Mono assembly image is corrupted at ") + assemblyPath);

View File

@@ -234,7 +234,7 @@ public:
#endif
/// <summary>
/// Gets the classes lookup cache. Performs ful initialization if not cached. The result cache contains all classes from the assembly.
/// Gets the classes lookup cache. Performs full initialization if not cached. The result cache contains all classes from the assembly.
/// </summary>
/// <returns>The cache.</returns>
const ClassesDictionary& GetClasses() const;

View File

@@ -193,7 +193,7 @@ public:
/// <summary>
/// Returns an object referencing a method with the specified name and number of parameters.
/// </summary>
/// <remarks>If the the type contains more than one method of the given name and parameters count the returned value can be non-deterministic (one of the matching methods).</remarks>
/// <remarks>If the type contains more than one method of the given name and parameters count the returned value can be non-deterministic (one of the matching methods).</remarks>
/// <param name="name">The method name.</param>
/// <param name="numParams">The method parameters count.</param>
/// <returns>The method or null if failed to get it.</returns>

View File

@@ -206,7 +206,7 @@ struct FLAXENGINE_API ScriptingType
SetupScriptObjectVTableHandler SetupScriptObjectVTable;
/// <summary>
/// The default instance of the scripting type. Used by serialization system for comparision to save only modified properties of the object.
/// The default instance of the scripting type. Used by serialization system for comparison to save only modified properties of the object.
/// </summary>
mutable ScriptingObject* DefaultInstance;
} Script;
@@ -282,7 +282,7 @@ struct FLAXENGINE_API ScriptingType
}
/// <summary>
/// Gets the default instance of the scripting type. Used by serialization system for comparision to save only modified properties of the object.
/// Gets the default instance of the scripting type. Used by serialization system for comparison to save only modified properties of the object.
/// </summary>
ScriptingObject* GetDefaultInstance() const;

View File

@@ -195,7 +195,7 @@ void JsonWriter::SceneObject(::SceneObject* obj)
auto prefab = Content::Load<Prefab>(obj->GetPrefabID());
if (prefab)
{
// Request the prefab to be deserialized to the default instance (used for comparision to generate a diff)
// Request the prefab to be deserialized to the default instance (used for comparison to generate a diff)
prefab->GetDefaultInstance();
// Get prefab object instance from the prefab

View File

@@ -4,8 +4,9 @@
#include "WriteStream.h"
#include "Engine/Core/Types/CommonValue.h"
#include "Engine/Core/Types/Variant.h"
#include "Engine/Content/Asset.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Content/Asset.h"
#include "Engine/Debug/DebugLog.h"
#include "Engine/Scripting/ScriptingObject.h"
#include "Engine/Scripting/ScriptingObjectReference.h"
@@ -330,8 +331,19 @@ void ReadStream::ReadVariant(Variant* data)
{
int32 length;
ReadInt32(&length);
ASSERT(data->AsBlob.Length == length);
ReadBytes(data->AsBlob.Data, length);
if (data->AsBlob.Length == length)
{
ReadBytes(data->AsBlob.Data, length);
}
else
{
LOG(Error, "Invalid Variant {2} data length {0}. Expected {1} bytes from stream.", data->AsBlob.Length, length, data->Type.ToString());
// Skip those bytes
void* ptr = Allocator::Allocate(length);
ReadBytes(ptr, length);
Allocator::Free(ptr);
}
break;
}
case VariantType::Blob:

View File

@@ -37,9 +37,9 @@ public:
public:
/// <summary>
/// Returns true if error occured during reading/writing to the stream
/// Returns true if error occurred during reading/writing to the stream
/// </summary>
/// <returns>True if error occured during reading/writing to the stream</returns>
/// <returns>True if error occurred during reading/writing to the stream</returns>
virtual bool HasError() const
{
return _hasError;

View File

@@ -92,7 +92,7 @@ void UpdateResource(StreamableResource* resource, DateTime now)
}
}
// Calculate residency level to stream in (resources may want to incease/decrease it's quality in steps rather than at once)
// Calculate residency level to stream in (resources may want to increase/decrease it's quality in steps rather than at once)
int32 requestedResidency = handler->CalculateRequestedResidency(resource, targetResidency);
// Create streaming task (resource type specific)

View File

@@ -489,7 +489,7 @@ void Terrain::RemovePatch(const Int2& patchCoord)
const auto patch = GetPatch(patchCoord);
if (patch == nullptr)
{
LOG(Warning, "Cannot remvoe patch at {0}x{1}. It does not exist.", patchCoord.X, patchCoord.Y);
LOG(Warning, "Cannot remove patch at {0}x{1}. It does not exist.", patchCoord.X, patchCoord.Y);
return;
}

Some files were not shown because too many files have changed in this diff Show More