Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d8c1b111a | ||
|
|
3298053d9d | ||
|
|
adccb74f44 | ||
|
|
97113b5df6 | ||
|
|
c374d86ec7 | ||
|
|
803fd7f8ba | ||
|
|
11a57f5285 | ||
|
|
0d015b485e | ||
|
|
17e4a6a589 | ||
|
|
c1a87ed946 | ||
|
|
20dae92be7 | ||
|
|
df67f32399 | ||
|
|
14a802d057 | ||
|
|
12d6df3edf | ||
|
|
2838449186 | ||
|
|
75513bea3d | ||
|
|
16c3d7c44d | ||
|
|
7ae069baf6 | ||
|
|
00dc3faa19 | ||
|
|
f39acdadb3 | ||
|
|
1254d01545 | ||
|
|
0bc517842f | ||
|
|
3e63281508 | ||
|
|
ef486b7082 | ||
|
|
81a61d5a90 | ||
|
|
37197cbdf1 | ||
|
|
b53ed2d8f2 |
@@ -8,3 +8,4 @@ imgui.ini
|
|||||||
GlitchyEditor/resources/scripts/ScriptCore.dll
|
GlitchyEditor/resources/scripts/ScriptCore.dll
|
||||||
GlitchyEditor/resources/scripts/ScriptCore.pdb
|
GlitchyEditor/resources/scripts/ScriptCore.pdb
|
||||||
GlitchyEditor/settings.bon
|
GlitchyEditor/settings.bon
|
||||||
|
GlitchyEditor/MonoDebugger.log
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ TargetType = "BeefGUIApplication"
|
|||||||
StartupObject = "GlitchyEngine.Program"
|
StartupObject = "GlitchyEngine.Program"
|
||||||
|
|
||||||
[Configs.Debug.Win64]
|
[Configs.Debug.Win64]
|
||||||
DebugCommandArguments = "\"content\\Scenes\\physics2D.scene\""
|
DebugCommandArguments = "\"D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEditor\\SandboxProject\""
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
project_user.bon
|
||||||
@@ -30,10 +30,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
MeshComponent = {
|
MeshComponent = {
|
||||||
Mesh = "Models/sphere.glb"
|
Mesh = "Assets/Models/sphere.glb"
|
||||||
},
|
},
|
||||||
MeshRendererComponent = {
|
MeshRendererComponent = {
|
||||||
Material = "Textures/TestMaterial.mat"
|
Material = "Assets/Textures/TestMaterial.mat"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -49,12 +49,12 @@
|
|||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
X = 0.614328027,
|
X = 0.614328027,
|
||||||
Y = 0.239776045,
|
Y = 0.23977606,
|
||||||
Z = 0.0315669999,
|
Z = 0.0315669999,
|
||||||
W = 0.751073837
|
W = 0.751073778
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
X = 0.999998868,
|
X = 0.999998808,
|
||||||
Y = 1,
|
Y = 1,
|
||||||
Z = 1.00000095
|
Z = 1.00000095
|
||||||
},
|
},
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
Color = {
|
Color = {
|
||||||
R = 1,
|
R = 1,
|
||||||
G = 0.991771996,
|
G = 0.991771996,
|
||||||
B = 0.74086225
|
B = 0.74086231
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -103,10 +103,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
MeshComponent = {
|
MeshComponent = {
|
||||||
Mesh = "Models/plane.glb"
|
Mesh = "Assets/Models/plane.glb"
|
||||||
},
|
},
|
||||||
MeshRendererComponent = {
|
MeshRendererComponent = {
|
||||||
Material = "Textures/TestMaterial.mat"
|
Material = "Assets/Textures/TestMaterial.mat"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
OrthographicHeight = 10,
|
OrthographicHeight = 10,
|
||||||
OrthographicNearPlane = 0,
|
OrthographicNearPlane = 0,
|
||||||
OrthographicFarPlane = 10,
|
OrthographicFarPlane = 10,
|
||||||
AspectRatio = 2.19888878,
|
AspectRatio = 1.87453413,
|
||||||
FixedAspectRatio = false
|
FixedAspectRatio = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
Rotation = {
|
Rotation = {
|
||||||
X = 0.18301262,
|
X = 0.18301262,
|
||||||
Y = -0.683013558,
|
Y = -0.683013558,
|
||||||
Z = 0.683012128,
|
Z = 0.683012187,
|
||||||
W = 0.183013007
|
W = 0.183013007
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
@@ -173,13 +173,13 @@
|
|||||||
Z = 1
|
Z = 1
|
||||||
},
|
},
|
||||||
EditorEulerRotation = {
|
EditorEulerRotation = {
|
||||||
X = 1.57079446,
|
X = 1.57079458,
|
||||||
Y = -2.61799312,
|
Y = -2.61799288,
|
||||||
Z = 0
|
Z = 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MeshComponent = {
|
MeshComponent = {
|
||||||
Mesh = "Models/plane.glb"
|
Mesh = ""
|
||||||
},
|
},
|
||||||
MeshRendererComponent = {
|
MeshRendererComponent = {
|
||||||
Material = ""
|
Material = ""
|
||||||
@@ -192,32 +192,32 @@
|
|||||||
},
|
},
|
||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = 2.37353587,
|
X = 2.37353563,
|
||||||
Y = 0.629615188,
|
Y = 0.629615188,
|
||||||
Z = -1.34831977
|
Z = -1.34831977
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
X = 0.270598024,
|
X = 0.270598024,
|
||||||
Y = -0.65328145,
|
Y = -0.65328151,
|
||||||
Z = 0.65328151,
|
Z = 0.65328151,
|
||||||
W = 0.270598054
|
W = 0.270598054
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
X = 0.999999881,
|
X = 0.999999821,
|
||||||
Y = 0.999999821,
|
Y = 0.999999762,
|
||||||
Z = 0.999999702
|
Z = 0.999999702
|
||||||
},
|
},
|
||||||
EditorEulerRotation = {
|
EditorEulerRotation = {
|
||||||
X = 1.57079637,
|
X = 1.57079649,
|
||||||
Y = -2.3561945,
|
Y = -2.35619426,
|
||||||
Z = 8.94069743e-08
|
Z = 8.94069601e-08
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MeshComponent = {
|
MeshComponent = {
|
||||||
Mesh = "Models/plane.glb"
|
Mesh = "Assets/Models/plane.glb"
|
||||||
},
|
},
|
||||||
MeshRendererComponent = {
|
MeshRendererComponent = {
|
||||||
Material = "Textures/RocketMaterial.mat"
|
Material = "Assets/Textures/RocketMaterial.mat"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
B = 0.32878688,
|
B = 0.32878688,
|
||||||
A = 1
|
A = 1
|
||||||
},
|
},
|
||||||
Sprite = "Textures/TestMat/rustediron2_albedo.png",
|
Sprite = "Assets/Textures/TestMat/rustediron2_albedo.png",
|
||||||
UvTransform = {
|
UvTransform = {
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
@@ -71,8 +71,8 @@
|
|||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 1,
|
R = 1,
|
||||||
G = 0.941886961,
|
G = 0.941887021,
|
||||||
B = 0.401484549,
|
B = 0.401484489,
|
||||||
A = 1
|
A = 1
|
||||||
},
|
},
|
||||||
Sprite = "",
|
Sprite = "",
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
OrthographicHeight = 10,
|
OrthographicHeight = 10,
|
||||||
OrthographicNearPlane = 0,
|
OrthographicNearPlane = 0,
|
||||||
OrthographicFarPlane = 10,
|
OrthographicFarPlane = 10,
|
||||||
AspectRatio = 0.884925187,
|
AspectRatio = 2.05582929,
|
||||||
FixedAspectRatio = false
|
FixedAspectRatio = false
|
||||||
},
|
},
|
||||||
ScriptComponent = {
|
ScriptComponent = {
|
||||||
@@ -195,8 +195,8 @@
|
|||||||
},
|
},
|
||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = -0.121203184,
|
X = -0.121203206,
|
||||||
Y = 0.660160959,
|
Y = 0.660161078,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
@@ -234,37 +234,12 @@
|
|||||||
ScriptComponent = {
|
ScriptComponent = {
|
||||||
ScriptClass = "Sandbox.MyTestEntity",
|
ScriptClass = "Sandbox.MyTestEntity",
|
||||||
Fields = [
|
Fields = [
|
||||||
Bo = (Bool)false,
|
_rigidBody = (Component)15710354273720487680,
|
||||||
By = (Byte)0,
|
|
||||||
Us = (UShort)57,
|
|
||||||
Ui = (UInt)54,
|
|
||||||
Ul = (ULong)53,
|
|
||||||
Sb = (SByte)-128,
|
|
||||||
Sh = (Short)95,
|
|
||||||
In = (Int)-149,
|
|
||||||
Lo = (Long)82,
|
|
||||||
Fl = (Float)-98.122963,
|
|
||||||
Do = (Double)118,
|
|
||||||
V2 = (float2){
|
|
||||||
X = 11,
|
|
||||||
Y = 12
|
|
||||||
},
|
|
||||||
V3 = (float3){
|
|
||||||
X = 13,
|
|
||||||
Y = 14,
|
|
||||||
Z = 15
|
|
||||||
},
|
|
||||||
V4 = (float4){
|
|
||||||
X = 14,
|
|
||||||
Y = 17,
|
|
||||||
Z = 18,
|
|
||||||
W = 19
|
|
||||||
},
|
|
||||||
TheEntity = (Entity)0,
|
TheEntity = (Entity)0,
|
||||||
JumpForce = (Float)200,
|
JumpForce = (Float)200,
|
||||||
MoveForce = (Float)148,
|
MoveForce = (Float)148,
|
||||||
MyNumber = (Int)22,
|
MyNumber = (Int)22,
|
||||||
MyDouble = (Double)23
|
Camera = (Entity)1491484622542812645
|
||||||
] }
|
] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -301,7 +276,7 @@
|
|||||||
Color = {
|
Color = {
|
||||||
R = 0.985467017,
|
R = 0.985467017,
|
||||||
G = 1,
|
G = 1,
|
||||||
B = 0.569978058
|
B = 0.569977939
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -334,10 +309,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
MeshComponent = {
|
MeshComponent = {
|
||||||
Mesh = "Models/sphere.glb"
|
Mesh = "Assets/Models/sphere.glb"
|
||||||
},
|
},
|
||||||
MeshRendererComponent = {
|
MeshRendererComponent = {
|
||||||
Material = "Textures/TestMaterial.mat"
|
Material = "Assets/Textures/TestMaterial.mat"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -348,8 +323,8 @@
|
|||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 0.425658971,
|
R = 0.425658971,
|
||||||
G = 0.855207562,
|
G = 0.855207443,
|
||||||
B = 0.0558161102,
|
B = 0.0558161177,
|
||||||
A = 1
|
A = 1
|
||||||
},
|
},
|
||||||
Sprite = "",
|
Sprite = "",
|
||||||
@@ -363,14 +338,14 @@
|
|||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = 6.74610233,
|
X = 6.74610233,
|
||||||
Y = -2.03225899,
|
Y = -2.03225946,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
Z = -0.331792623,
|
Z = -0.331792623,
|
||||||
W = 0.943352342
|
W = 0.94335258
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
X = 5.29557419,
|
X = 5.29557419,
|
||||||
@@ -409,7 +384,7 @@
|
|||||||
},
|
},
|
||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 0.666116953,
|
R = 0.666117013,
|
||||||
G = 0.0600316115,
|
G = 0.0600316115,
|
||||||
B = 1,
|
B = 1,
|
||||||
A = 1
|
A = 1
|
||||||
@@ -424,8 +399,8 @@
|
|||||||
},
|
},
|
||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = 15.2321301,
|
X = 15.2321281,
|
||||||
Y = -1.98709249,
|
Y = -1.98709273,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
@@ -435,7 +410,7 @@
|
|||||||
W = 0.990847468
|
W = 0.990847468
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
X = 13.9764566,
|
X = 13.9764528,
|
||||||
Y = 1,
|
Y = 1,
|
||||||
Z = 1
|
Z = 1
|
||||||
},
|
},
|
||||||
@@ -471,7 +446,7 @@
|
|||||||
},
|
},
|
||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 0.176544324,
|
R = 0.176544309,
|
||||||
G = 0.666713238,
|
G = 0.666713238,
|
||||||
B = 0.687030852,
|
B = 0.687030852,
|
||||||
A = 1
|
A = 1
|
||||||
@@ -487,24 +462,24 @@
|
|||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = -6.27842855,
|
X = -6.27842855,
|
||||||
Y = 2.62550211,
|
Y = 2.62550163,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
Z = 0.187087834,
|
Z = 0.187087879,
|
||||||
W = 0.982343197
|
W = 0.982343197
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
X = 0.999999523,
|
X = 0.999999464,
|
||||||
Y = 6.49634314,
|
Y = 6.49634314,
|
||||||
Z = 1
|
Z = 1
|
||||||
},
|
},
|
||||||
EditorEulerRotation = {
|
EditorEulerRotation = {
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
Z = 0.376393586
|
Z = 0.376393616
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Rigidbody2D = {
|
Rigidbody2D = {
|
||||||
@@ -522,7 +497,7 @@
|
|||||||
},
|
},
|
||||||
Density = 1,
|
Density = 1,
|
||||||
Friction = 0.5,
|
Friction = 0.5,
|
||||||
Restitution = 0.899999976,
|
Restitution = 0.899999857,
|
||||||
RestitutionThreshold = 0.5
|
RestitutionThreshold = 0.5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,9 +11,9 @@ namespace Sandbox
|
|||||||
|
|
||||||
public enum MyEnum
|
public enum MyEnum
|
||||||
{
|
{
|
||||||
Yes,
|
Yes = 1,
|
||||||
No,
|
No,
|
||||||
Maybe
|
Maybe = 1337
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MyStruct
|
public struct MyStruct
|
||||||
@@ -25,36 +25,38 @@ namespace Sandbox
|
|||||||
|
|
||||||
class MyTestEntity : Entity
|
class MyTestEntity : Entity
|
||||||
{
|
{
|
||||||
//[ShowInEditor]
|
[ShowInEditor]
|
||||||
RigidBody2D _rigidBody;
|
RigidBody2D _rigidBody;
|
||||||
|
|
||||||
public bool Bo;
|
//public bool Bo;
|
||||||
|
|
||||||
public byte By;
|
//public byte By;
|
||||||
public ushort Us;
|
//public ushort Us;
|
||||||
public uint Ui;
|
//public uint Ui;
|
||||||
public ulong Ul;
|
//public ulong Ul;
|
||||||
|
|
||||||
public sbyte Sb;
|
//public sbyte Sb;
|
||||||
public short Sh;
|
//public short Sh;
|
||||||
public int In;
|
//public int In;
|
||||||
public long Lo;
|
//public long Lo;
|
||||||
|
|
||||||
public float Fl;
|
//public float Fl;
|
||||||
public double Do;
|
//public double Do;
|
||||||
public float2 V2;
|
//public float2 V2;
|
||||||
public float3 V3;
|
//public float3 V3;
|
||||||
public float4 V4;
|
//public float4 V4;
|
||||||
|
|
||||||
public Entity TheEntity;
|
public Entity TheEntity;
|
||||||
|
|
||||||
public float JumpForce = 2000;
|
public float JumpForce = 2000;
|
||||||
[ShowInEditor] float MoveForce = 1000;
|
[ShowInEditor] float MoveForce = 1000;
|
||||||
[ShowInEditor] private int MyNumber = 1337;
|
[ShowInEditor] private int MyNumber = 1337;
|
||||||
[ShowInEditor] public double MyDouble = 1000.0f;
|
//[ShowInEditor] public double MyDouble = 1000.0f;
|
||||||
|
|
||||||
public MyStruct AStruct;
|
public MyStruct AStruct;
|
||||||
|
|
||||||
|
public MyEnum AEnum = MyEnum.Maybe;
|
||||||
|
|
||||||
public Camera Camera;
|
public Camera Camera;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -66,14 +68,39 @@ namespace Sandbox
|
|||||||
|
|
||||||
Log.Info($"Jump Force: {JumpForce}");
|
Log.Info($"Jump Force: {JumpForce}");
|
||||||
|
|
||||||
_rigidBody ??= GetComponent<RigidBody2D>() ?? AddComponent<RigidBody2D>();
|
//_rigidBody ??= GetComponent<RigidBody2D>() ?? AddComponent<RigidBody2D>();
|
||||||
|
|
||||||
Camera = FindEntityWithName("Camera").As<Camera>();
|
if (_rigidBody == null)
|
||||||
|
{
|
||||||
|
Log.Error("_rigidBody was not set in editor.");
|
||||||
|
}
|
||||||
|
|
||||||
if (Camera == null)
|
if (Camera == null)
|
||||||
{
|
{
|
||||||
Log.Error("Camera not found.");
|
Log.Warning("Camera wasn't set in editor. Searching...");
|
||||||
|
Camera = FindEntityWithName("Camera").As<Camera>();
|
||||||
|
|
||||||
|
if (Camera == null)
|
||||||
|
{
|
||||||
|
Log.Error("Camera not found.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Log.Warning("Achtung.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SubVoid();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubVoid()
|
||||||
|
{
|
||||||
|
throw new Exception("Ouha!", new IndexOutOfRangeException("Bist du jecke2?!", new AccessViolationException("Haleluja")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -105,6 +132,9 @@ namespace Sandbox
|
|||||||
force.Y += JumpForce;
|
force.Y += JumpForce;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Input.IsKeyPressing(Key.N))
|
||||||
|
SubVoid();
|
||||||
|
|
||||||
_rigidBody.ApplyForceToCenter(force);
|
_rigidBody.ApplyForceToCenter(force);
|
||||||
|
|
||||||
if (Input.IsMouseButtonReleasing(MouseButton.MiddleButton))
|
if (Input.IsMouseButtonReleasing(MouseButton.MiddleButton))
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
|
|||||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||||
// die einer Assembly zugeordnet sind.
|
// die einer Assembly zugeordnet sind.
|
||||||
[assembly: AssemblyTitle("Sanbox")]
|
[assembly: AssemblyTitle("SandboxProject")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("Sanbox")]
|
[assembly: AssemblyProduct("SandboxProject")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2023")]
|
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|||||||
@@ -7,15 +7,15 @@
|
|||||||
<ProjectGuid>{7A70819C-5317-402A-8553-95C5A001E370}</ProjectGuid>
|
<ProjectGuid>{7A70819C-5317-402A-8553-95C5A001E370}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>Sandbox</RootNamespace>
|
<RootNamespace>SandboxProject</RootNamespace>
|
||||||
<AssemblyName>Sandbox</AssemblyName>
|
<AssemblyName>SandboxProject</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>portable</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.4.33205.214
|
VisualStudioVersion = 17.4.33205.214
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox", "Sandbox.csproj", "{7A70819C-5317-402A-8553-95C5A001E370}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SandboxProject", "SandboxProject.csproj", "{7A70819C-5317-402A-8553-95C5A001E370}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScriptCore", "..\..\..\..\ScriptCore\ScriptCore.csproj", "{6222C226-FC78-498C-80BA-5CF10AC9123C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScriptCore", "..\..\..\..\ScriptCore\ScriptCore.csproj", "{6222C226-FC78-498C-80BA-5CF10AC9123C}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
Effect = "Resources/Shaders/myEffect.hlsl",
|
||||||
|
Textures = [
|
||||||
|
"AlbedoTexture": "Assets/Textures/rocket.png",
|
||||||
|
"NormalTexture": "Assets/Textures/TestMat/rustediron2_normal.png",
|
||||||
|
"MetallicTexture": "Assets/Textures/TestMat/rustediron2_metallic.png",
|
||||||
|
"RoughnessTexture": "Assets/Textures/TestMat/rustediron2_roughness.png"
|
||||||
|
],
|
||||||
|
Variables = [
|
||||||
|
"AlbedoColor": .ColorRGBA{
|
||||||
|
Value = {
|
||||||
|
R = 1,
|
||||||
|
G = 1,
|
||||||
|
B = 1,
|
||||||
|
A = 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NormalScaling": .Float2{
|
||||||
|
Value = {
|
||||||
|
X = 1,
|
||||||
|
Y = 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MetallicFactor": .Float{
|
||||||
|
Value = 0
|
||||||
|
},
|
||||||
|
"RoughnessFactor": .Float{
|
||||||
|
Value = 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 10 MiB After Width: | Height: | Size: 10 MiB |
|
Before Width: | Height: | Size: 3.3 MiB After Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 7.4 MiB After Width: | Height: | Size: 7.4 MiB |
|
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 3.0 MiB |
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
Effect = "Shaders/myEffect.hlsl",
|
Effect = "Resources/Shaders/myEffect.hlsl",
|
||||||
Textures = [
|
Textures = [
|
||||||
"AlbedoTexture": "Textures/TestMat/rustediron2_albedo.png",
|
"AlbedoTexture": "Assets/Textures/TestMat/rustediron2_albedo.png",
|
||||||
"NormalTexture": "Textures/TestMat/rustediron2_normal.png",
|
"NormalTexture": "Assets/Textures/TestMat/rustediron2_normal.png",
|
||||||
"MetallicTexture": "Textures/TestMat/rustediron2_metallic.png",
|
"MetallicTexture": "Assets/Textures/TestMat/rustediron2_metallic.png",
|
||||||
"RoughnessTexture": "Textures/TestMat/rustediron2_roughness.png",
|
"RoughnessTexture": "Assets/Textures/TestMat/rustediron2_roughness.png",
|
||||||
"EmissiveTexture": "Textures/rocket.png"
|
"EmissiveTexture": "Assets/Textures/rocket.png"
|
||||||
],
|
],
|
||||||
Variables = [
|
Variables = [
|
||||||
"AlbedoColor": .ColorRGBA{
|
"AlbedoColor": .ColorRGBA{
|
||||||
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
@@ -0,0 +1 @@
|
|||||||
|
{_projectName="SandboxProject"}
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
Effect = "Shaders/myEffect.hlsl",
|
|
||||||
Textures = [
|
|
||||||
"AlbedoTexture": "Textures/rocket.png",
|
|
||||||
"NormalTexture": "Textures/TestMat/rustediron2_normal.png",
|
|
||||||
"MetallicTexture": "Textures/TestMat/rustediron2_metallic.png",
|
|
||||||
"RoughnessTexture": "Textures/TestMat/rustediron2_roughness.png"
|
|
||||||
],
|
|
||||||
Variables = [
|
|
||||||
"AlbedoColor": .ColorRGBA{
|
|
||||||
Value = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"NormalScaling": .Float2{
|
|
||||||
Value = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"MetallicFactor": .Float{
|
|
||||||
Value = 0
|
|
||||||
},
|
|
||||||
"RoughnessFactor": .Float{
|
|
||||||
Value = 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
project_user.bon
|
||||||
@@ -0,0 +1,398 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.tlog
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||||
|
*.vbp
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||||
|
*.dsw
|
||||||
|
*.dsp
|
||||||
|
|
||||||
|
# Visual Studio 6 technical files
|
||||||
|
*.ncb
|
||||||
|
*.aps
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# Visual Studio History (VSHistory) files
|
||||||
|
.vshistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
# VS Code files for those working on multiple tools
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Windows Installer files from build outputs
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
*.sln.iml
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||||
|
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||||
|
// die einer Assembly zugeordnet sind.
|
||||||
|
[assembly: AssemblyTitle("[ProjectName]")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("[ProjectName]")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||||
|
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||||
|
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||||
|
[assembly: Guid("7a70819c-5317-402a-8553-95c5a001e370")]
|
||||||
|
|
||||||
|
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||||
|
//
|
||||||
|
// Hauptversion
|
||||||
|
// Nebenversion
|
||||||
|
// Buildnummer
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||||
|
// indem Sie "*" wie unten gezeigt eingeben:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{7A70819C-5317-402A-8553-95C5A001E370}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>[ProjectName]</RootNamespace>
|
||||||
|
<AssemblyName>[ProjectName]</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>portable</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="ScriptCore, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>[CoreLibPath]</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.4.33205.214
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "[ProjectName]", "[ProjectName].csproj", "{7A70819C-5317-402A-8553-95C5A001E370}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{7A70819C-5317-402A-8553-95C5A001E370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7A70819C-5317-402A-8553-95C5A001E370}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7A70819C-5317-402A-8553-95C5A001E370}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7A70819C-5317-402A-8553-95C5A001E370}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {B5D43D8D-D80B-41AA-BE40-1DC507D87148}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -9,8 +9,8 @@
|
|||||||
AddressModeU = .Clamp,
|
AddressModeU = .Clamp,
|
||||||
AddressModeV = .Clamp,
|
AddressModeV = .Clamp,
|
||||||
AddressModeW = .Clamp,
|
AddressModeW = .Clamp,
|
||||||
MipMinLOD = -340282346638528859811704183484516925440,
|
MipMinLOD = -3.40282347e+38,
|
||||||
MipMaxLOD = 340282346638528859811704183484516925440,
|
MipMaxLOD = 3.40282347e+38,
|
||||||
MaxAnisotropy = 1,
|
MaxAnisotropy = 1,
|
||||||
BorderColor = {
|
BorderColor = {
|
||||||
R = 1,
|
R = 1,
|
||||||
@@ -9,12 +9,21 @@
|
|||||||
".NETStandard,Version=v2.0/": {
|
".NETStandard,Version=v2.0/": {
|
||||||
"ScriptCore/1.0.0": {
|
"ScriptCore/1.0.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"Half": "1.0.0",
|
||||||
"NETStandard.Library": "2.0.3"
|
"NETStandard.Library": "2.0.3"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"ScriptCore.dll": {}
|
"ScriptCore.dll": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Half/1.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/System.Half.dll": {
|
||||||
|
"assemblyVersion": "1.0.0.0",
|
||||||
|
"fileVersion": "1.0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Microsoft.NETCore.Platforms/1.1.0": {},
|
"Microsoft.NETCore.Platforms/1.1.0": {},
|
||||||
"NETStandard.Library/2.0.3": {
|
"NETStandard.Library/2.0.3": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -29,6 +38,13 @@
|
|||||||
"serviceable": false,
|
"serviceable": false,
|
||||||
"sha512": ""
|
"sha512": ""
|
||||||
},
|
},
|
||||||
|
"Half/1.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-EPLLPQA1UjF9QM3ymNhWLhgcnBNc8e1po4qWRWTD3Hd9xiohYlkCob0QjDIbJs6Nvfd4eAbsjxIwRyh7httyXA==",
|
||||||
|
"path": "half/1.0.0",
|
||||||
|
"hashPath": "half.1.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
"Microsoft.NETCore.Platforms/1.1.0": {
|
"Microsoft.NETCore.Platforms/1.1.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public class AssetNode
|
|||||||
{
|
{
|
||||||
public String Name ~ delete _;
|
public String Name ~ delete _;
|
||||||
public String Path ~ delete _;
|
public String Path ~ delete _;
|
||||||
|
public String Identifier ~ delete _;
|
||||||
|
|
||||||
public bool IsDirectory;
|
public bool IsDirectory;
|
||||||
|
|
||||||
@@ -38,14 +39,43 @@ public static class AssetIdentifier
|
|||||||
{
|
{
|
||||||
public const char8 DirectorySeparatorChar = '/';
|
public const char8 DirectorySeparatorChar = '/';
|
||||||
|
|
||||||
|
// TODO: Asset identifiers and paths have little to do with each other and already caused a bit of pain, we should consider not using String for both.
|
||||||
|
/// Removes or unifies potential platform specific or file-path related stuff in the given asset identifier
|
||||||
public static void Fixup(String assetIdentifier)
|
public static void Fixup(String assetIdentifier)
|
||||||
{
|
{
|
||||||
const String DotSeperator = $".{DirectorySeparatorChar}";
|
int dotIndex = 0;
|
||||||
const String SeperatorDot = $"{DirectorySeparatorChar}.";
|
|
||||||
|
|
||||||
assetIdentifier.Replace('\\', DirectorySeparatorChar);
|
assetIdentifier.Replace('\\', DirectorySeparatorChar);
|
||||||
assetIdentifier.Replace(DotSeperator, "");
|
|
||||||
assetIdentifier.Replace(SeperatorDot, "");
|
// Replace /./ stuff
|
||||||
|
while ((dotIndex = assetIdentifier.IndexOf('.', dotIndex)) != -1)
|
||||||
|
{
|
||||||
|
char8 lastChar = '\0';
|
||||||
|
char8 nextChar = '\0';
|
||||||
|
|
||||||
|
int nextIndex = dotIndex + 1;
|
||||||
|
if (nextIndex < assetIdentifier.Length)
|
||||||
|
nextChar = assetIdentifier[nextIndex];
|
||||||
|
|
||||||
|
int lastIndex = dotIndex - 1;
|
||||||
|
if (lastIndex < assetIdentifier.Length)
|
||||||
|
lastChar = assetIdentifier[nextIndex];
|
||||||
|
|
||||||
|
// We either need to have a slash on both sides, or we have to be at the start or end of the string
|
||||||
|
if ((lastChar == '\0' || lastChar == DirectorySeparatorChar) &&
|
||||||
|
(lastChar == '\0' || lastChar == DirectorySeparatorChar))
|
||||||
|
{
|
||||||
|
if (lastChar != '\0')
|
||||||
|
assetIdentifier.Remove(lastIndex, 2);
|
||||||
|
else
|
||||||
|
assetIdentifier.Remove(dotIndex, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Skip the dot
|
||||||
|
dotIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (assetIdentifier.StartsWith(DirectorySeparatorChar))
|
if (assetIdentifier.StartsWith(DirectorySeparatorChar))
|
||||||
assetIdentifier.Remove(0, 1);
|
assetIdentifier.Remove(0, 1);
|
||||||
@@ -61,32 +91,124 @@ class AssetHierarchy
|
|||||||
|
|
||||||
bool _fileSystemDirty = false;
|
bool _fileSystemDirty = false;
|
||||||
|
|
||||||
internal TreeNode<AssetNode> _assetHierarchy = null ~ DeleteTreeAndChildren!(_);
|
internal TreeNode<AssetNode> _assetRootNode = null ~ DeleteTreeAndChildren!(_);
|
||||||
|
internal TreeNode<AssetNode> _resourcesDirectoryNode = null;
|
||||||
|
internal TreeNode<AssetNode> _assetsDirectoryNode = null;
|
||||||
private append Dictionary<StringView, TreeNode<AssetNode>> _pathToAssetNode = .();
|
private append Dictionary<StringView, TreeNode<AssetNode>> _pathToAssetNode = .();
|
||||||
|
private append Dictionary<StringView, TreeNode<AssetNode>> _identifierToAssetNode = .();
|
||||||
|
|
||||||
private append String _contentDirectory = .();
|
private append String _resourcesDirectory = .();
|
||||||
|
private append String _assetsDirectory = .();
|
||||||
|
|
||||||
private EditorContentManager _contentManager;
|
private EditorContentManager _contentManager;
|
||||||
|
|
||||||
public StringView ContentDirectory
|
public TreeNode<AssetNode> RootNode => _assetRootNode;
|
||||||
|
|
||||||
|
public StringView ResourcesDirectory
|
||||||
{
|
{
|
||||||
get => _contentDirectory;
|
get => _resourcesDirectory;
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
_contentDirectory.Clear();
|
_resourcesDirectory.Set(value);
|
||||||
_contentDirectory.Append(value);
|
Path.Fixup(_resourcesDirectory);
|
||||||
Path.Fixup(_contentDirectory);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringView AssetsDirectory
|
||||||
|
{
|
||||||
|
get => _assetsDirectory;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_assetsDirectory.Set(value);
|
||||||
|
Path.Fixup(_assetsDirectory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public this(EditorContentManager contentManager)
|
public this(EditorContentManager contentManager)
|
||||||
{
|
{
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
|
|
||||||
|
// Create a root node that will contain all Asset directory nodes.
|
||||||
|
_assetRootNode = new TreeNode<AssetNode>(new AssetNode());
|
||||||
|
_assetRootNode->Path = new String();
|
||||||
|
_assetRootNode->Name = new String();
|
||||||
|
_assetRootNode->IsDirectory = true;
|
||||||
|
|
||||||
|
Log.EngineLogger.Trace($"Created root node");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetContentDirectory(StringView contentDirectory)
|
public void SetResourcesDirectory(StringView fileName)
|
||||||
{
|
{
|
||||||
ContentDirectory = contentDirectory;
|
ResourcesDirectory = fileName;
|
||||||
|
|
||||||
|
_resourcesDirectoryNode?.ForEach(scope (node) => {
|
||||||
|
_pathToAssetNode.Remove(node->Path);
|
||||||
|
_identifierToAssetNode.Remove(node->Identifier);
|
||||||
|
});
|
||||||
|
_assetRootNode.RemoveChild(_resourcesDirectoryNode);
|
||||||
|
DeleteTreeAndChildren!(_resourcesDirectoryNode);
|
||||||
|
_resourcesDirectoryNode = null;
|
||||||
|
|
||||||
|
if (!Directory.Exists(ResourcesDirectory))
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"Resources directory \"{ResourcesDirectory}\" doesn't exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetNode assetNode = new AssetNode();
|
||||||
|
assetNode.Path = new String(ResourcesDirectory);
|
||||||
|
assetNode.Name = new String();
|
||||||
|
assetNode.Identifier = new String("###resources");
|
||||||
|
assetNode.IsDirectory = true;
|
||||||
|
Path.GetFileName(assetNode.Path, assetNode.Name);
|
||||||
|
|
||||||
|
_resourcesDirectoryNode = _assetRootNode.AddChild(assetNode);
|
||||||
|
_pathToAssetNode.Add(assetNode.Path, _resourcesDirectoryNode);
|
||||||
|
_identifierToAssetNode.Add(assetNode.Identifier, _resourcesDirectoryNode);
|
||||||
|
|
||||||
|
Log.EngineLogger.Trace($"Created directory node for: \"{ResourcesDirectory}\"");
|
||||||
|
|
||||||
|
_fileSystemDirty = true;
|
||||||
|
|
||||||
|
// TODO: Watch resources folder?
|
||||||
|
//SetupResourcesFileSystemWatcher();
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAssetsDirectory(StringView fileName)
|
||||||
|
{
|
||||||
|
AssetsDirectory = fileName;
|
||||||
|
|
||||||
|
_assetsDirectoryNode?.ForEach(scope (node) => {
|
||||||
|
_pathToAssetNode.Remove(node->Path);
|
||||||
|
_identifierToAssetNode.Remove(node->Identifier);
|
||||||
|
});
|
||||||
|
_assetRootNode.RemoveChild(_assetsDirectoryNode);
|
||||||
|
DeleteTreeAndChildren!(_assetsDirectoryNode);
|
||||||
|
_assetsDirectoryNode = null;
|
||||||
|
|
||||||
|
if (!Directory.Exists(AssetsDirectory))
|
||||||
|
{
|
||||||
|
// TODO: This is not an error, if no project is loaded
|
||||||
|
Log.EngineLogger.Warning($"Assets directory \"{AssetsDirectory}\" doesn't exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AssetNode assetNode = new AssetNode();
|
||||||
|
assetNode.Path = new String(AssetsDirectory);
|
||||||
|
assetNode.Name = new String();
|
||||||
|
assetNode.Identifier = new String("###assets");
|
||||||
|
assetNode.IsDirectory = true;
|
||||||
|
Path.GetFileName(assetNode.Path, assetNode.Name);
|
||||||
|
|
||||||
|
_assetsDirectoryNode = _assetRootNode.AddChild(assetNode);
|
||||||
|
_pathToAssetNode.Add(assetNode.Path, _assetsDirectoryNode);
|
||||||
|
_identifierToAssetNode.Add(assetNode.Identifier, _assetsDirectoryNode);
|
||||||
|
|
||||||
|
Log.EngineLogger.Trace($"Created directory node for: \"{AssetsDirectory}\"");
|
||||||
|
|
||||||
|
|
||||||
_fileSystemDirty = true;
|
_fileSystemDirty = true;
|
||||||
|
|
||||||
@@ -99,7 +221,7 @@ class AssetHierarchy
|
|||||||
private void SetupFileSystemWatcher()
|
private void SetupFileSystemWatcher()
|
||||||
{
|
{
|
||||||
delete fsw;
|
delete fsw;
|
||||||
fsw = new FileSystemWatcher(_contentDirectory);
|
fsw = new FileSystemWatcher(_assetsDirectory);
|
||||||
fsw.IncludeSubdirectories = true;
|
fsw.IncludeSubdirectories = true;
|
||||||
|
|
||||||
fsw.OnChanged.Add(new (filename) => {
|
fsw.OnChanged.Add(new (filename) => {
|
||||||
@@ -126,15 +248,7 @@ class AssetHierarchy
|
|||||||
fsw.OnRenamed.Add(new (oldName, newName) => {
|
fsw.OnRenamed.Add(new (oldName, newName) => {
|
||||||
Log.EngineLogger.Trace($"File renamed (From \"{oldName}\" to \"{newName}\")");
|
Log.EngineLogger.Trace($"File renamed (From \"{oldName}\" to \"{newName}\")");
|
||||||
|
|
||||||
//_fileSystemDirty = true;
|
|
||||||
FileRenamed(oldName, newName);
|
FileRenamed(oldName, newName);
|
||||||
/*String contentFilePath = scope String();
|
|
||||||
|
|
||||||
Path.InternalCombine(contentFilePath, ContentDirectory, oldName);
|
|
||||||
|
|
||||||
//_fileSystemDirty = true;
|
|
||||||
TreeNode<AssetNode> fileNode = GetNodeFromPath(contentFilePath);
|
|
||||||
fileNode->*/
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fsw.StartRaisingEvents();
|
fsw.StartRaisingEvents();
|
||||||
@@ -153,6 +267,19 @@ class AssetHierarchy
|
|||||||
return .Err;
|
return .Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the tree node for the given filePath or .Err, if the file/directory doesn't exist.
|
||||||
|
/// @param filePath the path for which to return the tree node.
|
||||||
|
/// @remarks Do not hold a reference to the TreeNode because it can become invalid when the file hierarchy changes.
|
||||||
|
public Result<TreeNode<AssetNode>> GetNodeFromIdentifier(StringView identifier)
|
||||||
|
{
|
||||||
|
if (_identifierToAssetNode.TryGetValue(identifier, let treeNode))
|
||||||
|
{
|
||||||
|
return treeNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
public bool FileExists(StringView filePath)
|
public bool FileExists(StringView filePath)
|
||||||
{
|
{
|
||||||
return _pathToAssetNode.ContainsKey(filePath);
|
return _pathToAssetNode.ContainsKey(filePath);
|
||||||
@@ -167,33 +294,36 @@ class AssetHierarchy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determines and set the Identfier for the given asset node.
|
||||||
|
private void DetermineIdentifier(TreeNode<AssetNode> assetNode)
|
||||||
|
{
|
||||||
|
if (assetNode->Identifier == null)
|
||||||
|
assetNode->Identifier = new String();
|
||||||
|
|
||||||
|
assetNode->Identifier.Clear();
|
||||||
|
|
||||||
|
// Get the Identifier which is simply the path relative to the asste root (either Resources- or Assets-Folder)
|
||||||
|
if (assetNode.IsInSubtree(_resourcesDirectoryNode))
|
||||||
|
{
|
||||||
|
Path.GetRelativePath(assetNode->Path, _resourcesDirectoryNode->Path, assetNode->Identifier);
|
||||||
|
assetNode->Identifier.Insert(0, "Resources/");
|
||||||
|
}
|
||||||
|
else if (assetNode.IsInSubtree(_assetsDirectoryNode))
|
||||||
|
{
|
||||||
|
Path.GetRelativePath(assetNode->Path, _assetsDirectoryNode->Path, assetNode->Identifier);
|
||||||
|
assetNode->Identifier.Insert(0, "Assets/");
|
||||||
|
}
|
||||||
|
AssetIdentifier.Fixup(assetNode->Identifier);
|
||||||
|
}
|
||||||
|
|
||||||
/// Rebuilds the asset file hierarchy.
|
/// Rebuilds the asset file hierarchy.
|
||||||
private void UpdateFiles()
|
private void UpdateFiles()
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Trace($"Updating asset hierarchy");
|
Log.EngineLogger.Trace($"Updating asset hierarchy");
|
||||||
|
|
||||||
if (_assetHierarchy == null)
|
|
||||||
{
|
|
||||||
// TODO: move to init?
|
|
||||||
|
|
||||||
_assetHierarchy = new TreeNode<AssetNode>(new AssetNode());
|
|
||||||
_assetHierarchy->Path = new String(ContentDirectory);
|
|
||||||
_assetHierarchy->Name = new String("Content");
|
|
||||||
_assetHierarchy->IsDirectory = true;
|
|
||||||
|
|
||||||
Log.EngineLogger.Trace($"Created directory node for: \"{_assetHierarchy->Path}\"");
|
|
||||||
|
|
||||||
_pathToAssetNode.Add(ContentDirectory, _assetHierarchy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleFile(AssetNode node)
|
void HandleFile(AssetNode node)
|
||||||
{
|
{
|
||||||
String identifier = scope .(node.Path.Length);
|
node.AssetFile = new AssetFile(_contentManager, node.Identifier, node.Path, node.IsDirectory);
|
||||||
Path.GetRelativePath(node.Path, _contentDirectory, identifier);
|
|
||||||
AssetIdentifier.Fixup(identifier);
|
|
||||||
|
|
||||||
node.AssetFile = new AssetFile(_contentManager, identifier, node.Path, node.IsDirectory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines the files that belong to the given directory and adds them to the tree.
|
/// Determines the files that belong to the given directory and adds them to the tree.
|
||||||
@@ -212,6 +342,7 @@ class AssetHierarchy
|
|||||||
entry.GetFilePath(filepathBuffer..Clear());
|
entry.GetFilePath(filepathBuffer..Clear());
|
||||||
|
|
||||||
Path.GetExtension(filepathBuffer, .. extensionBuffer..Clear());
|
Path.GetExtension(filepathBuffer, .. extensionBuffer..Clear());
|
||||||
|
filepathBuffer.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||||
|
|
||||||
// Ignore meta files.
|
// Ignore meta files.
|
||||||
if (extensionBuffer.Equals(AssetFile.ConfigFileExtension, .OrdinalIgnoreCase))
|
if (extensionBuffer.Equals(AssetFile.ConfigFileExtension, .OrdinalIgnoreCase))
|
||||||
@@ -225,13 +356,15 @@ class AssetHierarchy
|
|||||||
assetNode.Name = new String();
|
assetNode.Name = new String();
|
||||||
Path.GetFileName(filepathBuffer, assetNode.Name);
|
Path.GetFileName(filepathBuffer, assetNode.Name);
|
||||||
|
|
||||||
filepathBuffer.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
|
||||||
|
|
||||||
assetNode.Path = new String(filepathBuffer);
|
assetNode.Path = new String(filepathBuffer);
|
||||||
assetNode.IsDirectory = false;
|
assetNode.IsDirectory = false;
|
||||||
|
|
||||||
treeNode = directory.AddChild(assetNode);
|
treeNode = directory.AddChild(assetNode);
|
||||||
|
|
||||||
|
DetermineIdentifier(treeNode);
|
||||||
|
|
||||||
_pathToAssetNode.Add(assetNode.Path, treeNode);
|
_pathToAssetNode.Add(assetNode.Path, treeNode);
|
||||||
|
_identifierToAssetNode.Add(assetNode.Identifier, treeNode);
|
||||||
|
|
||||||
//GrabSubAssets(node);
|
//GrabSubAssets(node);
|
||||||
HandleFile(treeNode.Value);
|
HandleFile(treeNode.Value);
|
||||||
@@ -243,17 +376,6 @@ class AssetHierarchy
|
|||||||
|
|
||||||
void RemoveOrphanedEntries(TreeNode<AssetNode> node)
|
void RemoveOrphanedEntries(TreeNode<AssetNode> node)
|
||||||
{
|
{
|
||||||
/// Removes the node and its children from _pathToAssetNode
|
|
||||||
void RemoveSubtree(TreeNode<AssetNode> tree)
|
|
||||||
{
|
|
||||||
_pathToAssetNode.Remove(tree->Path);
|
|
||||||
|
|
||||||
for (var child in tree.Children)
|
|
||||||
{
|
|
||||||
RemoveSubtree(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TreeNode<AssetNode> child in node.Children)
|
for (TreeNode<AssetNode> child in node.Children)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(child->Path) && !File.Exists(child->Path))
|
if (!Directory.Exists(child->Path) && !File.Exists(child->Path))
|
||||||
@@ -262,7 +384,10 @@ class AssetHierarchy
|
|||||||
|
|
||||||
@child.Remove();
|
@child.Remove();
|
||||||
|
|
||||||
RemoveSubtree(child);
|
child.ForEach(scope (node) => {
|
||||||
|
_pathToAssetNode.Remove(node->Path);
|
||||||
|
_identifierToAssetNode.Remove(node->Identifier);
|
||||||
|
});
|
||||||
|
|
||||||
DeleteTreeAndChildren!(child);
|
DeleteTreeAndChildren!(child);
|
||||||
}
|
}
|
||||||
@@ -284,11 +409,30 @@ class AssetHierarchy
|
|||||||
AssetNode assetNode = new AssetNode();
|
AssetNode assetNode = new AssetNode();
|
||||||
assetNode.Path = new String(path);
|
assetNode.Path = new String(path);
|
||||||
assetNode.Name = new String();
|
assetNode.Name = new String();
|
||||||
|
//assetNode.Identifier = new String();
|
||||||
assetNode.IsDirectory = true;
|
assetNode.IsDirectory = true;
|
||||||
Path.GetFileName(assetNode.Path, assetNode.Name);
|
Path.GetFileName(assetNode.Path, assetNode.Name);
|
||||||
|
|
||||||
|
/*// Get the Identifier which is simply the path relative to the asste root (either Resources- or Assets-Folder)
|
||||||
|
if (parentNode == _resourcesDirectoryNode || parentNode.IsChildOf(_resourcesDirectoryNode))
|
||||||
|
{
|
||||||
|
Path.GetRelativePath(assetNode.Path, _resourcesDirectoryNode->Path, assetNode.Identifier);
|
||||||
|
assetNode.Identifier.Insert(0, "Resources/");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Path.GetRelativePath(assetNode.Path, _assetsDirectoryNode->Path, assetNode.Identifier);
|
||||||
|
assetNode.Identifier.Insert(0, "Assets/");
|
||||||
|
}
|
||||||
|
AssetIdentifier.Fixup(assetNode.Identifier);*/
|
||||||
|
|
||||||
treeNode = parentNode.AddChild(assetNode);
|
treeNode = parentNode.AddChild(assetNode);
|
||||||
|
|
||||||
|
DetermineIdentifier(treeNode);
|
||||||
|
|
||||||
_pathToAssetNode.Add(assetNode.Path, treeNode);
|
_pathToAssetNode.Add(assetNode.Path, treeNode);
|
||||||
|
// No Identifiers for Directories, because we can't use directories as Assets anyways...
|
||||||
|
//_identifierToAssetNode.Add(assetNode.Identifier, treeNode);
|
||||||
|
|
||||||
Log.EngineLogger.Trace($"Created directory node for: \"{assetNode.Path}\"");
|
Log.EngineLogger.Trace($"Created directory node for: \"{assetNode.Path}\"");
|
||||||
}
|
}
|
||||||
@@ -305,13 +449,46 @@ class AssetHierarchy
|
|||||||
AddDirectoryToTree(directoryNameBuffer, treeNode);
|
AddDirectoryToTree(directoryNameBuffer, treeNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddFilesOfDirectory(treeNode);
|
|
||||||
|
|
||||||
RemoveOrphanedEntries(treeNode);
|
RemoveOrphanedEntries(treeNode);
|
||||||
|
AddFilesOfDirectory(treeNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
String filter = scope $"{ContentDirectory}/*";
|
if (!AssetsDirectory.IsWhiteSpace)
|
||||||
|
{
|
||||||
|
String filter = scope $"{AssetsDirectory}/*";
|
||||||
|
|
||||||
|
String directoryNameBuffer = scope String(256);
|
||||||
|
|
||||||
|
for (var directory in Directory.Enumerate(filter, .Directories))
|
||||||
|
{
|
||||||
|
directory.GetFilePath(directoryNameBuffer..Clear());
|
||||||
|
|
||||||
|
AddDirectoryToTree(directoryNameBuffer, _assetsDirectoryNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveOrphanedEntries(_assetsDirectoryNode);
|
||||||
|
AddFilesOfDirectory(_assetsDirectoryNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ResourcesDirectory.IsWhiteSpace)
|
||||||
|
{
|
||||||
|
String filter = scope $"{ResourcesDirectory}/*";
|
||||||
|
|
||||||
|
String directoryNameBuffer = scope String(256);
|
||||||
|
|
||||||
|
for (var directory in Directory.Enumerate(filter, .Directories))
|
||||||
|
{
|
||||||
|
directory.GetFilePath(directoryNameBuffer..Clear());
|
||||||
|
|
||||||
|
AddDirectoryToTree(directoryNameBuffer, _resourcesDirectoryNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveOrphanedEntries(_resourcesDirectoryNode);
|
||||||
|
AddFilesOfDirectory(_resourcesDirectoryNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*String filter = scope $"{AssetsDirectory}/*";
|
||||||
|
/*
|
||||||
String directoryNameBuffer = scope String(256);
|
String directoryNameBuffer = scope String(256);
|
||||||
|
|
||||||
for (var directory in Directory.Enumerate(filter, .Directories))
|
for (var directory in Directory.Enumerate(filter, .Directories))
|
||||||
@@ -321,7 +498,7 @@ class AssetHierarchy
|
|||||||
AddDirectoryToTree(directoryNameBuffer, _assetHierarchy);
|
AddDirectoryToTree(directoryNameBuffer, _assetHierarchy);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveOrphanedEntries(_assetHierarchy);
|
RemoveOrphanedEntries(_assetHierarchy);*/
|
||||||
|
|
||||||
_fileSystemDirty = false;
|
_fileSystemDirty = false;
|
||||||
}
|
}
|
||||||
@@ -336,7 +513,7 @@ class AssetHierarchy
|
|||||||
fileName.RemoveFromEnd(AssetFile.ConfigFileExtension.Length);
|
fileName.RemoveFromEnd(AssetFile.ConfigFileExtension.Length);
|
||||||
|
|
||||||
String fileNameWithContentRoot = scope .();
|
String fileNameWithContentRoot = scope .();
|
||||||
Path.InternalCombine(fileNameWithContentRoot, _contentDirectory, fileName);
|
Path.InternalCombine(fileNameWithContentRoot, _assetsDirectory, fileName);
|
||||||
|
|
||||||
var nodeResult = GetNodeFromPath(fileNameWithContentRoot);
|
var nodeResult = GetNodeFromPath(fileNameWithContentRoot);
|
||||||
|
|
||||||
@@ -366,10 +543,10 @@ class AssetHierarchy
|
|||||||
|
|
||||||
|
|
||||||
String oldFileNameWithContentRoot = scope .();
|
String oldFileNameWithContentRoot = scope .();
|
||||||
Path.InternalCombine(oldFileNameWithContentRoot, _contentDirectory, oldFilePath);
|
Path.InternalCombine(oldFileNameWithContentRoot, _assetsDirectory, oldFilePath);
|
||||||
|
|
||||||
String newFileNameWithContentRoot = scope .();
|
String newFileNameWithContentRoot = scope .();
|
||||||
Path.InternalCombine(newFileNameWithContentRoot, _contentDirectory, newFilePath);
|
Path.InternalCombine(newFileNameWithContentRoot, _assetsDirectory, newFilePath);
|
||||||
|
|
||||||
// Rename config file
|
// Rename config file
|
||||||
{
|
{
|
||||||
@@ -397,10 +574,14 @@ class AssetHierarchy
|
|||||||
}
|
}
|
||||||
|
|
||||||
_pathToAssetNode.Remove(oldFileNameWithContentRoot);
|
_pathToAssetNode.Remove(oldFileNameWithContentRoot);
|
||||||
|
_identifierToAssetNode.Remove(node->Identifier);
|
||||||
|
|
||||||
node->Path.Set(newFileNameWithContentRoot);
|
node->Path.Set(newFileNameWithContentRoot);
|
||||||
_pathToAssetNode.Add(node->Path, node);
|
_pathToAssetNode.Add(node->Path, node);
|
||||||
|
|
||||||
|
DetermineIdentifier(node);
|
||||||
|
_identifierToAssetNode.Add(node->Identifier, node);
|
||||||
|
|
||||||
node->Name.Clear();
|
node->Name.Clear();
|
||||||
Path.GetFileName(newFileNameWithContentRoot, node->Name);
|
Path.GetFileName(newFileNameWithContentRoot, node->Name);
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -78,7 +78,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -120,7 +120,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit3(displayName.Ptr, *(float[3]*)&value))
|
if (ImGui.ColorEdit3(displayName.Ptr, ref *(float[3]*)&value))
|
||||||
{
|
{
|
||||||
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
@@ -132,7 +132,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit4(displayName.Ptr, *(float[4]*)&value))
|
if (ImGui.ColorEdit4(displayName.Ptr, ref *(float[4]*)&value))
|
||||||
{
|
{
|
||||||
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
@@ -149,7 +149,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit3(displayName.Ptr, *(float[3]*)&value, .HDR | .Float))
|
if (ImGui.ColorEdit3(displayName.Ptr, ref *(float[3]*)&value, .HDR | .Float))
|
||||||
{
|
{
|
||||||
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
@@ -161,7 +161,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit4(displayName.Ptr, *(float[4]*)&value, .HDR | .Float))
|
if (ImGui.ColorEdit4(displayName.Ptr, ref *(float[4]*)&value, .HDR | .Float))
|
||||||
{
|
{
|
||||||
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
|
|||||||
@@ -47,20 +47,16 @@ class AssetViewer : EditorWindow
|
|||||||
ImGui.TableSetColumnIndex(0);
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
|
||||||
if (ImGui.BeginChild("Assets"))
|
if (ImGui.BeginChild("Assets"))
|
||||||
{
|
|
||||||
DrawAssetList();
|
DrawAssetList();
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
if (ImGui.BeginChild("Files"))
|
if (ImGui.BeginChild("Files"))
|
||||||
{
|
|
||||||
DrawAssetViewer();
|
DrawAssetViewer();
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndTable();
|
ImGui.EndTable();
|
||||||
}
|
}
|
||||||
@@ -179,8 +175,8 @@ class TexturererViewerer
|
|||||||
|
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
_effect = Content.LoadAsset("Shaders\\textureViewerShader.hlsl");
|
_effect = Content.LoadAsset("Resources/Shaders/textureViewerShader.hlsl");
|
||||||
_renderTargetEffect = Content.LoadAsset("Shaders\\RenderTargetGroupViewer.hlsl");
|
_renderTargetEffect = Content.LoadAsset("Resources/Shaders/RenderTargetGroupViewer.hlsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
float2 _position;
|
float2 _position;
|
||||||
@@ -211,7 +207,7 @@ class TexturererViewerer
|
|||||||
|
|
||||||
float maxDimension = max(width, height);
|
float maxDimension = max(width, height);
|
||||||
|
|
||||||
ImGui.SliderFloat2("Position", *(float[2]*)&_position, 2 * -maxDimension * _zoom, 2 * maxDimension * _zoom);
|
ImGui.SliderFloat2("Position", ref *(float[2]*)&_position, 2 * -maxDimension * _zoom, 2 * maxDimension * _zoom);
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ using GlitchyEngine.Renderer;
|
|||||||
using GlitchyEngine;
|
using GlitchyEngine;
|
||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
using GlitchyEngine.Scripting;
|
using GlitchyEngine.Scripting;
|
||||||
|
using GlitchyEngine.Core;
|
||||||
|
using Mono;
|
||||||
|
|
||||||
namespace GlitchyEditor.EditWindows
|
namespace GlitchyEditor.EditWindows
|
||||||
{
|
{
|
||||||
@@ -110,7 +112,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (nodeOpen)
|
if (nodeOpen)
|
||||||
{
|
{
|
||||||
showComponentEditor(entity, component);
|
if (entity.TryGetComponent<TComponent>(let actualComponent))
|
||||||
|
showComponentEditor(entity, actualComponent);
|
||||||
|
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
}
|
}
|
||||||
@@ -278,7 +281,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -306,7 +309,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -338,7 +341,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -512,11 +515,89 @@ namespace GlitchyEditor.EditWindows
|
|||||||
scriptInstance.SetFieldValue<T>(scriptField, value);
|
scriptInstance.SetFieldValue<T>(scriptField, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T GetData<T>(void* instance, ScriptField scriptField)
|
||||||
|
{
|
||||||
|
T data = default;
|
||||||
|
Mono.mono_field_get_value((.)instance, scriptField.[Friend]_monoField, &data);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetData<T>(void* instance, ScriptField scriptField, T* data)
|
||||||
|
{
|
||||||
|
Mono.mono_field_get_value((.)instance, scriptField.[Friend]_monoField, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetData<T>(void* instance, ScriptField scriptField, in T value)
|
||||||
|
{
|
||||||
|
Mono.mono_field_set_value((.)instance, scriptField.[Friend]_monoField, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetData<T>(void* instance, ScriptField scriptField, T* data)
|
||||||
|
{
|
||||||
|
Mono.mono_field_set_value((.)instance, scriptField.[Friend]_monoField, data);
|
||||||
|
}
|
||||||
|
|
||||||
if (scriptComponent.Instance?.IsInitialized == true)
|
if (scriptComponent.Instance?.IsInitialized == true)
|
||||||
{
|
{
|
||||||
SharpClass sharpClass = scriptComponent.Instance.ScriptClass;
|
SharpClass sharpClass = scriptComponent.Instance.ScriptClass;
|
||||||
ScriptInstance scriptInstance = scriptComponent.Instance;
|
ScriptInstance scriptInstance = scriptComponent.Instance;
|
||||||
|
|
||||||
|
/*void DoFunnyStuff(void* instance, SharpType sharpType)
|
||||||
|
{
|
||||||
|
for (let (fieldName, scriptField) in sharpType.Fields)
|
||||||
|
{
|
||||||
|
var monoField = scriptField.[Friend]_monoField;
|
||||||
|
|
||||||
|
switch (scriptField.FieldType)
|
||||||
|
{
|
||||||
|
case .Float:
|
||||||
|
var value = GetData<float>(instance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Float, &value))
|
||||||
|
SetData(instance, scriptField, value);
|
||||||
|
|
||||||
|
case .Struct:
|
||||||
|
{
|
||||||
|
var v = Mono.mono_field_get_value_object(ScriptEngine.[Friend]s_AppDomain, scriptField.[Friend]_monoField, (.)instance);
|
||||||
|
|
||||||
|
void* dataPtr = Mono.mono_object_unbox(v);
|
||||||
|
|
||||||
|
Span<uint8> data = .((.)dataPtr, scriptField.SizeInBytes);
|
||||||
|
|
||||||
|
if (ImGui.CollapsingHeader(fieldName.Ptr))
|
||||||
|
{
|
||||||
|
DoFunnyStuff(dataPtr, scriptField.SharpType);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetData<MonoObject>(instance, scriptField, v);
|
||||||
|
|
||||||
|
//Mono.mono_field_set_value_object(ScriptEngine.[Friend]s_AppDomain, scriptField.[Friend]_monoField, (.)instance);
|
||||||
|
//uint8* data = ;
|
||||||
|
|
||||||
|
/*uint8[] data = scope .[scriptField.SizeInBytes];
|
||||||
|
|
||||||
|
GetData(instance, scriptField, data.Ptr);
|
||||||
|
|
||||||
|
if (ImGui.CollapsingHeader(fieldName.Ptr))
|
||||||
|
{
|
||||||
|
DoFunnyStuff(data.Ptr, scriptField.SharpType);
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoObject* boxed = Mono.mono_value_box(ScriptEngine.[Friend]s_AppDomain, ((SharpClass)scriptField.SharpType).[Friend]_monoClass, data.Ptr);
|
||||||
|
|
||||||
|
SetData<MonoObject>(instance, scriptField, boxed);*/
|
||||||
|
|
||||||
|
//Mono.mono_field_get_value(instance, scriptField.[Friend]_monoField, data.Ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
//Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DoFunnyStuff(scriptInstance.[Friend]_instance, sharpClass);*/
|
||||||
|
|
||||||
for (let (fieldName, scriptField) in sharpClass.Fields)
|
for (let (fieldName, scriptField) in sharpClass.Fields)
|
||||||
{
|
{
|
||||||
var monoField = scriptField.[Friend]_monoField;
|
var monoField = scriptField.[Friend]_monoField;
|
||||||
@@ -592,6 +673,22 @@ namespace GlitchyEditor.EditWindows
|
|||||||
// TODO!
|
// TODO!
|
||||||
case .Struct:
|
case .Struct:
|
||||||
// TODO!
|
// TODO!
|
||||||
|
/*{
|
||||||
|
uint8[] data = scope .[scriptField.SizeInBytes];
|
||||||
|
|
||||||
|
Mono.mono_field_get_value(scriptInstance.[Friend]_instance, scriptField.[Friend]_monoField, data.Ptr);
|
||||||
|
|
||||||
|
//scriptField.
|
||||||
|
|
||||||
|
//scriptInstance.GetFieldValue();
|
||||||
|
|
||||||
|
//scriptInstance.ScriptClass.Fields[]
|
||||||
|
/*
|
||||||
|
var value = GetFieldValue<double>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Double, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
*/
|
||||||
|
}*/
|
||||||
default:
|
default:
|
||||||
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
||||||
}
|
}
|
||||||
@@ -601,107 +698,111 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
let scriptFields = ScriptEngine.GetScriptFieldMap(entity);
|
let scriptFields = ScriptEngine.GetScriptFieldMap(entity);
|
||||||
|
|
||||||
for (var (name, field) in ref scriptFields)
|
for (var (fieldName, field) in ref scriptFields)
|
||||||
{
|
{
|
||||||
switch (field.Type)
|
switch (field.Type)
|
||||||
{
|
{
|
||||||
case .Bool:
|
case .Bool:
|
||||||
var value = field.GetData<bool>();
|
var value = field.GetData<bool>();
|
||||||
if (ImGui.Checkbox(name.CStr(), &value))
|
if (ImGui.Checkbox(fieldName.CStr(), &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .SByte:
|
case .SByte:
|
||||||
var value = field.GetData<int8>();
|
var value = field.GetData<int8>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .S8, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .S8, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Short:
|
||||||
|
var value = field.GetData<int16>();
|
||||||
|
if (ImGui.DragScalar(fieldName.CStr(), .S16, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Short:
|
|
||||||
var value = field.GetData<int16>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .S16, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Int:
|
case .Int:
|
||||||
var value = field.GetData<int32>();
|
var value = field.GetData<int32>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .S32, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .S32, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Int2:
|
case .Int2:
|
||||||
var value = field.GetData<int2>();
|
var value = field.GetData<int2>();
|
||||||
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 2))
|
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 2))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Int3:
|
case .Int3:
|
||||||
var value = field.GetData<int3>();
|
var value = field.GetData<int3>();
|
||||||
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 3))
|
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 3))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Int4:
|
case .Int4:
|
||||||
var value = field.GetData<int4>();
|
var value = field.GetData<int4>();
|
||||||
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 4))
|
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 4))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Long:
|
case .Long:
|
||||||
var value = field.GetData<int64>();
|
var value = field.GetData<int64>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .S64, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .S64, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Byte:
|
case .Byte:
|
||||||
var value = field.GetData<uint8>();
|
var value = field.GetData<uint8>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .U8, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .U8, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .UShort:
|
case .UShort:
|
||||||
var value = field.GetData<uint16>();
|
var value = field.GetData<uint16>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .U16, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .U16, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .UInt:
|
case .UInt:
|
||||||
var value = field.GetData<uint32>();
|
var value = field.GetData<uint32>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .U32, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .U32, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .ULong:
|
case .ULong:
|
||||||
var value = field.GetData<uint64>();
|
var value = field.GetData<uint64>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .U64, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .U64, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Float:
|
case .Float:
|
||||||
var value = field.GetData<float>();
|
var value = field.GetData<float>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .Float, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .Float, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .float2:
|
case .float2:
|
||||||
var value = field.GetData<float2>();
|
var value = field.GetData<float2>();
|
||||||
if (ImGui.Editfloat2(name, ref value))
|
if (ImGui.Editfloat2(fieldName, ref value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .float3:
|
case .float3:
|
||||||
var value = field.GetData<float3>();
|
var value = field.GetData<float3>();
|
||||||
if (ImGui.Editfloat3(name, ref value))
|
if (ImGui.Editfloat3(fieldName, ref value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .float4:
|
case .float4:
|
||||||
var value = field.GetData<float4>();
|
var value = field.GetData<float4>();
|
||||||
if (ImGui.Editfloat4(name, ref value))
|
if (ImGui.Editfloat4(fieldName, ref value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Double:
|
case .Double:
|
||||||
var value = field.GetData<double>();
|
var value = field.GetData<double>();
|
||||||
if (ImGui.DragScalar(name.CStr(), .Double, &value))
|
if (ImGui.DragScalar(fieldName.CStr(), .Double, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Double2:
|
case .Double2:
|
||||||
var value = field.GetData<double2>();
|
var value = field.GetData<double2>();
|
||||||
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 2))
|
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 2))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Double3:
|
case .Double3:
|
||||||
var value = field.GetData<double3>();
|
var value = field.GetData<double3>();
|
||||||
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 3))
|
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 3))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Double4:
|
case .Double4:
|
||||||
var value = field.GetData<double4>();
|
var value = field.GetData<double4>();
|
||||||
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 4))
|
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 4))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Enum:
|
case .Enum:
|
||||||
// TODO!
|
ShowEnumSelector(field, fieldName, scriptClass);
|
||||||
|
|
||||||
//case .String:
|
//case .String:
|
||||||
// TODO!
|
// TODO!
|
||||||
|
|
||||||
case .Entity:
|
case .Entity:
|
||||||
// TODO!
|
ShowEntityReceiver(field, fieldName, scriptClass);
|
||||||
|
case .Component:
|
||||||
|
ShowComponentReceiver(field, fieldName, scriptClass);
|
||||||
|
|
||||||
case .Struct:
|
case .Struct:
|
||||||
// TODO!
|
// TODO!
|
||||||
|
|
||||||
|
case .Class:
|
||||||
|
// We don't support editing classes
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.EngineLogger.Error($"Unhandled field type {field.Type}");
|
Log.EngineLogger.Error($"Unhandled field type {field.Type}");
|
||||||
}
|
}
|
||||||
@@ -709,6 +810,201 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ShowEnumSelector(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
||||||
|
{
|
||||||
|
ScriptField scriptField = scriptClass.Fields[fieldName];
|
||||||
|
SharpEnum enumType = scriptField.SharpType as SharpEnum;
|
||||||
|
|
||||||
|
Log.EngineLogger.Assert(enumType != null, "Enum must have a SharpEnum!");
|
||||||
|
|
||||||
|
// Simply get Enum as a uint64
|
||||||
|
var fieldValue = field.GetData<uint64>();
|
||||||
|
|
||||||
|
StringView valueName = "<Invalid Value>";
|
||||||
|
|
||||||
|
if (enumType.Values.TryGetValue(fieldValue, let enumValue))
|
||||||
|
valueName = enumValue.Name;
|
||||||
|
|
||||||
|
if (ImGui.BeginCombo(fieldName.Ptr, valueName.Ptr))
|
||||||
|
{
|
||||||
|
for (let (entryValue, enumEntry) in enumType.Values)
|
||||||
|
{
|
||||||
|
if (ImGui.Selectable(enumEntry.Name.Ptr, fieldValue == entryValue))
|
||||||
|
field.SetData(entryValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Entity? ShowEntitySelector()
|
||||||
|
{
|
||||||
|
static char8[128] entitySearch = .();
|
||||||
|
|
||||||
|
Entity? result = null;
|
||||||
|
|
||||||
|
if (ImGui.BeginPopup("ENTITY_SELECTOR"))
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Search:");
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.InputText("##entitySearcher", &entitySearch, (uint64)entitySearch.Count))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ShowEntityReceiver(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
||||||
|
{
|
||||||
|
var entityId = field.GetData<UUID>();
|
||||||
|
|
||||||
|
Result<Entity> fieldEntity = Editor.Instance.CurrentScene.GetEntityByID(entityId);
|
||||||
|
|
||||||
|
String entityName = scope .(32);
|
||||||
|
|
||||||
|
if (entityId == UUID(0))
|
||||||
|
entityName.Set("None");
|
||||||
|
else if (fieldEntity case .Ok(Entity e))
|
||||||
|
entityName.Set(e.Name);
|
||||||
|
else
|
||||||
|
entityName..Clear().AppendF($"Missing entity ({entityId})");
|
||||||
|
|
||||||
|
ImGui.Text($"{fieldName}: ");
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.Button(entityName))
|
||||||
|
{
|
||||||
|
if (fieldEntity case .Ok)
|
||||||
|
Editor.Instance.EntityHierarchyWindow.HighlightEntity(fieldEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginDragDropTarget())
|
||||||
|
{
|
||||||
|
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.Entity, .AcceptPeekOnly);
|
||||||
|
|
||||||
|
bool allowDrop = false;
|
||||||
|
|
||||||
|
if (peekPayload != null)
|
||||||
|
{
|
||||||
|
Entity draggedEntity = *(Entity*)peekPayload.Data;
|
||||||
|
|
||||||
|
ScriptClass draggedScriptClass = ScriptEngine.[Friend]s_EntityRoot;
|
||||||
|
|
||||||
|
if (draggedEntity.TryGetComponent<ScriptComponent>(let draggedScript))
|
||||||
|
{
|
||||||
|
var draggedClassName = draggedScript.ScriptClassName;
|
||||||
|
draggedScriptClass = ScriptEngine.GetScriptClass(draggedClassName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: I don't like the fact, that we are using mono directly
|
||||||
|
|
||||||
|
ScriptField scriptField = scriptClass.Fields[fieldName];
|
||||||
|
var fieldMonoClass = Mono.mono_type_get_class(scriptField.GetMonoType());
|
||||||
|
|
||||||
|
allowDrop = draggedScriptClass.[Friend]IsSubclass(fieldMonoClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowDrop)
|
||||||
|
{
|
||||||
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
||||||
|
|
||||||
|
if (payload != null)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(payload.DataSize == sizeof(Entity));
|
||||||
|
|
||||||
|
Entity droppedEntity = *(Entity*)payload.Data;
|
||||||
|
|
||||||
|
if (droppedEntity.IsValid)
|
||||||
|
field.SetData<UUID>(droppedEntity.UUID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndDragDropTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private static Entity?
|
||||||
|
|
||||||
|
private static void ShowComponentReceiver(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
||||||
|
{
|
||||||
|
var entityId = field.GetData<UUID>();
|
||||||
|
|
||||||
|
Result<Entity> fieldEntity = Editor.Instance.CurrentScene.GetEntityByID(entityId);
|
||||||
|
|
||||||
|
String entityName = scope .(32);
|
||||||
|
|
||||||
|
if (entityId == UUID(0))
|
||||||
|
entityName.Set("None");
|
||||||
|
else if (fieldEntity case .Ok(Entity e))
|
||||||
|
entityName.Set(e.Name);
|
||||||
|
else
|
||||||
|
entityName..Clear().AppendF($"Missing reference ({entityId})");
|
||||||
|
|
||||||
|
ImGui.Text($"{fieldName}: ");
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.Button(entityName))
|
||||||
|
{
|
||||||
|
if (fieldEntity case .Ok)
|
||||||
|
Editor.Instance.EntityHierarchyWindow.HighlightEntity(fieldEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginDragDropTarget())
|
||||||
|
{
|
||||||
|
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.Entity, .AcceptPeekOnly);
|
||||||
|
|
||||||
|
bool allowDrop = false;
|
||||||
|
|
||||||
|
if (peekPayload != null)
|
||||||
|
{
|
||||||
|
Entity draggedEntity = *(Entity*)peekPayload.Data;
|
||||||
|
|
||||||
|
// TODO: I don't like the fact, that we are using mono directly
|
||||||
|
|
||||||
|
ScriptField scriptField = scriptClass.Fields[fieldName];
|
||||||
|
|
||||||
|
// For some reason we have to retrieve the MonoType like this. Using scriptField.GetMonoType() directly returns the wrong type...
|
||||||
|
MonoReflectionType* reflectionType = Mono.mono_type_get_object(ScriptEngine.[Friend]s_AppDomain, scriptField.GetMonoType());
|
||||||
|
MonoType* actualMonoType = Mono.mono_reflection_type_get_type(reflectionType);
|
||||||
|
|
||||||
|
// TODO: We shouldn't abuse the script glue like that.
|
||||||
|
// ScriptGlue should only be called by C#, not by Beef.
|
||||||
|
if (ScriptGlue.[Friend]s_HasComponentMethods.TryGetValue(actualMonoType, let has_component))
|
||||||
|
{
|
||||||
|
allowDrop = has_component(draggedEntity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Warning($"No HasComponent-Function found for field {scriptField.Name}");
|
||||||
|
allowDrop = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowDrop)
|
||||||
|
{
|
||||||
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
||||||
|
|
||||||
|
if (payload != null)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(payload.DataSize == sizeof(Entity));
|
||||||
|
|
||||||
|
Entity droppedEntity = *(Entity*)payload.Data;
|
||||||
|
|
||||||
|
if (droppedEntity.IsValid)
|
||||||
|
field.SetData<UUID>(droppedEntity.UUID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndDragDropTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void LabelColumn(StringView label)
|
private static void LabelColumn(StringView label)
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted(label);
|
ImGui.TextUnformatted(label);
|
||||||
@@ -773,7 +1069,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using ImGui;
|
using ImGui;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using GlitchyEngine.Collections;
|
using GlitchyEngine.Collections;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using GlitchyEngine.Renderer;
|
using GlitchyEngine.Renderer;
|
||||||
@@ -12,8 +13,35 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
using internal GlitchyEditor.EditorContentManager;
|
using internal GlitchyEditor.EditorContentManager;
|
||||||
|
|
||||||
|
class AssetCreator
|
||||||
|
{
|
||||||
|
private String _name ~ delete _;
|
||||||
|
private String _defaultFileName ~ delete _;
|
||||||
|
private CreateAssetFunc _doCreateAsset ~ delete _;
|
||||||
|
|
||||||
|
public delegate void CreateAssetFunc(StringView outputPath);
|
||||||
|
|
||||||
|
public StringView Name => _name;
|
||||||
|
public StringView DefaultFileName => _defaultFileName;
|
||||||
|
|
||||||
|
public CreateAssetFunc CreateAsset => _doCreateAsset;
|
||||||
|
|
||||||
|
public this(StringView name, StringView defaultFileName, CreateAssetFunc createAsset)
|
||||||
|
{
|
||||||
|
_name = new String(name);
|
||||||
|
_defaultFileName = new String(defaultFileName);
|
||||||
|
_doCreateAsset = createAsset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ContentBrowserWindow : EditorWindow
|
class ContentBrowserWindow : EditorWindow
|
||||||
{
|
{
|
||||||
|
private append List<AssetCreator> _assetCreators = .() ~ ClearAndDeleteItems!(_);
|
||||||
|
|
||||||
|
private typealias AssetCreatorTree = TreeNode<(StringView Name, AssetCreator Creator)>;
|
||||||
|
|
||||||
|
private AssetCreatorTree _creatorTree = new AssetCreatorTree(("Create new Asset", null)) ~ delete _;
|
||||||
|
|
||||||
public const String s_WindowTitle = "Content Browser";
|
public const String s_WindowTitle = "Content Browser";
|
||||||
|
|
||||||
private append String _currentDirectory = .();
|
private append String _currentDirectory = .();
|
||||||
@@ -32,6 +60,28 @@ namespace GlitchyEditor.EditWindows
|
|||||||
_manager = contentManager;
|
_manager = contentManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterAssetCreator(AssetCreator assetCreator)
|
||||||
|
{
|
||||||
|
_assetCreators.Add(assetCreator);
|
||||||
|
|
||||||
|
AssetCreatorTree tree = _creatorTree;
|
||||||
|
|
||||||
|
for (StringView entryName in assetCreator.Name.Split('/'))
|
||||||
|
{
|
||||||
|
AssetCreatorTree nextNode = tree.Children.Where(scope (node) => node->Name == entryName).FirstOrDefault();
|
||||||
|
|
||||||
|
// Create new node if we didn't find it
|
||||||
|
nextNode ??= tree.AddChild((entryName, null));
|
||||||
|
|
||||||
|
tree = nextNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tree->Creator == null)
|
||||||
|
{
|
||||||
|
tree->Creator = assetCreator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void InternalShow()
|
protected override void InternalShow()
|
||||||
{
|
{
|
||||||
_manager.Update();
|
_manager.Update();
|
||||||
@@ -39,7 +89,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
// Make sure we are in an existing directory.
|
// Make sure we are in an existing directory.
|
||||||
if (!_manager.AssetHierarchy.FileExists(_currentDirectory))
|
if (!_manager.AssetHierarchy.FileExists(_currentDirectory))
|
||||||
{
|
{
|
||||||
_currentDirectory.Set(_manager.ContentDirectory);
|
_currentDirectory.Set(_manager.AssetDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ImGui.Begin(s_WindowTitle, &_open, .None))
|
if(!ImGui.Begin(s_WindowTitle, &_open, .None))
|
||||||
@@ -120,12 +170,69 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if (Path.OpenFolder(_currentDirectory) case .Err)
|
if (Path.OpenFolder(_currentDirectory) case .Err)
|
||||||
Log.EngineLogger.Error("Failed to open directory in file browser.");
|
Log.EngineLogger.Error("Failed to open directory in file browser.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
ShowCreateContextMenu(_creatorTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shows the menu for the given asset creator tree.
|
||||||
|
private void ShowCreateContextMenu(AssetCreatorTree subtree)
|
||||||
|
{
|
||||||
|
if (subtree.Children.Count == 0)
|
||||||
|
{
|
||||||
|
if (ImGui.MenuItem(subtree->Name.ToScopeCStr!()))
|
||||||
|
{
|
||||||
|
CreateAsset(subtree->Creator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ImGui.BeginMenu(subtree->Name.ToScopeCStr!()))
|
||||||
|
{
|
||||||
|
for (let node in subtree.Children)
|
||||||
|
{
|
||||||
|
ShowCreateContextMenu(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new asset with the given creator
|
||||||
|
private void CreateAsset(AssetCreator creator)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(_currentDirectory))
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"Directory {_currentDirectory} doesn't exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String currentFile = scope String();
|
||||||
|
Path.Combine(currentFile, _currentDirectory, creator.DefaultFileName);
|
||||||
|
|
||||||
|
String fileExtension = scope String();
|
||||||
|
Path.GetExtension(currentFile, fileExtension);
|
||||||
|
|
||||||
|
StringView fileWithoutExtension = currentFile[0...^(fileExtension.Length + 1)];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (File.Exists(currentFile))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
currentFile.Set(fileWithoutExtension);
|
||||||
|
currentFile.AppendF($"({i})");
|
||||||
|
currentFile.Append(fileExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
creator.CreateAsset(currentFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders a sidebar that shows a tree of all directories in the asset folder.
|
/// Renders a sidebar that shows a tree of all directories in the asset folder.
|
||||||
private void DrawDirectorySideBar()
|
private void DrawDirectorySideBar()
|
||||||
{
|
{
|
||||||
for(var child in _manager.AssetHierarchy.[Friend]_assetHierarchy.Children)
|
for(var child in _manager.AssetHierarchy.RootNode.Children)
|
||||||
{
|
{
|
||||||
ImGuiPrintEntityTree(child);
|
ImGuiPrintEntityTree(child);
|
||||||
}
|
}
|
||||||
@@ -142,17 +249,22 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
ImGui.TreeNodeFlags flags = .OpenOnArrow | .SpanAvailWidth;
|
ImGui.TreeNodeFlags flags = .OpenOnArrow | .SpanAvailWidth;
|
||||||
|
|
||||||
if(tree.Children.Count == 0)
|
if(tree.Children.Where(scope (node) => node->IsDirectory).Count() == 0)
|
||||||
flags |= .Leaf;
|
flags |= .Leaf;
|
||||||
|
|
||||||
if (tree->Path == _currentDirectory)
|
if (tree->Path == _currentDirectory)
|
||||||
{
|
|
||||||
flags |= .Selected;
|
flags |= .Selected;
|
||||||
}
|
|
||||||
|
// TODO: this kinda works, but the user should be able to close the directory
|
||||||
|
/*if (_manager.AssetHierarchy.GetNodeFromPath(_currentDirectory) case .Ok(let currentTreeNode))
|
||||||
|
{
|
||||||
|
if (currentTreeNode.IsInSubtree(tree))
|
||||||
|
ImGui.SetNextItemOpen(true);
|
||||||
|
}*/
|
||||||
|
|
||||||
bool isOpen = ImGui.TreeNodeEx(name, flags, $"{name}");
|
bool isOpen = ImGui.TreeNodeEx(name, flags, $"{name}");
|
||||||
|
|
||||||
if (ImGui.IsItemClicked(.Left))
|
if (!ImGui.IsItemToggledOpen() && ImGui.IsItemClicked(.Left))
|
||||||
{
|
{
|
||||||
_currentDirectory.Set(tree->Path);
|
_currentDirectory.Set(tree->Path);
|
||||||
}
|
}
|
||||||
@@ -186,7 +298,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if (_searchEverywhere && searchFilter.Length > 0)
|
if (_searchEverywhere && searchFilter.Length > 0)
|
||||||
{
|
{
|
||||||
files = scope:: List<TreeNode<AssetNode>>();
|
files = scope:: List<TreeNode<AssetNode>>();
|
||||||
_manager.AssetHierarchy.[Friend]_assetHierarchy.ForEach(scope (node) =>
|
_manager.AssetHierarchy.[Friend]_assetRootNode.ForEach(scope (node) =>
|
||||||
{
|
{
|
||||||
if (node->Name.Contains(searchFilter, true))
|
if (node->Name.Contains(searchFilter, true))
|
||||||
{
|
{
|
||||||
@@ -253,10 +365,23 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float _zoom = 1.0f;
|
||||||
|
static readonly float2 IconBaseSize = .(100, 100);
|
||||||
|
|
||||||
|
float2 IconSize => IconBaseSize * _zoom;
|
||||||
|
|
||||||
/// Renders the button for the given directory item.
|
/// Renders the button for the given directory item.
|
||||||
private void DrawBackButton(TreeNode<AssetNode> entry)
|
private void DrawBackButton(TreeNode<AssetNode> entry)
|
||||||
{
|
{
|
||||||
ImGui.BeginChild("item", (.)DirectoryItemSize);
|
ImGui.PushStyleVar(.WindowPadding, .(0, 0));
|
||||||
|
ImGui.PushStyleVar(.FramePadding, .(0, 0));
|
||||||
|
ImGui.PushStyleVar(.ItemSpacing, .(0, 0));
|
||||||
|
|
||||||
|
defer {ImGui.PopStyleVar(3); }
|
||||||
|
|
||||||
|
float2 DirectoryItemSize = IconSize + (float2)ImGui.GetStyle().WindowPadding * 2 + float2(0, ImGui.GetFontSize());
|
||||||
|
|
||||||
|
ImGui.BeginChild("item", (.)DirectoryItemSize, false, .NoScrollbar);
|
||||||
|
|
||||||
if (entry->Path == _selectedFile)
|
if (entry->Path == _selectedFile)
|
||||||
{
|
{
|
||||||
@@ -270,7 +395,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
SubTexture2D image = s_FolderTexture;
|
SubTexture2D image = s_FolderTexture;
|
||||||
|
|
||||||
ImGui.ImageButton(image, (.)(DirectoryItemSize - padding));
|
ImGui.ImageButton("BackFolder", image, (.)IconSize);
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
@@ -295,7 +420,15 @@ namespace GlitchyEditor.EditWindows
|
|||||||
/// Renders the button for the given directory item.
|
/// Renders the button for the given directory item.
|
||||||
private void DrawDirectoryItem(TreeNode<AssetNode> entry)
|
private void DrawDirectoryItem(TreeNode<AssetNode> entry)
|
||||||
{
|
{
|
||||||
ImGui.BeginChild("item", (.)DirectoryItemSize);
|
ImGui.PushStyleVar(.WindowPadding, .(0, 0));
|
||||||
|
ImGui.PushStyleVar(.FramePadding, .(0, 0));
|
||||||
|
ImGui.PushStyleVar(.ItemSpacing, .(0, 0));
|
||||||
|
|
||||||
|
defer {ImGui.PopStyleVar(3); }
|
||||||
|
|
||||||
|
float2 DirectoryItemSize = IconSize + (float2)ImGui.GetStyle().WindowPadding * 2 + float2(0, ImGui.GetFontSize());
|
||||||
|
|
||||||
|
ImGui.BeginChild("item", (.)DirectoryItemSize, false, .NoScrollbar);
|
||||||
|
|
||||||
if (entry->Path == _selectedFile)
|
if (entry->Path == _selectedFile)
|
||||||
{
|
{
|
||||||
@@ -310,21 +443,13 @@ namespace GlitchyEditor.EditWindows
|
|||||||
// TODO: preview images
|
// TODO: preview images
|
||||||
SubTexture2D image = entry->IsDirectory ? s_FolderTexture : s_FileTexture;
|
SubTexture2D image = entry->IsDirectory ? s_FolderTexture : s_FileTexture;
|
||||||
|
|
||||||
ImGui.ImageButton(image, (.)(DirectoryItemSize - padding));
|
ImGui.ImageButton("FileImage", image, (.)IconSize);
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
if (ImGui.BeginDragDropSource())
|
if (ImGui.BeginDragDropSource())
|
||||||
{
|
{
|
||||||
String fullpath = scope String(entry->Path);
|
ImGui.SetDragDropPayload(.ContentBrowserItem, entry->Identifier, (uint64)entry->Identifier.Length, .Once);
|
||||||
|
|
||||||
// TODO: this is dirty
|
|
||||||
if (fullpath.StartsWith(_manager.ContentDirectory, .OrdinalIgnoreCase))
|
|
||||||
fullpath.Remove(0, _manager.ContentDirectory.Length);
|
|
||||||
|
|
||||||
Path.Fixup(fullpath);
|
|
||||||
|
|
||||||
ImGui.SetDragDropPayload("CONTENT_BROWSER_ITEM", fullpath.CStr(), (.)fullpath.Length, .Once);
|
|
||||||
|
|
||||||
ImGui.EndDragDropSource();
|
ImGui.EndDragDropSource();
|
||||||
}
|
}
|
||||||
@@ -350,6 +475,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.EndPopup();
|
ImGui.EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Sub assets are probably borked now... I don't know if they ever worked, didn't test them
|
||||||
if (entry->SubAssets?.Count > 0)
|
if (entry->SubAssets?.Count > 0)
|
||||||
{
|
{
|
||||||
// Button for revealing sub assets (e.g. Meshes in 3D-Model)
|
// Button for revealing sub assets (e.g. Meshes in 3D-Model)
|
||||||
@@ -370,7 +496,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
String fullpath = scope String(entry->Path);
|
String fullpath = scope String(entry->Path);
|
||||||
fullpath.AppendF($"#{subAsset.Name}");
|
fullpath.AppendF($"#{subAsset.Name}");
|
||||||
|
|
||||||
ImGui.SetDragDropPayload("CONTENT_BROWSER_ITEM", fullpath.CStr(), (.)fullpath.Length, .Once);
|
ImGui.SetDragDropPayload(.ContentBrowserItem, fullpath.CStr(), (.)fullpath.Length, .Once);
|
||||||
|
|
||||||
ImGui.EndDragDropSource();
|
ImGui.EndDragDropSource();
|
||||||
}
|
}
|
||||||
@@ -382,6 +508,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
DeleteItemPopup(entry);
|
DeleteItemPopup(entry);
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
|
|
||||||
|
ImGui.AttachTooltip(entry->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteItemPopup(TreeNode<AssetNode> fileOrFolder)
|
private void DeleteItemPopup(TreeNode<AssetNode> fileOrFolder)
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,8 +21,26 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
private List<Entity> _selectedEntities = new .() ~ delete _;
|
private List<Entity> _selectedEntities = new .() ~ delete _;
|
||||||
|
|
||||||
|
private Entity _entityToHighlight;
|
||||||
|
|
||||||
public List<Entity> SelectedEntities => _selectedEntities;
|
public List<Entity> SelectedEntities => _selectedEntities;
|
||||||
|
|
||||||
|
private List<Entity> _entitiesToUnfold = new .() ~ delete _;
|
||||||
|
|
||||||
|
public void HighlightEntity(Entity e)
|
||||||
|
{
|
||||||
|
_entityToHighlight = e;
|
||||||
|
|
||||||
|
Entity walker = _entityToHighlight;
|
||||||
|
|
||||||
|
while (walker.Parent != null)
|
||||||
|
{
|
||||||
|
walker = walker.Parent.Value;
|
||||||
|
|
||||||
|
_entitiesToUnfold.Add(walker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public this(Editor editor, Scene scene)
|
public this(Editor editor, Scene scene)
|
||||||
{
|
{
|
||||||
_editor = editor;
|
_editor = editor;
|
||||||
@@ -322,8 +340,21 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if(inSelectedList)
|
if(inSelectedList)
|
||||||
flags |= .Selected;
|
flags |= .Selected;
|
||||||
|
|
||||||
|
if (_entitiesToUnfold.Contains(tree.Value))
|
||||||
|
{
|
||||||
|
_entitiesToUnfold.Remove(tree.Value);
|
||||||
|
|
||||||
|
ImGui.SetNextItemOpen(true, .None);
|
||||||
|
}
|
||||||
|
|
||||||
bool isOpen = ImGui.TreeNodeEx((void*)(uint)tree.Value.Handle.[Friend]Index, flags, $"{name}");
|
bool isOpen = ImGui.TreeNodeEx((void*)(uint)tree.Value.Handle.[Friend]Index, flags, $"{name}");
|
||||||
|
|
||||||
|
if (_entityToHighlight == tree.Value)
|
||||||
|
{
|
||||||
|
ImGui.SetScrollHereY(0);
|
||||||
|
_entityToHighlight = .();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.PushID((void*)(uint)tree.Value.Handle.[Friend]Index);
|
ImGui.PushID((void*)(uint)tree.Value.Handle.[Friend]Index);
|
||||||
|
|
||||||
bool deleted = false;
|
bool deleted = false;
|
||||||
@@ -341,9 +372,13 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if (deleted)
|
if (deleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool isDragged = false;
|
||||||
|
|
||||||
if(ImGui.BeginDragDropSource())
|
if(ImGui.BeginDragDropSource())
|
||||||
{
|
{
|
||||||
ImGui.SetDragDropPayload("DND_Entity", &tree.Value, sizeof(Entity));
|
isDragged = true;
|
||||||
|
|
||||||
|
ImGui.SetDragDropPayload(.Entity, &tree.Value, sizeof(Entity));
|
||||||
|
|
||||||
ImGui.Text(name);
|
ImGui.Text(name);
|
||||||
|
|
||||||
@@ -352,7 +387,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if(ImGui.BeginDragDropTarget())
|
if(ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("DND_Entity");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
||||||
|
|
||||||
if(payload != null)
|
if(payload != null)
|
||||||
{
|
{
|
||||||
@@ -407,6 +442,12 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clicked || clickedRight)
|
if (clicked || clickedRight)
|
||||||
|
{
|
||||||
|
lastClickedEntity = tree.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (!isDragged && (clicked || clickedRight))
|
||||||
|
if (!isDragged && (!ImGui.IsMouseDown(.Left) && !ImGui.IsMouseDown(.Right) && ImGui.IsItemHovered()) && tree.Value == lastClickedEntity)
|
||||||
{
|
{
|
||||||
if (inSelectedList && !clickedRight)
|
if (inSelectedList && !clickedRight)
|
||||||
{
|
{
|
||||||
@@ -418,13 +459,23 @@ namespace GlitchyEditor.EditWindows
|
|||||||
SelectEntity(tree.Value, !ImGui.GetIO().KeyCtrl && !clickedRight);
|
SelectEntity(tree.Value, !ImGui.GetIO().KeyCtrl && !clickedRight);
|
||||||
inSelectedList = true;
|
inSelectedList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastClickedEntity = .();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Entity lastClickedEntity;
|
||||||
|
|
||||||
private void ShowEntityHierarchy()
|
private void ShowEntityHierarchy()
|
||||||
{
|
{
|
||||||
StringView searchString = StringView(&_entitySearchChars);
|
StringView searchString = StringView(&_entitySearchChars);
|
||||||
|
|
||||||
|
if (_scene == null)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("<No scene open>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(searchString.IsWhiteSpace)
|
if(searchString.IsWhiteSpace)
|
||||||
{
|
{
|
||||||
// Show entity hierarchy as tree
|
// Show entity hierarchy as tree
|
||||||
@@ -464,7 +515,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if(ImGui.BeginDragDropTarget())
|
if(ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("DND_Entity");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
||||||
|
|
||||||
if(payload != null)
|
if(payload != null)
|
||||||
{
|
{
|
||||||
@@ -527,6 +578,10 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGuiPrintEntityTree(scope .(entity));
|
ImGuiPrintEntityTree(scope .(entity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the mouse was released and no entity took the chance to become selected we probably hovered the background while releasing -> select no entity
|
||||||
|
if (!ImGui.IsMouseDown(.Left) && !ImGui.IsMouseDown(.Right))
|
||||||
|
lastClickedEntity = .();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,375 @@
|
|||||||
|
using System;
|
||||||
|
using ImGui;
|
||||||
|
using System.Collections;
|
||||||
|
using GlitchyEngine.Core;
|
||||||
|
using GlitchyEngine.World;
|
||||||
|
using GlitchLog;
|
||||||
|
using GlitchyEngine.Scripting;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
|
||||||
|
namespace GlitchyEditor.EditWindows;
|
||||||
|
|
||||||
|
enum MessageType
|
||||||
|
{
|
||||||
|
case None = 0;
|
||||||
|
case Trace = 1;
|
||||||
|
case Info = 2;
|
||||||
|
case Warning = 4;
|
||||||
|
case Error = 8;
|
||||||
|
|
||||||
|
public this(LogLevel level)
|
||||||
|
{
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case .Error:
|
||||||
|
this = Error;
|
||||||
|
case .Warning:
|
||||||
|
this = Warning;
|
||||||
|
case .Info:
|
||||||
|
this = Info;
|
||||||
|
case .Trace:
|
||||||
|
this = Trace;
|
||||||
|
default:
|
||||||
|
this = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageSource
|
||||||
|
{
|
||||||
|
public UUID? Entity = null;
|
||||||
|
public StringView? ScriptName = null;
|
||||||
|
public int? Line = null;
|
||||||
|
|
||||||
|
/// If true, the message is only meant for engine developers... so only me :(
|
||||||
|
public bool IsEngineMessage = false;
|
||||||
|
|
||||||
|
public MonoExceptionHelper Exception = null ~ _?.ReleaseRef();
|
||||||
|
|
||||||
|
public String AdditionalData = null ~ delete _;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogMessage
|
||||||
|
{
|
||||||
|
private String _message ~ delete _;
|
||||||
|
|
||||||
|
public MessageType MessageType { get; private set; }
|
||||||
|
|
||||||
|
public DateTime Timestamp { get; private set; }
|
||||||
|
|
||||||
|
public MessageSource Source { get; private set; } ~ delete _;
|
||||||
|
|
||||||
|
public StringView Message => _message;
|
||||||
|
|
||||||
|
public this(DateTime timestamp, StringView message, MessageType logLevel, MessageSource ownSource)
|
||||||
|
{
|
||||||
|
Timestamp = timestamp;
|
||||||
|
_message = new String(message);
|
||||||
|
MessageType = logLevel;
|
||||||
|
Source = ownSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogWindow : EditorWindow
|
||||||
|
{
|
||||||
|
public const String s_WindowTitle = "Log";
|
||||||
|
|
||||||
|
private append List<LogMessage> _messages = .() ~ ClearAndDeleteItems!(_);
|
||||||
|
|
||||||
|
public static SubTexture2D s_ErrorIcon;
|
||||||
|
public static SubTexture2D s_WarningIcon;
|
||||||
|
public static SubTexture2D s_InfoIcon;
|
||||||
|
public static SubTexture2D s_TraceIcon;
|
||||||
|
|
||||||
|
private bool _showGameMessages = true;
|
||||||
|
private bool _showEngineMessages = false;
|
||||||
|
private bool _autoScroll = true;
|
||||||
|
private bool _collapseMessages = true;
|
||||||
|
|
||||||
|
private MessageType _visibleMessageTypes = .Error | .Warning | .Info | .Trace;
|
||||||
|
|
||||||
|
protected override void InternalShow()
|
||||||
|
{
|
||||||
|
defer { ImGui.End(); }
|
||||||
|
if(!ImGui.Begin(s_WindowTitle, &_open, .MenuBar))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ShowMenuBar();
|
||||||
|
|
||||||
|
ShowMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowMenuBar()
|
||||||
|
{
|
||||||
|
if(ImGui.BeginMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui.MenuItem("Clear"))
|
||||||
|
{
|
||||||
|
ClearLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginMenu("Filter"))
|
||||||
|
{
|
||||||
|
ImGui.Checkbox("Show game messages", &_showGameMessages);
|
||||||
|
ImGui.AttachTooltip("If checked, the log will show messages generated by the game (e.g. scripts).");
|
||||||
|
|
||||||
|
ImGui.Checkbox("Show engine messages", &_showEngineMessages);
|
||||||
|
ImGui.AttachTooltip("""
|
||||||
|
If checked, the log will show messages generated by the engine.
|
||||||
|
These messages are usually only necessary for engine debugging/development and don't provide practical information for game developers.
|
||||||
|
""");
|
||||||
|
|
||||||
|
ImGui.EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Checkbox("Collapse", &_collapseMessages);
|
||||||
|
ImGui.AttachTooltip("If checked, identical messages will be collapsed into one.");
|
||||||
|
|
||||||
|
var maxSpace = ImGui.GetFontSize();
|
||||||
|
|
||||||
|
ImGui.Vec2 buttonSize = .(maxSpace, maxSpace);
|
||||||
|
|
||||||
|
var col = ImGui.GetStyleColorVec4(.Button);
|
||||||
|
ImGui.PushStyleVar(.FramePadding, ImGui.Vec2(2, 2));
|
||||||
|
|
||||||
|
if (_visibleMessageTypes.HasFlag(.Trace))
|
||||||
|
ImGui.PushStyleColor(.Button, *col);
|
||||||
|
else
|
||||||
|
ImGui.PushStyleColor(.Button, .(0, 0, 0, 0));
|
||||||
|
|
||||||
|
if (ImGui.ImageButtonEx(1, s_TraceIcon, buttonSize, .Zero, .Ones))
|
||||||
|
_visibleMessageTypes ^= .Trace;
|
||||||
|
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
|
if (_visibleMessageTypes.HasFlag(.Info))
|
||||||
|
ImGui.PushStyleColor(.Button, *col);
|
||||||
|
else
|
||||||
|
ImGui.PushStyleColor(.Button, .(0, 0, 0, 0));
|
||||||
|
|
||||||
|
if (ImGui.ImageButtonEx(2, s_InfoIcon, buttonSize, .Zero, .Ones))
|
||||||
|
_visibleMessageTypes ^= .Info;
|
||||||
|
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
|
if (_visibleMessageTypes.HasFlag(.Warning))
|
||||||
|
ImGui.PushStyleColor(.Button, *col);
|
||||||
|
else
|
||||||
|
ImGui.PushStyleColor(.Button, .(0, 0, 0, 0));
|
||||||
|
|
||||||
|
if (ImGui.ImageButtonEx(3, s_WarningIcon, buttonSize, .Zero, .Ones))
|
||||||
|
_visibleMessageTypes ^= .Warning;
|
||||||
|
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
|
if (_visibleMessageTypes.HasFlag(.Error))
|
||||||
|
ImGui.PushStyleColor(.Button, *col);
|
||||||
|
else
|
||||||
|
ImGui.PushStyleColor(.Button, .(0, 0, 0, 0));
|
||||||
|
|
||||||
|
|
||||||
|
if (ImGui.ImageButtonEx(4, s_ErrorIcon, buttonSize, .Zero, .Ones))
|
||||||
|
_visibleMessageTypes ^= .Error;
|
||||||
|
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
|
ImGui.PopStyleVar();
|
||||||
|
|
||||||
|
ImGui.EndMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowMessages()
|
||||||
|
{
|
||||||
|
if (ImGui.BeginTable("Messages", 3, .BordersInnerH | .SizingFixedFit))
|
||||||
|
{
|
||||||
|
ImGui.TableSetupColumn("", .WidthFixed);
|
||||||
|
ImGui.TableSetupColumn("", .WidthStretch);
|
||||||
|
ImGui.TableSetupColumn("", .WidthFixed);
|
||||||
|
|
||||||
|
//LogMessage lastMessage = null;
|
||||||
|
int count = 1;
|
||||||
|
|
||||||
|
// Message ID for ImGui
|
||||||
|
int imGuiMessageId = 0;
|
||||||
|
|
||||||
|
for (let message in _messages)
|
||||||
|
{
|
||||||
|
if (!_visibleMessageTypes.HasFlag(message.MessageType))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((message.Source.IsEngineMessage && !_showEngineMessages) || (!message.Source.IsEngineMessage && !_showGameMessages))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*defer
|
||||||
|
{
|
||||||
|
lastMessage = message;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
LogMessage lastMessage = (message != _messages.Back) ? _messages[@message.Index + 1] : null;
|
||||||
|
|
||||||
|
if (_collapseMessages && lastMessage != null)
|
||||||
|
{
|
||||||
|
if (message.MessageType != lastMessage.MessageType)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (message.Message != lastMessage.Message)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (message.Source.Entity != lastMessage.Source.Entity)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// For exceptions the stack trace is basically the only relevant thing
|
||||||
|
if (message.Source.Exception?.StackTrace != lastMessage.Source.Exception?.StackTrace)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// We collapse this message with the previous one:
|
||||||
|
// Increment counter and go to next message.
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push current index as ID
|
||||||
|
ImGui.PushID((void*)++imGuiMessageId);
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
|
||||||
|
switch (message.MessageType)
|
||||||
|
{
|
||||||
|
case .Error:
|
||||||
|
ImGui.Image(s_ErrorIcon, ImGui.Vec2(32, 32));
|
||||||
|
ImGui.AttachTooltip("Error");
|
||||||
|
case .Warning:
|
||||||
|
ImGui.Image(s_WarningIcon, ImGui.Vec2(32, 32));
|
||||||
|
ImGui.AttachTooltip("Warning");
|
||||||
|
case .Info:
|
||||||
|
ImGui.Image(s_InfoIcon, ImGui.Vec2(32, 32));
|
||||||
|
ImGui.AttachTooltip("Info");
|
||||||
|
case .Trace:
|
||||||
|
ImGui.Image(s_TraceIcon, ImGui.Vec2(32, 32));
|
||||||
|
ImGui.AttachTooltip("Trace");
|
||||||
|
default:
|
||||||
|
ImGui.TextUnformatted("Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
// Timestamp
|
||||||
|
ImGui.TextWrapped($"[{message.Timestamp:HH:mm:ss.fff}]");
|
||||||
|
|
||||||
|
if (message.Source.IsEngineMessage)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted("Engine");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show entity
|
||||||
|
if (message.Source?.Entity != null)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
Result<Entity> entity = Editor.Instance.CurrentScene.GetEntityByID(message.Source.Entity.Value);
|
||||||
|
|
||||||
|
if (entity case .Ok(let e))
|
||||||
|
{
|
||||||
|
ImGui.Text($"Entity: \"{e.Name}\" (ID: {message.Source.Entity})");
|
||||||
|
|
||||||
|
if (ImGui.IsItemClicked())
|
||||||
|
Editor.Instance.EntityHierarchyWindow.HighlightEntity(entity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.Text($"Entity: (ID: {message.Source.Entity})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.Source.Exception != null)
|
||||||
|
{
|
||||||
|
if (ImGui.CollapsingHeader(message.Message.Ptr))
|
||||||
|
{
|
||||||
|
// Show the native to managed entry point only if we show engine messages
|
||||||
|
|
||||||
|
if (_showEngineMessages)
|
||||||
|
ImGui.TextUnformatted(message.Source.Exception.StackTrace);
|
||||||
|
else
|
||||||
|
ImGui.TextUnformatted(message.Source.Exception.CleanStackTrace);
|
||||||
|
|
||||||
|
ImGui.NewLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted(message.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dont show the counter if we only have one message.
|
||||||
|
if (count > 1)
|
||||||
|
{
|
||||||
|
// the message is not collapsible with the previous one.
|
||||||
|
// Print message count for last message and reset counter.
|
||||||
|
// This message will be printed normally.
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text($"{count}");
|
||||||
|
}
|
||||||
|
|
||||||
|
count = 1;
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_autoScroll)
|
||||||
|
{
|
||||||
|
if (ImGui.GetIO().MouseWheel > 0)
|
||||||
|
{
|
||||||
|
_autoScroll = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.SetScrollY(ImGui.GetScrollMaxY());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ImGui.GetScrollMaxY() == ImGui.GetScrollY())
|
||||||
|
{
|
||||||
|
_autoScroll = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearLog()
|
||||||
|
{
|
||||||
|
ClearAndDeleteItems!(_messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(DateTime timestamp, LogLevel severity, StringView message, MessageSource source)
|
||||||
|
{
|
||||||
|
LogMessage logMessage = new LogMessage(timestamp, message, MessageType(severity), source);
|
||||||
|
_messages.Add(logMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogException(DateTime timestamp, MonoExceptionHelper exception)
|
||||||
|
{
|
||||||
|
StringView firstLine = exception.StackTrace;
|
||||||
|
|
||||||
|
int firstInIndex = exception.StackTrace.IndexOf("\n");
|
||||||
|
|
||||||
|
if (firstInIndex != -1)
|
||||||
|
firstLine = firstLine.Substring(0, firstInIndex);
|
||||||
|
|
||||||
|
String message = scope .(128);
|
||||||
|
message.AppendF($"Exception: \"{exception.FullName}\" | Message: \"{exception.Message}\" {firstLine}\0");
|
||||||
|
|
||||||
|
// TODO: are mono exceptions never engine only?
|
||||||
|
LogMessage logMessage = new LogMessage(timestamp, message, .Error, new MessageSource(){Entity = exception.Instance, Exception = exception..AddRef(), IsEngineMessage = false});
|
||||||
|
_messages.Add(logMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ namespace GlitchyEditor
|
|||||||
private ContentBrowserWindow _contentBrowserWindow ~ delete _;
|
private ContentBrowserWindow _contentBrowserWindow ~ delete _;
|
||||||
private PropertiesWindow _propertiesWindow ~ delete _;
|
private PropertiesWindow _propertiesWindow ~ delete _;
|
||||||
private AssetViewer _assetViewer ~ delete _;
|
private AssetViewer _assetViewer ~ delete _;
|
||||||
|
private LogWindow _logWindow ~ delete _;
|
||||||
|
|
||||||
public Scene CurrentScene
|
public Scene CurrentScene
|
||||||
{
|
{
|
||||||
@@ -45,6 +46,7 @@ namespace GlitchyEditor
|
|||||||
public ContentBrowserWindow ContentBrowserWindow => _contentBrowserWindow;
|
public ContentBrowserWindow ContentBrowserWindow => _contentBrowserWindow;
|
||||||
public PropertiesWindow PropertiesWindow => _propertiesWindow;
|
public PropertiesWindow PropertiesWindow => _propertiesWindow;
|
||||||
public AssetViewer AssetViewer => _assetViewer;
|
public AssetViewer AssetViewer => _assetViewer;
|
||||||
|
public LogWindow LogWindow => _logWindow;
|
||||||
|
|
||||||
public EditorCamera* CurrentCamera { get; set; }
|
public EditorCamera* CurrentCamera { get; set; }
|
||||||
|
|
||||||
@@ -53,15 +55,27 @@ namespace GlitchyEditor
|
|||||||
public SceneRenderer GameSceneRenderer {get; set;}
|
public SceneRenderer GameSceneRenderer {get; set;}
|
||||||
public SceneRenderer EditorSceneRenderer {get; set;}
|
public SceneRenderer EditorSceneRenderer {get; set;}
|
||||||
|
|
||||||
|
private static Editor s_Instance;
|
||||||
|
|
||||||
|
public static Editor Instance => s_Instance;
|
||||||
|
|
||||||
/// Creates a new editor for the given world
|
/// Creates a new editor for the given world
|
||||||
public this(Scene scene, EditorContentManager contentManager)
|
public this(Scene scene, EditorContentManager contentManager)
|
||||||
{
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(s_Instance == null, "Cannot create a second instance of a singleton.");
|
||||||
|
s_Instance = this;
|
||||||
|
|
||||||
_scene = scene;
|
_scene = scene;
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
|
|
||||||
InitWindows();
|
InitWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
s_Instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
private void InitWindows()
|
private void InitWindows()
|
||||||
{
|
{
|
||||||
_sceneViewportWindow = new EditorViewportWindow(this);
|
_sceneViewportWindow = new EditorViewportWindow(this);
|
||||||
@@ -71,6 +85,7 @@ namespace GlitchyEditor
|
|||||||
_contentBrowserWindow = new ContentBrowserWindow((.)Application.Get().ContentManager);
|
_contentBrowserWindow = new ContentBrowserWindow((.)Application.Get().ContentManager);
|
||||||
_propertiesWindow = new PropertiesWindow(this);
|
_propertiesWindow = new PropertiesWindow(this);
|
||||||
_assetViewer = new AssetViewer((.)Application.Get().ContentManager);
|
_assetViewer = new AssetViewer((.)Application.Get().ContentManager);
|
||||||
|
_logWindow = new LogWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -82,6 +97,7 @@ namespace GlitchyEditor
|
|||||||
_contentBrowserWindow.Show();
|
_contentBrowserWindow.Show();
|
||||||
_propertiesWindow.Show();
|
_propertiesWindow.Show();
|
||||||
_assetViewer.Show();
|
_assetViewer.Show();
|
||||||
|
_logWindow.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ namespace GlitchyEditor
|
|||||||
public this(String[] args)
|
public this(String[] args)
|
||||||
{
|
{
|
||||||
PushLayer(new EditorLayer(args, _contentManager));
|
PushLayer(new EditorLayer(args, _contentManager));
|
||||||
|
|
||||||
|
Log.ClientLogger = new EditorLogger();
|
||||||
|
Log.EngineLogger = new EditorLogger() { IsEngineLogger = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IContentManager InitContentManager()
|
protected override IContentManager InitContentManager()
|
||||||
@@ -33,7 +36,7 @@ namespace GlitchyEditor
|
|||||||
_contentManager.SetAsDefaultAssetLoader<EffectAssetLoader>(".hlsl");
|
_contentManager.SetAsDefaultAssetLoader<EffectAssetLoader>(".hlsl");
|
||||||
_contentManager.SetAssetPropertiesEditor<EffectAssetLoader>(=> EffectAssetPropertiesEditor.Factory);
|
_contentManager.SetAssetPropertiesEditor<EffectAssetLoader>(=> EffectAssetPropertiesEditor.Factory);
|
||||||
|
|
||||||
_contentManager.SetContentDirectory("./content");
|
_contentManager.SetResourcesDirectory("./Resources");
|
||||||
|
|
||||||
return _contentManager;
|
return _contentManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ namespace GlitchyEditor;
|
|||||||
|
|
||||||
class EditorContentManager : IContentManager
|
class EditorContentManager : IContentManager
|
||||||
{
|
{
|
||||||
private append String _contentDirectory = .();
|
private append String _resourcesDirectory = .();
|
||||||
|
private append String _assetsDirectory = .();
|
||||||
|
|
||||||
public StringView ContentDirectory => _contentDirectory;
|
public StringView ResourcesDirectory => _resourcesDirectory;
|
||||||
|
public StringView AssetDirectory => _assetsDirectory;
|
||||||
//private append List<String> _identifiers = .() ~ _.ClearAndDeleteItems();
|
|
||||||
|
|
||||||
private append Dictionary<StringView, AssetHandle> _identiferToHandle = .(); // TODO: Check if all resources are unloaded
|
private append Dictionary<StringView, AssetHandle> _identiferToHandle = .(); // TODO: Check if all resources are unloaded
|
||||||
|
|
||||||
@@ -64,13 +64,20 @@ class EditorContentManager : IContentManager
|
|||||||
_identiferToHandle.Add(asset.Identifier, asset.Handle);
|
_identiferToHandle.Add(asset.Identifier, asset.Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetContentDirectory(StringView contentDirectory)
|
public void SetResourcesDirectory(StringView fileName)
|
||||||
{
|
{
|
||||||
_contentDirectory.Clear();
|
_resourcesDirectory.Set(fileName);
|
||||||
_contentDirectory.Append(contentDirectory);
|
Path.Fixup(_resourcesDirectory);
|
||||||
Path.Fixup(_contentDirectory);
|
|
||||||
|
|
||||||
_assetHierarchy.SetContentDirectory(contentDirectory);
|
_assetHierarchy.SetResourcesDirectory(_resourcesDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAssetDirectory(StringView fileName)
|
||||||
|
{
|
||||||
|
_assetsDirectory.Set(fileName);
|
||||||
|
Path.Fixup(_assetsDirectory);
|
||||||
|
|
||||||
|
_assetHierarchy.SetAssetsDirectory(_assetsDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -302,7 +309,7 @@ class EditorContentManager : IContentManager
|
|||||||
|
|
||||||
private void GetResourceFilePath(StringView resourceName, String filePath)
|
private void GetResourceFilePath(StringView resourceName, String filePath)
|
||||||
{
|
{
|
||||||
Path.Combine(filePath, _contentDirectory, resourceName);
|
Path.Combine(filePath, _assetsDirectory, resourceName);
|
||||||
|
|
||||||
Path.Fixup(filePath);
|
Path.Fixup(filePath);
|
||||||
}
|
}
|
||||||
@@ -337,7 +344,10 @@ class EditorContentManager : IContentManager
|
|||||||
{
|
{
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
// Todo: How strict should we be on paths?
|
// It's valid to request no entity, but no entity is obviously invalid.
|
||||||
|
if (identifier.IsWhiteSpace)
|
||||||
|
return .Invalid;
|
||||||
|
|
||||||
String fixedIdentifier = scope String(identifier);
|
String fixedIdentifier = scope String(identifier);
|
||||||
AssetIdentifier.Fixup(fixedIdentifier);
|
AssetIdentifier.Fixup(fixedIdentifier);
|
||||||
|
|
||||||
@@ -346,30 +356,34 @@ class EditorContentManager : IContentManager
|
|||||||
|
|
||||||
GetResourceAndSubassetName(fixedIdentifier, let resourceName, let subassetName);
|
GetResourceAndSubassetName(fixedIdentifier, let resourceName, let subassetName);
|
||||||
|
|
||||||
String filePath = scope .();
|
Result<TreeNode<AssetNode>> resultNode = AssetHierarchy.GetNodeFromIdentifier(fixedIdentifier);
|
||||||
GetResourceFilePath(resourceName, filePath);
|
|
||||||
|
|
||||||
Result<TreeNode<AssetNode>> resultNode = AssetHierarchy.GetNodeFromPath(filePath);
|
|
||||||
|
|
||||||
if (resultNode case .Err)
|
if (resultNode case .Err)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"Could not find asset \"{filePath}\".");
|
Log.EngineLogger.Error($"Could not find asset \"{fixedIdentifier}\".");
|
||||||
return .Invalid;
|
return .Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String filePath = scope String(resultNode->Value.Path);
|
||||||
|
|
||||||
AssetFile file = resultNode->Value.AssetFile;
|
AssetFile file = resultNode->Value.AssetFile;
|
||||||
|
|
||||||
IAssetLoader assetLoader = GetAssetLoader(file);
|
IAssetLoader assetLoader = GetAssetLoader(file);
|
||||||
|
|
||||||
// TODO: what are we supposed to do if we don't find a loader? Sure not crash...
|
// TODO: what are we supposed to do if we don't find a loader? Surely not crash...
|
||||||
Log.EngineLogger.AssertDebug(assetLoader != null);
|
//Log.EngineLogger.AssertDebug(assetLoader != null);
|
||||||
|
if (assetLoader == null)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"No asset loader registered for asset {identifier}.");
|
||||||
|
return .Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
Asset loadedAsset;
|
Asset loadedAsset;
|
||||||
|
|
||||||
// TODO: Support lazy loading for all asset types
|
// TODO: Support lazy loading for all asset types
|
||||||
if (!(assetLoader is EditorTextureAssetLoader) || blocking)
|
if (!(assetLoader is EditorTextureAssetLoader) || blocking)
|
||||||
{
|
{
|
||||||
Stream stream = GetStream(filePath);
|
Stream stream = OpenStream(filePath, true);
|
||||||
|
|
||||||
loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this);
|
loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this);
|
||||||
|
|
||||||
@@ -413,7 +427,7 @@ class EditorContentManager : IContentManager
|
|||||||
{
|
{
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
Stream stream = GetStream(filePath);
|
Stream stream = OpenStream(filePath, true);
|
||||||
|
|
||||||
Asset loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this);
|
Asset loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this);
|
||||||
|
|
||||||
@@ -506,23 +520,13 @@ class EditorContentManager : IContentManager
|
|||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream OpenStream(StringView assetIdentifier, bool openOnly)
|
private Stream OpenStream(StringView fileName, bool openOnly)
|
||||||
{
|
{
|
||||||
var assetIdentifier;
|
|
||||||
|
|
||||||
if (!assetIdentifier.StartsWith(_contentDirectory))
|
|
||||||
{
|
|
||||||
String filePath = scope:: String(assetIdentifier.Length + _contentDirectory.Length + 2);
|
|
||||||
Path.Combine(filePath, _contentDirectory, assetIdentifier);
|
|
||||||
|
|
||||||
assetIdentifier = filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileStream fs = new FileStream();
|
FileStream fs = new FileStream();
|
||||||
|
|
||||||
FileMode fileMode = openOnly ? FileMode.Open : FileMode.OpenOrCreate;
|
FileMode fileMode = openOnly ? FileMode.Open : FileMode.OpenOrCreate;
|
||||||
|
|
||||||
var result = fs.Open(assetIdentifier, fileMode, openOnly ? .Read : .ReadWrite, .ReadWrite);
|
var result = fs.Open(fileName, fileMode, openOnly ? .Read : .ReadWrite, .ReadWrite);
|
||||||
|
|
||||||
if (result case .Err)
|
if (result case .Err)
|
||||||
return null;
|
return null;
|
||||||
@@ -530,28 +534,21 @@ class EditorContentManager : IContentManager
|
|||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: probably not needed
|
/// Returns a file stream for the given assetIdentifier
|
||||||
public Stream GetStream(StringView assetIdentifier)
|
public Stream GetStream(StringView assetIdentifier)
|
||||||
{
|
{
|
||||||
return OpenStream(assetIdentifier, true);
|
String fixuppedIdentifier = scope .(assetIdentifier);
|
||||||
|
AssetIdentifier.Fixup(fixuppedIdentifier);
|
||||||
|
|
||||||
/*var assetIdentifier;
|
var node = _assetHierarchy.GetNodeFromIdentifier(fixuppedIdentifier);
|
||||||
|
|
||||||
if (!assetIdentifier.StartsWith(_contentDirectory))
|
if (node case .Err)
|
||||||
{
|
{
|
||||||
String filePath = scope:: String(assetIdentifier.Length + _contentDirectory.Length + 2);
|
Log.EngineLogger.Error($"Could not find asset node \"{assetIdentifier}\".");
|
||||||
Path.Combine(filePath, _contentDirectory, assetIdentifier);
|
return null;
|
||||||
|
|
||||||
assetIdentifier = filePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream fs = new FileStream();
|
return OpenStream(node->Value.Path, true);
|
||||||
var result = fs.Open(assetIdentifier, .Open, .Read, .ReadWrite);
|
|
||||||
|
|
||||||
if (result case .Err)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return fs;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssetHandle ManageAsset(Asset asset)
|
public AssetHandle ManageAsset(Asset asset)
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ namespace GlitchyEditor
|
|||||||
public SubTexture2D Simulate ~ _.ReleaseRef();
|
public SubTexture2D Simulate ~ _.ReleaseRef();
|
||||||
public SubTexture2D Pause ~ _.ReleaseRef();
|
public SubTexture2D Pause ~ _.ReleaseRef();
|
||||||
public SubTexture2D SingleStep ~ _.ReleaseRef();
|
public SubTexture2D SingleStep ~ _.ReleaseRef();
|
||||||
|
public SubTexture2D Error ~ _.ReleaseRef();
|
||||||
|
public SubTexture2D Warning ~ _.ReleaseRef();
|
||||||
|
public SubTexture2D Info ~ _.ReleaseRef();
|
||||||
|
public SubTexture2D Trace ~ _.ReleaseRef();
|
||||||
|
|
||||||
public SamplerState SamplerState
|
public SamplerState SamplerState
|
||||||
{
|
{
|
||||||
@@ -41,6 +45,10 @@ namespace GlitchyEditor
|
|||||||
Simulate = GetNextGridTexture(ref pen, iconSize);
|
Simulate = GetNextGridTexture(ref pen, iconSize);
|
||||||
Pause = GetNextGridTexture(ref pen, iconSize);
|
Pause = GetNextGridTexture(ref pen, iconSize);
|
||||||
SingleStep = GetNextGridTexture(ref pen, iconSize);
|
SingleStep = GetNextGridTexture(ref pen, iconSize);
|
||||||
|
Error = GetNextGridTexture(ref pen, iconSize);
|
||||||
|
Warning = GetNextGridTexture(ref pen, iconSize);
|
||||||
|
Info = GetNextGridTexture(ref pen, iconSize);
|
||||||
|
Trace = GetNextGridTexture(ref pen, iconSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SubTexture2D GetNextGridTexture(ref float2 pen, float2 iconSize)
|
private SubTexture2D GetNextGridTexture(ref float2 pen, float2 iconSize)
|
||||||
|
|||||||