Compare commits
134 Commits
eca4f6d9bc
...
goake
| Author | SHA1 | Date | |
|---|---|---|---|
| cdbb9baeb8 | |||
| e12bb0ffe7 | |||
| 27e45554a4 | |||
| bdb28b8589 | |||
| 83b301684d | |||
| d70aa20a7a | |||
| b958ecc64f | |||
| e573703c4a | |||
| 48fa41fc58 | |||
| 25036be05f | |||
| c16ec763c2 | |||
| a986ede53f | |||
| 5c110fe154 | |||
| 460128dd82 | |||
| 75d83a2ef3 | |||
| 91a6450c94 | |||
| 440ecea5ca | |||
| d32f690eac | |||
| f7677b6ab8 | |||
| 6d9c6fecf7 | |||
| 81f94e08a9 | |||
| a5ffe8893a | |||
| 8a41e04641 | |||
| 22132d550c | |||
| 9f2016b619 | |||
| 43e85e58ee | |||
| e50f87a5fb | |||
| 79135e596a | |||
| 63d298ca84 | |||
| db318b56e3 | |||
| 0fb0492738 | |||
| 7ed59a4426 | |||
| a818f39464 | |||
| d83220aad6 | |||
| 70d7e9204a | |||
| 84da819f30 | |||
| f29a014aec | |||
| a2edead792 | |||
| 479b65fab5 | |||
| e175c2ce3a | |||
| 9d1b65730f | |||
| dea5f7aa4e | |||
| 0c8064fb0c | |||
| 49497d1a78 | |||
| 674d5b9709 | |||
| 26ae90a999 | |||
| cad96d8131 | |||
| df62892725 | |||
| 43b2348d62 | |||
| 54761f40fe | |||
| 4ad78fdb80 | |||
| e8cb1686c3 | |||
| 20a92a994e | |||
| 3df1e86ecb | |||
| 70edfbb146 | |||
| a8ef6e69fe | |||
| 753a6c73f8 | |||
| 66b0b4c965 | |||
| 57ab58608e | |||
| 210dd603b0 | |||
| 44e726ceca | |||
| e8c50ec442 | |||
| 983c22a3a6 | |||
| 9e8865bd12 | |||
| 203cede21d | |||
| e21c06e595 | |||
| 279badf0f9 | |||
| af326f934c | |||
| 68c9ff92b9 | |||
| d65af4c621 | |||
| d3f14efbbd | |||
| 07c34fa70b | |||
| 19b5da4338 | |||
| 9b68acd648 | |||
| 1f265bddf4 | |||
| 3237849132 | |||
| 2be4d2b717 | |||
| dc3a1e142a | |||
| b6d375e9a3 | |||
| 495b6d6abc | |||
| a49b398c7f | |||
| c8e893d2ec | |||
| 3a665199e7 | |||
| ca1aa89ba1 | |||
| d92aaeb2b0 | |||
| 5f950cbb7e | |||
| 8f613774cb | |||
| c5c440469e | |||
| 1e6ed32c63 | |||
| 3ee6bffef7 | |||
| 6105323ecc | |||
| 23f8707927 | |||
| 761c8415dc | |||
|
|
cdeb9a3b15 | ||
|
|
60e8d73079 | ||
|
|
cf23892bd4 | ||
|
|
25f3cef8c3 | ||
|
|
00f2a0b825 | ||
|
|
7342629a86 | ||
|
|
5f860db6a5 | ||
|
|
6233718b06 | ||
|
|
62444315de | ||
|
|
a532ea7b42 | ||
|
|
803249f126 | ||
|
|
4e65b76b8c | ||
|
|
890b2da108 | ||
|
|
eac1d19a09 | ||
|
|
c4949de28f | ||
|
|
340ef194d3 | ||
|
|
b4547ec4d2 | ||
|
|
89f7e442f7 | ||
|
|
e7bef5e880 | ||
|
|
ff7c986fb1 | ||
|
|
708fba5136 | ||
|
|
7d92779e99 | ||
|
|
4c8528dcae | ||
|
|
3efd1e4e84 | ||
|
|
0cc6669cbd | ||
|
|
8bd409e95d | ||
|
|
3d0d41ebff | ||
|
|
61323f8526 | ||
|
|
017def29d4 | ||
|
|
13a04c2941 | ||
|
|
bc9cdf5cdb | ||
|
|
f7470af42d | ||
|
|
5c356ec22a | ||
|
|
06a35da0a8 | ||
|
|
55af307c43 | ||
|
|
4ab572426d | ||
|
|
01d91bf102 | ||
|
|
2dfb1058b2 | ||
|
|
cdbb2cc813 | ||
|
|
0e00f1e0eb | ||
|
|
d13621e631 |
@@ -1,4 +1,4 @@
|
||||
# Redirect to our own Git LFS server
|
||||
[lfs]
|
||||
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||
locksverify = false
|
||||
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||
locksverify = false
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -16,7 +16,6 @@
|
||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||
@2// Forward Shading: Constants
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
@@ -26,9 +25,9 @@ LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
@3// Forward Shading: Resources
|
||||
TextureCube EnvProbe : register(t__SRV__);
|
||||
TextureCube SkyLightTexture : register(t__SRV__);
|
||||
Texture2DArray DirectionalLightShadowMap : register(t__SRV__);
|
||||
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
||||
Texture2D<float> ShadowMap : register(t__SRV__);
|
||||
@4// Forward Shading: Utilities
|
||||
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
@5// Forward Shading: Shaders
|
||||
|
||||
// Pixel Shader function for Forward Pass
|
||||
@@ -80,11 +79,8 @@ void PS_Forward(
|
||||
|
||||
// Calculate lighting from a single directional light
|
||||
float4 shadowMask = 1.0f;
|
||||
if (DirectionalLight.CastShadows > 0)
|
||||
{
|
||||
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||
}
|
||||
ShadowSample shadow = SampleDirectionalLightShadow(DirectionalLight, ShadowsBuffer, ShadowMap, gBuffer);
|
||||
shadowMask = GetShadowMask(shadow);
|
||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||
|
||||
// Calculate lighting from sky light
|
||||
|
||||
@@ -26,7 +26,7 @@ struct RibbonInput
|
||||
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
uint SortedIndicesOffset;
|
||||
float PerInstanceRandom;
|
||||
int ParticleStride;
|
||||
@@ -45,7 +45,7 @@ int RibbonWidthOffset;
|
||||
int RibbonTwistOffset;
|
||||
int RibbonFacingVectorOffset;
|
||||
uint RibbonSegmentCount;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
float4x3 WorldMatrixInverseTransposed;
|
||||
@1META_CB_END
|
||||
|
||||
// Particles attributes buffer
|
||||
@@ -138,7 +138,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
||||
#if USE_INSTANCING
|
||||
#define GetInstanceTransform(input) float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f))
|
||||
#else
|
||||
#define GetInstanceTransform(input) WorldMatrix;
|
||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
||||
#endif
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
@@ -264,12 +264,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
|
||||
float3 TransformParticlePosition(float3 input)
|
||||
{
|
||||
return mul(float4(input, 1.0f), WorldMatrix).xyz;
|
||||
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
||||
}
|
||||
|
||||
@8
|
||||
@@ -333,7 +333,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
||||
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
|
||||
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
|
||||
|
||||
float4x4 world = WorldMatrix;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||
float3x3 viewRot = transpose((float3x3)ViewMatrix);
|
||||
float3 position = mul(float4(particlePosition, 1), world).xyz;
|
||||
@@ -463,11 +463,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
}
|
||||
|
||||
// Read particle data
|
||||
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
||||
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
|
||||
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
|
||||
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
|
||||
int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1;
|
||||
float3 position = mul(float4(particlePosition, 1), WorldMatrix).xyz;
|
||||
float3 position = mul(float4(particlePosition, 1), worldMatrix).xyz;
|
||||
|
||||
// Compute final vertex position in the world
|
||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||
@@ -506,7 +507,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
world = mul(world, scaleMatrix);
|
||||
}
|
||||
world = transpose(world);
|
||||
world = mul(world, WorldMatrix);
|
||||
world = mul(world, worldMatrix);
|
||||
|
||||
// Calculate the vertex position in world space
|
||||
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
|
||||
@@ -520,12 +521,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = input.Color;
|
||||
#endif
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
output.InstanceOrigin = worldMatrix[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = CalcTangentToLocal(input);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
||||
output.TBN = tangentToWorld;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
@@ -625,12 +626,13 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = 1;
|
||||
#endif
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
output.InstanceOrigin = world[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
|
||||
output.TBN = tangentToWorld;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 PrevWorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
float4x3 PrevWorldMatrix;
|
||||
float2 Dummy0;
|
||||
float LODDitherFactor;
|
||||
float PerInstanceRandom;
|
||||
@@ -171,7 +171,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
||||
#if USE_INSTANCING
|
||||
#define CalculateInstanceTransform(input) float4x4 world = GetInstanceTransform(input); output.Geometry.InstanceTransform1 = input.InstanceTransform1.xyz; output.Geometry.InstanceTransform2 = input.InstanceTransform2.xyz; output.Geometry.InstanceTransform3 = input.InstanceTransform3.xyz;
|
||||
#else
|
||||
#define CalculateInstanceTransform(input) float4x4 world = WorldMatrix; output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz;
|
||||
#define CalculateInstanceTransform(input) float4x4 world = ToMatrix4x4(WorldMatrix); output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz;
|
||||
#endif
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
@@ -328,7 +328,7 @@ VertexOutput VS(ModelInput input)
|
||||
// Compute world space vertex position
|
||||
CalculateInstanceTransform(input);
|
||||
output.Geometry.WorldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
|
||||
// Compute clip space position
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -402,7 +402,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
|
||||
#if USE_INSTANCING
|
||||
float4x4 world = GetInstanceTransform(input);
|
||||
#else
|
||||
float4x4 world = WorldMatrix;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
#endif
|
||||
float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||
float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -508,9 +508,9 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), world).xyz;
|
||||
#if PER_BONE_MOTION_BLUR
|
||||
float3 prevPosition = SkinPrevPosition(input);
|
||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
#else
|
||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
#endif
|
||||
|
||||
// Compute clip space position
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
float3 WorldInvScale;
|
||||
float WorldDeterminantSign;
|
||||
float PerInstanceRandom;
|
||||
@@ -194,7 +194,7 @@ float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||
{
|
||||
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localVector, localToWorld);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
{
|
||||
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localToWorld, worldVector);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
// Gets the current object position
|
||||
float3 GetObjectPosition(MaterialInput input)
|
||||
{
|
||||
return WorldMatrix[3].xyz;
|
||||
return ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||
}
|
||||
|
||||
// Gets the current object size
|
||||
@@ -365,7 +365,8 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
float3 position = float3(positionXZ.x, height, positionXZ.y);
|
||||
|
||||
// Compute world space vertex position
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), WorldMatrix).xyz;
|
||||
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), worldMatrix).xyz;
|
||||
|
||||
// Compute clip space position
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -389,7 +390,7 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
|
||||
// Compute world space normal vector
|
||||
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
||||
output.Geometry.WorldNormal = tangentToWorld[2];
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 InverseViewProjectionMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
float4x3 WorldMatrix;
|
||||
float4x3 WorldMatrixInverseTransposed;
|
||||
float3 GridSize;
|
||||
float PerInstanceRandom;
|
||||
float Dummy0;
|
||||
@@ -49,7 +49,7 @@ struct MaterialInput
|
||||
#endif
|
||||
};
|
||||
|
||||
#define GetInstanceTransform(input) WorldMatrix;
|
||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
|
||||
@@ -170,12 +170,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
|
||||
float3 TransformParticlePosition(float3 input)
|
||||
{
|
||||
return mul(float4(input, 1.0f), WorldMatrix).xyz;
|
||||
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
||||
}
|
||||
|
||||
@8
|
||||
@@ -219,7 +219,7 @@ void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out fl
|
||||
materialInput.ParticleIndex = ParticleIndex;
|
||||
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
||||
materialInput.TwoSidedSign = 1.0f;
|
||||
materialInput.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
materialInput.InstanceOrigin = ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||
materialInput.InstanceParams = PerInstanceRandom;
|
||||
materialInput.SvPosition = clipPos;
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Lights.flax
LFS
BIN
Content/Shaders/Lights.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Quad.flax
LFS
BIN
Content/Shaders/Quad.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Shadows.flax
LFS
BIN
Content/Shaders/Shadows.flax
LFS
Binary file not shown.
Binary file not shown.
@@ -2,9 +2,9 @@
|
||||
"Name": "Flax",
|
||||
"Version": {
|
||||
"Major": 1,
|
||||
"Minor": 8,
|
||||
"Revision": 1,
|
||||
"Build": 6511
|
||||
"Minor": 9,
|
||||
"Revision": 0,
|
||||
"Build": 6601
|
||||
},
|
||||
"Company": "Flax",
|
||||
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
|
||||
|
||||
@@ -1246,6 +1246,8 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
assetStats.Count++;
|
||||
assetStats.ContentSize += FileSystem::GetFileSize(cookedFilePath);
|
||||
|
||||
LOG(Info, "Cooked size of {0}: {1}KB", assetId, (FileSystem::GetFileSize(cookedFilePath) / (1024)));
|
||||
|
||||
if (packageBuilder.Add(data, i->Value, cookedFilePath))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -353,9 +353,9 @@ bool DeployDataStep::Perform(CookingData& data)
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/NormalTexture"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/BlackTexture"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/WhiteTexture"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensStarburst"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensColor"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensDirt"));
|
||||
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensStarburst"));
|
||||
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensColor"));
|
||||
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensDirt"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Circle"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Hexagon"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Octagon"));
|
||||
|
||||
@@ -377,6 +377,10 @@ namespace FlaxEditor.CustomEditors
|
||||
else if (Values.HasDefaultValue && CanRevertDefaultValue)
|
||||
color = Color.Yellow * 0.8f;
|
||||
LinkedLabel.HighlightStripColor = color;
|
||||
|
||||
// Grey out deprecated members
|
||||
if (Values.IsObsolete)
|
||||
LinkedLabel.TextColor = LinkedLabel.TextColorHighlighted = FlaxEngine.GUI.Style.Current.ForegroundGrey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +663,7 @@ namespace FlaxEditor.CustomEditors
|
||||
}
|
||||
}
|
||||
|
||||
if (obj == null || Values.Type.IsInstanceOfType(obj))
|
||||
if ((obj == null && !Values.Type.IsValueType) || Values.Type.IsInstanceOfType(obj))
|
||||
{
|
||||
result = obj;
|
||||
return true;
|
||||
@@ -671,20 +675,7 @@ namespace FlaxEditor.CustomEditors
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether can paste value from the system clipboard to the property value container.
|
||||
/// </summary>
|
||||
public bool CanPaste
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetClipboardObject(out _, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool CanPaste => !string.IsNullOrEmpty(Clipboard.Text);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value from the system clipboard.
|
||||
|
||||
@@ -192,6 +192,15 @@ namespace FlaxEditor.CustomEditors
|
||||
Presenter.AfterLayout?.Invoke(layout);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
Editor = null;
|
||||
_overrideEditor = null;
|
||||
|
||||
base.Deinitialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnModified()
|
||||
{
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
if (_linkedPrefabId != Guid.Empty)
|
||||
{
|
||||
_linkedPrefabId = Guid.Empty;
|
||||
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplying;
|
||||
Editor.Instance.Prefabs.PrefabApplying -= OnPrefabApplying;
|
||||
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplied;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1029,6 +1029,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
_scriptToggles = null;
|
||||
_scripts.Clear();
|
||||
|
||||
base.Deinitialize();
|
||||
}
|
||||
|
||||
@@ -474,32 +474,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
if (layout.Editors.Count != 0)
|
||||
{
|
||||
var sb = Clipboard.Text;
|
||||
if (!string.IsNullOrEmpty(sb))
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<string[]>(sb);
|
||||
if (data == null || data.Length != layout.Editors.Count)
|
||||
return false;
|
||||
for (var i = 0; i < layout.Editors.Count; i++)
|
||||
{
|
||||
Clipboard.Text = data[i];
|
||||
if (!layout.Editors[i].CanPaste)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Clipboard.Text = sb;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return !string.IsNullOrEmpty(Clipboard.Text);
|
||||
}
|
||||
if (layout.Children.Any(x => x is LayoutElementsContainer))
|
||||
{
|
||||
@@ -824,6 +799,15 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
OnGroupsEnd();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
_visibleIfCaches = null;
|
||||
_visibleIfPropertiesListsCache = null;
|
||||
|
||||
base.Deinitialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Refresh()
|
||||
{
|
||||
|
||||
@@ -139,6 +139,11 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
public bool IsArray => Type != ScriptType.Null && Type.IsArray;
|
||||
|
||||
/// <summary>
|
||||
/// True if member or type has <see cref="System.ObsoleteAttribute"/> that marks it as obsolete.
|
||||
/// </summary>
|
||||
public bool IsObsolete { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values types array (without duplicates).
|
||||
/// </summary>
|
||||
@@ -160,6 +165,7 @@ namespace FlaxEditor.CustomEditors
|
||||
{
|
||||
Info = info;
|
||||
Type = Info.ValueType;
|
||||
IsObsolete = Info.HasAttribute(typeof(ObsoleteAttribute), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -497,6 +497,8 @@ namespace FlaxEditor
|
||||
Debug.LogException(ex);
|
||||
}
|
||||
|
||||
ManagedHandle.ManagedHandlePool.TryCollectWeakHandles();
|
||||
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
|
||||
|
||||
@@ -235,6 +235,9 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
_previouslyFocused = parentWin.FocusedControl;
|
||||
Focus();
|
||||
OnShow();
|
||||
|
||||
// Throttle rendering of static content
|
||||
_window.RenderTask.RenderFPS = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -178,6 +178,9 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
windowGUI.PerformLayout();
|
||||
|
||||
OnShow();
|
||||
|
||||
// Throttle rendering of static content
|
||||
_window.RenderTask.RenderFPS = 2;
|
||||
}
|
||||
|
||||
private void OnClosing(ClosingReason reason, ref bool cancel)
|
||||
|
||||
@@ -346,6 +346,10 @@ namespace FlaxEditor.GUI.Docking
|
||||
{
|
||||
if (button == MouseButton.Left)
|
||||
{
|
||||
// Workaround to make sure the mouse down event which initiated dragging in moved window gets properly
|
||||
// released when this window gets destroyed.
|
||||
_toMove.Window.Window.Internal_OnMouseUp(ref location, button);
|
||||
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -447,6 +451,9 @@ namespace FlaxEditor.GUI.Docking
|
||||
Window = Platform.CreateWindow(ref settings);
|
||||
Window.Opacity = 0.6f;
|
||||
Window.GUI.BackgroundColor = Style.Current.DragWindow;
|
||||
|
||||
// Throttle rendering of static content
|
||||
Window.RenderTask.RenderFPS = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -480,6 +487,9 @@ namespace FlaxEditor.GUI.Docking
|
||||
win = Platform.CreateWindow(ref settings);
|
||||
win.Opacity = 0.6f;
|
||||
win.GUI.BackgroundColor = Style.Current.DragWindow;
|
||||
|
||||
// Throttle rendering of static content
|
||||
win.RenderTask.RenderFPS = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -88,6 +88,8 @@ namespace FlaxEditor.Modules
|
||||
|
||||
// Register AssetItems serialization helper (serialize ref ID only)
|
||||
FlaxEngine.Json.JsonSerializer.Settings.Converters.Add(new AssetItemConverter());
|
||||
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
private void OnContentAssetDisposing(Asset asset)
|
||||
@@ -1260,6 +1262,47 @@ namespace FlaxEditor.Modules
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
var enabledEvents = _enableEvents;
|
||||
_enableEvents = false;
|
||||
_isDuringFastSetup = true;
|
||||
var startItems = _itemsCreated;
|
||||
foreach (var project in Projects)
|
||||
{
|
||||
if (project.Content != null)
|
||||
{
|
||||
//Dispose(project.Content.Folder);
|
||||
for (int i = 0; i < project.Content.Folder.Children.Count; i++)
|
||||
{
|
||||
Dispose(project.Content.Folder.Children[i]);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (project.Source != null)
|
||||
{
|
||||
//Dispose(project.Source.Folder);
|
||||
for (int i = 0; i < project.Source.Folder.Children.Count; i++)
|
||||
{
|
||||
Dispose(project.Source.Folder.Children[i]);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<ContentProxy> removeProxies = new List<ContentProxy>();
|
||||
foreach (var proxy in Editor.Instance.ContentDatabase.Proxy)
|
||||
{
|
||||
if (proxy.GetType().IsCollectible)
|
||||
removeProxies.Add(proxy);
|
||||
}
|
||||
foreach (var proxy in removeProxies)
|
||||
RemoveProxy(proxy, false);
|
||||
|
||||
_isDuringFastSetup = false;
|
||||
_enableEvents = enabledEvents;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnUpdate()
|
||||
{
|
||||
@@ -1285,6 +1328,7 @@ namespace FlaxEditor.Modules
|
||||
public override void OnExit()
|
||||
{
|
||||
FlaxEngine.Content.AssetDisposing -= OnContentAssetDisposing;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
|
||||
// Disable events
|
||||
_enableEvents = false;
|
||||
|
||||
@@ -391,6 +391,20 @@ namespace FlaxEditor.Modules
|
||||
public override void OnInit()
|
||||
{
|
||||
ImportFileEntry.RegisterDefaultTypes();
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
// Remove import file types from scripting assemblies
|
||||
List<string> removeFileTypes = new List<string>();
|
||||
foreach (var pair in ImportFileEntry.FileTypes)
|
||||
{
|
||||
if (pair.Value.Method.IsCollectible || (pair.Value.Target != null && pair.Value.Target.GetType().IsCollectible))
|
||||
removeFileTypes.Add(pair.Key);
|
||||
}
|
||||
foreach (var fileType in removeFileTypes)
|
||||
ImportFileEntry.FileTypes.Remove(fileType);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -451,6 +465,7 @@ namespace FlaxEditor.Modules
|
||||
/// <inheritdoc />
|
||||
public override void OnExit()
|
||||
{
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
EndWorker();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,12 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI.Dialogs;
|
||||
using FlaxEditor.GUI.Docking;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEditor.Windows.Profiler;
|
||||
@@ -39,6 +41,7 @@ namespace FlaxEditor.Modules
|
||||
|
||||
public DockState DockState;
|
||||
public DockPanel DockedTo;
|
||||
public int DockedTabIndex;
|
||||
public float? SplitterValue = null;
|
||||
|
||||
public bool SelectOnShow = false;
|
||||
@@ -48,6 +51,8 @@ namespace FlaxEditor.Modules
|
||||
public Float2 FloatSize;
|
||||
public Float2 FloatPosition;
|
||||
|
||||
public AssetItem Item;
|
||||
|
||||
// Constructor, to allow for default values
|
||||
public WindowRestoreData()
|
||||
{
|
||||
@@ -807,6 +812,56 @@ namespace FlaxEditor.Modules
|
||||
Editor.StateMachine.StateChanged += OnEditorStateChanged;
|
||||
}
|
||||
|
||||
internal void AddToRestore(PrefabWindow win)
|
||||
{
|
||||
var type = win.GetType();
|
||||
var winData = new WindowRestoreData();
|
||||
var panel = win.ParentDockPanel;
|
||||
|
||||
// Ensure that this window is only selected following recompilation
|
||||
// if it was the active tab in its dock panel. Otherwise, there is a
|
||||
// risk of interrupting the user's workflow by potentially selecting
|
||||
// background tabs.
|
||||
var window = win.RootWindow?.Window;
|
||||
winData.SelectOnShow = panel.SelectedTab == win;
|
||||
winData.DockedTabIndex = 0;
|
||||
if (panel is FloatWindowDockPanel && window != null && panel.TabsCount == 1)
|
||||
{
|
||||
winData.DockState = DockState.Float;
|
||||
winData.FloatPosition = window.Position;
|
||||
winData.FloatSize = window.ClientSize;
|
||||
winData.Maximize = window.IsMaximized;
|
||||
winData.Minimize = window.IsMinimized;
|
||||
winData.DockedTo = panel;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < panel.Tabs.Count; i++)
|
||||
{
|
||||
if (panel.Tabs[i] == win)
|
||||
{
|
||||
winData.DockedTabIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (panel.TabsCount > 1)
|
||||
{
|
||||
winData.DockState = DockState.DockFill;
|
||||
winData.DockedTo = panel;
|
||||
}
|
||||
else
|
||||
{
|
||||
winData.DockState = panel.TryGetDockState(out var splitterValue);
|
||||
winData.DockedTo = panel.ParentDockPanel;
|
||||
winData.SplitterValue = splitterValue;
|
||||
}
|
||||
}
|
||||
winData.AssemblyName = type.Assembly.GetName().Name;
|
||||
winData.TypeName = type.FullName;
|
||||
winData.Item = win.Item;
|
||||
_restoreWindows.Add(winData);
|
||||
}
|
||||
|
||||
internal void AddToRestore(CustomEditorWindow win)
|
||||
{
|
||||
var type = win.GetType();
|
||||
@@ -839,7 +894,8 @@ namespace FlaxEditor.Modules
|
||||
{
|
||||
winData.DockState = DockState.DockFill;
|
||||
winData.DockedTo = panel;
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
winData.DockState = panel.TryGetDockState(out var splitterValue);
|
||||
winData.DockedTo = panel.ParentDockPanel;
|
||||
@@ -853,36 +909,89 @@ namespace FlaxEditor.Modules
|
||||
|
||||
private void OnScriptsReloadEnd()
|
||||
{
|
||||
for (int i = 0; i < _restoreWindows.Count; i++)
|
||||
// Go in reverse order to create floating Prefab windows first before docked windows
|
||||
for (int i = _restoreWindows.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var winData = _restoreWindows[i];
|
||||
|
||||
try
|
||||
{
|
||||
var assembly = Utils.GetAssemblyByName(winData.AssemblyName);
|
||||
if (assembly != null)
|
||||
if (assembly == null)
|
||||
continue;
|
||||
|
||||
var type = assembly.GetType(winData.TypeName);
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
if (type == typeof(PrefabWindow))
|
||||
{
|
||||
var type = assembly.GetType(winData.TypeName);
|
||||
if (type != null)
|
||||
var win = new PrefabWindow(Editor.Instance, winData.Item);
|
||||
win.Show(winData.DockState, winData.DockState != DockState.Float ? winData.DockedTo : null, winData.SelectOnShow, winData.SplitterValue);
|
||||
if (winData.DockState == DockState.Float)
|
||||
{
|
||||
var win = (CustomEditorWindow)Activator.CreateInstance(type);
|
||||
win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue);
|
||||
if (winData.DockState == DockState.Float)
|
||||
var window = win.RootWindow.Window;
|
||||
window.Position = winData.FloatPosition;
|
||||
if (winData.Maximize)
|
||||
{
|
||||
var window = win.Window.RootWindow.Window;
|
||||
window.Position = winData.FloatPosition;
|
||||
if (winData.Maximize)
|
||||
{
|
||||
window.Maximize();
|
||||
}
|
||||
else if (winData.Minimize)
|
||||
{
|
||||
window.Minimize();
|
||||
}
|
||||
else
|
||||
{
|
||||
window.ClientSize = winData.FloatSize;
|
||||
}
|
||||
window.Maximize();
|
||||
}
|
||||
else if (winData.Minimize)
|
||||
{
|
||||
window.Minimize();
|
||||
}
|
||||
else
|
||||
{
|
||||
window.ClientSize = winData.FloatSize;
|
||||
}
|
||||
|
||||
// Update panel reference in other windows docked to this panel
|
||||
foreach (ref var otherData in CollectionsMarshal.AsSpan(_restoreWindows))
|
||||
{
|
||||
if (otherData.DockedTo == winData.DockedTo)
|
||||
otherData.DockedTo = win.ParentDockPanel;
|
||||
}
|
||||
}
|
||||
var panel = win.ParentDockPanel;
|
||||
int currentTabIndex = 0;
|
||||
for (int pi = 0; pi < panel.TabsCount; pi++)
|
||||
{
|
||||
if (panel.Tabs[pi] == win)
|
||||
{
|
||||
currentTabIndex = pi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (currentTabIndex > winData.DockedTabIndex)
|
||||
{
|
||||
win.ParentDockPanel.MoveTabLeft(currentTabIndex);
|
||||
currentTabIndex--;
|
||||
}
|
||||
while (currentTabIndex < winData.DockedTabIndex)
|
||||
{
|
||||
win.ParentDockPanel.MoveTabRight(currentTabIndex);
|
||||
currentTabIndex++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var win = (CustomEditorWindow)Activator.CreateInstance(type);
|
||||
win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue);
|
||||
if (winData.DockState == DockState.Float)
|
||||
{
|
||||
var window = win.Window.RootWindow.Window;
|
||||
window.Position = winData.FloatPosition;
|
||||
if (winData.Maximize)
|
||||
{
|
||||
window.Maximize();
|
||||
}
|
||||
else if (winData.Minimize)
|
||||
{
|
||||
window.Minimize();
|
||||
}
|
||||
else
|
||||
{
|
||||
window.ClientSize = winData.FloatSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,13 +175,6 @@ namespace FlaxEditor.Options
|
||||
[EditorDisplay("Interface", "New Window Location"), EditorOrder(150), Tooltip("Define the opening method for new windows, open in a new tab by default.")]
|
||||
public DockStateProxy NewWindowLocation { get; set; } = DockStateProxy.Float;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timestamps prefix mode for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(TimestampsFormats.None)]
|
||||
[EditorDisplay("Interface"), EditorOrder(210), Tooltip("The timestamps prefix mode for debug log messages.")]
|
||||
public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the editor icons scale. Editor restart required.
|
||||
/// </summary>
|
||||
@@ -211,23 +204,72 @@ namespace FlaxEditor.Options
|
||||
public bool SeparateValueAndUnit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timestamps prefix mode for output log messages.
|
||||
/// Gets or sets the timestamps prefix mode for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(TimestampsFormats.TimeSinceStartup)]
|
||||
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(300), Tooltip("The timestamps prefix mode for output log messages.")]
|
||||
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup;
|
||||
[DefaultValue(TimestampsFormats.None)]
|
||||
[EditorDisplay("Debug Log"), EditorOrder(350), Tooltip("The timestamps prefix mode for debug log messages.")]
|
||||
public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the clear on play for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log", "Clear on Play"), EditorOrder(360), Tooltip("Clears all log entries on enter playmode.")]
|
||||
public bool DebugLogClearOnPlay { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collapse mode for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log"), EditorOrder(361), Tooltip("Collapses similar or repeating log entries.")]
|
||||
public bool DebugLogCollapse { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic pause on error for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
[EditorDisplay("Debug Log", "Pause on Error"), EditorOrder(362), Tooltip("Performs auto pause on error.")]
|
||||
public bool DebugLogPauseOnError { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic pause on error for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log", "Show error messages"), EditorOrder(370), Tooltip("Shows/hides error messages.")]
|
||||
public bool DebugLogShowErrorMessages { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic pause on error for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log", "Show warning messages"), EditorOrder(371), Tooltip("Shows/hides warning messages.")]
|
||||
public bool DebugLogShowWarningMessages { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic pause on error for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log", "Show info messages"), EditorOrder(372), Tooltip("Shows/hides info messages.")]
|
||||
public bool DebugLogShowInfoMessages { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timestamps prefix mode for output log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(TimestampsFormats.TimeSinceStartup)]
|
||||
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(400), Tooltip("The timestamps prefix mode for output log messages.")]
|
||||
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the log type prefix mode for output log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Output Log", "Show Log Type"), EditorOrder(310), Tooltip("Determines whether show log type prefix in output log messages.")]
|
||||
[EditorDisplay("Output Log", "Show Log Type"), EditorOrder(410), Tooltip("Determines whether show log type prefix in output log messages.")]
|
||||
public bool OutputLogShowLogType { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output log text font.
|
||||
/// </summary>
|
||||
[EditorDisplay("Output Log", "Text Font"), EditorOrder(320), Tooltip("The output log text font.")]
|
||||
[EditorDisplay("Output Log", "Text Font"), EditorOrder(420), Tooltip("The output log text font.")]
|
||||
public FontReference OutputLogTextFont
|
||||
{
|
||||
get => _outputLogFont;
|
||||
@@ -246,63 +288,70 @@ namespace FlaxEditor.Options
|
||||
/// Gets or sets the output log text color.
|
||||
/// </summary>
|
||||
[DefaultValue(typeof(Color), "1,1,1,1")]
|
||||
[EditorDisplay("Output Log", "Text Color"), EditorOrder(330), Tooltip("The output log text color.")]
|
||||
[EditorDisplay("Output Log", "Text Color"), EditorOrder(430), Tooltip("The output log text color.")]
|
||||
public Color OutputLogTextColor { get; set; } = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output log text shadow color.
|
||||
/// </summary>
|
||||
[DefaultValue(typeof(Color), "0,0,0,0.5")]
|
||||
[EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(340), Tooltip("The output log text shadow color.")]
|
||||
[EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(440), Tooltip("The output log text shadow color.")]
|
||||
public Color OutputLogTextShadowColor { get; set; } = new Color(0, 0, 0, 0.5f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output log text shadow offset. Set to 0 to disable this feature.
|
||||
/// </summary>
|
||||
[DefaultValue(typeof(Float2), "1,1")]
|
||||
[EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(340), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")]
|
||||
[EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(445), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")]
|
||||
public Float2 OutputLogTextShadowOffset { get; set; } = new Float2(1);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether auto-focus output log window on code compilation error.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(350), Tooltip("Determines whether auto-focus output log window on code compilation error.")]
|
||||
[EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(450), Tooltip("Determines whether auto-focus output log window on code compilation error.")]
|
||||
public bool FocusOutputLogOnCompilationError { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether auto-focus output log window on game build error.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(360), Tooltip("Determines whether auto-focus output log window on game build error.")]
|
||||
[EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(460), Tooltip("Determines whether auto-focus output log window on game build error.")]
|
||||
public bool FocusOutputLogOnGameBuildError { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value for automatic scroll to bottom in output log.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Output Log", "Scroll to bottom"), EditorOrder(470), Tooltip("Scroll the output log view to bottom automatically after new lines are added.")]
|
||||
public bool OutputLogScrollToBottom { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether auto-focus game window on play mode start.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(400), Tooltip("Determines whether auto-focus game window on play mode start.")]
|
||||
[EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(500), Tooltip("Determines whether auto-focus game window on play mode start.")]
|
||||
public bool FocusGameWinOnPlay { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating what action should be taken upon pressing the play button.
|
||||
/// </summary>
|
||||
[DefaultValue(PlayAction.PlayScenes)]
|
||||
[EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(410)]
|
||||
[EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(510)]
|
||||
public PlayAction PlayButtonAction { get; set; } = PlayAction.PlayScenes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating how the game window should be displayed when the game is launched.
|
||||
/// </summary>
|
||||
[DefaultValue(GameWindowMode.Docked)]
|
||||
[EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(420), Tooltip("Determines how the game window is displayed when the game is launched.")]
|
||||
[EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(520), Tooltip("Determines how the game window is displayed when the game is launched.")]
|
||||
public GameWindowMode DefaultGameWindowMode { get; set; } = GameWindowMode.Docked;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game.
|
||||
/// </summary>
|
||||
[DefaultValue(1), Range(1, 4)]
|
||||
[EditorDisplay("Cook & Run"), EditorOrder(500)]
|
||||
[EditorDisplay("Cook & Run"), EditorOrder(600)]
|
||||
public int NumberOfGameClientsToLaunch = 1;
|
||||
|
||||
private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont);
|
||||
@@ -317,13 +366,13 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(650)]
|
||||
[EditorDisplay("Fonts"), EditorOrder(750)]
|
||||
public FontAsset[] FallbackFonts = new FontAsset[1] { FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.FallbackFont) };
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title font for editor UI.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(600), Tooltip("The title font for editor UI.")]
|
||||
[EditorDisplay("Fonts"), EditorOrder(700), Tooltip("The title font for editor UI.")]
|
||||
public FontReference TitleFont
|
||||
{
|
||||
get => _titleFont;
|
||||
@@ -341,7 +390,7 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Gets or sets the large font for editor UI.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(610), Tooltip("The large font for editor UI.")]
|
||||
[EditorDisplay("Fonts"), EditorOrder(710), Tooltip("The large font for editor UI.")]
|
||||
public FontReference LargeFont
|
||||
{
|
||||
get => _largeFont;
|
||||
@@ -359,7 +408,7 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Gets or sets the medium font for editor UI.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(620), Tooltip("The medium font for editor UI.")]
|
||||
[EditorDisplay("Fonts"), EditorOrder(720), Tooltip("The medium font for editor UI.")]
|
||||
public FontReference MediumFont
|
||||
{
|
||||
get => _mediumFont;
|
||||
@@ -377,7 +426,7 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Gets or sets the small font for editor UI.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(630), Tooltip("The small font for editor UI.")]
|
||||
[EditorDisplay("Fonts"), EditorOrder(730), Tooltip("The small font for editor UI.")]
|
||||
public FontReference SmallFont
|
||||
{
|
||||
get => _smallFont;
|
||||
|
||||
@@ -469,6 +469,7 @@ namespace FlaxEditor.SceneGraph
|
||||
{
|
||||
ChildNodes[i].OnDispose();
|
||||
}
|
||||
ChildNodes.Clear();
|
||||
|
||||
SceneGraphFactory.Nodes.Remove(ID);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ namespace FlaxEditor.Surface
|
||||
[HideInEditor]
|
||||
public class AnimGraphSurface : VisjectSurface
|
||||
{
|
||||
private static NodesCache _nodesCache = new NodesCache(IterateNodesCache);
|
||||
|
||||
private static readonly List<GroupArchetype> StateMachineGroupArchetypes = new List<GroupArchetype>(new[]
|
||||
{
|
||||
// Customized Animations group with special nodes to use here
|
||||
@@ -87,8 +89,6 @@ namespace FlaxEditor.Surface
|
||||
}
|
||||
};
|
||||
|
||||
private static NodesCache _nodesCache = new NodesCache(IterateNodesCache);
|
||||
|
||||
/// <summary>
|
||||
/// The state machine editing context menu.
|
||||
/// </summary>
|
||||
@@ -158,6 +158,8 @@ namespace FlaxEditor.Surface
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
_nodesCache.Clear();
|
||||
|
||||
// Check if any of the nodes comes from the game scripts - those can be reloaded at runtime so prevent crashes
|
||||
bool hasTypeFromGameScripts = Editor.Instance.CodeEditing.AnimGraphNodes.HasTypeFromGameScripts;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace FlaxEditor.Surface
|
||||
public BehaviorTreeSurface(IVisjectSurfaceOwner owner, Action onSave, FlaxEditor.Undo undo)
|
||||
: base(owner, onSave, undo, CreateStyle())
|
||||
{
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
private static SurfaceStyle CreateStyle()
|
||||
@@ -35,6 +36,11 @@ namespace FlaxEditor.Surface
|
||||
return style;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
_nodesCache.Clear();
|
||||
}
|
||||
|
||||
private static void DrawBox(Box box)
|
||||
{
|
||||
var rect = new Rectangle(Float2.Zero, box.Size);
|
||||
@@ -186,6 +192,7 @@ namespace FlaxEditor.Surface
|
||||
{
|
||||
if (IsDisposing)
|
||||
return;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
_nodesCache.Wait();
|
||||
|
||||
base.OnDestroy();
|
||||
|
||||
@@ -190,15 +190,7 @@ namespace FlaxEditor.Surface
|
||||
if (data == null || data.Length < 2)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var model = JsonConvert.DeserializeObject<DataModel>(data);
|
||||
return model?.Nodes != null && model.Nodes.Length != 0;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -215,7 +207,15 @@ namespace FlaxEditor.Surface
|
||||
try
|
||||
{
|
||||
// Load Mr Json
|
||||
var model = FlaxEngine.Json.JsonSerializer.Deserialize<DataModel>(data);
|
||||
DataModel model;
|
||||
try
|
||||
{
|
||||
model = FlaxEngine.Json.JsonSerializer.Deserialize<DataModel>(data);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (model.Nodes == null)
|
||||
model.Nodes = new DataModelNode[0];
|
||||
|
||||
|
||||
@@ -397,6 +397,15 @@ namespace FlaxEditor.Surface
|
||||
// Init drag handlers
|
||||
DragHandlers.Add(_dragAssets = new DragAssets<DragDropEventArgs>(ValidateDragItem));
|
||||
DragHandlers.Add(_dragParameters = new DragNames<DragDropEventArgs>(SurfaceParameter.DragPrefix, ValidateDragParameter));
|
||||
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
_activeVisjectCM = null;
|
||||
_cmPrimaryMenu?.Dispose();
|
||||
_cmPrimaryMenu = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -995,6 +1004,8 @@ namespace FlaxEditor.Surface
|
||||
_activeVisjectCM = null;
|
||||
_cmPrimaryMenu?.Dispose();
|
||||
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,12 @@ namespace FlaxEditor.Surface
|
||||
{
|
||||
_supportsImplicitCastFromObjectToBoolean = true;
|
||||
DragHandlers.Add(_dragActors = new DragActors(ValidateDragActor));
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
_nodesCache.Clear();
|
||||
}
|
||||
|
||||
private bool ValidateDragActor(ActorNode actor)
|
||||
@@ -596,6 +602,7 @@ namespace FlaxEditor.Surface
|
||||
{
|
||||
if (IsDisposing)
|
||||
return;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
_nodesCache.Wait();
|
||||
|
||||
base.OnDestroy();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using FlaxEngine;
|
||||
|
||||
@@ -101,6 +102,7 @@ namespace FlaxEditor.Utilities
|
||||
|
||||
Editor.Log("Creating scenes");
|
||||
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
// Deserialize new scenes
|
||||
int scenesCount = _scenesData.Count;
|
||||
for (int i = 0; i < scenesCount; i++)
|
||||
@@ -113,6 +115,9 @@ namespace FlaxEditor.Utilities
|
||||
throw new Exception("Failed to deserialize scene");
|
||||
}
|
||||
}
|
||||
sw.Stop();
|
||||
|
||||
Editor.Log("Creating scenes time: " + sw.Elapsed.TotalMilliseconds + "ms");
|
||||
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
enum class PixelFormat : unsigned;
|
||||
enum class DirectorySearchOption;
|
||||
class TextureData;
|
||||
struct TextureData;
|
||||
|
||||
/// <summary>
|
||||
/// Helper functions for the editor.
|
||||
|
||||
@@ -1241,6 +1241,10 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
private class FpsCounter : Control
|
||||
{
|
||||
private int fps;
|
||||
private int accumFrames;
|
||||
private float lastUpdate;
|
||||
|
||||
public FpsCounter(float x, float y)
|
||||
: base(x, y, 64, 32)
|
||||
{
|
||||
@@ -1250,7 +1254,15 @@ namespace FlaxEditor.Viewport
|
||||
{
|
||||
base.Draw();
|
||||
|
||||
int fps = Engine.FramesPerSecond;
|
||||
accumFrames++;
|
||||
float timeNow = Time.TimeSinceStartup;
|
||||
if (timeNow - lastUpdate >= 1.0f)
|
||||
{
|
||||
fps = accumFrames;
|
||||
lastUpdate = timeNow;
|
||||
accumFrames = 0;
|
||||
}
|
||||
|
||||
Color color = Color.Green;
|
||||
if (fps < 13)
|
||||
color = Color.Red;
|
||||
|
||||
@@ -471,7 +471,13 @@ namespace FlaxEditor.Viewport
|
||||
trans.SetRotation(ref world);
|
||||
trans.Translation += world.TranslationVector;
|
||||
}
|
||||
obj.Transform = trans;
|
||||
if (obj is ActorNode actorNode)
|
||||
{
|
||||
actorNode.Actor.Position = trans.Translation;
|
||||
actorNode.Actor.Orientation = trans.Orientation;
|
||||
}
|
||||
else
|
||||
obj.Transform = trans;
|
||||
}
|
||||
TransformGizmo.EndTransforming();
|
||||
}
|
||||
@@ -520,7 +526,9 @@ namespace FlaxEditor.Viewport
|
||||
/// <param name="scaleDelta">The scale delta.</param>
|
||||
public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
|
||||
{
|
||||
bool applyTranslation = !translationDelta.IsZero;
|
||||
bool applyRotation = !rotationDelta.IsIdentity;
|
||||
bool applyScale = !scaleDelta.IsZero;
|
||||
bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter;
|
||||
Vector3 gizmoPosition = TransformGizmo.Position;
|
||||
|
||||
@@ -555,13 +563,29 @@ namespace FlaxEditor.Viewport
|
||||
}
|
||||
|
||||
// Apply scale
|
||||
const float scaleLimit = 99_999_999.0f;
|
||||
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
|
||||
if (applyScale)
|
||||
{
|
||||
const float scaleLimit = 99_999_999.0f;
|
||||
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit)); ;
|
||||
}
|
||||
|
||||
// Apply translation
|
||||
trans.Translation += translationDelta;
|
||||
if (applyTranslation)
|
||||
{
|
||||
trans.Translation += translationDelta;
|
||||
}
|
||||
|
||||
obj.Transform = trans;
|
||||
if (obj is ActorNode actorNode)
|
||||
{
|
||||
if (applyTranslation)
|
||||
actorNode.Actor.Position = trans.Translation;
|
||||
if (applyRotation)
|
||||
actorNode.Actor.Orientation = trans.Orientation;
|
||||
if (applyScale)
|
||||
actorNode.Actor.Scale = trans.Scale;
|
||||
}
|
||||
else
|
||||
obj.Transform = trans;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -357,7 +357,9 @@ namespace FlaxEditor.Viewport
|
||||
/// <param name="scaleDelta">The scale delta.</param>
|
||||
public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
|
||||
{
|
||||
bool applyTranslation = !translationDelta.IsZero;
|
||||
bool applyRotation = !rotationDelta.IsIdentity;
|
||||
bool applyScale = !scaleDelta.IsZero;
|
||||
bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter;
|
||||
Vector3 gizmoPosition = TransformGizmo.Position;
|
||||
|
||||
@@ -387,13 +389,29 @@ namespace FlaxEditor.Viewport
|
||||
}
|
||||
|
||||
// Apply scale
|
||||
const float scaleLimit = 99_999_999.0f;
|
||||
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
|
||||
if (applyScale)
|
||||
{
|
||||
const float scaleLimit = 99_999_999.0f;
|
||||
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
|
||||
}
|
||||
|
||||
// Apply translation
|
||||
trans.Translation += translationDelta;
|
||||
if (applyTranslation)
|
||||
{
|
||||
trans.Translation += translationDelta;
|
||||
}
|
||||
|
||||
obj.Transform = trans;
|
||||
if (obj is ActorNode actorNode)
|
||||
{
|
||||
if (applyTranslation)
|
||||
actorNode.Actor.Position = trans.Translation;
|
||||
if (applyRotation)
|
||||
actorNode.Actor.Orientation = trans.Orientation;
|
||||
if (applyScale)
|
||||
actorNode.Actor.Scale = trans.Scale;
|
||||
}
|
||||
else
|
||||
obj.Transform = trans;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,6 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
Editor.Prefabs.PrefabApplied += OnPrefabApplied;
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
||||
|
||||
// Setup input actions
|
||||
InputActions.Add(options => options.Undo, () =>
|
||||
@@ -305,24 +304,18 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsHidden)
|
||||
{
|
||||
Editor.Instance.Windows.AddToRestore(this);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
Deselect();
|
||||
Graph.MainActor = null;
|
||||
_viewport.Prefab = null;
|
||||
_undo?.Clear(); // TODO: maybe don't clear undo?
|
||||
}
|
||||
|
||||
private void OnScriptsReloadEnd()
|
||||
{
|
||||
_isScriptsReloading = false;
|
||||
|
||||
if (_asset == null || !_asset.IsLoaded)
|
||||
return;
|
||||
|
||||
// Restore
|
||||
OnPrefabOpened();
|
||||
_undo.Clear();
|
||||
ClearEditedFlag();
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnUndoEvent(IUndoAction action)
|
||||
@@ -532,7 +525,6 @@ namespace FlaxEditor.Windows.Assets
|
||||
{
|
||||
Editor.Prefabs.PrefabApplied -= OnPrefabApplied;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||
|
||||
_undo.Dispose();
|
||||
Graph.Dispose();
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace FlaxEditor.Windows
|
||||
private const string ProjectDataLastViewedFolder = "LastViewedFolder";
|
||||
private bool _isWorkspaceDirty;
|
||||
private string _workspaceRebuildLocation;
|
||||
private string _lastViewedFolderBeforeReload;
|
||||
private SplitPanel _split;
|
||||
private Panel _contentViewPanel;
|
||||
private Panel _contentTreePanel;
|
||||
@@ -144,26 +145,6 @@ namespace FlaxEditor.Windows
|
||||
|
||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||
|
||||
// Content database events
|
||||
editor.ContentDatabase.WorkspaceModified += () => _isWorkspaceDirty = true;
|
||||
editor.ContentDatabase.ItemRemoved += OnContentDatabaseItemRemoved;
|
||||
editor.ContentDatabase.WorkspaceRebuilding += () => { _workspaceRebuildLocation = SelectedNode?.Path; };
|
||||
editor.ContentDatabase.WorkspaceRebuilt += () =>
|
||||
{
|
||||
var selected = Editor.ContentDatabase.Find(_workspaceRebuildLocation);
|
||||
if (selected is ContentFolder selectedFolder)
|
||||
{
|
||||
_navigationUnlocked = false;
|
||||
RefreshView(selectedFolder.Node);
|
||||
_tree.Select(selectedFolder.Node);
|
||||
UpdateItemsSearch();
|
||||
_navigationUnlocked = true;
|
||||
UpdateUI();
|
||||
}
|
||||
else
|
||||
ShowRoot();
|
||||
};
|
||||
|
||||
var options = Editor.Options;
|
||||
options.OptionsChanged += OnOptionsChanged;
|
||||
|
||||
@@ -1028,6 +1009,61 @@ namespace FlaxEditor.Windows
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnInit()
|
||||
{
|
||||
// Content database events
|
||||
Editor.ContentDatabase.WorkspaceModified += () => _isWorkspaceDirty = true;
|
||||
Editor.ContentDatabase.ItemRemoved += OnContentDatabaseItemRemoved;
|
||||
Editor.ContentDatabase.WorkspaceRebuilding += () => { _workspaceRebuildLocation = SelectedNode?.Path; };
|
||||
Editor.ContentDatabase.WorkspaceRebuilt += () =>
|
||||
{
|
||||
var selected = Editor.ContentDatabase.Find(_workspaceRebuildLocation);
|
||||
if (selected is ContentFolder selectedFolder)
|
||||
{
|
||||
_navigationUnlocked = false;
|
||||
RefreshView(selectedFolder.Node);
|
||||
_tree.Select(selectedFolder.Node);
|
||||
UpdateItemsSearch();
|
||||
_navigationUnlocked = true;
|
||||
UpdateUI();
|
||||
}
|
||||
else if (_root != null)
|
||||
ShowRoot();
|
||||
};
|
||||
|
||||
Refresh();
|
||||
|
||||
// Load last viewed folder
|
||||
if (Editor.ProjectCache.TryGetCustomData(ProjectDataLastViewedFolder, out var lastViewedFolder))
|
||||
{
|
||||
if (Editor.ContentDatabase.Find(lastViewedFolder) is ContentFolder folder)
|
||||
_tree.Select(folder.Node);
|
||||
}
|
||||
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
var lastViewedFolder = _tree.Selection.Count == 1 ? _tree.SelectedNode as ContentTreeNode : null;
|
||||
_lastViewedFolderBeforeReload = lastViewedFolder?.Path ?? string.Empty;
|
||||
|
||||
_tree.RemoveChild(_root);
|
||||
_root = null;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadEnd()
|
||||
{
|
||||
Refresh();
|
||||
|
||||
if (!string.IsNullOrEmpty(_lastViewedFolderBeforeReload))
|
||||
{
|
||||
if (Editor.ContentDatabase.Find(_lastViewedFolderBeforeReload) is ContentFolder folder)
|
||||
_tree.Select(folder.Node);
|
||||
}
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
// Setup content root node
|
||||
_root = new RootContentTreeNode
|
||||
@@ -1064,13 +1100,6 @@ namespace FlaxEditor.Windows
|
||||
// Update UI layout
|
||||
_isLayoutLocked = false;
|
||||
PerformLayout();
|
||||
|
||||
// Load last viewed folder
|
||||
if (Editor.ProjectCache.TryGetCustomData(ProjectDataLastViewedFolder, out var lastViewedFolder))
|
||||
{
|
||||
if (Editor.ContentDatabase.Find(lastViewedFolder) is ContentFolder folder)
|
||||
_tree.Select(folder.Node);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -1218,6 +1247,8 @@ namespace FlaxEditor.Windows
|
||||
_viewDropdown = null;
|
||||
|
||||
Editor.Options.OptionsChanged -= OnOptionsChanged;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
@@ -318,7 +318,6 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
Title = "Debug Log";
|
||||
Icon = IconInfo;
|
||||
OnEditorOptionsChanged(Editor.Options.Options);
|
||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||
|
||||
// Toolstrip
|
||||
@@ -327,14 +326,42 @@ namespace FlaxEditor.Windows
|
||||
Parent = this,
|
||||
};
|
||||
toolstrip.AddButton("Clear", Clear).LinkTooltip("Clears all log entries");
|
||||
_clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play").SetAutoCheck(true).SetChecked(true).LinkTooltip("Clears all log entries on enter playmode");
|
||||
_collapseLogsButton = (ToolStripButton)toolstrip.AddButton("Collapse").SetAutoCheck(true).SetChecked(true).LinkTooltip("Collapses similar logs.");
|
||||
_pauseOnErrorButton = (ToolStripButton)toolstrip.AddButton("Pause on Error").SetAutoCheck(true).LinkTooltip("Performs auto pause on error");
|
||||
_clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play", () =>
|
||||
{
|
||||
editor.Options.Options.Interface.DebugLogClearOnPlay = _clearOnPlayButton.Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Clears all log entries on enter playmode");
|
||||
_collapseLogsButton = (ToolStripButton)toolstrip.AddButton("Collapse", () =>
|
||||
{
|
||||
editor.Options.Options.Interface.DebugLogCollapse = _collapseLogsButton.Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Collapses similar logs.");
|
||||
_pauseOnErrorButton = (ToolStripButton)toolstrip.AddButton("Pause on Error", () =>
|
||||
{
|
||||
editor.Options.Options.Interface.DebugLogPauseOnError = _pauseOnErrorButton.Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Performs auto pause on error");
|
||||
toolstrip.AddSeparator();
|
||||
_groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () => UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides error messages");
|
||||
_groupButtons[1] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Warning32, () => UpdateLogTypeVisibility(LogGroup.Warning, _groupButtons[1].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides warning messages");
|
||||
_groupButtons[2] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Info32, () => UpdateLogTypeVisibility(LogGroup.Info, _groupButtons[2].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides info messages");
|
||||
_groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () =>
|
||||
{
|
||||
UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked);
|
||||
editor.Options.Options.Interface.DebugLogShowErrorMessages = _groupButtons[0].Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Shows/hides error messages");
|
||||
_groupButtons[1] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Warning32, () =>
|
||||
{
|
||||
UpdateLogTypeVisibility(LogGroup.Warning, _groupButtons[1].Checked);
|
||||
editor.Options.Options.Interface.DebugLogShowWarningMessages = _groupButtons[1].Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Shows/hides warning messages");
|
||||
_groupButtons[2] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Info32, () =>
|
||||
{
|
||||
UpdateLogTypeVisibility(LogGroup.Info, _groupButtons[2].Checked);
|
||||
editor.Options.Options.Interface.DebugLogShowInfoMessages = _groupButtons[2].Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Shows/hides info messages");
|
||||
UpdateCount();
|
||||
OnEditorOptionsChanged(Editor.Options.Options);
|
||||
|
||||
// Split panel
|
||||
_split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both)
|
||||
@@ -380,6 +407,12 @@ namespace FlaxEditor.Windows
|
||||
private void OnEditorOptionsChanged(EditorOptions options)
|
||||
{
|
||||
_timestampsFormats = options.Interface.DebugLogTimestampsFormat;
|
||||
_clearOnPlayButton.Checked = options.Interface.DebugLogClearOnPlay;
|
||||
_collapseLogsButton.Checked = options.Interface.DebugLogCollapse;
|
||||
_pauseOnErrorButton.Checked = options.Interface.DebugLogPauseOnError;
|
||||
_groupButtons[0].Checked = options.Interface.DebugLogShowErrorMessages;
|
||||
_groupButtons[1].Checked = options.Interface.DebugLogShowWarningMessages;
|
||||
_groupButtons[2].Checked = options.Interface.DebugLogShowInfoMessages;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace FlaxEditor.Windows
|
||||
|
||||
Editor.Options.Apply(_options);
|
||||
|
||||
ClearDirtyFlag();
|
||||
GatherData();
|
||||
}
|
||||
|
||||
private void SetupCustomTabs()
|
||||
@@ -234,6 +234,18 @@ namespace FlaxEditor.Windows
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnShow()
|
||||
{
|
||||
if (!_isDataDirty)
|
||||
{
|
||||
// Refresh the data, skip when data is modified during window docking
|
||||
GatherData();
|
||||
}
|
||||
|
||||
base.OnShow();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool OnClosing(ClosingReason reason)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEngine;
|
||||
@@ -96,14 +95,6 @@ namespace FlaxEditor.Windows
|
||||
set => Graphics.ShadowMapsQuality = value;
|
||||
}
|
||||
|
||||
[DefaultValue(false)]
|
||||
[EditorOrder(1320), EditorDisplay("Quality", "Allow CSM Blending"), Tooltip("Enables cascades splits blending for directional light shadows.")]
|
||||
public bool AllowCSMBlending
|
||||
{
|
||||
get => Graphics.AllowCSMBlending;
|
||||
set => Graphics.AllowCSMBlending = value;
|
||||
}
|
||||
|
||||
[NoSerialize, DefaultValue(1.0f), Limit(0.05f, 5, 0)]
|
||||
[EditorOrder(1400), EditorDisplay("Quality")]
|
||||
[Tooltip("The scale of the rendering resolution relative to the output dimensions. If lower than 1 the scene and postprocessing will be rendered at a lower resolution and upscaled to the output backbuffer.")]
|
||||
|
||||
@@ -561,7 +561,7 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
ref var line = ref lines[j];
|
||||
textBlock.Range.StartIndex = startIndex + line.FirstCharIndex;
|
||||
textBlock.Range.EndIndex = startIndex + line.LastCharIndex + 1;
|
||||
textBlock.Range.EndIndex = startIndex + line.LastCharIndex;
|
||||
textBlock.Bounds = new Rectangle(new Float2(0.0f, prevBlockBottom), line.Size);
|
||||
|
||||
if (textBlock.Range.Length > 0)
|
||||
@@ -570,7 +570,7 @@ namespace FlaxEditor.Windows
|
||||
var regexStart = line.FirstCharIndex;
|
||||
if (j == 0)
|
||||
regexStart += prefixLength;
|
||||
var regexLength = line.LastCharIndex + 1 - regexStart;
|
||||
var regexLength = line.LastCharIndex - regexStart;
|
||||
if (regexLength > 0)
|
||||
{
|
||||
var match = _compileRegex.Match(entryText, regexStart, regexLength);
|
||||
|
||||
@@ -526,7 +526,7 @@ namespace FlaxEditor.Windows.Profiler
|
||||
}
|
||||
row.Depth = e.Depth;
|
||||
row.Width = _table.Width;
|
||||
row.Visible = e.Depth < 2;
|
||||
row.Visible = e.Depth < 10;
|
||||
row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent;
|
||||
row.Parent = _table;
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ namespace FlaxEditor.Windows.Profiler
|
||||
}
|
||||
row.Depth = e.Depth;
|
||||
row.Width = _table.Width;
|
||||
row.Visible = e.Depth < 3;
|
||||
row.Visible = e.Depth < 13;
|
||||
row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent;
|
||||
row.Parent = _table;
|
||||
}
|
||||
|
||||
@@ -150,6 +150,22 @@ namespace FlaxEditor.Windows
|
||||
_searchBox.Clear();
|
||||
_groupSearch.DisposeChildren();
|
||||
_groupSearch.PerformLayout();
|
||||
|
||||
// Remove tabs
|
||||
var tabs = new List<Tab>();
|
||||
foreach (var child in _actorGroups.Children)
|
||||
{
|
||||
if (child is Tab tab)
|
||||
{
|
||||
if (tab.Text != "Search")
|
||||
tabs.Add(tab);
|
||||
}
|
||||
}
|
||||
foreach (var tab in tabs)
|
||||
{
|
||||
var group = _actorGroups.Children.Find(T => T == tab);
|
||||
group.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScriptsReloadEnd()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.Marshalling;
|
||||
using FlaxEngine.Interop;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
|
||||
@@ -28,8 +28,8 @@ public class Audio : EngineModule
|
||||
{
|
||||
case TargetPlatform.Windows:
|
||||
useNone = true;
|
||||
useOpenAL = true;
|
||||
//useXAudio2 = true;
|
||||
//useOpenAL = true;
|
||||
useXAudio2 = true;
|
||||
break;
|
||||
case TargetPlatform.XboxOne:
|
||||
case TargetPlatform.UWP:
|
||||
|
||||
@@ -428,23 +428,23 @@ void AudioSource::Update()
|
||||
// Handle streaming buffers queue submit (ensure that clip has loaded the first chunk with audio data)
|
||||
if (_needToUpdateStreamingBuffers && clip->Buffers[_streamingFirstChunk] != AUDIO_BUFFER_ID_INVALID)
|
||||
{
|
||||
// Clear flag
|
||||
_needToUpdateStreamingBuffers = false;
|
||||
|
||||
// Get buffers in a queue count
|
||||
int32 numQueuedBuffers;
|
||||
AudioBackend::Source::GetQueuedBuffersCount(this, numQueuedBuffers);
|
||||
|
||||
// Queue missing buffers
|
||||
// Queue missing buffers, make sure there is at least two buffers in queue to avoid gaps in playback
|
||||
uint32 bufferId;
|
||||
if (numQueuedBuffers < 1 && (bufferId = clip->Buffers[_streamingFirstChunk]) != AUDIO_BUFFER_ID_INVALID)
|
||||
for (int i = numQueuedBuffers; i < 2; i++)
|
||||
{
|
||||
AudioBackend::Source::QueueBuffer(this, bufferId);
|
||||
int bufferIndex = (_streamingFirstChunk + i) % clip->Buffers.Count();
|
||||
if ((bufferId = clip->Buffers[bufferIndex]) != AUDIO_BUFFER_ID_INVALID)
|
||||
AudioBackend::Source::QueueBuffer(this, bufferId);
|
||||
else
|
||||
_needToUpdateStreamingBuffers = true; // The buffer has not been streamed yet, try again later
|
||||
}
|
||||
if (numQueuedBuffers < 2 && _streamingFirstChunk + 1 < clip->Buffers.Count() && (bufferId = clip->Buffers[_streamingFirstChunk + 1]) != AUDIO_BUFFER_ID_INVALID)
|
||||
{
|
||||
AudioBackend::Source::QueueBuffer(this, bufferId);
|
||||
}
|
||||
|
||||
// Clear flag
|
||||
_needToUpdateStreamingBuffers = false;
|
||||
|
||||
// Play it if need to
|
||||
if (!_isActuallyPlayingSth)
|
||||
@@ -469,18 +469,25 @@ void AudioSource::Update()
|
||||
// Move the chunk pointer (AudioStreamingHandler will request new chunks streaming)
|
||||
_streamingFirstChunk += numProcessedBuffers;
|
||||
|
||||
if (GetIsLooping())
|
||||
{
|
||||
int32 numQueuedBuffers;
|
||||
AudioBackend::Source::GetQueuedBuffersCount(this, numQueuedBuffers);
|
||||
if (numQueuedBuffers < 1)
|
||||
{
|
||||
// Audio engine unexpectedly stopped playing the clip after queue emptied, restart the clip
|
||||
_isActuallyPlayingSth = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if reached the end
|
||||
if (_streamingFirstChunk >= clip->Buffers.Count())
|
||||
{
|
||||
// Loop over the clip or end play
|
||||
if (GetIsLooping())
|
||||
{
|
||||
// Move to the begin
|
||||
// Move to the beginning
|
||||
_streamingFirstChunk = 0;
|
||||
|
||||
// Stop audio and request buffers re-sync and then play continue
|
||||
Stop();
|
||||
Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -686,8 +686,6 @@ void AudioBackendXAudio2::Source_DequeueProcessedBuffers(AudioSource* source)
|
||||
auto aSource = XAudio2::GetSource(source);
|
||||
if (aSource && aSource->Voice)
|
||||
{
|
||||
const HRESULT hr = aSource->Voice->FlushSourceBuffers();
|
||||
XAUDIO2_CHECK_ERROR(FlushSourceBuffers);
|
||||
aSource->BuffersProcessed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -872,6 +872,13 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
|
||||
|
||||
// Find event binding callback
|
||||
auto eventBinder = ScriptingEvents::EventsTable.TryGet(Pair<ScriptingTypeHandle, StringView>(eventType, eventName));
|
||||
if (!eventBinder)
|
||||
{
|
||||
const StringAnsiView eventNameAnsi(node->Values[1]);
|
||||
auto managedEvent = eventType.GetClass()->GetEvent(eventNameAnsi.GetText());
|
||||
//eventBinder = (void(**)(ScriptingObject*, void*, bool))managedEvent;
|
||||
}
|
||||
|
||||
if (!eventBinder)
|
||||
{
|
||||
LOG(Error, "Cannot bind to missing event {0} from type {1}.", eventName, eventTypeName);
|
||||
|
||||
@@ -477,7 +477,7 @@ const String& BinaryAsset::GetPath() const
|
||||
|
||||
uint64 BinaryAsset::GetMemoryUsage() const
|
||||
{
|
||||
Locker.Lock();
|
||||
//ScopeLock lock(Locker);
|
||||
uint64 result = Asset::GetMemoryUsage();
|
||||
result += sizeof(BinaryAsset) - sizeof(Asset);
|
||||
result += _dependantAssets.Capacity() * sizeof(BinaryAsset*);
|
||||
@@ -487,7 +487,6 @@ uint64 BinaryAsset::GetMemoryUsage() const
|
||||
if (chunk != nullptr && chunk->IsLoaded())
|
||||
result += chunk->Size();
|
||||
}
|
||||
Locker.Unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
#define DECLARE_BINARY_ASSET_HEADER(type, serializedVersion) \
|
||||
DECLARE_ASSET_HEADER(type); \
|
||||
static const uint32 SerializedVersion = serializedVersion; \
|
||||
uint32 GetSerializedVersion() const override { return SerializedVersion; }
|
||||
uint32 GetSerializedVersion() const override { return SerializedVersion; } \
|
||||
static_assert(true, "")
|
||||
|
||||
#define REGISTER_BINARY_ASSET_ABSTRACT(type, typeName) \
|
||||
const String type::TypeName = TEXT(typeName)
|
||||
|
||||
@@ -1336,6 +1336,11 @@ FileReadStream* FlaxStorage::OpenFile()
|
||||
|
||||
bool FlaxStorage::CloseFileHandles()
|
||||
{
|
||||
// Early out if no handles are opened
|
||||
Array<FileReadStream*> streams;
|
||||
_file.GetValues(streams);
|
||||
if (streams.IsEmpty() && Platform::AtomicRead(&_chunksLock) == 0)
|
||||
return false;
|
||||
PROFILE_CPU();
|
||||
|
||||
// Note: this is usually called by the content manager when this file is not used or on exit
|
||||
@@ -1367,7 +1372,7 @@ bool FlaxStorage::CloseFileHandles()
|
||||
return true; // Failed, someone is still accessing the file
|
||||
|
||||
// Close file handles (from all threads)
|
||||
Array<FileReadStream*> streams;
|
||||
streams.Clear();
|
||||
_file.GetValues(streams);
|
||||
for (FileReadStream* stream : streams)
|
||||
{
|
||||
|
||||
@@ -149,6 +149,6 @@ public:
|
||||
CreateAssetFunction Callback;
|
||||
};
|
||||
|
||||
#define IMPORT_SETUP(type, serializedVersion) context.Data.Header.TypeName = type::TypeName; context.Data.SerializedVersion = serializedVersion;
|
||||
#define IMPORT_SETUP(type, serializedVersion) context.Data.Header.TypeName = type::TypeName; context.Data.SerializedVersion = serializedVersion
|
||||
|
||||
#endif
|
||||
|
||||
@@ -53,5 +53,5 @@
|
||||
#define API_PARAM(...)
|
||||
#define API_TYPEDEF(...)
|
||||
#define API_INJECT_CODE(...)
|
||||
#define API_AUTO_SERIALIZATION(...) public: void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
#define DECLARE_SCRIPTING_TYPE_MINIMAL(type) public: friend class type##Internal; static struct ScriptingTypeInitializer TypeInitializer;
|
||||
#define API_AUTO_SERIALIZATION(...) public: void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override
|
||||
#define DECLARE_SCRIPTING_TYPE_MINIMAL(type) public: friend class type##Internal; static struct ScriptingTypeInitializer TypeInitializer
|
||||
|
||||
@@ -61,9 +61,10 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// Enables cascades splits blending for directional light shadows.
|
||||
/// [Deprecated in v1.9]
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1320), DefaultValue(false), EditorDisplay(\"Quality\", \"Allow CSM Blending\")")
|
||||
bool AllowCSMBlending = false;
|
||||
DEPRECATED bool AllowCSMBlending = false;
|
||||
|
||||
/// <summary>
|
||||
/// Default probes cubemap resolution (use for Environment Probes, can be overriden per-actor).
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
} \
|
||||
} \
|
||||
return result; \
|
||||
}
|
||||
} static_assert(true, "")
|
||||
|
||||
// [Deprecated on 20.01.2022, expires on 20.01.2024]
|
||||
#define IMPLEMENT_SETTINGS_GETTER(type, field) IMPLEMENT_ENGINE_SETTINGS_GETTER(type, field)
|
||||
@@ -69,6 +69,6 @@ public:
|
||||
} \
|
||||
} \
|
||||
return result; \
|
||||
}
|
||||
} static_assert(true, "")
|
||||
|
||||
#define DECLARE_SETTINGS_GETTER(type) static type* Get()
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "Compiler.h"
|
||||
|
||||
#define SAFE_DISPOSE(x) if(x) { (x)->Dispose(); (x) = nullptr; }
|
||||
#define SAFE_RELEASE(x) if(x) { (x)->Release(); (x) = nullptr; }
|
||||
#define SAFE_DELETE(x) if(x) { ::Delete(x); (x) = nullptr; }
|
||||
#define SAFE_DISPOSE(x) if(x) { (x)->Dispose(); (x) = nullptr; } static_assert(true, "")
|
||||
#define SAFE_RELEASE(x) if(x) { (x)->Release(); (x) = nullptr; } static_assert(true, "")
|
||||
#define SAFE_DELETE(x) if(x) { ::Delete(x); (x) = nullptr; } static_assert(true, "")
|
||||
#define INVALID_INDEX (-1)
|
||||
#define _INTERNAL_CONCAT_MACROS(a, b) a ## b
|
||||
#define CONCAT_MACROS(a, b) _INTERNAL_CONCAT_MACROS(a, b)
|
||||
@@ -22,4 +22,9 @@
|
||||
}
|
||||
#define OUT_OF_MEMORY Platform::OutOfMemory(__LINE__, __FILE__)
|
||||
#define MISSING_CODE(info) Platform::MissingCode(__LINE__, __FILE__, info)
|
||||
#define NON_COPYABLE(type) type(type&&) = delete; type(const type&) = delete; type& operator=(const type&) = delete; type& operator=(type&&) = delete;
|
||||
#define NON_COPYABLE(type) type(type&&) = delete; type(const type&) = delete; type& operator=(const type&) = delete; type& operator=(type&&) = delete
|
||||
#define POD_COPYABLE(type) \
|
||||
type(const type& other) { Platform::MemoryCopy(this, &other, sizeof(type)); } \
|
||||
type(type&& other) noexcept { Platform::MemoryCopy(this, &other, sizeof(type)); } \
|
||||
type& operator=(const type& other) { Platform::MemoryCopy(this, &other, sizeof(type)); return *this; } \
|
||||
type& operator=(type&& other) noexcept { Platform::MemoryCopy(this, &other, sizeof(type)); return *this; } static_assert(true, "")
|
||||
|
||||
@@ -13,154 +13,154 @@
|
||||
#define DECLARE_ENUM_1(name, t0) enum class name{t0=0};\
|
||||
static const int name##_Count = 1;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_2(name, t0, t1) enum class name{t0=0,t1};\
|
||||
static const int name##_Count = 2;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_3(name, t0, t1, t2) enum class name{t0=0,t1,t2};\
|
||||
static const int name##_Count = 3;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_4(name, t0, t1, t2, t3) enum class name{t0=0,t1,t2,t3};\
|
||||
static const int name##_Count = 4;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_5(name, t0, t1, t2, t3, t4) enum class name{t0=0,t1,t2,t3,t4};\
|
||||
static const int name##_Count = 5;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_6(name, t0, t1, t2, t3, t4, t5) enum class name{t0=0,t1,t2,t3,t4,t5};\
|
||||
static const int name##_Count = 6;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_7(name, t0, t1, t2, t3, t4, t5, t6) enum class name{t0=0,t1,t2,t3,t4,t5,t6};\
|
||||
static const int name##_Count = 7;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_8(name, t0, t1, t2, t3, t4, t5, t6, t7) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7};\
|
||||
static const int name##_Count = 8;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_9(name, t0, t1, t2, t3, t4, t5, t6, t7, t8) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8};\
|
||||
static const int name##_Count = 9;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_10(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9};\
|
||||
static const int name##_Count = 10;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_11(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10};\
|
||||
static const int name##_Count = 11;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_12(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11};\
|
||||
static const int name##_Count = 12;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10),ENUM_TO_STR(t11)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_13(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12};\
|
||||
static const int name##_Count = 13;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10),ENUM_TO_STR(t11),ENUM_TO_STR(t12)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_14(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13};\
|
||||
static const int name##_Count = 14;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10),ENUM_TO_STR(t11),ENUM_TO_STR(t12),ENUM_TO_STR(t13)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_15(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14};\
|
||||
static const int name##_Count = 15;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10),ENUM_TO_STR(t11),ENUM_TO_STR(t12),ENUM_TO_STR(t13),ENUM_TO_STR(t14)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_16(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15};\
|
||||
static const int name##_Count = 16;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10),ENUM_TO_STR(t11),ENUM_TO_STR(t12),ENUM_TO_STR(t13),ENUM_TO_STR(t14),ENUM_TO_STR(t15)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_17(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16};\
|
||||
static const int name##_Count = 17;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10),ENUM_TO_STR(t11),ENUM_TO_STR(t12),ENUM_TO_STR(t13),ENUM_TO_STR(t14),ENUM_TO_STR(t15),ENUM_TO_STR(t16)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_18(name, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17) enum class name{t0=0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17};\
|
||||
static const int name##_Count = 17;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10),ENUM_TO_STR(t11),ENUM_TO_STR(t12),ENUM_TO_STR(t13),ENUM_TO_STR(t14),ENUM_TO_STR(t15),ENUM_TO_STR(t16),ENUM_TO_STR(t17)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e];}static_assert(true, "")
|
||||
|
||||
// ..and those with base type and base value
|
||||
|
||||
#define DECLARE_ENUM_EX_1(name, baseType, baseVal, t0) enum class name:baseType{t0=baseVal};\
|
||||
static const int name##_Count = 1;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_2(name, baseType, baseVal, t0, t1) enum class name:baseType{t0=baseVal,t1};\
|
||||
static const int name##_Count = 2;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_3(name, baseType, baseVal, t0, t1, t2) enum class name:baseType{t0=baseVal,t1,t2};\
|
||||
static const int name##_Count = 3;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_4(name, baseType, baseVal, t0, t1, t2, t3) enum class name:baseType{t0=baseVal,t1,t2,t3};\
|
||||
static const int name##_Count = 4;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_5(name, baseType, baseVal, t0, t1, t2, t3, t4) enum class name:baseType{t0=baseVal,t1,t2,t3,t4};\
|
||||
static const int name##_Count = 5;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_6(name, baseType, baseVal, t0, t1, t2, t3, t4, t5) enum class name:baseType{t0=baseVal,t1,t2,t3,t4,t5};\
|
||||
static const int name##_Count = 6;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_7(name, baseType, baseVal, t0, t1, t2, t3, t4, t5, t6) enum class name:baseType{t0=baseVal,t1,t2,t3,t4,t5,t6};\
|
||||
static const int name##_Count = 7;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_8(name, baseType, baseVal, t0, t1, t2, t3, t4, t5, t6, t7) enum class name:baseType{t0=baseVal,t1,t2,t3,t4,t5,t6,t7};\
|
||||
static const int name##_Count = 8;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_9(name, baseType, baseVal, t0, t1, t2, t3, t4, t5, t6, t7, t8) enum class name:baseType{t0=baseVal,t1,t2,t3,t4,t5,t6,t7,t8};\
|
||||
static const int name##_Count = 9;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_10(name, baseType, baseVal, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) enum class name:baseType{t0=baseVal,t1,t2,t3,t4,t5,t6,t7,t8,t9};\
|
||||
static const int name##_Count = 10;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_11(name, baseType, baseVal, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) enum class name:baseType{t0=baseVal,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10};\
|
||||
static const int name##_Count = 11;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_EX_12(name, baseType, baseVal, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) enum class name:baseType{t0=baseVal,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11};\
|
||||
static const int name##_Count = 11;static const Char**name##_Str(){static const Char* str[]={\
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9),ENUM_TO_STR(t10),ENUM_TO_STR(t11)};\
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}
|
||||
return str;}static inline const Char*ToString(name e){return name##_Str()[(int)e - baseVal];}static_assert(true, "")
|
||||
|
||||
// ..and those for flags
|
||||
|
||||
@@ -170,7 +170,7 @@ static const int name##_Count = 1;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_2(name, baseType, t0, v0, t1, v1) \
|
||||
enum class name:baseType{t0=v0,t1=v1};\
|
||||
@@ -178,7 +178,7 @@ static const int name##_Count = 2;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_3(name, baseType, t0, v0, t1, v1, t2, v2) \
|
||||
enum class name:baseType{t0=v0,t1=v1,t2=v2};\
|
||||
@@ -186,7 +186,7 @@ static const int name##_Count = 3;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1), (baseType)(v2)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_4(name, baseType, t0, v0, t1, v1, t2, v2, t3, v3) \
|
||||
enum class name:baseType{t0=v0,t1=v1,t2=v2,t3=v3};\
|
||||
@@ -194,7 +194,7 @@ static const int name##_Count = 4;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1), (baseType)(v2), (baseType)(v3)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_5(name, baseType, t0, v0, t1, v1, t2, v2, t3, v3, t4, v4) \
|
||||
enum class name:baseType{t0=v0,t1=v1,t2=v2,t3=v3,t4=v4};\
|
||||
@@ -202,7 +202,7 @@ static const int name##_Count = 5;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1), (baseType)(v2), (baseType)(v3), (baseType)(v4)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_6(name, baseType, t0, v0, t1, v1, t2, v2, t3, v3, t4, v4, t5, v5) \
|
||||
enum class name:baseType{t0=v0,t1=v1,t2=v2,t3=v3,t4=v4,t5=v5};\
|
||||
@@ -210,7 +210,7 @@ static const int name##_Count = 6;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1), (baseType)(v2), (baseType)(v3), (baseType)(v4), (baseType)(v5)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_7(name, baseType, t0, v0, t1, v1, t2, v2, t3, v3, t4, v4, t5, v5, t6, v6) \
|
||||
enum class name:baseType{t0=v0,t1=v1,t2=v2,t3=v3,t4=v4,t5=v5,t6=v6};\
|
||||
@@ -218,7 +218,7 @@ static const int name##_Count = 7;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1), (baseType)(v2), (baseType)(v3), (baseType)(v4), (baseType)(v5), (baseType)(v6)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_8(name, baseType, t0, v0, t1, v1, t2, v2, t3, v3, t4, v4, t5, v5, t6, v6, t7, v7) \
|
||||
enum class name:baseType{t0=v0,t1=v1,t2=v2,t3=v3,t4=v4,t5=v5,t6=v6,t7=v7};\
|
||||
@@ -226,7 +226,7 @@ static const int name##_Count = 8;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1), (baseType)(v2), (baseType)(v3), (baseType)(v4), (baseType)(v5), (baseType)(v6), (baseType)(v7)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_9(name, baseType, t0, v0, t1, v1, t2, v2, t3, v3, t4, v4, t5, v5, t6, v6, t7, v7, t8, v8) \
|
||||
enum class name:baseType{t0=v0,t1=v1,t2=v2,t3=v3,t4=v4,t5=v5,t6=v6,t7=v7,t8=v8};\
|
||||
@@ -234,7 +234,7 @@ static const int name##_Count = 9;static const Char**name##_Str(){static const C
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1), (baseType)(v2), (baseType)(v3), (baseType)(v4), (baseType)(v5), (baseType)(v6), (baseType)(v7), (baseType)(v8)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
#define DECLARE_ENUM_FLAGS_10(name, baseType, t0, v0, t1, v1, t2, v2, t3, v3, t4, v4, t5, v5, t6, v6, t7, v7, t8, v8, t9, v9) \
|
||||
enum class name:baseType{t0=v0,t1=v1,t2=v2,t3=v3,t4=v4,t5=v5,t6=v6,t7=v7,t8=v8,t9=v9};\
|
||||
@@ -242,4 +242,4 @@ static const int name##_Count = 10;static const Char**name##_Str(){static const
|
||||
ENUM_TO_STR(t0),ENUM_TO_STR(t1),ENUM_TO_STR(t2),ENUM_TO_STR(t3),ENUM_TO_STR(t4),ENUM_TO_STR(t5),ENUM_TO_STR(t6),ENUM_TO_STR(t7),ENUM_TO_STR(t8),ENUM_TO_STR(t9)};\
|
||||
return str;}static inline const Char*ToString(name e){static baseType val[]={\
|
||||
(baseType)(v0), (baseType)(v1), (baseType)(v2), (baseType)(v3), (baseType)(v4), (baseType)(v5), (baseType)(v6), (baseType)(v7), (baseType)(v8), (baseType)(v9)}; \
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }
|
||||
for (baseType i = 0; i < name##_Count; i++) { if (val[i] == (baseType)e) return name##_Str()[(int)i]; } return ENUM_TO_STR_FALLBACK; }static_assert(true, "")
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace fmt_flax
|
||||
return fmt::format_to(ctx.out(), basic_string_view<Char>(TEXT(formatText)), ##__VA_ARGS__); \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
} static_assert(true, "")
|
||||
|
||||
#define DEFINE_DEFAULT_FORMATTING_VIA_TO_STRING(type) \
|
||||
namespace fmt \
|
||||
@@ -59,4 +59,4 @@ namespace fmt_flax
|
||||
return fmt::detail::copy_str<Char>(str.Get(), str.Get() + str.Length(), ctx.out()); \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
} static_assert(true, "")
|
||||
|
||||
@@ -51,7 +51,11 @@ bool BoundingSphere::Intersects(const BoundingBox& box) const
|
||||
|
||||
bool BoundingSphere::Intersects(const BoundingSphere& sphere) const
|
||||
{
|
||||
return CollisionsHelper::SphereIntersectsSphere(*this, sphere);
|
||||
const Real radiisum = Radius + sphere.Radius;
|
||||
const Real x = Center.X - sphere.Center.X;
|
||||
const Real y = Center.Y - sphere.Center.Y;
|
||||
const Real z = Center.Z - sphere.Center.Z;
|
||||
return x * x + y * y + z * z <= radiisum * radiisum;
|
||||
}
|
||||
|
||||
ContainmentType BoundingSphere::Contains(const Vector3& point) const
|
||||
|
||||
@@ -10,9 +10,23 @@ static_assert(sizeof(Half2) == 4, "Invalid Half2 type size.");
|
||||
static_assert(sizeof(Half3) == 6, "Invalid Half3 type size.");
|
||||
static_assert(sizeof(Half4) == 8, "Invalid Half4 type size.");
|
||||
|
||||
Half2 Half2::Zero(0.0f, 0.0f);
|
||||
Half3 Half3::Zero(0.0f, 0.0f, 0.0f);
|
||||
Half4 Half4::Zero(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
const Half2 Half2::Zero(0.0f, 0.0f);
|
||||
const Half2 Half2::One(1.0f, 1.0f);
|
||||
const Half2 Half2::UnitX(1.0f, 0.0f);
|
||||
const Half2 Half2::UnitY(0.0f, 1.0f);
|
||||
|
||||
const Half3 Half3::Zero(0.0f, 0.0f, 0.0f);
|
||||
const Half3 Half3::One(1.0f, 1.0f, 1.0f);
|
||||
const Half3 Half3::UnitX(1.0f, 0.0f, 0.0f);
|
||||
const Half3 Half3::UnitY(0.0f, 1.0f, 0.0f);
|
||||
const Half3 Half3::UnitZ(0.0f, 0.0f, 1.0f);
|
||||
|
||||
const Half4 Half4::Zero(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
const Half4 Half4::One(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
const Half4 Half4::UnitX(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
const Half4 Half4::UnitY(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
const Half4 Half4::UnitZ(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
const Half4 Half4::UnitW(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
#if !USE_SSE_HALF_CONVERSION
|
||||
|
||||
|
||||
@@ -6,13 +6,23 @@
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
|
||||
#if PLATFORM_SIMD_AVX
|
||||
// MSVC generates slower code without AVX
|
||||
#define USE_SSE_HALF_CONVERSION 1
|
||||
#else
|
||||
#define USE_SSE_HALF_CONVERSION 0
|
||||
#endif
|
||||
|
||||
#if USE_SSE_HALF_CONVERSION
|
||||
#include <intrin.h>
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Half-precision 16 bit floating point number consisting of a sign bit, a 5 bit biased exponent, and a 10 bit mantissa
|
||||
/// </summary>
|
||||
typedef uint16 Half;
|
||||
|
||||
#define USE_SSE_HALF_CONVERSION 0
|
||||
|
||||
/// <summary>
|
||||
/// Utility for packing/unpacking floating point value from single precision (32 bit) to half precision (16 bit).
|
||||
/// </summary>
|
||||
@@ -72,10 +82,17 @@ public:
|
||||
struct FLAXENGINE_API Half2
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// Zero vector
|
||||
/// </summary>
|
||||
static Half2 Zero;
|
||||
// Vector with all components equal 0
|
||||
static const Half2 Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Half2 One;
|
||||
|
||||
// Vector X=1, Y=0
|
||||
static const Half2 UnitX;
|
||||
|
||||
// Vector X=0, Y=1
|
||||
static const Half2 UnitY;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -136,10 +153,20 @@ public:
|
||||
struct FLAXENGINE_API Half3
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// Zero vector
|
||||
/// </summary>
|
||||
static Half3 Zero;
|
||||
// Vector with all components equal 0
|
||||
static const Half3 Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Half3 One;
|
||||
|
||||
// Vector X=1, Y=0, Z=0
|
||||
static const Half3 UnitX;
|
||||
|
||||
// Vector X=0, Y=1, Z=0
|
||||
static const Half3 UnitY;
|
||||
|
||||
// Vector X=0, Y=0, Z=1
|
||||
static const Half3 UnitZ;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -191,10 +218,23 @@ public:
|
||||
struct FLAXENGINE_API Half4
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// Zero vector
|
||||
/// </summary>
|
||||
static Half4 Zero;
|
||||
// Vector with all components equal 0
|
||||
static const Half4 Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Half4 One;
|
||||
|
||||
// Vector X=1, Y=0, Z=0, W=0
|
||||
static const Half4 UnitX;
|
||||
|
||||
// Vector X=0, Y=1, Z=0, W=0
|
||||
static const Half4 UnitY;
|
||||
|
||||
// Vector X=0, Y=0, Z=1, W=0
|
||||
static const Half4 UnitZ;
|
||||
|
||||
// Vector X=0, Y=0, Z=0, W=1
|
||||
static const Half4 UnitW;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Matrix.h"
|
||||
#include "Matrix3x3.h"
|
||||
#include "Matrix3x4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Quaternion.h"
|
||||
#include "Transform.h"
|
||||
@@ -887,3 +888,39 @@ Float4 Matrix::TransformPosition(const Matrix& m, const Float4& v)
|
||||
m.Values[0][3] * v.Raw[0] + m.Values[1][3] * v.Raw[1] + m.Values[2][3] * v.Raw[2] + m.Values[3][3] * v.Raw[3]
|
||||
);
|
||||
}
|
||||
|
||||
void Matrix3x4::SetMatrix(const Matrix& m)
|
||||
{
|
||||
const float* src = m.Raw;
|
||||
float* dst = Raw;
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[3] = src[3];
|
||||
dst[4] = src[4];
|
||||
dst[5] = src[5];
|
||||
dst[6] = src[6];
|
||||
dst[7] = src[7];
|
||||
dst[8] = src[8];
|
||||
dst[9] = src[9];
|
||||
dst[10] = src[10];
|
||||
dst[11] = src[11];
|
||||
}
|
||||
|
||||
void Matrix3x4::SetMatrixTranspose(const Matrix& m)
|
||||
{
|
||||
const float* src = m.Raw;
|
||||
float* dst = Raw;
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[4];
|
||||
dst[2] = src[8];
|
||||
dst[3] = src[12];
|
||||
dst[4] = src[1];
|
||||
dst[5] = src[5];
|
||||
dst[6] = src[9];
|
||||
dst[7] = src[13];
|
||||
dst[8] = src[2];
|
||||
dst[9] = src[6];
|
||||
dst[10] = src[10];
|
||||
dst[11] = src[14];
|
||||
}
|
||||
|
||||
@@ -890,7 +890,7 @@ public:
|
||||
/// <param name="translation">The translation.</param>
|
||||
/// <param name="rotation">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.</param>
|
||||
/// <param name="scaling">The scaling.</param>
|
||||
/// <param name="result">When the method completes, contains the created rotation matrix.</param>
|
||||
/// <param name="result">When the method completes, contains the created transformation matrix.</param>
|
||||
static void Transformation(const Float3& scaling, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
||||
|
||||
// Creates a 3D affine transformation matrix.
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "Quaternion.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
#include <intrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
const Matrix3x3 Matrix3x3::Zero(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
const Matrix3x3 Matrix3x3::Identity(
|
||||
1.0f, 0.0f, 0.0f,
|
||||
@@ -139,6 +142,67 @@ void Matrix3x3::Multiply(const Matrix3x3& left, float right, Matrix3x3& result)
|
||||
|
||||
void Matrix3x3::Multiply(const Matrix3x3& left, const Matrix3x3& right, Matrix3x3& result)
|
||||
{
|
||||
|
||||
#if true
|
||||
{
|
||||
// First : naive solution with but with some tricks to make compiler (MSVC) behave
|
||||
//* Note that, in this case, manually unrolling the loop helps
|
||||
//* as the compiler can't auto-vectorize non-contagious memory access
|
||||
float* __restrict const matData = result.Raw;
|
||||
|
||||
//Mat matC{ matB.width, matA.height, matB.rowSpan, matData };
|
||||
|
||||
for (int rowC = 0; rowC < 3; ++rowC) {
|
||||
for (int colC = 0; colC < 3; ++colC) {
|
||||
// an independent, local accumulator.
|
||||
float accumulate = 0;
|
||||
int pos = 0;
|
||||
// manual unrolling IS helpful in this case
|
||||
for (; pos < 3 - 4; pos += 4) {
|
||||
accumulate += left.Raw[rowC * 3 + pos] *
|
||||
right.Raw[pos * 3 + colC] +
|
||||
left.Raw[rowC * 3 + pos + 1] *
|
||||
right.Raw[(pos + 1) * 3 + colC] +
|
||||
left.Raw[rowC * 3 + pos + 2] *
|
||||
right.Raw[(pos + 2) * 3 + colC] +
|
||||
left.Raw[rowC * 3 + pos + 3] *
|
||||
right.Raw[(pos + 3) * 3 + colC];
|
||||
}
|
||||
for (; pos < 3; ++pos) {
|
||||
accumulate += left.Raw[rowC * 3 + pos] *
|
||||
right.Raw[pos * 3 + colC];
|
||||
}
|
||||
matData[rowC * 3 + colC] = accumulate;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
__m256i vec_multi_res = _mm256_setzero_si256();
|
||||
__m256i vec_mat1 = _mm256_setzero_si256();
|
||||
__m256i vec_mat2 = _mm256_setzero_si256();
|
||||
|
||||
int i, j, k;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; ++j)
|
||||
{
|
||||
//Stores one element in mat1 and use it in all computations needed before proceeding
|
||||
//Stores as vector to increase computations per cycle
|
||||
vec_mat1 = _mm256_set1_epi32(left.Values[j][i]);
|
||||
|
||||
for (k = 0; k < 3; k += 8)
|
||||
{
|
||||
vec_mat2 = _mm256_loadu_si256((__m256i*) & right.Values[k][j]); //Stores row of second matrix (eight in each iteration)
|
||||
vec_multi_res = _mm256_loadu_si256((__m256i*) & result.Values[k][i]); //Loads the result matrix row as a vector
|
||||
vec_multi_res = _mm256_add_epi32(vec_multi_res, _mm256_mullo_epi32(vec_mat1, vec_mat2));//Multiplies the vectors and adds to th the result vector
|
||||
|
||||
_mm256_storeu_si256((__m256i*) & result.Values[k][i], vec_multi_res); //Stores the result vector into the result array
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
result = Matrix3x3(
|
||||
left.M11 * right.M11 + left.M12 * right.M21 + left.M13 * right.M31,
|
||||
left.M11 * right.M12 + left.M12 * right.M22 + left.M13 * right.M32,
|
||||
@@ -150,6 +214,19 @@ void Matrix3x3::Multiply(const Matrix3x3& left, const Matrix3x3& right, Matrix3x
|
||||
left.M31 * right.M12 + left.M32 * right.M22 + left.M33 * right.M32,
|
||||
left.M31 * right.M13 + left.M32 * right.M23 + left.M33 * right.M33
|
||||
);
|
||||
/*Matrix3x3 result2 = Matrix3x3(
|
||||
left.M11 * right.M11 + left.M12 * right.M21 + left.M13 * right.M31,
|
||||
left.M11 * right.M12 + left.M12 * right.M22 + left.M13 * right.M32,
|
||||
left.M11 * right.M13 + left.M12 * right.M23 + left.M13 * right.M33,
|
||||
left.M21 * right.M11 + left.M22 * right.M21 + left.M23 * right.M31,
|
||||
left.M21 * right.M12 + left.M22 * right.M22 + left.M23 * right.M32,
|
||||
left.M21 * right.M13 + left.M22 * right.M23 + left.M23 * right.M33,
|
||||
left.M31 * right.M11 + left.M32 * right.M21 + left.M33 * right.M31,
|
||||
left.M31 * right.M12 + left.M32 * right.M22 + left.M33 * right.M32,
|
||||
left.M31 * right.M13 + left.M32 * right.M23 + left.M33 * right.M33
|
||||
);
|
||||
ASSERT(result2 == result);*/
|
||||
#endif
|
||||
}
|
||||
|
||||
void Matrix3x3::Divide(const Matrix3x3& left, float right, Matrix3x3& result)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
#include "Engine/Platform/Platform.h"
|
||||
|
||||
/// <summary>
|
||||
@@ -538,6 +539,47 @@ public:
|
||||
/// <param name="result">The result.</param>
|
||||
static void Transform2DPoint(const Float2& point, const Matrix3x3& transform, Float2& result)
|
||||
{
|
||||
//Float4 pointVector = Float4(0.0f, 0.0f, point.Y, point.X);
|
||||
/*
|
||||
// Load the matrix into SIMD registers
|
||||
const Float4 row1 = Float4((Float3)transform.Values[0], 0.0f);
|
||||
const Float4 row2 = Float4((Float3)transform.Values[1], 0.0f);
|
||||
const Float4 row3 = Float4((Float3)transform.Values[2], 0.0f);
|
||||
|
||||
const Float4 res(
|
||||
point.X * row1.Raw[0] + point.Y * row2.Raw[0] + row3.Raw[0],
|
||||
point.X * row1.Raw[1] + point.Y * row2.Raw[1] + row3.Raw[1], 0.0f, 0.0f
|
||||
);
|
||||
result = Float2(res.X, res.Y);
|
||||
|
||||
*/
|
||||
/*
|
||||
// Load the point into SIMD registers
|
||||
__m128 pointVector = _mm_set_ps(0.0f, 0.0f, point.Y, point.X);
|
||||
|
||||
// Load the matrix into SIMD registers
|
||||
__m128 row1 = _mm_loadu_ps(transform.Values[0]);
|
||||
__m128 row2 = _mm_loadu_ps(transform.Values[1]);
|
||||
__m128 row3 = _mm_loadu_ps(transform.Values[2]);
|
||||
|
||||
// Perform the matrix-vector multiplication
|
||||
__m128 result2 = _mm_add_ps(
|
||||
_mm_add_ps(_mm_mul_ps(row1, pointVector), _mm_mul_ps(row2, pointVector)),
|
||||
row3
|
||||
);
|
||||
|
||||
// Store the result back into a Point2D structure
|
||||
_mm_storeu_ps(&result.X, result2);
|
||||
|
||||
*/
|
||||
|
||||
/*auto result3 = Float2(
|
||||
point.X * transform.M11 + point.Y * transform.M21 + transform.M31,
|
||||
point.X * transform.M12 + point.Y * transform.M22 + transform.M32);
|
||||
|
||||
ASSERT(result == result3);*/
|
||||
|
||||
|
||||
result = Float2(
|
||||
point.X * transform.M11 + point.Y * transform.M21 + transform.M31,
|
||||
point.X * transform.M12 + point.Y * transform.M22 + transform.M32);
|
||||
@@ -552,6 +594,39 @@ public:
|
||||
/// <param name="result">The result.</param>
|
||||
static void Transform2DVector(const Float2& vector, const Matrix3x3& transform, Float2& result)
|
||||
{
|
||||
//Float4 pointVector = Float4(0.0f, 0.0f, vector.Y, vector.X);
|
||||
|
||||
// Load the matrix into SIMD registers
|
||||
/*const Float4 row1 = Float4((Float3)transform.Values[0], 0.0f);
|
||||
const Float4 row2 = Float4((Float3)transform.Values[1], 0.0f);
|
||||
const Float4 row3 = Float4((Float3)transform.Values[2], 0.0f);
|
||||
|
||||
const Float4 res(
|
||||
vector.X * row1.Raw[0] + vector.Y * row2.Raw[0],
|
||||
vector.X * row1.Raw[1] + vector.Y * row2.Raw[1], 0.0f, 0.0f
|
||||
);
|
||||
result = Float2(res.X, res.Y);*/
|
||||
/*
|
||||
// Load the point into SIMD registers
|
||||
__m128 pointVector = _mm_set_ps(0.0f, 0.0f, vector.Y, vector.X);
|
||||
|
||||
// Load the matrix into SIMD registers
|
||||
__m128 row1 = _mm_loadu_ps(transform.Values[0]);
|
||||
__m128 row2 = _mm_loadu_ps(transform.Values[1]);
|
||||
|
||||
// Perform the matrix-vector multiplication
|
||||
__m128 result2 = _mm_add_ps(_mm_mul_ps(row1, pointVector), _mm_mul_ps(row2, pointVector));
|
||||
|
||||
// Store the result back into a Point2D structure
|
||||
_mm_storeu_ps(&result.X, result2);
|
||||
*/
|
||||
/*auto result3 = Float2(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22);
|
||||
|
||||
ASSERT(result == result3);*/
|
||||
|
||||
|
||||
result = Float2(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user