Merge remote-tracking branch 'origin/master' into 1.13
# Conflicts: # Content/Shaders/DepthOfField.flax # Source/Engine/Content/Asset.cpp
This commit is contained in:
@@ -433,7 +433,7 @@ void Asset::Reload()
|
||||
// Cancel any still-running loading task (e.g. if WaitForLoaded timed out)
|
||||
Platform::AtomicStore(&_loadingTask, 0);
|
||||
|
||||
if (IsLoaded())
|
||||
if (IsLoaded() || LastLoadFailed())
|
||||
{
|
||||
// Unload current data
|
||||
unload(true);
|
||||
|
||||
@@ -85,21 +85,31 @@ CreateAssetResult ImportAudio::Import(CreateAssetContext& context, AudioDecoder&
|
||||
LOG(Info, "Audio: {0}kHz, channels: {1}, Bit depth: {2}, Length: {3}s", info.SampleRate / 1000.0f, info.NumChannels, info.BitDepth, info.GetLength());
|
||||
|
||||
// Load the whole audio data
|
||||
uint32 bytesPerSample = info.BitDepth / 8;
|
||||
uint32 bufferSize = info.NumSamples * bytesPerSample;
|
||||
DataContainer<byte> sampleBuffer;
|
||||
sampleBuffer.Link(audioData.Get());
|
||||
sampleBuffer.Link(audioData.Get(), info.NumSamples * (info.BitDepth / 8));
|
||||
|
||||
if (!Math::IsOne(options.Volume))
|
||||
{
|
||||
// Scale PCM signal
|
||||
Array<float> pcm;
|
||||
pcm.Resize(info.NumSamples);
|
||||
AudioTool::ConvertToFloat(sampleBuffer.Get(), info.BitDepth, pcm.Get(), info.NumSamples);
|
||||
for (float& e : pcm)
|
||||
e *= options.Volume;
|
||||
sampleBuffer.Allocate(info.NumSamples * sizeof(int32));
|
||||
AudioTool::ConvertFromFloat(pcm.Get(), (int32*)sampleBuffer.Get(), info.NumSamples);
|
||||
info.BitDepth = 32;
|
||||
}
|
||||
|
||||
// Convert bit depth if need to
|
||||
uint32 outputBitDepth = (uint32)options.BitDepth;
|
||||
if (outputBitDepth != info.BitDepth)
|
||||
{
|
||||
DataContainer<byte> sampleBufferPrev = MoveTemp(sampleBuffer);
|
||||
const uint32 outBufferSize = info.NumSamples * (outputBitDepth / 8);
|
||||
sampleBuffer.Allocate(outBufferSize);
|
||||
AudioTool::ConvertBitDepth(audioData.Get(), info.BitDepth, sampleBuffer.Get(), outputBitDepth, info.NumSamples);
|
||||
AudioTool::ConvertBitDepth(sampleBufferPrev.Get(), info.BitDepth, sampleBuffer.Get(), outputBitDepth, info.NumSamples);
|
||||
info.BitDepth = outputBitDepth;
|
||||
bytesPerSample = info.BitDepth / 8;
|
||||
bufferSize = outBufferSize;
|
||||
}
|
||||
|
||||
// Base
|
||||
@@ -157,13 +167,14 @@ CreateAssetResult ImportAudio::Import(CreateAssetContext& context, AudioDecoder&
|
||||
if (context.AllocateChunk(0))
|
||||
return CreateAssetResult::CannotAllocateChunk;
|
||||
|
||||
WRITE_DATA(0, sampleBuffer.Get(), bufferSize);
|
||||
WRITE_DATA(0, sampleBuffer.Get(), sampleBuffer.Length());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Split audio data into a several chunks (uniform data spread)
|
||||
const uint32 minChunkSize = 1 * 1024 * 1024; // 1 MB
|
||||
const uint32 dataAlignment = info.NumChannels * bytesPerSample * ASSET_FILE_DATA_CHUNKS; // Ensure to never split samples in-between (eg. 24-bit that uses 3 bytes)
|
||||
const uint32 bufferSize = sampleBuffer.Length();
|
||||
const uint32 dataAlignment = info.NumChannels * (info.BitDepth / 8) * ASSET_FILE_DATA_CHUNKS; // Ensure to never split samples in-between (eg. 24-bit that uses 3 bytes)
|
||||
const uint32 chunkSize = Math::AlignUp(Math::Max(minChunkSize, bufferSize / ASSET_FILE_DATA_CHUNKS), dataAlignment);
|
||||
const int32 chunksCount = Math::CeilToInt((float)bufferSize / (float)chunkSize);
|
||||
ASSERT(chunksCount > 0 && chunksCount <= ASSET_FILE_DATA_CHUNKS);
|
||||
|
||||
@@ -264,29 +264,29 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new frustum relaying on perspective camera parameters
|
||||
/// Creates a new frustum based on a perspective camera parameters.
|
||||
/// </summary>
|
||||
/// <param name="cameraPos">The camera pos.</param>
|
||||
/// <param name="lookDir">The look dir.</param>
|
||||
/// <param name="upDir">Up dir.</param>
|
||||
/// <param name="fov">The fov.</param>
|
||||
/// <param name="znear">The Z near.</param>
|
||||
/// <param name="zfar">The Z far.</param>
|
||||
/// <param name="aspect">The aspect.</param>
|
||||
/// <returns>The bounding frustum calculated from perspective camera</returns>
|
||||
public static BoundingFrustum FromCamera(Vector3 cameraPos, Vector3 lookDir, Vector3 upDir, float fov, float znear, float zfar, float aspect)
|
||||
/// <param name="cameraPos">The camera position.</param>
|
||||
/// <param name="lookDir">The look direction.</param>
|
||||
/// <param name="upDir">Up direction.</param>
|
||||
/// <param name="fov">The fov in radians.</param>
|
||||
/// <param name="zNear">The Z near plane.</param>
|
||||
/// <param name="zFar">The Z far plane.</param>
|
||||
/// <param name="aspectRatio">The aspect ratio.</param>
|
||||
/// <returns>The bounding frustum calculated from the perspective camera</returns>
|
||||
public static BoundingFrustum FromCamera(Vector3 cameraPos, Vector3 lookDir, Vector3 upDir, float fov, float zNear, float zFar, float aspectRatio)
|
||||
{
|
||||
//http://knol.google.com/k/view-frustum
|
||||
|
||||
lookDir = Vector3.Normalize(lookDir);
|
||||
upDir = Vector3.Normalize(upDir);
|
||||
|
||||
Vector3 nearCenter = cameraPos + lookDir * znear;
|
||||
Vector3 farCenter = cameraPos + lookDir * zfar;
|
||||
var nearHalfHeight = (float)(znear * Math.Tan(fov / 2f));
|
||||
var farHalfHeight = (float)(zfar * Math.Tan(fov / 2f));
|
||||
float nearHalfWidth = nearHalfHeight * aspect;
|
||||
float farHalfWidth = farHalfHeight * aspect;
|
||||
Vector3 nearCenter = cameraPos + lookDir * zNear;
|
||||
Vector3 farCenter = cameraPos + lookDir * zFar;
|
||||
var nearHalfHeight = (float)(zNear * Math.Tan(fov / 2f));
|
||||
var farHalfHeight = (float)(zFar * Math.Tan(fov / 2f));
|
||||
float nearHalfWidth = nearHalfHeight * aspectRatio;
|
||||
float farHalfWidth = farHalfHeight * aspectRatio;
|
||||
|
||||
Vector3 rightDir = Vector3.Normalize(Vector3.Cross(upDir, lookDir));
|
||||
Vector3 near1 = nearCenter - nearHalfHeight * upDir + nearHalfWidth * rightDir;
|
||||
@@ -315,20 +315,21 @@ namespace FlaxEngine
|
||||
result.pTop.Normalize();
|
||||
result.pBottom.Normalize();
|
||||
|
||||
result.pMatrix = Matrix.LookAt(cameraPos, cameraPos + lookDir * 10, upDir) * Matrix.PerspectiveFov(fov, aspect, znear, zfar);
|
||||
result.pMatrix = Matrix.LookAt(cameraPos, cameraPos + lookDir * 10, upDir) * Matrix.PerspectiveFov(fov, aspectRatio, zNear, zFar);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the 8 corners of the frustum, element0 is Near1 (near right down corner)
|
||||
/// , element1 is Near2 (near right top corner)
|
||||
/// , element2 is Near3 (near Left top corner)
|
||||
/// , element3 is Near4 (near Left down corner)
|
||||
/// , element4 is Far1 (far right down corner)
|
||||
/// , element5 is Far2 (far right top corner)
|
||||
/// , element6 is Far3 (far left top corner)
|
||||
/// , element7 is Far4 (far left down corner)
|
||||
/// Returns the 8 corners of the frustum:
|
||||
/// <para>[0] is Near1 (Near right down corner)</para>
|
||||
/// <para>[1] is Near2 (Near right top corner)</para>
|
||||
/// <para>[2] is Near3 (Near left top corner)</para>
|
||||
/// <para>[3] is Near4 (Near left down corner)</para>
|
||||
/// <para>[4] is Far1 (Far right down corner)</para>
|
||||
/// <para>[5] is Far2 (Far right top corner)</para>
|
||||
/// <para>[6] is Far3 (Far left top corner)</para>
|
||||
/// <para>[7] is Far4 (Far left down corner)</para>
|
||||
/// </summary>
|
||||
/// <returns>The 8 corners of the frustum</returns>
|
||||
public Vector3[] GetCorners()
|
||||
@@ -339,16 +340,16 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the 8 corners of the frustum, element0 is Near1 (near right down corner)
|
||||
/// , element1 is Near2 (near right top corner)
|
||||
/// , element2 is Near3 (near Left top corner)
|
||||
/// , element3 is Near4 (near Left down corner)
|
||||
/// , element4 is Far1 (far right down corner)
|
||||
/// , element5 is Far2 (far right top corner)
|
||||
/// , element6 is Far3 (far left top corner)
|
||||
/// , element7 is Far4 (far left down corner)
|
||||
/// Populates the array with the 8 corners of the frustum:
|
||||
/// <para>[0] is Near1 (Near right down corner)</para>
|
||||
/// <para>[1] is Near2 (Near right top corner)</para>
|
||||
/// <para>[2] is Near3 (Near left top corner)</para>
|
||||
/// <para>[3] is Near4 (Near left down corner)</para>
|
||||
/// <para>[4] is Far1 (Far right down corner)</para>
|
||||
/// <para>[5] is Far2 (Far right top corner)</para>
|
||||
/// <para>[6] is Far3 (Far left top corner)</para>
|
||||
/// <para>[7] is Far4 (Far left down corner)</para>
|
||||
/// </summary>
|
||||
/// <returns>The 8 corners of the frustum</returns>
|
||||
public void GetCorners(Vector3[] corners)
|
||||
{
|
||||
corners[0] = Get3PlanesInterPoint(ref pNear, ref pBottom, ref pRight); //Near1
|
||||
@@ -362,7 +363,7 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a point lay inside, intersects or lay outside the frustum.
|
||||
/// Checks whether a point lays inside, intersects or lays outside the frustum.
|
||||
/// </summary>
|
||||
/// <param name="point">The point.</param>
|
||||
/// <returns>Type of the containment</returns>
|
||||
@@ -669,15 +670,15 @@ namespace FlaxEngine
|
||||
{
|
||||
if (Contains(ray.Position) != ContainmentType.Disjoint)
|
||||
{
|
||||
Real nearstPlaneDistance = Real.MaxValue;
|
||||
Real nearestPlaneDistance = Real.MaxValue;
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
Plane plane = GetPlane(i);
|
||||
if (CollisionsHelper.RayIntersectsPlane(ref ray, ref plane, out Real distance) && (distance < nearstPlaneDistance))
|
||||
nearstPlaneDistance = distance;
|
||||
if (CollisionsHelper.RayIntersectsPlane(ref ray, ref plane, out Real distance) && (distance < nearestPlaneDistance))
|
||||
nearestPlaneDistance = distance;
|
||||
}
|
||||
|
||||
inDistance = nearstPlaneDistance;
|
||||
inDistance = nearestPlaneDistance;
|
||||
outDistance = null;
|
||||
return true;
|
||||
}
|
||||
@@ -711,9 +712,9 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents (zoom to fit) operation, so all the passed points will fit in the current view.
|
||||
/// if the returned value is positive, the camera will move toward the lookat direction (ZoomIn).
|
||||
/// if the returned value is negative, the camera will move in the reverse direction of the lookat direction (ZoomOut).
|
||||
/// Get the distance which when added to camera position along the look-at direction will do the effect of zoom to extents (zoom to fit) operation, so all the passed points will fit in the current view.
|
||||
/// if the returned value is positive, the camera will move toward the look-at direction (ZoomIn).
|
||||
/// if the returned value is negative, the camera will move in the reverse direction of the look-at direction (ZoomOut).
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <returns>The zoom to fit distance</returns>
|
||||
@@ -740,9 +741,9 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents (zoom to fit) operation, so all the passed points will fit in the current view.
|
||||
/// if the returned value is positive, the camera will move toward the lookat direction (ZoomIn).
|
||||
/// if the returned value is negative, the camera will move in the reverse direction of the lookat direction (ZoomOut).
|
||||
/// Get the distance which when added to camera position along the look-at direction will do the effect of zoom to extents (zoom to fit) operation, so all the passed points will fit in the current view.
|
||||
/// if the returned value is positive, the camera will move toward the look-at direction (ZoomIn).
|
||||
/// if the returned value is negative, the camera will move in the reverse direction of the look-at direction (ZoomOut).
|
||||
/// </summary>
|
||||
/// <param name="boundingBox">The bounding box.</param>
|
||||
/// <returns>The zoom to fit distance</returns>
|
||||
|
||||
@@ -357,7 +357,7 @@ struct DebugDrawContext
|
||||
Vector3 Origin = Vector3::Zero;
|
||||
DebugDrawData DebugDrawDefault;
|
||||
DebugDrawData DebugDrawDepthTest;
|
||||
Float3 LastViewPos = Float3::Zero;
|
||||
Vector3 LastViewPosition = Vector3::Zero;
|
||||
Matrix LastViewProjection = Matrix::Identity;
|
||||
BoundingFrustum LastViewFrustum;
|
||||
|
||||
@@ -790,9 +790,14 @@ bool DebugDraw::CanClear(void* context)
|
||||
|
||||
#endif
|
||||
|
||||
Vector3 DebugDraw::GetViewPos()
|
||||
Vector3 DebugDraw::GetViewPosition()
|
||||
{
|
||||
return Context->LastViewPos;
|
||||
return Context->LastViewPosition;
|
||||
}
|
||||
|
||||
Vector3 DebugDraw::GetViewOrigin()
|
||||
{
|
||||
return Context->Origin;
|
||||
}
|
||||
|
||||
BoundingFrustum DebugDraw::GetViewFrustum()
|
||||
@@ -802,7 +807,7 @@ BoundingFrustum DebugDraw::GetViewFrustum()
|
||||
|
||||
void DebugDraw::SetView(const RenderView& view)
|
||||
{
|
||||
Context->LastViewPos = view.Position;
|
||||
Context->LastViewPosition = view.WorldPosition;
|
||||
Context->LastViewProjection = view.Projection;
|
||||
Context->LastViewFrustum = view.Frustum;
|
||||
}
|
||||
@@ -1423,7 +1428,8 @@ void DebugDraw::DrawWireSphere(const BoundingSphere& sphere, const Color& color,
|
||||
int32 index;
|
||||
const Float3 centerF = sphere.Center - Context->Origin;
|
||||
const float radiusF = (float)sphere.Radius;
|
||||
const float screenRadiusSquared = RenderTools::ComputeBoundsScreenRadiusSquared(centerF, radiusF, Context->LastViewPos, Context->LastViewProjection);
|
||||
const Float3 drawPos = Context->LastViewPosition - Context->Origin;
|
||||
const float screenRadiusSquared = RenderTools::ComputeBoundsScreenRadiusSquared(centerF, radiusF, drawPos, Context->LastViewProjection);
|
||||
if (screenRadiusSquared > DEBUG_DRAW_SPHERE_LOD0_SCREEN_SIZE * DEBUG_DRAW_SPHERE_LOD0_SCREEN_SIZE * 0.25f)
|
||||
index = 0;
|
||||
else if (screenRadiusSquared > DEBUG_DRAW_SPHERE_LOD1_SCREEN_SIZE * DEBUG_DRAW_SPHERE_LOD1_SCREEN_SIZE * 0.25f)
|
||||
@@ -1523,6 +1529,44 @@ void DebugDraw::DrawCircle(const Vector3& position, const Float3& normal, float
|
||||
}
|
||||
}
|
||||
|
||||
void DebugDraw::DrawPoint(const Vector3& position, float radius, const Color& color, float duration, bool depthTest)
|
||||
{
|
||||
Float3 normal = (Float3)(Context->LastViewPosition - position);
|
||||
if (normal.Length() < ZeroTolerance)
|
||||
normal = Float3::Up;
|
||||
normal.Normalize();
|
||||
|
||||
// Create matrix transform for unit circle points
|
||||
Matrix world, scale, matrix;
|
||||
Float3 right, up;
|
||||
if (Float3::Dot(normal, Float3::Up) > 0.99f)
|
||||
right = Float3::Right;
|
||||
else if (Float3::Dot(normal, Float3::Down) > 0.99f)
|
||||
right = Float3::Left;
|
||||
else
|
||||
Float3::Cross(normal, Float3::Up, right);
|
||||
Float3::Cross(right, normal, up);
|
||||
Matrix::Scaling(radius, scale);
|
||||
const Float3 positionF = position - Context->Origin;
|
||||
Matrix::CreateWorld(positionF, normal, up, world);
|
||||
Matrix::Multiply(scale, world, matrix);
|
||||
|
||||
// Build a filled disc as a triangle fan from the center over the transformed unit circle points
|
||||
PROFILE_MEM(EngineDebug);
|
||||
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
|
||||
auto& debugDrawList = duration > 0 ? debugDrawData.DefaultTriangles : debugDrawData.OneFrameTriangles;
|
||||
for (int32 i = 0; i < DEBUG_DRAW_CIRCLE_VERTICES; i += 2)
|
||||
{
|
||||
DebugTriangle t;
|
||||
t.Color = Color32(color);
|
||||
t.TimeLeft = duration;
|
||||
t.V0 = positionF;
|
||||
t.V1 = Float3::Transform(CircleCache[i], matrix);
|
||||
t.V2 = Float3::Transform(CircleCache[i + 1], matrix);
|
||||
debugDrawList.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugDraw::DrawWireTriangle(const Vector3& v0, const Vector3& v1, const Vector3& v2, const Color& color, float duration, bool depthTest)
|
||||
{
|
||||
DrawLine(v0, v1, color, duration, depthTest);
|
||||
|
||||
@@ -74,8 +74,10 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
API_FUNCTION() static bool CanClear(void* context = nullptr);
|
||||
#endif
|
||||
|
||||
// Gets the last view position when rendering the current context. Can be used for custom culling or LODing when drawing more complex shapes.
|
||||
static Vector3 GetViewPos();
|
||||
// Gets the last view position (world-space) when rendering the current context. Can be used for custom culling or LODing when drawing more complex shapes.
|
||||
static Vector3 GetViewPosition();
|
||||
// Gets the last view origin (world-space) when rendering the current context. Can be used for custom culling or LODing when drawing more complex shapes.
|
||||
static Vector3 GetViewOrigin();
|
||||
// Gets the last view frustum when rendering the current context. Can be used for custom culling or LODing when drawing more complex shapes.
|
||||
static BoundingFrustum GetViewFrustum();
|
||||
|
||||
@@ -265,6 +267,16 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
API_FUNCTION() static void DrawCircle(const Vector3& position, const Float3& normal, float radius, const Color& color = Color::White, float duration = 0.0f, bool depthTest = true);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the point facing camera.
|
||||
/// </summary>
|
||||
/// <param name="position">The center position.</param>
|
||||
/// <param name="radius">The radius.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
API_FUNCTION() static void DrawPoint(const Vector3& position, float radius, const Color& color = Color::White, float duration = 0.0f, bool depthTest = true);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the wireframe triangle.
|
||||
@@ -778,6 +790,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
#define DEBUG_DRAW_LINES(lines, transform, color, duration, depthTest) DebugDraw::DrawLines(lines, transform, color, duration, depthTest)
|
||||
#define DEBUG_DRAW_BEZIER(p1, p2, p3, p4, color, duration, depthTest) DebugDraw::DrawBezier(p1, p2, p3, p4, color, duration, depthTest)
|
||||
#define DEBUG_DRAW_CIRCLE(position, normal, radius, color, duration, depthTest) DebugDraw::DrawCircle(position, normal, radius, color, duration, depthTest)
|
||||
#define DEBUG_DRAW_POINT(position, radius, color, duration, depthTest) DebugDraw::DrawPoint(position, radius, color, duration, depthTest)
|
||||
#define DEBUG_DRAW_TRIANGLE(v0, v1, v2, color, duration, depthTest) DebugDraw::DrawTriangle(v0, v1, v2, color, duration, depthTest)
|
||||
#define DEBUG_DRAW_TRIANGLES(vertices, color, duration, depthTest) DebugDraw::DrawTriangles(vertices, color, duration, depthTest)
|
||||
#define DEBUG_DRAW_TRIANGLES_EX(vertices, indices, color, duration, depthTest) DebugDraw::DrawTriangles(vertices, indices, color, duration, depthTest)
|
||||
|
||||
@@ -149,6 +149,18 @@ bool GameplayGlobals::Save(const StringView& path)
|
||||
return false;
|
||||
}
|
||||
|
||||
void GameplayGlobals::GetReferences(Array<Guid>& assets, Array<String>& files) const
|
||||
{
|
||||
BinaryAsset::GetReferences(assets, files);
|
||||
|
||||
for (auto& e : Variables)
|
||||
{
|
||||
auto asset = (Asset*)e.Value.DefaultValue;
|
||||
if (asset)
|
||||
assets.Add(asset->GetID());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void GameplayGlobals::InitAsVirtual()
|
||||
|
||||
@@ -85,6 +85,7 @@ public:
|
||||
void InitAsVirtual() override;
|
||||
#if USE_EDITOR
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -472,7 +472,24 @@ void MaterialParameter::Bind(BindMeta& meta) const
|
||||
ASSERT_LOW_LAYER(meta.Constants.Get() && meta.Constants.Length() >= (int32)(_offset + sizeof(Int4)));
|
||||
*((Int4*)(meta.Constants.Get() + _offset)) = (Int4)e->Value.AsInt4();
|
||||
break;
|
||||
default: ;
|
||||
case VariantType::Asset:
|
||||
{
|
||||
auto texture = Cast<TextureBase>(e->Value.AsAsset);
|
||||
meta.Context->BindSR(_registerIndex, texture ? texture->GetTexture() : nullptr);
|
||||
break;
|
||||
}
|
||||
case VariantType::Object:
|
||||
{
|
||||
// GPU Texture bind must match dimensions of the value archetype (eg. 2d or cube texture)
|
||||
auto gpuTexture = Cast<GPUTexture>(e->Value.AsObject);
|
||||
meta.Context->BindSR(_registerIndex, gpuTexture);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
#if !BUILD_RELEASE
|
||||
LOG(Warning, "Invalid Gameplay Global '{}' ({}) value type '{}' to bind to material", _name, _asAsset->GetPath(), e->Value.Type.ToString());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +70,7 @@ namespace
|
||||
if (accessor.AllocateBuffer(MeshBufferType::Vertex0, vertexCount, vb0layout))
|
||||
return true;
|
||||
auto positionStream = accessor.Position();
|
||||
ASSERT(positionStream.IsLinear(PixelFormat::R32G32B32_Float));
|
||||
positionStream.SetLinear(vertices);
|
||||
positionStream.Set(Span<Float3>(vertices, vertexCount));
|
||||
}
|
||||
|
||||
// Vertex Buffer 1 (general purpose components)
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace
|
||||
|
||||
// Index Buffer
|
||||
{
|
||||
if (accessor.AllocateBuffer(MeshBufferType::Index, triangleCount, indexFormat))
|
||||
if (accessor.AllocateBuffer(MeshBufferType::Index, triangleCount * 3, indexFormat))
|
||||
return true;
|
||||
auto indexStream = accessor.Index();
|
||||
ASSERT(indexStream.IsLinear(indexFormat));
|
||||
@@ -73,8 +73,7 @@ namespace
|
||||
return true;
|
||||
|
||||
auto positionStream = accessor.Position();
|
||||
ASSERT(positionStream.IsLinear(PixelFormat::R32G32B32_Float));
|
||||
positionStream.SetLinear(vertices);
|
||||
positionStream.Set(Span<Float3>(vertices, vertexCount));
|
||||
if (normals)
|
||||
{
|
||||
auto normalStream = accessor.Normal();
|
||||
|
||||
@@ -41,6 +41,15 @@ namespace FlaxEngine
|
||||
NonJitteredProjection = Projection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets projection matrix for overlay geometry rendered after temporal anti-aliasing has been resolved.
|
||||
/// </summary>
|
||||
/// <param name="projection">Projection matrix valid for rendering before or after (matches current TAA jitter stage).</param>
|
||||
public void GetOverlayProjection(out Matrix projection)
|
||||
{
|
||||
projection = IsTaaResolved ? NonJitteredProjection : Projection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes render view data.
|
||||
/// </summary>
|
||||
|
||||
@@ -1516,8 +1516,8 @@ MaterialBase* AnimatedModel::GetMaterial(int32 entryIndex)
|
||||
SkinnedModel->WaitForLoaded();
|
||||
else
|
||||
return nullptr;
|
||||
CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
|
||||
MaterialBase* material = Entries[entryIndex].Material.Get();
|
||||
CHECK_RETURN(entryIndex >= 0 && entryIndex < SkinnedModel->MaterialSlots.Count(), nullptr);
|
||||
MaterialBase* material = entryIndex < Entries.Count() ? Entries[entryIndex].Material.Get() : nullptr;
|
||||
if (!material)
|
||||
{
|
||||
material = SkinnedModel->MaterialSlots[entryIndex].Material.Get();
|
||||
|
||||
@@ -39,6 +39,9 @@ void ModelInstanceActor::SetMaterial(int32 entryIndex, MaterialBase* material)
|
||||
WaitForModelLoad();
|
||||
if (Entries.Count() == 0 && !material)
|
||||
return;
|
||||
const int32 slotsCount = GetMaterialSlots().Length();
|
||||
if (Entries.Count() != slotsCount)
|
||||
Entries.Setup(slotsCount);
|
||||
CHECK(entryIndex >= 0 && entryIndex < Entries.Count());
|
||||
if (Entries[entryIndex].Material == material)
|
||||
return;
|
||||
@@ -50,6 +53,10 @@ void ModelInstanceActor::SetMaterial(int32 entryIndex, MaterialBase* material)
|
||||
MaterialInstance* ModelInstanceActor::CreateAndSetVirtualMaterialInstance(int32 entryIndex)
|
||||
{
|
||||
WaitForModelLoad();
|
||||
const int32 slotsCount = GetMaterialSlots().Length();
|
||||
CHECK_RETURN(entryIndex >= 0 && entryIndex < slotsCount, nullptr);
|
||||
if (Entries.Count() != slotsCount)
|
||||
Entries.Setup(slotsCount);
|
||||
MaterialBase* material = GetMaterial(entryIndex);
|
||||
CHECK_RETURN(material && !material->WaitForLoaded(), nullptr);
|
||||
MaterialInstance* result = material->CreateVirtualInstance();
|
||||
|
||||
@@ -496,7 +496,7 @@ namespace
|
||||
FORCE_INLINE float NodeSizeByDistance(const Vector3& nodePosition, bool scaleByDistance)
|
||||
{
|
||||
if (scaleByDistance)
|
||||
return (float)(Vector3::Distance(DebugDraw::GetViewPos(), nodePosition) / 100);
|
||||
return (float)(Vector3::Distance(DebugDraw::GetViewPosition(), nodePosition) / 100);
|
||||
return 5.0f;
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ namespace
|
||||
return;
|
||||
Spline::Keyframe* prev = spline->Curve.GetKeyframes().Get();
|
||||
Vector3 prevPos = transform.LocalToWorld(prev->Value.Translation);
|
||||
Real distance = Vector3::Distance(prevPos, DebugDraw::GetViewPos());
|
||||
Real distance = Vector3::Distance(prevPos, DebugDraw::GetViewPosition());
|
||||
if (distance < METERS_TO_UNITS(800)) // 800m
|
||||
{
|
||||
// Bezier curve
|
||||
@@ -540,7 +540,9 @@ namespace
|
||||
|
||||
void Spline::OnDebugDraw()
|
||||
{
|
||||
if (DebugDraw::GetViewFrustum().Intersects(_sphere))
|
||||
BoundingSphere sphere(_sphere);
|
||||
sphere.Center -= DebugDraw::GetViewOrigin();
|
||||
if (DebugDraw::GetViewFrustum().Intersects(sphere))
|
||||
DrawSpline(this, GetSplineColor().AlphaMultiplied(0.7f), _transform, true);
|
||||
|
||||
// Base
|
||||
|
||||
@@ -356,8 +356,8 @@ MaterialBase* SplineModel::GetMaterial(int32 entryIndex)
|
||||
Model->WaitForLoaded();
|
||||
else
|
||||
return nullptr;
|
||||
CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
|
||||
MaterialBase* material = Entries[entryIndex].Material.Get();
|
||||
CHECK_RETURN(entryIndex >= 0 && entryIndex < Model->MaterialSlots.Count(), nullptr);
|
||||
MaterialBase* material = entryIndex < Entries.Count() ? Entries[entryIndex].Material.Get() : nullptr;
|
||||
if (!material)
|
||||
{
|
||||
material = Model->MaterialSlots[entryIndex].Material.Get();
|
||||
|
||||
@@ -154,7 +154,7 @@ MaterialBase* StaticModel::GetMaterial(int32 meshIndex, int32 lodIndex) const
|
||||
Math::IsInRange(meshIndex, 0, model->LODs[lodIndex].Meshes.Count()));
|
||||
const auto& mesh = model->LODs[lodIndex].Meshes[meshIndex];
|
||||
const auto materialSlotIndex = mesh.GetMaterialSlotIndex();
|
||||
MaterialBase* material = Entries[materialSlotIndex].Material.Get();
|
||||
MaterialBase* material = materialSlotIndex < Entries.Count() ? Entries[materialSlotIndex].Material.Get() : nullptr;
|
||||
return material ? material : model->MaterialSlots[materialSlotIndex].Material.Get();
|
||||
}
|
||||
|
||||
@@ -607,9 +607,9 @@ MaterialBase* StaticModel::GetMaterial(int32 entryIndex)
|
||||
{
|
||||
if (!Model || Model->WaitForLoaded())
|
||||
return nullptr;
|
||||
CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
|
||||
MaterialBase* material = Entries[entryIndex].Material.Get();
|
||||
if (!material && entryIndex < Model->MaterialSlots.Count())
|
||||
CHECK_RETURN(entryIndex >= 0 && entryIndex < Model->MaterialSlots.Count(), nullptr);
|
||||
MaterialBase* material = entryIndex < Entries.Count() ? Entries[entryIndex].Material.Get() : nullptr;
|
||||
if (!material)
|
||||
{
|
||||
material = Model->MaterialSlots[entryIndex].Material.Get();
|
||||
if (!material)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "ParticleEmitterGraph.GPU.h"
|
||||
#include "Engine/Graphics/Materials/MaterialInfo.h"
|
||||
|
||||
bool ParticleEmitterGPUGenerator::loadTexture(Node* caller, Box* box, const SerializedMaterialParam& texture, Value& result)
|
||||
bool ParticleEmitterGPUGenerator::loadTexture(Node* caller, Box* box, const SerializedMaterialParam& texture, const Value& textureValue, Value& result)
|
||||
{
|
||||
ASSERT(caller && box && texture.ID.IsValid());
|
||||
|
||||
@@ -22,7 +22,8 @@ bool ParticleEmitterGPUGenerator::loadTexture(Node* caller, Box* box, const Seri
|
||||
&& texture.Type != MaterialParameterType::GPUTextureVolume
|
||||
&& texture.Type != MaterialParameterType::GPUTextureCube
|
||||
&& texture.Type != MaterialParameterType::GPUTextureArray
|
||||
&& texture.Type != MaterialParameterType::CubeTexture)
|
||||
&& texture.Type != MaterialParameterType::CubeTexture
|
||||
&& textureValue.Type != VariantType::Object)
|
||||
{
|
||||
result = Value::Zero;
|
||||
OnError(caller, box, TEXT("No parameter for texture load or invalid type."));
|
||||
@@ -41,7 +42,8 @@ bool ParticleEmitterGPUGenerator::loadTexture(Node* caller, Box* box, const Seri
|
||||
|
||||
// Load texture
|
||||
const Char* format = TEXT("{0}.Load({1})");
|
||||
const String sampledValue = String::Format(format, texture.ShaderName, location.Value);
|
||||
auto& shaderName = textureValue.Type == VariantType::Object ? textureValue.Value : texture.ShaderName;
|
||||
const String sampledValue = String::Format(format, shaderName, location.Value);
|
||||
result = writeLocal(VariantType::Float4, sampledValue, parent);
|
||||
|
||||
return false;
|
||||
@@ -300,7 +302,7 @@ void ParticleEmitterGPUGenerator::ProcessGroupTextures(Box* box, Node* node, Val
|
||||
const auto copy = *textureParam;
|
||||
|
||||
// Load texture
|
||||
loadTexture(node, box, copy, value);
|
||||
loadTexture(node, box, copy, texture, value);
|
||||
break;
|
||||
}
|
||||
// Sample Global SDF
|
||||
|
||||
@@ -127,7 +127,7 @@ private:
|
||||
|
||||
Parameter* findGraphParam(const Guid& id);
|
||||
bool sampleSceneTexture(Node* caller, Box* box, const SerializedMaterialParam& texture, Value& result);
|
||||
bool loadTexture(Node* caller, Box* box, const SerializedMaterialParam& texture, Value& result);
|
||||
bool loadTexture(Node* caller, Box* box, const SerializedMaterialParam& texture, const Value& textureValue, Value& result);
|
||||
void sampleSceneDepth(Node* caller, Value& value, Box* box);
|
||||
void linearizeSceneDepth(Node* caller, const Value& depth, Value& value);
|
||||
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
#include "Engine/Platform/Base/DragDropHelper.h"
|
||||
#endif
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Input/Input.h"
|
||||
#include "Engine/Input/Mouse.h"
|
||||
#include "Engine/Input/Keyboard.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/Textures/TextureData.h"
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <QuartzCore/CAMetalLayer.h>
|
||||
@@ -200,6 +202,19 @@ Float2 GetMousePosition(MacWindow* window, NSEvent* event)
|
||||
return Float2(point.x, frame.size.height - point.y) * MacPlatform::ScreenScale - GetWindowTitleSize(window);
|
||||
}
|
||||
|
||||
NSRect GetFrameRectForClientBounds(MacWindow* macWindow, NSWindow* window, const Rectangle& clientArea)
|
||||
{
|
||||
const float screenScale = MacPlatform::ScreenScale;
|
||||
NSRect rect = NSMakeRect(0, 0, clientArea.Size.X / screenScale, clientArea.Size.Y / screenScale);
|
||||
rect = [window frameRectForContentRect:rect];
|
||||
|
||||
Float2 pos = AppleUtils::PosToCoca(clientArea.Location) / screenScale;
|
||||
Float2 titleSize = GetWindowTitleSize(macWindow);
|
||||
rect.origin.x = pos.X + titleSize.X;
|
||||
rect.origin.y = pos.Y - rect.size.height + titleSize.Y;
|
||||
return rect;
|
||||
}
|
||||
|
||||
class MacDropData : public IGuiData
|
||||
{
|
||||
public:
|
||||
@@ -310,6 +325,12 @@ NSDragOperation GetDragDropOperation(DragDropEffect dragDropEffect)
|
||||
Window->OnLostFocus();
|
||||
}
|
||||
|
||||
- (void)windowDidMove:(NSNotification*)notification
|
||||
{
|
||||
if (IsWindowInvalid(Window)) return;
|
||||
Window->SyncWindowState();
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification*)notification
|
||||
{
|
||||
[self setDelegate: nil];
|
||||
@@ -518,6 +539,28 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
|
||||
if (IsWindowInvalid(Window)) return;
|
||||
Float2 mousePos = GetMousePosition(Window, event);
|
||||
mousePos = Window->ClientToScreen(mousePos);
|
||||
|
||||
if ([event clickCount] == 1 && !Input::Mouse->IsRelative())
|
||||
{
|
||||
WindowHitCodes hit = WindowHitCodes::Client;
|
||||
bool handled = false;
|
||||
Window->OnHitTest(mousePos, hit, handled);
|
||||
|
||||
if (hit == WindowHitCodes::Caption)
|
||||
{
|
||||
bool consumed = false;
|
||||
Window->OnLeftButtonHit(hit, consumed);
|
||||
|
||||
if (!consumed)
|
||||
{
|
||||
[(NSWindow*)Window->GetNativePtr() performWindowDragWithEvent:event];
|
||||
Window->SyncWindowState();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MouseButton mouseButton = MouseButton::Left;
|
||||
if ([event clickCount] == 2 && !Input::Mouse->IsRelative())
|
||||
Input::Mouse->OnMouseDoubleClick(mousePos, mouseButton, Window);
|
||||
@@ -835,15 +878,28 @@ MacWindow::MacWindow(const CreateWindowSettings& settings)
|
||||
|
||||
MacWindow::~MacWindow()
|
||||
{
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
[window close];
|
||||
[window release];
|
||||
if (NSWindow* window = (NSWindow*)_window)
|
||||
{
|
||||
[window close];
|
||||
[window release];
|
||||
}
|
||||
_window = nullptr;
|
||||
_view = nullptr;
|
||||
}
|
||||
|
||||
void MacWindow::SyncWindowState()
|
||||
{
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
if (window)
|
||||
{
|
||||
_minimized = window.miniaturized;
|
||||
_maximized = window.zoomed;
|
||||
}
|
||||
}
|
||||
|
||||
void MacWindow::CheckForResize(float width, float height)
|
||||
{
|
||||
SyncWindowState();
|
||||
const Float2 clientSize(width, height);
|
||||
if (clientSize != _clientSize)
|
||||
{
|
||||
@@ -940,7 +996,7 @@ void MacWindow::Hide()
|
||||
[window orderOut:nil];
|
||||
|
||||
// Transfer focus back to the parent when hiding popup
|
||||
if (_settings.Parent && wasKey)
|
||||
if (_settings.Parent && wasKey && _settings.Type != WindowType::Popup && _settings.Type != WindowType::Tooltip)
|
||||
{
|
||||
NSWindow* parent = (NSWindow*)_settings.Parent->GetNativePtr();
|
||||
[parent makeKeyAndOrderFront:nil];
|
||||
@@ -951,6 +1007,27 @@ void MacWindow::Hide()
|
||||
}
|
||||
}
|
||||
|
||||
void MacWindow::Close(ClosingReason reason)
|
||||
{
|
||||
const BOOL wasKey = _window && [(NSWindow*)_window isKeyWindow];
|
||||
WindowBase::Close(reason);
|
||||
|
||||
// Closing can be cancelled by managed Window.Closing handlers.
|
||||
if (!IsClosed())
|
||||
return;
|
||||
|
||||
if (NSWindow* window = (NSWindow*)_window)
|
||||
{
|
||||
[window close];
|
||||
}
|
||||
|
||||
if (_settings.Parent && wasKey && _settings.Type != WindowType::Popup && _settings.Type != WindowType::Tooltip)
|
||||
{
|
||||
NSWindow* parent = (NSWindow*)_settings.Parent->GetNativePtr();
|
||||
[parent makeKeyAndOrderFront:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void MacWindow::Minimize()
|
||||
{
|
||||
if (!_settings.AllowMinimize)
|
||||
@@ -967,17 +1044,43 @@ void MacWindow::Maximize()
|
||||
if (!_settings.AllowMaximize)
|
||||
return;
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
if (!window)
|
||||
return;
|
||||
if (!window.zoomed)
|
||||
{
|
||||
if (!_maximized)
|
||||
{
|
||||
_restoreClientBounds = GetClientBounds();
|
||||
_hasRestoreClientBounds = true;
|
||||
}
|
||||
[window zoom:nil];
|
||||
}
|
||||
SyncWindowState();
|
||||
}
|
||||
|
||||
void MacWindow::Restore()
|
||||
{
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
if (!window)
|
||||
return;
|
||||
if (window.miniaturized)
|
||||
{
|
||||
[window deminiaturize:nil];
|
||||
SyncWindowState();
|
||||
}
|
||||
else if (_maximized && _hasRestoreClientBounds)
|
||||
{
|
||||
const Rectangle restoreClientBounds = _restoreClientBounds;
|
||||
_hasRestoreClientBounds = false;
|
||||
NSRect restoreFrame = GetFrameRectForClientBounds(this, window, restoreClientBounds);
|
||||
[window setFrame:restoreFrame display:YES animate:YES];
|
||||
_maximized = false;
|
||||
}
|
||||
else if (window.zoomed)
|
||||
{
|
||||
[window zoom:nil];
|
||||
SyncWindowState();
|
||||
}
|
||||
}
|
||||
|
||||
bool MacWindow::IsForegroundWindow() const
|
||||
@@ -1001,17 +1104,7 @@ void MacWindow::SetClientBounds(const Rectangle& clientArea)
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
if (!window)
|
||||
return;
|
||||
const float screenScale = MacPlatform::ScreenScale;
|
||||
|
||||
NSRect oldRect = [window frame];
|
||||
NSRect newRect = NSMakeRect(0, 0, clientArea.Size.X / screenScale, clientArea.Size.Y / screenScale);
|
||||
newRect = [window frameRectForContentRect:newRect];
|
||||
|
||||
Float2 pos = AppleUtils::PosToCoca(clientArea.Location) / screenScale;
|
||||
Float2 titleSize = GetWindowTitleSize(this);
|
||||
newRect.origin.x = pos.X + titleSize.X;
|
||||
newRect.origin.y = pos.Y - newRect.size.height + titleSize.Y;
|
||||
|
||||
NSRect newRect = GetFrameRectForClientBounds(this, window, clientArea);
|
||||
[window setFrame:newRect display:YES];
|
||||
}
|
||||
|
||||
@@ -1213,4 +1306,37 @@ void MacWindow::SetCursor(CursorType type)
|
||||
}
|
||||
}
|
||||
|
||||
void MacWindow::SetIcon(TextureData& icon)
|
||||
{
|
||||
// Get pixels
|
||||
Array<Color32> colorData;
|
||||
icon.GetPixels(colorData);
|
||||
|
||||
// Convert to Cocoa image
|
||||
NSImage* image = [[NSImage alloc] initWithSize:NSMakeSize(icon.Width, icon.Height)];
|
||||
if (image == nil)
|
||||
return;
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
||||
pixelsWide:icon.Width
|
||||
pixelsHigh:icon.Height
|
||||
bitsPerSample:8
|
||||
samplesPerPixel:4
|
||||
hasAlpha:YES
|
||||
isPlanar:NO
|
||||
colorSpaceName:NSDeviceRGBColorSpace
|
||||
bytesPerRow:icon.Width * 4
|
||||
bitsPerPixel:32];
|
||||
if (rep == nil)
|
||||
return;
|
||||
|
||||
// Copy the pixels
|
||||
Platform::MemoryCopy([rep bitmapData], colorData.Get(), colorData.Count() * sizeof(Color32));
|
||||
|
||||
// Add the image representation
|
||||
[image addRepresentation:rep];
|
||||
|
||||
// Set app icon
|
||||
[NSApp setApplicationIconImage:image];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,13 +17,16 @@ private:
|
||||
void* _window = nullptr;
|
||||
void* _view = nullptr;
|
||||
bool _isMouseOver = false;
|
||||
bool _hasRestoreClientBounds = false;
|
||||
Rectangle _restoreClientBounds;
|
||||
Float2 _mouseTrackPos = Float2::Minimum;
|
||||
String _dragText;
|
||||
|
||||
public:
|
||||
MacWindow(const CreateWindowSettings& settings);
|
||||
~MacWindow();
|
||||
~MacWindow() override;
|
||||
|
||||
void SyncWindowState();
|
||||
void CheckForResize(float width, float height);
|
||||
void SetIsMouseOver(bool value);
|
||||
const String& GetDragText() const
|
||||
@@ -37,6 +40,7 @@ public:
|
||||
void OnUpdate(float dt) override;
|
||||
void Show() override;
|
||||
void Hide() override;
|
||||
void Close(ClosingReason reason) override;
|
||||
void Minimize() override;
|
||||
void Maximize() override;
|
||||
void Restore() override;
|
||||
@@ -59,6 +63,7 @@ public:
|
||||
void StartTrackingMouse(bool useMouseScreenOffset) override;
|
||||
void EndTrackingMouse() override;
|
||||
void SetCursor(CursorType type) override;
|
||||
void SetIcon(TextureData& icon) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,7 +36,7 @@ public class Platform : EngineModule
|
||||
{
|
||||
options.OutputFiles.Add("dbghelp.lib");
|
||||
options.DelayLoadLibraries.Add("dbghelp.dll");
|
||||
options.DependencyFiles.Add(Path.Combine(options.DepsFolder, "dbghelp.dll"));
|
||||
options.OptionalDependencyFiles.Add(Path.Combine(options.DepsFolder, "dbghelp.dll"));
|
||||
}
|
||||
if (options.Target.IsEditor)
|
||||
{
|
||||
|
||||
@@ -247,6 +247,13 @@ FORCE_INLINE void ApplyTransform(const Float2& value, Float2& result)
|
||||
Matrix3x3::Transform2DPoint(value, TransformCached, result);
|
||||
}
|
||||
|
||||
FORCE_INLINE float GetTransformScale()
|
||||
{
|
||||
const Float2 axisX(TransformCached.M11, TransformCached.M12);
|
||||
const Float2 axisY(TransformCached.M21, TransformCached.M22);
|
||||
return (axisX.Length() + axisY.Length()) * 0.5f;
|
||||
}
|
||||
|
||||
void ApplyTransform(const Rectangle& value, RotatedRectangle& result)
|
||||
{
|
||||
const RotatedRectangle rotated(value);
|
||||
@@ -1464,7 +1471,7 @@ void Render2D::DrawRectangle(const Rectangle& rect, const Color& color1, const C
|
||||
|
||||
const auto& mask = ClipLayersStack.Peek().Mask;
|
||||
float thick = thickness;
|
||||
thickness *= (TransformCached.M11 + TransformCached.M22 + TransformCached.M33) * 0.3333333f;
|
||||
thickness *= GetTransformScale();
|
||||
|
||||
// When lines thickness is very large, don't use corner caps and place line ends to not overlap
|
||||
if (thickness > 4.0f)
|
||||
@@ -1840,7 +1847,7 @@ void DrawLines(const Float2* points, int32 pointsCount, const Color& color1, con
|
||||
ASSERT(points && pointsCount >= 2);
|
||||
const auto& mask = ClipLayersStack.Peek().Mask;
|
||||
|
||||
thickness *= (TransformCached.M11 + TransformCached.M22 + TransformCached.M33) * 0.3333333f;
|
||||
thickness *= GetTransformScale();
|
||||
|
||||
Render2DDrawCall& drawCall = DrawCalls.AddOne();
|
||||
drawCall.StartIB = IBIndex;
|
||||
|
||||
@@ -21,27 +21,7 @@
|
||||
|
||||
String AudioTool::Options::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("Format:{}, DisableStreaming:{}, Is3D:{}, Quality:{}, BitDepth:{}"), ScriptingEnum::ToString(Format), DisableStreaming, Is3D, Quality, (int32)BitDepth);
|
||||
}
|
||||
|
||||
void AudioTool::Options::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
{
|
||||
SERIALIZE_GET_OTHER_OBJ(AudioTool::Options);
|
||||
|
||||
SERIALIZE(Format);
|
||||
SERIALIZE(DisableStreaming);
|
||||
SERIALIZE(Is3D);
|
||||
SERIALIZE(Quality);
|
||||
SERIALIZE(BitDepth);
|
||||
}
|
||||
|
||||
void AudioTool::Options::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
DESERIALIZE(Format);
|
||||
DESERIALIZE(DisableStreaming);
|
||||
DESERIALIZE(Is3D);
|
||||
DESERIALIZE(Quality);
|
||||
DESERIALIZE(BitDepth);
|
||||
return String::Format(TEXT("Volume: {}, Format:{}, DisableStreaming:{}, Is3D:{}, Quality:{}, BitDepth:{}"), Volume, ScriptingEnum::ToString(Format), DisableStreaming, Is3D, Quality, (int32)BitDepth);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,13 @@ public:
|
||||
API_STRUCT(Attributes="HideInEditor") struct FLAXENGINE_API Options : public ISerializable
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Options);
|
||||
API_AUTO_SERIALIZATION();
|
||||
|
||||
/// <summary>
|
||||
/// The audio volume. Can be used to scale source audio data at import time.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(5), Limit(0, 10, 0.01f)")
|
||||
float Volume = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The audio data format to import the audio clip as.
|
||||
@@ -74,10 +81,6 @@ public:
|
||||
BitDepth BitDepth = BitDepth::_16;
|
||||
|
||||
String ToString() const;
|
||||
|
||||
// [ISerializable]
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -475,7 +475,11 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
|
||||
uv = MaterialValue::Cast(tryGetValue(uvBox, getUVs), VariantType::Float2).Value;
|
||||
else
|
||||
uv = TEXT("input.TexCoord.xy");
|
||||
value = writeLocal(VariantType::Float3, String::Format(TEXT("GetWorldPos({1}, {0}.rgb)"), depthSample->Value, uv), node);
|
||||
const auto layer = GetRootLayer();
|
||||
if (layer && layer->Domain == MaterialDomain::PostProcess)
|
||||
value = writeLocal(VariantType::Float3, String::Format(TEXT("GetWorldPos({1}, {0})"), depthSample->Value, uv), node);
|
||||
else // TODO: reimpl GetWorldPos() for other domains (see 'Content/Editor/MaterialTemplates/PostProcess.shader'), can be via matrix inverse in a shader
|
||||
value = ShaderGraphValue::InitForZero(VariantType::Float3);
|
||||
break;
|
||||
}
|
||||
case MaterialSceneTextures::SceneStencil:
|
||||
|
||||
@@ -228,19 +228,27 @@ namespace FlaxEngine.GUI
|
||||
float progressNormalized = Mathf.InverseLerp(_minimum, _maximum, _current);
|
||||
if (progressNormalized > 0.001f)
|
||||
{
|
||||
Rectangle barRect = new Rectangle(0, 0, Width * progressNormalized, Height);
|
||||
Rectangle rect = new Rectangle(0, 0, Width, Height);
|
||||
BarMargin.ShrinkRectangle(ref rect);
|
||||
if (rect.Width <= 0.0f || rect.Height <= 0.0f)
|
||||
return;
|
||||
|
||||
Rectangle barRect = rect;
|
||||
switch (Origin)
|
||||
{
|
||||
case BarOrigin.HorizontalLeft:
|
||||
barRect.Width *= progressNormalized;
|
||||
break;
|
||||
case BarOrigin.HorizontalRight:
|
||||
barRect = new Rectangle(Width - Width * progressNormalized, 0, Width * progressNormalized, Height);
|
||||
barRect.Width *= progressNormalized;
|
||||
barRect.X = rect.Right - barRect.Width;
|
||||
break;
|
||||
case BarOrigin.VerticalTop:
|
||||
barRect = new Rectangle(0, 0, Width, Height * progressNormalized);
|
||||
barRect.Height *= progressNormalized;
|
||||
break;
|
||||
case BarOrigin.VerticalBottom:
|
||||
barRect = new Rectangle(0, Height - Height * progressNormalized, Width, Height * progressNormalized);
|
||||
barRect.Height *= progressNormalized;
|
||||
barRect.Y = rect.Bottom - barRect.Height;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
@@ -248,15 +256,12 @@ namespace FlaxEngine.GUI
|
||||
switch (Method)
|
||||
{
|
||||
case BarMethod.Stretch:
|
||||
BarMargin.ShrinkRectangle(ref barRect);
|
||||
if (BarBrush != null)
|
||||
BarBrush.Draw(barRect, BarColor);
|
||||
else
|
||||
Render2D.FillRectangle(barRect, BarColor);
|
||||
break;
|
||||
case BarMethod.Clip:
|
||||
var rect = new Rectangle(0, 0, Width, Height);
|
||||
BarMargin.ShrinkRectangle(ref rect);
|
||||
Render2D.PushClip(ref barRect);
|
||||
if (BarBrush != null)
|
||||
BarBrush.Draw(rect, BarColor);
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace FlaxEngine
|
||||
Matrix.Multiply(ref worldMatrix, ref renderContext.View.View, out Matrix viewMatrix);
|
||||
Matrix projectionMatrix = renderContext.View.Projection;
|
||||
if (worldSpace && (Canvas.RenderLocation == PostProcessEffectLocation.Default || Canvas.RenderLocation == PostProcessEffectLocation.AfterAntiAliasingPass))
|
||||
projectionMatrix = renderContext.View.NonJitteredProjection; // Fix TAA jittering when rendering UI in world after TAA resolve
|
||||
renderContext.View.GetOverlayProjection(out projectionMatrix); // Fix TAA jittering when rendering UI in world after TAA resolve
|
||||
Matrix.Multiply(ref viewMatrix, ref projectionMatrix, out Matrix viewProjectionMatrix);
|
||||
|
||||
// Pick a depth buffer
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "ShaderGraph.h"
|
||||
#include "GraphUtilities.h"
|
||||
#include "ShaderGraphUtilities.h"
|
||||
#include "Engine/Content/Assets/Texture.h"
|
||||
#include "Engine/Content/Assets/CubeTexture.h"
|
||||
#include "Engine/Engine/GameplayGlobals.h"
|
||||
|
||||
const Char* ShaderGenerator::_mathFunctions[] =
|
||||
@@ -742,6 +744,37 @@ void ShaderGenerator::ProcessGroupTools(Box* box, Node* node, Value& value)
|
||||
// Get param value
|
||||
value.Type = variable.DefaultValue.Type.Type;
|
||||
value.Value = param->ShaderName;
|
||||
switch (variable.DefaultValue.Type.Type)
|
||||
{
|
||||
case VariantType::Bool:
|
||||
case VariantType::Int:
|
||||
case VariantType::Uint:
|
||||
case VariantType::Float:
|
||||
case VariantType::Float2:
|
||||
case VariantType::Float3:
|
||||
case VariantType::Float4:
|
||||
case VariantType::Color:
|
||||
case VariantType::Double2:
|
||||
case VariantType::Double3:
|
||||
case VariantType::Double4:
|
||||
case VariantType::Int2:
|
||||
case VariantType::Int3:
|
||||
case VariantType::Int4:
|
||||
// POD value types
|
||||
break;
|
||||
case VariantType::Asset:
|
||||
if (Texture::GetStaticType().Fullname == variable.DefaultValue.Type.TypeName ||
|
||||
CubeTexture::GetStaticType().Fullname == variable.DefaultValue.Type.TypeName)
|
||||
{
|
||||
// Texture or Cube Texture
|
||||
value.Type = VariantType::Object;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG(Warning, "Invalid Gameplay Global '{}' ({}) value type '{}' to bind to material", name, asset->GetPath(), variable.DefaultValue.Type.ToString());
|
||||
value = Value::Zero;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Platform Switch
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "Engine/Core/Types/StringBuilder.h"
|
||||
#include "Engine/Core/Math/Vector4.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Assets/Texture.h"
|
||||
#include "Engine/Content/Assets/CubeTexture.h"
|
||||
#include "Engine/Engine/GameplayGlobals.h"
|
||||
#include "Engine/Graphics/Config.h"
|
||||
#include "Engine/Renderer/GlobalSignDistanceFieldPass.h"
|
||||
@@ -172,6 +174,26 @@ const Char* ShaderGraphUtilities::GenerateShaderResources(TextWriterUnicode& wri
|
||||
case MaterialParameterType::GPUTextureVolume:
|
||||
format = TEXT("Texture3D {0} : register(t{1});");
|
||||
break;
|
||||
case MaterialParameterType::GameplayGlobal:
|
||||
{
|
||||
auto asset = Content::LoadAsync<GameplayGlobals>(param.AsGuid);
|
||||
if (!asset || asset->WaitForLoaded())
|
||||
break;
|
||||
GameplayGlobals::Variable variable;
|
||||
if (!asset->Variables.TryGet(param.Name, variable))
|
||||
break;
|
||||
if (Texture::GetStaticType().Fullname == variable.DefaultValue.Type.TypeName)
|
||||
{
|
||||
// Texture
|
||||
format = TEXT("Texture2D {0} : register(t{1});");
|
||||
}
|
||||
else if (CubeTexture::GetStaticType().Fullname == variable.DefaultValue.Type.TypeName)
|
||||
{
|
||||
// Cube Texture
|
||||
format = TEXT("TextureCube {0} : register(t{1});");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MaterialParameterType::GlobalSDF:
|
||||
format = TEXT("Texture3D<snorm float> {0}_Tex : register(t{1});\nTexture3D<snorm float> {0}_Mip : register(t{2});");
|
||||
zeroOffset = false;
|
||||
|
||||
Reference in New Issue
Block a user