Compare commits
134 Commits
mac_change
...
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
|
||||
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
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);
|
||||
|
||||
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax
(Stored with Git LFS)
BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Lights.flax
(Stored with Git LFS)
BIN
Content/Shaders/Lights.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Quad.flax
(Stored with Git LFS)
BIN
Content/Shaders/Quad.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Shadows.flax
(Stored with Git LFS)
BIN
Content/Shaders/Shadows.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
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