247 Commits

Author SHA1 Message Date
antopilo
076960c41d vma 2024-12-23 23:46:31 -05:00
antopilo
2898a6f5b0 Fixed compilation errors 2024-12-21 11:57:32 -05:00
antopilo
f1a36c495d Removed DOF manual focus serialization, its always on by default 2024-12-02 17:54:27 -05:00
Antoine Pilote
31388612bb Merge pull request #93 from xiaohunqupo/patch-1
Update glfw_p5.lua
2024-12-02 17:04:44 -05:00
antopilo
5b529bd97d Fixed game engine not recompiling + improved prefab instancing from TB 2024-12-02 00:12:42 -05:00
antopilo
d93d69d059 Added controller support 2024-12-01 20:52:34 -05:00
antopilo
82459a6e4c Now instancing prefab from trenchbroom correctly 2024-12-01 13:49:06 -05:00
antopilo
5b4d6d915a Now exports prefabs to trenchbroom automatically 2024-12-01 13:21:58 -05:00
antopilo
ea044a2357 Added GetAllFiles to filesystem 2024-12-01 13:21:44 -05:00
antopilo
b6c3220797 Depth of field no unit accurate 2024-12-01 13:06:13 -05:00
antopilo
15051a4eb7 Improved env setting labels 2024-12-01 13:03:58 -05:00
antopilo
ef25a932b5 Now serializing all environment settings + optimized transform system 2024-12-01 12:15:27 -05:00
antopilo
d7e60cfe96 Fixed runtime 2024-12-01 02:30:06 -05:00
antopilo
a27039d7c5 More blending code + ShapeCastSphere now works 2024-12-01 02:11:05 -05:00
antopilo
18eec6c570 No longer using custom panel for skinned model component 2024-12-01 02:10:49 -05:00
antopilo
699375f1a7 Prefab window no longer crashing 2024-12-01 02:10:31 -05:00
antopilo
c8aa609ab1 Added skeletal animation 1D blending 2024-12-01 02:10:19 -05:00
antopilo
6a96ce497c Capsule and Cylinder now correct height in dynamic world 2024-12-01 02:09:29 -05:00
antopilo
fb217221b7 Added new postfx UI widgets in environment properties 2024-12-01 02:09:06 -05:00
antopilo
9238a59a00 Improved play mode startup time 2024-12-01 02:08:32 -05:00
antopilo
f1b4aaad76 Added lens dirt, posterization and pixelization postfx 2024-12-01 02:07:55 -05:00
Danny许
b32ee08b65 Update glfw_p5.lua
Fix link error.
2024-11-26 10:49:04 +08:00
antopilo
b33bfcab57 Added LookAt to transform C# API 2024-11-24 04:18:55 -05:00
antopilo
6744a58043 Fixed crash when deserializing a skinned mesh if no mesh is set 2024-11-24 00:03:13 -05:00
antopilo
32273eece9 Changed default volumetric strength to 1.0 2024-11-24 00:02:51 -05:00
antopilo
d43c48207c Hide camera speed UI if not controlling camera 2024-11-24 00:02:38 -05:00
antopilo
d714ac0f35 Fixed snapping not working on Z axis 2024-11-24 00:02:14 -05:00
antopilo
dd46e32bee Better SSAO + added shader reloading in debug 2024-11-23 19:46:39 -05:00
antopilo
1782f18f26 Added search feature with text hightlight 2024-11-22 01:08:51 -05:00
antopilo
84b2b63ba9 Added shortcut to open resource in component widgets 2024-11-21 22:14:14 -05:00
antopilo
4ab59bf7e8 Moved environment to a resource and a component 2024-11-21 21:06:14 -05:00
Antoine Pilote
d546228089 Merge pull request #92 from antopilo/develop
Merge develop into main
2024-11-20 22:28:05 -05:00
antopilo
9937d35579 updated readme image 2024-11-20 22:26:41 -05:00
antopilo
1063ffcd58 Removed useless menu items 2024-11-20 01:36:52 -05:00
antopilo
e4c11140e0 Better UI 2024-11-20 01:30:57 -05:00
antopilo
9b853aef7e Added separte settings for gizmo, shape drawing, fixed sky, better UI 2024-11-20 00:07:56 -05:00
antopilo
26ad1507eb Merged static resources 2024-11-19 23:23:38 -05:00
antopilo
3fbb1bd33d Merge branch 'develop' of https://github.com/antopilo/Nuake into develop
# Conflicts:
#	Nuake/src/Resource/StaticResources.cpp
2024-11-19 23:23:16 -05:00
antopilo
2c4d0faf64 Added custom titlebar to the editor 2024-11-19 23:22:41 -05:00
antopilo
0ac0934622 Serialize Sky Component 2024-11-11 11:45:12 -05:00
antopilo
0311862b65 Merge branch 'develop' of https://github.com/antopilo/Nuake into develop 2024-11-06 20:40:58 -05:00
antopilo
89209dc7ba Added support for skyboxes using a new SkyBox resource and component 2024-11-06 20:40:38 -05:00
antopilo
e47142a3e4 Swapped for custom glfw 2024-10-29 20:40:47 -04:00
antopilo
5c2311d7b5 Master volume in project settings now works 2024-10-29 20:37:59 -04:00
antopilo
9647cac48b Disabled thumbnails for now 2024-10-28 20:15:43 -04:00
antopilo
03d785f016 Fixed inverted spatialized audio direction in play mode 2024-10-28 20:14:49 -04:00
antopilo
f1be4f7cef Fixed memory leak + added visibility UI node C# endpoints + size 2024-10-19 23:23:26 -04:00
antopilo
cbf11abcf5 Fixed scene leaking 2024-10-19 15:04:32 -04:00
antopilo
3d630483f6 Added world space UI Input aka doom3 UI 2024-10-19 15:04:07 -04:00
antopilo
c432077328 Added exposed var bool + fixed transform panel 2024-10-19 15:02:36 -04:00
antopilo
39cf28c91e Raycasts now returns the body instance it collided with + serialize spot light cones 2024-10-18 00:21:08 -04:00
Antoine Pilote
4e0817b761 Fixed UI not rendering 2024-10-16 12:28:03 -04:00
antopilo
8ed6a53cf4 Setter and Getter for UIResource on component - Removed useless Environment creation 2024-10-15 20:35:42 -04:00
antopilo
534c35c76f Fixed sprites not working 2024-10-15 19:00:56 -04:00
antopilo
28bbb255c5 Model loader now takes into account submeshes transform 2024-09-27 01:39:40 -04:00
antopilo
e18dbd292f Fixed inverted Y velocity in velocity buffer 2024-09-26 18:47:51 -04:00
antopilo
102ccc530b Finally finished TAA 2024-09-25 22:37:31 -04:00
Antoine Pilote
31c8a2e598 Changed format to gl-float 2024-09-25 13:17:25 -04:00
Antoine Pilote
a37bdd9d7a Added debug display with arrows of velocity buffer 2024-09-25 12:58:53 -04:00
antopilo
6e8f14c5da Added velocity buffer + start of TAA implementation 2024-09-24 21:19:56 -04:00
antopilo
bf75c04a8c Made imgui use another ID for prefab window 2024-09-24 19:29:27 -04:00
antopilo
2dfcb683fc Added imguizo + overlay to prefab editor 2024-09-22 00:01:36 -04:00
antopilo
f1c403f94c Can now delete from prefab editor 2024-09-21 23:49:51 -04:00
antopilo
114adab73f Fixed crash when prefab gets instantiated with C# script 2024-09-21 19:26:20 -04:00
antopilo
0e750bda89 work 2024-09-21 14:02:20 -04:00
antopilo
8079c47832 Instancing prefab through code should instance body and scripts immediatly 2024-09-21 13:18:35 -04:00
antopilo
29b35a6932 Can now reparent prefab with drag n drop 2024-09-21 13:02:36 -04:00
antopilo
ef6e7ac0dc Prevented displaying child of prefab 2024-09-21 13:00:35 -04:00
antopilo
0c784d4462 Stopped display child of prefabs 2024-09-21 12:58:01 -04:00
antopilo
954e2110f1 Fixed prefab serialization and instancing into scene 2024-09-21 12:52:56 -04:00
antopilo
3d9cda2990 Minor improvements with prefab deserialization 2024-09-19 21:36:44 -04:00
antopilo
6ac1ff8386 Work 2024-09-19 21:11:07 -04:00
Antoine Pilote
7791cd9f29 Merge pull request #91 from WiggleWizard/feature/cs-scene-callbacks
Exposed subsystem to scene events
2024-09-19 16:55:31 -04:00
WiggleWizard
a487d31c48 Completed work on exposing subsystems to scene events 2024-09-19 21:43:04 +01:00
WiggleWizard
edce52bb17 Finished up MVP for scene callbacks 2024-09-19 18:50:52 +01:00
WiggleWizard
d0c5ef1a1d Initial infrastructure for C# scene callbacks in subsystems 2024-09-19 17:52:19 +01:00
antopilo
98797e15f8 Prefab editor now somewhat works with live-reload 2024-09-19 12:24:05 -04:00
antopilo
216fa230b6 Saving prefab from prefab editor now works 2024-09-19 10:37:22 -04:00
antopilo
616532e78b Added MVP for prefab editor window and made the whole editor modular to support multi-scene editing 2024-09-19 00:56:22 -04:00
antopilo
a87aebe12b Merge branch 'develop' of https://github.com/antopilo/Nuake into develop 2024-09-18 17:10:18 -04:00
antopilo
7fc10b4e56 Improvements 2024-09-18 17:10:12 -04:00
Antoine Pilote
bd6b4362bc Merge pull request #90 from WiggleWizard/feature/scriptable-subsystems
First pass scriptable subsystems that has the same lifetime of the engine
2024-09-18 16:51:07 -04:00
WiggleWizard
ca645e2026 Fixed a few things 2024-09-18 21:48:14 +01:00
WiggleWizard
066b2998ac Much more stable and simplified subsystem architecture 2024-09-18 21:20:14 +01:00
WiggleWizard
510b577f49 First pass scriptable subsystems that has the same lifetime of the engine 2024-09-18 12:44:46 +01:00
Antoine Pilote
67d7865a20 Merge branch 'develop' of https://github.com/antopilo/nuake into develop 2024-09-17 17:32:13 -04:00
Antoine Pilote
ef0fde5847 Can now drag n drop proejct in project launcher + delete or right click to remove from list 2024-09-17 17:32:05 -04:00
Antoine Pilote
1b2d2985f5 Merge pull request #87 from WiggleWizard/fix/wrenremoval
Removed the last remnants of Wren QQ
2024-09-17 17:20:32 -04:00
Antoine Pilote
07871123cb Fixed runtime linker issues 2024-09-17 12:39:38 -04:00
Antoine Pilote
5f1b9dc65b Merge branch 'develop' of https://github.com/antopilo/nuake into develop 2024-09-17 12:32:48 -04:00
antopilo
c6a2d916a8 Fixed crash when html file is empty and when canvas fails to aprse 2024-09-16 21:42:35 -04:00
antopilo
7ed37d0bbb Fixed crash when canvas parser fails + added resolution settings for worldspace UI 2024-09-16 21:32:17 -04:00
antopilo
f58e09cfc3 Removed overlay when in play mode 2024-09-16 21:31:51 -04:00
antopilo
bd77025ed0 Added script icon in scene hierarchy 2024-09-16 20:55:24 -04:00
antopilo
dd3cc823c0 Improved filesystem browser, color accent, drag n drop, new icons 2024-09-16 20:12:36 -04:00
antopilo
da995b99c8 Renamed textures to Textures 2024-09-16 20:12:02 -04:00
WiggleWizard
1b2abced1e Removed the last remnants of Wren QQ 2024-09-17 00:08:04 +01:00
antopilo
38484415f1 Now displaying camera frustum gizmo 2024-09-16 17:28:01 -04:00
Antoine Pilote
cf9612c5b1 Added a popup to configure trenchbroom when creating a new project 2024-09-16 13:27:22 -04:00
Antoine Pilote
7f92311f12 Fixed crash when ctrl-s in project browser haha 2024-09-16 12:46:15 -04:00
Antoine Pilote
4ac7d1cfc9 Added OpenFolderDialog + now project creation selects folder instead 2024-09-16 12:40:57 -04:00
Antoine Pilote
cff63d71cc Removed glew 2024-09-16 12:18:52 -04:00
Antoine Pilote
4a3d15e7d3 Merge pull request #76 from WiggleWizard/feature/morereflection
Second pass reflection
2024-09-16 11:10:44 -04:00
WiggleWizard
d19ba4f979 Converted last components to new component drawing system 2024-09-16 14:49:25 +01:00
antopilo
ae426f7f17 Added support for SVG images inUI + added a texture flag to flip on load 2024-09-16 08:57:52 -04:00
WiggleWizard
8b2511f995 Better API for binding inspector drawers and added the ability to add whole component drawers 2024-09-16 10:57:22 +01:00
WiggleWizard
d338a98c9b Removed Wren script references in the UI 2024-09-16 10:18:32 +01:00
WiggleWizard
bb43bbe1b8 Fixed rebuild action for quake map component 2024-09-16 10:05:55 +01:00
WiggleWizard
52776186d3 Added the ability to remove components 2024-09-16 00:17:28 +01:00
WiggleWizard
b23d418f23 Compile issues fixed 2024-09-15 23:14:23 +01:00
WiggleWizard
baac971deb A little bit of cleanup 2024-09-15 23:06:06 +01:00
antopilo
24be72b10a Made text calculate proper width with different fonts 2024-09-15 17:29:41 -04:00
WiggleWizard
269533eb03 Particle Emitter Component reflected 2024-09-15 21:34:38 +01:00
WiggleWizard
7846a667a2 Quake Map Component reflected 2024-09-15 21:34:38 +01:00
WiggleWizard
0dcd383dbb Added the ability to add actions (buttons) to the inspector through reflection 2024-09-15 21:34:38 +01:00
WiggleWizard
2b06fe32de Small refactor of trait reflection 2024-09-15 21:34:38 +01:00
WiggleWizard
1d5f578e86 Rigidbody Component reflection 2024-09-15 21:34:38 +01:00
WiggleWizard
6149907576 Skinned Model Component now reflected 2024-09-15 21:34:38 +01:00
WiggleWizard
d8d904b6ba New reflection type DynamicItemList 2024-09-15 21:34:38 +01:00
WiggleWizard
1e570e17fd Made component field type ResourceFile easier to work with 2024-09-15 21:34:38 +01:00
WiggleWizard
d62f241a16 Sphere collider reflection 2024-09-15 21:34:38 +01:00
WiggleWizard
5d0eb4a597 Sprite component reflected 2024-09-15 21:34:37 +01:00
WiggleWizard
dabd9c01a6 Removed trigger zone component 2024-09-15 21:34:37 +01:00
WiggleWizard
aed98dd648 UI system now working well with the new component changes, fixed trait compile issues, fixed inspector rendering issues 2024-09-15 21:34:37 +01:00
WiggleWizard
59505b0664 Fix for audio emitter component not compiling 2024-09-15 21:31:07 +01:00
WiggleWizard
9e94006d2b Added generic ability to (de)serialize ResourceFiles, a templated function to allow easier setting of entt traits and renamed float limits function 2024-09-15 21:31:07 +01:00
WiggleWizard
82771d43da Removed old rubbish from audio emitter component 2024-09-15 21:31:06 +01:00
WiggleWizard
65c8ab79af New component field type to support files
Also fixed Audio System to work with this new supported component field type
2024-09-15 21:31:06 +01:00
WiggleWizard
68ffe1d6b4 Basic inspector reflection working for 2 components 2024-09-15 21:31:06 +01:00
WiggleWizard
90a60e8d87 Initial inspector work to render using reflection 2024-09-15 21:31:06 +01:00
WiggleWizard
56e12c2647 DrawVec3 helper now returns true if changed 2024-09-15 21:31:06 +01:00
WiggleWizard
7d66a19ab2 Architecture rework for components to accomodate for reflection 2024-09-15 21:31:06 +01:00
WiggleWizard
bf6fb0f8b6 Fix for entt update 2024-09-15 21:31:06 +01:00
WiggleWizard
ded6fd2e03 Upgraded entt
Deleted the header only entt lib and added the full and latest library to the dependencies list
2024-09-15 21:31:05 +01:00
antopilo
c2e50822f1 Fixed invalid uniforms in shaders 2024-09-15 16:30:06 -04:00
antopilo
24a4281a3d Added css style propagation + hover propagation from child 2024-09-15 11:08:21 -04:00
Antoine Pilote
c5dca4dc37 Merge pull request #75 from xypherorion/main
FIxed warnings for Premake5 [Issue #74]
2024-09-15 10:28:10 -04:00
Xypher Orion
edc4d43f97 Corrected config 2024-09-15 08:42:27 -04:00
Xypher Orion
a7cbbf2830 Patched for Main Repo Issue #74 2024-09-15 07:31:47 -04:00
antopilo
68ae15594f Started relationional styles 2024-09-14 14:12:08 -04:00
antopilo
79908a12a5 More accurate text size when using px font-size. Added CSS imports to canvas sourceFiles for live reload + started implement descendant css rules 2024-09-14 13:54:23 -04:00
antopilo
fad8b4033b Better default + made root node constraint other nodes 2024-09-13 21:46:21 -04:00
antopilo
efc4b8bae7 Added stylesheet @import into live reload filewatch for a canvas 2024-09-13 21:45:56 -04:00
antopilo
6e92674bba UI hot-reloads if child widgets or stylesheet gets updated 2024-09-13 19:14:46 -04:00
antopilo
ee852f7f3d Prevented abusive resizing when virtual camera is displayed + hide virtual cam in play mode 2024-09-13 18:24:42 -04:00
antopilo
bb0da25682 Fixed newly generated solution not building 2024-09-13 18:24:08 -04:00
antopilo
1b89eaa695 Disabled UI rendering in camera previews 2024-09-13 17:26:21 -04:00
antopilo
89ea32a4b3 Added SceneSwitching, Better font rendering, DOM inspector, Font-family prop 2024-09-13 17:18:09 -04:00
antopilo
4c76e9e493 Can now edit text of text nodes and fetch any other nodes in the DOM from ID 2024-09-13 01:25:41 -04:00
antopilo
3b148b76c4 Started to expose DOM to C# API with support for custom nodes. Currently crash when doing FindNodeByID<T> 2024-09-13 00:51:34 -04:00
Antoine Pilote
9e87dca9ce Set editor viewport dimension for InputManager 2024-09-12 17:01:34 -04:00
Antoine Pilote
5e1483e111 Added mouse position relative to viewport 2024-09-12 13:17:47 -04:00
antopilo
c7621b31e0 Added CustomWidget through C# reflection with callbacks 2024-09-11 22:58:33 -04:00
antopilo
596e4a484c Added C# UIWidget API 2024-09-11 22:58:06 -04:00
antopilo
a5bf5d99c7 Refactor CodeStyle of NuakeUI Renderer 2024-09-11 22:57:36 -04:00
antopilo
8b6991822f Removed NuakeUI FileSystem 2024-09-11 22:57:17 -04:00
antopilo
7ee76a129e Now calls Tick on UI Canvas 2024-09-11 22:57:05 -04:00
antopilo
a75bcc260f Added UI for IsWorldspace 2024-09-11 17:42:04 -04:00
antopilo
f1903de9ab Fixed input manager for UI + WorldSpace UI 2024-09-11 17:41:39 -04:00
Antoine Pilote
40da75eeeb Merge pull request #73 from WiggleWizard/fix/buildoptimizations
Enabled multithreaded compilation and fixed some build warnings
2024-09-11 09:46:12 -04:00
WiggleWizard
7efa69a20d Enabled multithreaded compilation and fixed some build warnings
Enabled MT compilation for all first party TUs and some third party ones too. Disabled specific warnings in third party code, started fixing warnings in first party code as well
2024-09-11 12:03:09 +01:00
Antoine Pilote
706821861b Forgot to push shader source files changes on ui_text.shader 2024-09-11 00:14:46 -04:00
Antoine Pilote
0e78c7d889 Added serialization for UI components 2024-09-10 23:53:29 -04:00
Antoine Pilote
7a5568b513 Removed automatic mipmap generation for texture set from data buffer + exposed subpixel uniforms from text shader 2024-09-10 23:19:32 -04:00
Antoine Pilote
ebedefb6a7 Added UI component, resource & system. Now renders on screen and live reloads 2024-09-10 22:27:15 -04:00
Antoine Pilote
552fe0ee04 Removed annoying debug window 2024-09-10 19:24:24 -04:00
Antoine Pilote
2c48590a4a Added shaders for UI and fixed UI renderer 2024-09-10 19:18:29 -04:00
Antoine Pilote
1949946cdd Removed wrong submodules 2024-09-10 18:10:16 -04:00
Antoine Pilote
dcbd6d0fe3 Merge pull request #72 from WiggleWizard/feature/basiccomponentreflection
Initial reflection for components using the entt reflection API
2024-09-10 12:42:12 -04:00
WiggleWizard
ffc79ccdf4 Initial reflection for components using the entt reflection API
Currently the only system using reflection is the drop down box when clicking "Add Component" in the entity inspector. The other systems and architecture is still designed around concrete compile time typing
2024-09-10 15:53:32 +01:00
Antoine Pilote
7e341b34cf Fixed broken shader uniform caused by automatic casting from uint to int 2024-09-09 21:40:06 -04:00
Antoine Pilote
1051f0cdd3 More work 2024-09-09 21:21:47 -04:00
Antoine Pilote
aef5f65f75 Refactor Shader uniform API + Added back NuakeUI 2024-09-09 20:55:51 -04:00
Antoine Pilote
5a0f7c06f0 Added Yoga 2024-09-09 18:01:05 -04:00
Antoine Pilote
0f14e303b2 Attempt to fix kinematic not generating collision callbacks 2024-09-09 00:09:04 -04:00
Antoine Pilote
22a859b3e1 Prevent .map rebuilding during play mode 2024-09-09 00:08:45 -04:00
Antoine Pilote
e36e33aa9a Renamed exe to Nuake Engine + added C# endpoints i forgot to push 2024-09-08 23:17:51 -04:00
Antoine Pilote
f30e178e87 Added AddComponent C# API + SetGet light intensity 2024-09-08 23:17:28 -04:00
Antoine Pilote
9f09773636 Removed debug window for shadwo maps 2024-09-08 23:17:12 -04:00
Antoine Pilote
73e0498287 Fixed crash in gizmo drawer when selection is invalid 2024-09-08 23:17:02 -04:00
Antoine Pilote
13c0fb414d Fixed crash when trying to generate trenchbroom game config 2024-09-08 23:16:47 -04:00
antopilo
7c123e1c0a Made it possible to open projects directly from the .project file 2024-09-08 15:01:19 -04:00
antopilo
219c9a97cd Made project list in welcome window the same style as template list in new project wizard 2024-09-08 12:32:32 -04:00
antopilo
20ade88fd9 Added a cancel button in new project wizard 2024-09-08 12:32:05 -04:00
Antoine Pilote
6005eb51d3 Merge branch 'develop' of https://github.com/antopilo/Nuake into develop 2024-09-05 21:49:27 -04:00
Antoine Pilote
8d69094cf2 Prevented crash on isValid on entity entity 2024-09-05 21:49:11 -04:00
Antoine Pilote
5034adca8e Now exporting entities to TB on build 2024-09-05 21:48:41 -04:00
Antoine Pilote
81b69749d9 Merge pull request #71 from antopilo/trenchbroom-path-project-settings
Added .project properties to Project Settings
2024-09-05 21:42:40 -04:00
emerycp
89971b2d77 Added .project properties to Project Settings 2024-09-05 21:37:55 -04:00
Antoine Pilote
43e9d6e7fc rip 2024-09-05 20:01:12 -04:00
Antoine Pilote
2c2ed94eea Fixed other mix shader fail casting 2024-09-05 20:00:19 -04:00
Antoine Pilote
120af20237 Fix outline shader for AMD cards 2024-09-05 19:54:21 -04:00
Antoine Pilote
422331dec2 Automatically refresh filebrowser on window focus, and preserve path after scanning 2024-09-05 19:44:27 -04:00
Antoine Pilote
9e05e6883a Forgot to include functional header 2024-09-05 19:09:45 -04:00
Antoine Pilote
73c927fdaf Added window callbacks for focused and closed 2024-09-05 19:07:48 -04:00
Antoine Pilote
5e3472c256 Fixed Coral crash with base type classes, temp fix for logs crash + added light color param to C# api 2024-09-05 00:52:55 -04:00
Antoine Pilote
732e94899c Added Physics.Raycast and Transform shortcut on entity objects 2024-09-04 22:26:59 -04:00
Antoine Pilote
ea97133e94 Bumped coral 2024-09-04 22:26:34 -04:00
Antoine Pilote
e1550fbff9 Forgot premake45 2024-09-04 21:05:14 -04:00
Antoine Pilote
780b95fba7 Removed line 2024-09-04 21:02:58 -04:00
Antoine Pilote
a2f28c4c86 Added AMD code path 2024-09-04 20:50:57 -04:00
Antoine Pilote
9c5f05f224 Fixed camera preview wrong translation + made it smaller 2024-09-04 20:45:32 -04:00
Antoine Pilote
e607b99191 Added preview window when selecting a camera in the scene 2024-09-04 20:31:43 -04:00
Antoine Pilote
e1813870a2 Fixedruntime refact 2024-09-04 16:38:52 -04:00
Antoine Pilote
ec9748ecd7 Removed old documentation 2024-09-04 01:09:35 -04:00
Antoine Pilote
7140d2b4ff Reverted ImUI namespace to avoir unresolved errors 2024-09-04 01:07:33 -04:00
Antoine Pilote
8c620be479 Fixed compilation errors 2024-09-04 01:02:05 -04:00
Antoine Pilote
10b8c862e7 Applying code standard new window, job, jobsystem and imui 2024-09-04 00:51:43 -04:00
Antoine Pilote
dc3c993962 Refactor pass #3 2024-09-04 00:33:05 -04:00
Antoine Pilote
db0ec40948 Moved project out of engine.h 2024-09-04 00:30:35 -04:00
Antoine Pilote
f650f0485b Forgot to change usage of SetcurrentScene 2024-09-04 00:30:11 -04:00
Antoine Pilote
156bf8c5cc Renamed LoadScene to SetCurrentScene 2024-09-04 00:16:37 -04:00
Antoine Pilote
87f58d890e Moved FileDialog into its own class 2024-09-04 00:14:00 -04:00
Antoine Pilote
c91812c65e Moved FileSystem stuff into seprate files and a FileSystem Folder 2024-09-03 23:49:22 -04:00
Antoine Pilote
db21f342b5 Attempt at fixing AMD Driver crash 2024-09-03 20:28:51 -04:00
Antoine Pilote
adb90b4f42 Fixed typo preventing setting game mode 2024-09-03 20:02:05 -04:00
Antoine Pilote
112718d1ac Removed pch 2024-09-03 19:32:00 -04:00
Antoine Pilote
aaf553f8ba Fixed wrong include 2024-09-03 19:31:07 -04:00
Antoine Pilote
db8ec0fbfd Merge branch 'develop' of https://github.com/antopilo/Nuake into develop 2024-09-03 18:48:10 -04:00
Antoine Pilote
1ac0337863 Refactor pass #1 2024-09-03 18:47:45 -04:00
Antoine Pilote
be725f52f2 Check if .map file exists 2024-09-03 16:41:52 -04:00
Antoine Pilote
55a2403b88 Merge branch 'develop' of https://github.com/antopilo/nuake into develop
# Conflicts:
#	Nuake/src/Rendering/Renderer.cpp
2024-09-03 12:40:19 -04:00
Antoine Pilote
54e5787472 Merge branch 'develop' of https://github.com/antopilo/Nuake into develop 2024-09-02 18:12:49 -04:00
Antoine Pilote
8aef2aaff9 Removed some empty line 2024-09-02 18:12:42 -04:00
Antoine Pilote
ced74170c5 Merge pull request #70 from WiggleWizard/feature/tracy
Tracy MVP integration
2024-09-02 18:12:15 -04:00
Antoine Pilote
000a1d564e Added base 2024-09-02 18:10:36 -04:00
Antoine Pilote
d9237f83d2 Added ground normal & ground velocity C# API e 2024-09-02 18:09:02 -04:00
WiggleWizard
5a801e642c Tracy MVP integration 2024-09-02 20:37:47 +01:00
Antoine Pilote
01000b9d13 Added float type and default values for trenchbroom integration 2024-09-02 14:05:59 -04:00
Antoine Pilote
d20847b4e3 Moved audio update last 2024-09-02 13:03:49 -04:00
Antoine Pilote
c7a1c10ff0 Removed spinning audio thread 2024-09-02 12:59:49 -04:00
Antoine Pilote
5077b1b7f8 Changed to only use 1 file watcher 2024-09-02 12:56:02 -04:00
Antoine Pilote
8f72f1711d Merge branch 'develop' of https://github.com/antopilo/Nuake into develop 2024-09-02 11:34:26 -04:00
Antoine Pilote
7af703b5fc Now scaling depth in viewport Depth mode and removed debug windows 2024-09-02 11:34:23 -04:00
Antoine Pilote
178ad898b9 Merge pull request #68 from WiggleWizard/develop
Initial module architecture
2024-09-02 11:30:52 -04:00
Antoine Pilote
63578ced2d Merge pull request #69 from WiggleWizard/refactor/buildassets
Removed build asset bash script in favor of a pure Lua version to make it easier to maintain and cross-platform
2024-09-02 11:30:16 -04:00
WiggleWizard
5971e4f2d6 Removed build asset bash script in favor of a pure Lua version to make it easier to maintain and cross-platform 2024-09-02 12:33:30 +01:00
WiggleWizard
67a1406e1b Fixed trailing comma missing in list within build script 2024-09-02 11:11:05 +01:00
WiggleWizard
bcf3e9751a Initial module architecture 2024-09-02 10:50:41 +01:00
Antoine Pilote
636736f567 Fixed a bug where bsp wouldnt get serialized properly + displaying brush in darker in scene hierarchy 2024-09-01 23:50:00 -04:00
Antoine Pilote
b7ee13c0eb Fixed crash when live reloading a map and a brush was selected 2024-09-01 23:18:51 -04:00
Antoine Pilote
d289c5431d Added live reloading for quake maps 2024-09-01 23:04:34 -04:00
Antoine Pilote
63712edc6d Added C# Point entities + automatic export of FGD entities 2024-09-01 19:37:05 -04:00
Antoine Pilote
f59a7e931f Now renders func brush materials correclty 2024-08-31 12:33:48 -04:00
Antoine Pilote
8aa41a1bf8 Now diplaying links between brushes 2024-08-31 00:07:45 -04:00
Antoine Pilote
05096355be Fixed spot light transformation 2024-08-29 12:54:31 -04:00
Antoine Pilote
c5563c204c Merge pull request #67 from antopilo/develop
Updated read me
2024-08-16 00:00:58 -04:00
386 changed files with 361632 additions and 328485 deletions

View File

@@ -1,59 +0,0 @@
#!/bin/bash
# Directory containing the files
input_directory="Resources"
# Output C++ header file for variable declarations
output_header="Nuake/src/Resource/StaticResources.h"
# Output C++ source file for data storage
output_source="Nuake/src/Resource/StaticResources.cpp"
# Remove existing header and source files (if any)
rm -f "$output_header" "$output_source"
# Create the C++ header file with an initial guard
echo "#ifndef FILES_DATA_H" >> "$output_header"
echo "#define FILES_DATA_H" >> "$output_header"
echo "#include <string> " >> "$output_header"
echo "namespace Nuake { " >> "$output_header"
echo " namespace StaticResources { " >> "$output_header"
# Create the C++ source file
echo "#include \"StaticResources.h\"" >> "$output_source"
echo "namespace Nuake { " >> "$output_source"
echo " namespace StaticResources { " >> "$output_source"
# Use find to search for files in the directory and its subdirectories
find "$input_directory" -type f -print0 | while IFS= read -r -d $'\0' file_path; do
# Get the relative path of the file within the input_directory
relative_path="${file_path/}"
# Sanitize the relative path to make it suitable for C++ variable names
sanitized_path="${relative_path//[^[:alnum:]_]/_}"
# Generate C++ variable declarations for file path and size
echo "extern const std::string ${sanitized_path}_path;" >> "$output_header"
echo "extern unsigned int ${sanitized_path}_len;" >> "$output_header"
echo "extern unsigned char ${sanitized_path}[];" >> "$output_header"
# Append C++ code to the source file for storing file data
echo -e "\n// Data for file: ${sanitized_path}_path" >> "$output_source"
echo "const std::string ${sanitized_path}_path = R\"(${relative_path})\";" >> "$output_source"
xxd -i "$file_path" | sed -e 's/^/ /' >> "$output_source"
done
echo " }" >> "$output_source"
echo "}">> "$output_source"
echo " }" >> "$output_header"
echo "}">> "$output_header"
# Close the header file guard
echo "#endif // FILES_DATA_H" >> "$output_header"
echo "Header file '$output_header' generated with variable declarations."
echo "Source file '$output_source' generated with file data."

1
.gitignore vendored
View File

@@ -864,3 +864,4 @@ Nuake/dependencies/glad/glad.vcxproj.filters
*.csproj
*.filters
cloc.exe
Nuake/src/Modules/Modules.cpp

27
.gitmodules vendored
View File

@@ -1,15 +1,6 @@
[submodule "Nuake/dependencies/glfw"]
path = Nuake/dependencies/glfw
url = https://github.com/glfw/glfw.git
[submodule "Nuake/dependencies/assimp"]
path = Nuake/dependencies/assimp
url = https://github.com/assimp/assimp.git
[submodule "Nuake/dependencies/bullet3"]
path = Nuake/dependencies/bullet3
url = https://github.com/bulletphysics/bullet3.git
[submodule "Nuake/dependencies/glew"]
path = Nuake/dependencies/glew
url = https://github.com/nigels-com/glew.git
[submodule "Nuake/dependencies/JoltPhysics"]
path = Nuake/dependencies/JoltPhysics
url = https://github.com/antopilo/JoltPhysics.git
@@ -22,3 +13,21 @@
[submodule "Nuake/dependencies/recastnavigation"]
path = Nuake/dependencies/recastnavigation
url = https://github.com/antopilo/recastnavigation.git
[submodule "Nuake/dependencies/tracy"]
path = Nuake/dependencies/tracy
url = https://github.com/wolfpld/tracy.git
[submodule "Nuake/dependencies/msdf-atlas-gen"]
path = Nuake/dependencies/msdf-atlas-gen
url = https://github.com/antopilo/msdf-atlas-gen.git
[submodule "Nuake/dependencies/yoga"]
path = Nuake/dependencies/yoga
url = https://github.com/facebook/yoga.git
[submodule "Nuake/dependencies/freetype"]
path = Nuake/dependencies/freetype
url = https://github.com/freetype/freetype.git
[submodule "Nuake/dependencies/entt"]
path = Nuake/dependencies/entt
url = https://github.com/skypjack/entt.git
[submodule "Nuake/dependencies/glfw"]
path = Nuake/dependencies/glfw
url = https://github.com/antopilo/glfw.git

View File

@@ -1,20 +0,0 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# Optionally build your docs in additional formats such as PDF
formats:
- pdf
# Optionally set the version of Python and requirements required to build your docs
python:
version: 3.7
#install:
#- requirements: docs/requirements.txt

View File

@@ -5,23 +5,19 @@
#include <src/Core/Input.h>
#include <src/Scene/Scene.h>
#include <src/Scene/Entities/Entity.h>
#include <src/Scene/Components/Components.h>
#include <src/Scene/Components.h>
#include "src/Windows/EditorInterface.h"
#include <src/Scene/Components/QuakeMap.h>
#include <src/Vendors/imgui/imgui.h>
#include <src/Vendors/imgui/ImGuizmo.h>
#include <src/Physics/PhysicsManager.h>
#include "src/Scene/Components/BoxCollider.h"
#include <GLFW/glfw3.h>
#include <src/Vendors/glm/trigonometric.hpp>
#include <src/Scripting/ScriptingEngine.h>
#include <src/Resource/FGD/FGDFile.h>
#include <src/Rendering/Shaders/ShaderManager.h>
#include <src/Rendering/Renderer.h>
#include <src/Scene/Components/BSPBrushComponent.h>
#include "src/Actions/EditorSelection.h"
#include "src/Misc/GizmoDrawer.h"
@@ -98,6 +94,13 @@ LaunchSettings ParseLaunchSettings(const std::vector<std::string>& arguments)
launchSettings.monitor = stoi(arguments[i + 1]);
}
}
else if (argumentSize == 2 && Nuake::FileSystem::FileExists(arg))
{
if (Nuake::String::EndsWith(arg, ".project"))
{
launchSettings.projectPath = arg;
}
}
i++;
}
@@ -116,11 +119,12 @@ Nuake::Application* Nuake::CreateApplication(int argc, char** argv)
ApplicationSpecification specification
{
.Name = "Editor",
.WindowWidth = 1100,
.WindowHeight = 630,
.WindowWidth = static_cast<uint32_t>(launchSettings.resolution.x),
.WindowHeight = static_cast<uint32_t>(launchSettings.resolution.y),
.VSync = true
};
#ifdef NK_DEBUG
specification.Name += "(DEBUG BUILD)";
#endif

View File

@@ -5,7 +5,7 @@
struct LaunchSettings
{
int32_t monitor = 1;
Nuake::Vector2 resolution = { 1920, 1080 };
Nuake::Vector2 resolution = { 1100, 630 };
std::string windowTitle = "Nuake Editor ";
std::string projectPath;
};

Binary file not shown.

View File

@@ -41,7 +41,6 @@ public:
EditorSelection(const Nuake::Entity& entity)
{
Type = EditorSelectionType::Entity;
Nuake::Engine::GetCurrentScene()->m_SceneRenderer->mOutlineEntityID = (uint32_t)entity.GetHandle();
Entity = entity;
}

View File

@@ -1,7 +1,10 @@
#include "Commands.h"
#include <Engine.h>
#include "src/Core/FileSystem.h"
#include "src/FileSystem/FileSystem.h"
#include <filesystem>
namespace NuakeEditor
{
@@ -39,6 +42,12 @@ namespace NuakeEditor
{
const std::string& cleanProjectName = String::Sanitize(mProject->Name);
const std::string& gameConfigFolderPath = mProject->TrenchbroomPath + "/../games/" + cleanProjectName + "/";
if (!FileSystem::DirectoryExists(gameConfigFolderPath))
{
FileSystem::MakeDirectory(gameConfigFolderPath, true);
}
const std::string& gameConfigFilePath = gameConfigFolderPath + "GameConfig.cfg";
FileSystem::BeginWriteFile(gameConfigFilePath, true);
@@ -56,7 +65,7 @@ namespace NuakeEditor
"packageformat": { "extension": ".zip", "format": "zip" }
},
"textures": {
"root": "textures",
"root": "Textures",
"extensions": [ ".jpg", ".png", ".tga" ]
},
"entities": {
@@ -69,8 +78,8 @@ namespace NuakeEditor
"name": "Trigger",
"attribs": [ "transparent" ],
"match": "classname",
"pattern": "trigger_*",
"texture": "trigger"
"pattern": "Trigger*",
"texture": "trigger.png"
}
],
"brushface": [
@@ -135,7 +144,7 @@ namespace NuakeEditor
// Copy Icon.png
if (FileSystem::FileExists("icon.png"))
{
std::filesystem::copy_file(FileSystem::RelativeToAbsolute("icon.png"), gameConfigFolderPath + "Icon.png");
std::filesystem::copy_file(FileSystem::RelativeToAbsolute("icon.png"), gameConfigFolderPath + "Icon.png", std::filesystem::copy_options::overwrite_existing);
}
return true;
}

View File

@@ -1,147 +0,0 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Core/FileSystem.h>
#include <src/Core/Maths.h>
#include <src/Scene/Components/AudioEmitterComponent.h>
#include <src/Scene/Entities/ImGuiHelper.h>
class AudioEmitterPanel : ComponentPanel
{
public:
AudioEmitterPanel() = default;
~AudioEmitterPanel() = default;
void Draw(Nuake::Entity entity) override
{
using namespace Nuake;
if (!entity.HasComponent<AudioEmitterComponent>())
return;
auto& component = entity.GetComponent<AudioEmitterComponent>();
BeginComponentTable(AUDIO EMITTER, AudioEmitterComponent);
{
{
ImGui::Text("Audio File");
ImGui::TableNextColumn();
std::string path = component.FilePath;
ImGui::Button(component.FilePath.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0));
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_AudioFile"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 256);
path = Nuake::FileSystem::AbsoluteToRelative(fullPath);
component.FilePath = path;
}
ImGui::EndDragDropTarget();
}
ImGui::TableNextColumn();
ComponentTableReset(component.FilePath, "");
}
ImGui::TableNextColumn();
{
ImGui::Text("Playing");
ImGui::TableNextColumn();
UI::ToggleButton("##Player", &component.IsPlaying);
//ImGui::Checkbox("##Playing", &component.IsPlaying);
ImGui::TableNextColumn();
ComponentTableReset(component.IsPlaying, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Loop");
ImGui::TableNextColumn();
ImGui::Checkbox("##Loop", &component.Loop);
ImGui::TableNextColumn();
ComponentTableReset(component.Loop, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Volume");
ImGui::TableNextColumn();
ImGui::DragFloat("##Volume", &component.Volume, 0.001f, 0.0f, 2.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.Volume, 1.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Playback Speed");
ImGui::TableNextColumn();
ImGui::DragFloat("##PlaybackSpeed", &component.PlaybackSpeed, 0.01f, 0.0001f);
ImGui::TableNextColumn();
ComponentTableReset(component.PlaybackSpeed, 1.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Pan");
ImGui::TableNextColumn();
ImGui::DragFloat("##Pan", &component.Pan, 0.01f, -1.0f, 1.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.Pan, 0.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Spatialized");
ImGui::TableNextColumn();
ImGui::Checkbox("##Spatialized", &component.Spatialized);
ImGui::TableNextColumn();
ComponentTableReset(component.Spatialized, false);
}
if (component.Spatialized)
{
ImGui::TableNextColumn();
{
ImGui::Text("Min Distance");
ImGui::TableNextColumn();
ImGui::DragFloat("##minDistance", &component.MinDistance, 0.001f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.MinDistance, 1.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Max Distance");
ImGui::TableNextColumn();
ImGui::DragFloat("##maxDistance", &component.MaxDistance, 0.001f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.MaxDistance, 10.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Attenuation Factor");
ImGui::TableNextColumn();
ImGui::DragFloat("##attenuationFactor", &component.AttenuationFactor, 0.001f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.AttenuationFactor, 1.0f);
}
}
}
EndComponentTable();
}
};

View File

@@ -1,24 +1,25 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Core/FileSystem.h>
#include "src/FileSystem/FileSystem.h"
#include <src/Core/Maths.h>
#include <src/Scene/Components/BoneComponent.h>
#include <src/Scene/Entities/ImGuiHelper.h>
class BonePanel : ComponentPanel
class BonePanel
{
public:
BonePanel() {}
void Draw(Nuake::Entity entity) override
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
if (!entity.HasComponent<BoneComponent>())
Nuake::BoneComponent* componentPtr = componentInstance.try_cast<Nuake::BoneComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::BoneComponent& component = *componentPtr;
auto& component = entity.GetComponent<BoneComponent>();
BeginComponentTable(BONE, BoneComponent);
{
{

View File

@@ -1,7 +1,7 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Core/FileSystem.h>
#include "src/FileSystem/FileSystem.h"
#include <src/Core/Maths.h>
#include <src/Scene/Components/BoxCollider.h>
#include <src/Scene/Entities/ImGuiHelper.h>

View File

@@ -1,19 +1,22 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Scene/Components/CameraComponent.h>
#include <src/Core/FileSystem.h>
#include "src/FileSystem/FileSystem.h"
class CameraPanel : ComponentPanel {
class CameraPanel {
public:
CameraPanel() {}
void Draw(Nuake::Entity entity) override
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
if (!entity.HasComponent<Nuake::CameraComponent>())
return;
using namespace Nuake;
Nuake::CameraComponent* componentPtr = componentInstance.try_cast<Nuake::CameraComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::CameraComponent& component = *componentPtr;
auto& component = entity.GetComponent<Nuake::CameraComponent>();
BeginComponentTable(CAMERA, Nuake::CameraComponent);
{
{

View File

@@ -3,48 +3,47 @@
#include <src/Scene/Components/CapsuleColliderComponent.h>
class CapsuleColliderPanel : ComponentPanel
class CapsuleColliderPanel
{
public:
CapsuleColliderPanel() = default;
void Draw(Nuake::Entity entity) override
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
if (!entity.HasComponent<CapsuleColliderComponent>())
Nuake::CapsuleColliderComponent* componentPtr = componentInstance.try_cast<Nuake::CapsuleColliderComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::CapsuleColliderComponent& component = *componentPtr;
auto& [Capsule, Radius, Height, IsTrigger] = entity.GetComponent<CapsuleColliderComponent>();
BeginComponentTable(CAPSULE COLLIDER, CapsuleColliderComponent)
{
{
ImGui::Text("Radius");
ImGui::TableNextColumn();
ImGui::DragFloat("##Radius", &Radius, 0.01f, 0.001f);
Radius = std::max(Radius, 0.001f);
ImGui::DragFloat("##Radius", &component.Radius, 0.01f, 0.001f);
component.Radius = std::max(component.Radius, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(Radius, 0.5f)
ComponentTableReset(component.Radius, 0.5f)
}
ImGui::TableNextColumn();
{
ImGui::Text("Height");
ImGui::TableNextColumn();
ImGui::DragFloat("##Height", &Height, 0.01f, 0.001f);
Height = std::max(Height, 0.001f);
ImGui::DragFloat("##Height", &component.Height, 0.01f, 0.001f);
component.Height = std::max(component.Height, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(Height, 1.0f)
ComponentTableReset(component.Height, 1.0f)
}
ImGui::TableNextColumn();
{
ImGui::Text("Is Trigger");
ImGui::TableNextColumn();
ImGui::Checkbox("##isTrigger", &IsTrigger);
ImGui::Checkbox("##isTrigger", &component.IsTrigger);
ImGui::TableNextColumn();
ComponentTableReset(IsTrigger, false);
ComponentTableReset(component.IsTrigger, false);
}
}
EndComponentTable()

View File

@@ -1,20 +1,22 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Scene/Components/CharacterControllerComponent.h>
#include <src/Core/FileSystem.h>
class CharacterControllerPanel : ComponentPanel {
#include "src/FileSystem/FileSystem.h"
class CharacterControllerPanel
{
public:
CharacterControllerPanel() {}
void Draw(Nuake::Entity entity) override
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
if (!entity.HasComponent<Nuake::CharacterControllerComponent>())
return;
using namespace Nuake;
auto& component = entity.GetComponent<Nuake::CharacterControllerComponent>();
Nuake::CharacterControllerComponent* componentPtr = componentInstance.try_cast<Nuake::CharacterControllerComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::CharacterControllerComponent& component = *componentPtr;
BeginComponentTable(CHARACTER CONTROLLER, Nuake::CharacterControllerComponent);
{
{
@@ -50,7 +52,7 @@ public:
{
ImGui::Text("Stick to floor step down");
ImGui::TableNextColumn();
ImGui::DragFloat("##StickToFloorStepDown", &component.StickToFloorStepDown.y, -10.0f, 0.01, 0.0f);
ImGui::DragFloat("##StickToFloorStepDown", &component.StickToFloorStepDown.y, -10.0f, 0.01f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.StickToFloorStepDown.y, -0.5f);
}
@@ -58,7 +60,7 @@ public:
{
ImGui::Text("Step down extra");
ImGui::TableNextColumn();
ImGui::DragFloat("##StepDownExtra", &component.StepDownExtra.y, -10.0f, 0.01, 0.0f);
ImGui::DragFloat("##StepDownExtra", &component.StepDownExtra.y, -10.0f, 0.01f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.StepDownExtra.y, 0.0f);
}
@@ -66,7 +68,7 @@ public:
{
ImGui::Text("Step up");
ImGui::TableNextColumn();
ImGui::DragFloat("##StepUp", &component.SteppingStepUp.y, 0.0f, 0.01, 10.0f);
ImGui::DragFloat("##StepUp", &component.SteppingStepUp.y, 0.0f, 0.01f, 10.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.SteppingStepUp.y, 0.4f);
}

View File

@@ -26,7 +26,7 @@ ImGui::Text(##name);
bool removed = false; \
bool headerOpened = ImGui::CollapsingHeader(#name, ImGuiTreeNodeFlags_DefaultOpen); \
ImGui::PopStyleVar(); \
if (#name != "TRANSFORM" && ImGui::BeginPopupContextItem()) \
if (strcmp(#name, "TRANSFORM") != 0 && ImGui::BeginPopupContextItem()) \
{ \
if (ImGui::Selectable("Remove")) { removed = true; } \
ImGui::EndPopup(); \
@@ -93,5 +93,7 @@ ImGui::Text(##name);
class ComponentPanel {
public:
virtual void Draw(Nuake::Entity entity) = 0;
virtual void Draw(Nuake::Entity entity);
};
inline void ComponentPanel::Draw(Nuake::Entity entity) {}

View File

@@ -3,48 +3,47 @@
#include <src/Scene/Components/CylinderColliderComponent.h>
class CylinderColliderPanel : ComponentPanel
class CylinderColliderPanel
{
public:
CylinderColliderPanel() = default;
void Draw(Nuake::Entity entity) override
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
if (!entity.HasComponent<CylinderColliderComponent>())
Nuake::CylinderColliderComponent* componentPtr = componentInstance.try_cast<Nuake::CylinderColliderComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::CylinderColliderComponent& component = *componentPtr;
auto& [Cylinder, Radius, Height, IsTrigger] = entity.GetComponent<CylinderColliderComponent>();
BeginComponentTable(CYLINDER COLLIDER, CylinderColliderComponent)
{
{
ImGui::Text("Radius");
ImGui::TableNextColumn();
ImGui::DragFloat("##Radius", &Radius, 0.01f, 0.001f);
Radius = std::max(Radius, 0.001f);
ImGui::DragFloat("##Radius", &component.Radius, 0.01f, 0.001f);
component.Radius = std::max(component.Radius, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(Radius, 0.5f)
ComponentTableReset(component.Radius, 0.5f)
}
ImGui::TableNextColumn();
{
ImGui::Text("Height");
ImGui::TableNextColumn();
ImGui::DragFloat("##Height", &Height, 0.01f, 0.0001f);
Height = std::max(Height, 0.001f);
ImGui::DragFloat("##Height", &component.Height, 0.01f, 0.0001f);
component.Height = std::max(component.Height, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(Height, 1.0f)
ComponentTableReset(component.Height, 1.0f)
}
ImGui::TableNextColumn();
{
ImGui::Text("Is Trigger");
ImGui::TableNextColumn();
ImGui::Checkbox("##isTrigger", &IsTrigger);
ImGui::Checkbox("##isTrigger", &component.IsTrigger);
ImGui::TableNextColumn();
ComponentTableReset(IsTrigger, false);
ComponentTableReset(component.IsTrigger, false);
}
}
EndComponentTable()

View File

@@ -2,17 +2,18 @@
#include "ComponentPanel.h"
#include "src/Scene/Components/LightComponent.h"
class LightPanel :ComponentPanel {
class LightPanel
{
public:
LightPanel() { }
void Draw(Nuake::Entity entity) override
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
Nuake::LightComponent* componentPtr = componentInstance.try_cast<Nuake::LightComponent>();
if (componentPtr == nullptr)
{
if (!entity.HasComponent<Nuake::LightComponent>())
return;
Nuake::LightComponent& component = entity.GetComponent<Nuake::LightComponent>();
}
Nuake::LightComponent& component = *componentPtr;
BeginComponentTable(LIGHT, Nuake::LightComponent);
{

View File

@@ -1,9 +1,12 @@
#include "MaterialEditor.h"
#include <imgui/imgui.h>
#include <src/Resource/FontAwesome5.h>
#include <src/Vendors/imgui/imgui_internal.h>
#include "../Misc/InterfaceFonts.h"
#include <src/Resource/FontAwesome5.h>
#include <src/Resource/ResourceManager.h>
#include <src/FileSystem/FileDialog.h>
#include <imgui/imgui.h>
#include <src/Vendors/imgui/imgui_internal.h>
void MaterialEditor::Draw(Ref<Nuake::Material> material)
{

View File

@@ -9,23 +9,25 @@
#include <src/Resource/ResourceLoader.h>
#include <src/Core/String.h>
class MeshColliderPanel : ComponentPanel {
private:
Scope<ModelResourceInspector> _modelInspector;
bool _expanded = false;
class MeshColliderPanel : ComponentPanel
{
public:
MeshColliderPanel()
{
CreateScope<ModelResourceInspector>();
}
void Draw(Nuake::Entity entity) override
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
if (!entity.HasComponent<MeshColliderComponent>())
return;
MeshColliderComponent& component = entity.GetComponent<MeshColliderComponent>();
Nuake::MeshColliderComponent* componentPtr = componentInstance.try_cast<Nuake::MeshColliderComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::MeshColliderComponent& component = *componentPtr;
BeginComponentTable(MESH, MeshColliderComponent);
{
ImGui::Text("Model");

View File

@@ -8,6 +8,8 @@
#include <src/Scene/Components/ModelComponent.h>
#include <src/Resource/ResourceLoader.h>
#include <src/Resource/ResourceManager.h>
#include <src/Core/String.h>
#include <src/Resource/ModelLoader.h>
@@ -24,13 +26,17 @@ public:
CreateScope<ModelResourceInspector>();
}
void Draw(Nuake::Entity entity) override
void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
if (!entity.HasComponent<ModelComponent>())
return;
ModelComponent& component = entity.GetComponent<ModelComponent>();
Nuake::ModelComponent* componentPtr = componentInstance.try_cast<Nuake::ModelComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::ModelComponent& component = *componentPtr;
BeginComponentTable(MESH, ModelComponent);
{
ImGui::Text("Model");

View File

@@ -3,24 +3,25 @@
#include <src/Scene/Entities/ImGuiHelper.h>
#include <src/Scene/Components/NavMeshVolumeComponent.h>
#include "src/AI/NavManager.h"
#include "src/Scene/Components/QuakeMap.h"
#include <src/Core/Maths.h>
#include <src/AI/RecastConfig.h>
class NavMeshVolumePanel : ComponentPanel {
class NavMeshVolumePanel
{
public:
NavMeshVolumePanel() {}
void Draw(Nuake::Entity entity) override
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
if (!entity.HasComponent<NavMeshVolumeComponent>())
Nuake::NavMeshVolumeComponent* componentPtr = componentInstance.try_cast<Nuake::NavMeshVolumeComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::NavMeshVolumeComponent& component = *componentPtr;
auto& component = entity.GetComponent<NavMeshVolumeComponent>();
BeginComponentTable(NAVMESH VOLUME, NavMeshVolumeComponent);
{
{

View File

@@ -1,16 +1,57 @@
#include "NetScriptPanel.h"
#include "../Windows/FileSystemUI.h"
#include <src/Scene/Components/NetScriptComponent.h>
#include <src/Core/FileSystem.h>
#include <src/FileSystem/FileDialog.h>
#include "src/FileSystem/FileSystem.h"
#include <src/Scripting/ScriptingEngineNet.h>
#include <src/Scene/Components/NetScriptComponent.h>
#include <src/Scene/Entities/ImGuiHelper.h>
void NetScriptPanel::Draw(Nuake::Entity entity)
{
if (!entity.HasComponent<Nuake::NetScriptComponent>())
return;
const std::string NET_TEMPLATE_SCRIPT_FIRST = R"(using Nuake.Net;
namespace NuakeShowcase
{
class )";
const std::string NET_TEMPLATE_SCRIPT_SECOND = R"( : Entity
{
public override void OnInit()
{
// Called once at the start of the game
}
public override void OnUpdate(float dt)
{
// Called every frame
}
public override void OnFixedUpdate(float dt)
{
// Called every fixed update
}
public override void OnDestroy()
{
// Called at the end of the game fixed update
}
}
}
)";
void NetScriptPanel::Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
Nuake::NetScriptComponent* componentPtr = componentInstance.try_cast<Nuake::NetScriptComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::NetScriptComponent& component = *componentPtr;
auto& component = entity.GetComponent<Nuake::NetScriptComponent>();
BeginComponentTable(.NETSCRIPT, Nuake::NetScriptComponent);
{
{
@@ -130,6 +171,11 @@ void NetScriptPanel::Draw(Nuake::Entity entity)
{
if (!field.Value.has_value())
{
if (!field.DefaultValue.has_value())
{
field.DefaultValue = 0.0f;
}
field.Value = field.DefaultValue;
}
@@ -143,6 +189,11 @@ void NetScriptPanel::Draw(Nuake::Entity entity)
{
if (!field.Value.has_value())
{
if (!field.DefaultValue.has_value())
{
field.DefaultValue = 0.0;
}
field.Value = field.DefaultValue;
}
@@ -156,14 +207,23 @@ void NetScriptPanel::Draw(Nuake::Entity entity)
{
if (!field.Value.has_value())
{
if (!field.DefaultValue.has_value())
{
field.DefaultValue = false;
}
field.Value = field.DefaultValue;
}
auto typeName = field.Value.type().name();
if (typeName == std::string("bool"))
{
bool currentValue = std::any_cast<bool>(field.Value);
const std::string sliderName = "##" + field.Name + "slider";
ImGui::Checkbox(sliderName.c_str(), &currentValue);
field.Value = currentValue;
}
}
if (field.Type == Nuake::NetScriptExposedVarType::String)
{
@@ -188,6 +248,11 @@ void NetScriptPanel::Draw(Nuake::Entity entity)
{
if (!field.Value.has_value())
{
if (!field.DefaultValue.has_value())
{
field.DefaultValue = Nuake::Vector2(0, 0);
}
field.Value = field.DefaultValue;
}
@@ -203,6 +268,11 @@ void NetScriptPanel::Draw(Nuake::Entity entity)
{
if (!field.Value.has_value())
{
if (!field.DefaultValue.has_value())
{
field.DefaultValue = Nuake::Vector3(0, 0, 0);
}
field.Value = field.DefaultValue;
}

View File

@@ -1,45 +1,9 @@
#pragma once
#include "ComponentPanel.h"
const std::string NET_TEMPLATE_SCRIPT_FIRST = R"(using Nuake.Net;
namespace NuakeShowcase
class NetScriptPanel
{
class )";
const std::string NET_TEMPLATE_SCRIPT_SECOND = R"( : Entity
{
public override void OnInit()
{
// Called once at the start of the game
}
public override void OnUpdate(float dt)
{
// Called every frame
}
public override void OnFixedUpdate(float dt)
{
// Called every fixed update
}
public override void OnDestroy()
{
// Called at the end of the game fixed update
}
}
}
)";
class NetScriptPanel : ComponentPanel {
public:
NetScriptPanel() {}
void Draw(Nuake::Entity entity) override;
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance);
};

View File

@@ -1,155 +0,0 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Core/FileSystem.h>
#include <src/Core/Maths.h>
#include <src/Scene/Components/ParticleEmitterComponent.h>
#include <src/Scene/Entities/ImGuiHelper.h>
#include "MaterialEditor.h"
#include <src/Resource/ResourceLoader.h>
#include <src/Resource/ResourceLoader.h>
class ParticleEmitterPanel : ComponentPanel
{
public:
Scope<ModelResourceInspector> _modelInspector;
ParticleEmitterPanel() {}
void Draw(Nuake::Entity entity) override
{
if (!entity.HasComponent<Nuake::ParticleEmitterComponent>())
return;
auto& component = entity.GetComponent<Nuake::ParticleEmitterComponent>();
BeginComponentTable(PARTICLE EMITTER, Nuake::ParticleEmitterComponent);
{
{
ImGui::Text("Particle Material");
ImGui::TableNextColumn();
std::string label = "Empty";
if (component.ParticleMaterial && !component.ParticleMaterial->Path.empty())
{
label = component.ParticleMaterial->Path;
}
if (ImGui::Button(label.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0)))
{
}
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Material"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 256);
fullPath = Nuake::FileSystem::AbsoluteToRelative(fullPath);
Ref<Nuake::Material> material = Nuake::ResourceLoader::LoadMaterial(fullPath);
component.ParticleMaterial = material;
}
ImGui::EndDragDropTarget();
}
//std::string childId = "materialEditorParticle";
//ImGui::BeginChild(childId.c_str(), ImVec2(0, 0), false);
//{
// MaterialEditor editor;
// editor.Draw(component.ParticleMaterial);
//}
//ImGui::EndChild();
ImGui::TableNextColumn();
//ComponentTableReset(component.ParticleColor, Nuake::Vector4(1, 1, 1, 1));
}
ImGui::TableNextColumn();
{
ImGui::Text("Amount");
ImGui::TableNextColumn();
ImGui::DragFloat("##ParticleAmount", &component.Amount, 0.1f, 0.0f, 500.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.Amount, 10.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Particle Scale");
ImGui::TableNextColumn();
ImGuiHelper::DrawVec3("##particleSize", &component.ParticleScale);
ImGui::TableNextColumn();
ComponentTableReset(component.ParticleScale, Nuake::Vector3(0.1, 0.1, 0.1));
}
ImGui::TableNextColumn();
{
ImGui::Text("Particle Scale Random");
ImGui::TableNextColumn();
ImGui::DragFloat("##particleSizeRandom", &component.ScaleRandomness, 0.01f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.ScaleRandomness, 0.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Global Space");
ImGui::TableNextColumn();
ImGui::Checkbox("##globalSpace", &component.GlobalSpace);
ImGui::TableNextColumn();
ComponentTableReset(component.GlobalSpace, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Rate");
ImGui::TableNextColumn();
ImGui::DragFloat("##ParticleRate", &component.Rate, 0.1f, 0.0f, 10.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.Rate, 0.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Life");
ImGui::TableNextColumn();
ImGui::DragFloat("##ParticleLife", &component.Life, 0.1f, 0.0f, 100.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.Life, 5.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Gravity");
ImGui::TableNextColumn();
ImGuiHelper::DrawVec3("Gravity", &component.Gravity);
ImGui::TableNextColumn();
ComponentTableReset(component.Gravity, Nuake::Vector3(0, -1, 0));
}
ImGui::TableNextColumn();
{
ImGui::Text("Gravity Random");
ImGui::TableNextColumn();
ImGui::DragFloat("##GravityRandom", &component.GravityRandom, 0.01f, 0.0f, 1.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.GravityRandom, 0.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Radius");
ImGui::TableNextColumn();
ImGui::DragFloat("##ParticleRadius", &component.Radius, 0.01f, 0.0f, 10.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.Radius, 1.0f);
}
}
EndComponentTable();
}
};

View File

@@ -1,79 +0,0 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Scene/Components/QuakeMap.h>
#include "src/Scene/Systems/QuakeMapBuilder.h"
#include <src/Core/FileSystem.h>
#include <src/AI/NavManager.h>
#include <src/UI/ImUI.h>
class QuakeMapPanel : ComponentPanel {
public:
QuakeMapPanel() {}
void Draw(Nuake::Entity entity) override
{
using namespace Nuake;
if (!entity.HasComponent<Nuake::QuakeMapComponent>())
return;
Nuake::QuakeMapComponent& component = entity.GetComponent<Nuake::QuakeMapComponent>();
BeginComponentTable(QUAKEMAP, Nuake::QuakeMapComponent);
{
{
ImGui::Text("Map");
ImGui::TableNextColumn();
std::string path = component.Path;
ImGui::Button(component.Path.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0));
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Map"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 256);
path = Nuake::FileSystem::AbsoluteToRelative(fullPath);
component.Path = path;
}
ImGui::EndDragDropTarget();
}
ImGui::TableNextColumn();
ComponentTableReset(component.Path, "");
}
ImGui::TableNextColumn();
{
ImGui::Text("Collision");
ImGui::TableNextColumn();
ImGui::Checkbox("##Collison", &component.HasCollisions);
ImGui::TableNextColumn();
ComponentTableReset(component.HasCollisions, true);
}
ImGui::TableNextColumn();
{
ImGui::Text("Auto Rebuild");
ImGui::TableNextColumn();
ImGui::Checkbox("##AutoRebuild", &component.AutoRebuild);
ImGui::TableNextColumn();
ComponentTableReset(component.AutoRebuild, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Build");
ImGui::TableNextColumn();
if (UI::SecondaryButton("Build Geometry"))
{
Nuake::QuakeMapBuilder builder;
builder.BuildQuakeMap(entity, component.HasCollisions);
}
}
}
EndComponentTable();
}
};

View File

@@ -1,62 +0,0 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Scene/Components/RigidbodyComponent.h>
#include <src/Core/FileSystem.h>
class RigidbodyPanel : ComponentPanel {
public:
RigidbodyPanel() {}
void Draw(Nuake::Entity entity) override
{
if (!entity.HasComponent<Nuake::RigidBodyComponent>())
return;
auto& component = entity.GetComponent<Nuake::RigidBodyComponent>();
BeginComponentTable(RIGIDBODY, Nuake::RigidBodyComponent);
{
{
ImGui::Text("Mass");
ImGui::TableNextColumn();
ImGui::DragFloat("##Mass", &component.Mass, 0.01f, 0.1f);
component.Mass = std::max(component.Mass, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.Mass, 0.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Lock X axis");
ImGui::TableNextColumn();
ImGui::Checkbox("##lockx", &component.LockX);
ImGui::TableNextColumn();
ComponentTableReset(component.LockX, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Lock Y axis");
ImGui::TableNextColumn();
ImGui::Checkbox("##locky", &component.LockY);
ImGui::TableNextColumn();
ComponentTableReset(component.LockY, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Lock Z axis");
ImGui::TableNextColumn();
ImGui::Checkbox("##lockz", &component.LockZ);
ImGui::TableNextColumn();
ComponentTableReset(component.LockZ, false);
}
ImGui::TableNextColumn();
}
EndComponentTable();
}
};

View File

@@ -1,114 +0,0 @@
#include "ScriptPanel.h"
#include "../Windows/FileSystemUI.h"
#include <src/Scene/Components/WrenScriptComponent.h>
#include <src/Core/FileSystem.h>
void ScriptPanel::Draw(Nuake::Entity entity)
{
if (!entity.HasComponent<Nuake::WrenScriptComponent>())
return;
Nuake::WrenScriptComponent& component = entity.GetComponent<Nuake::WrenScriptComponent>();
BeginComponentTable(SCRIPT, Nuake::WrenScriptComponent);
{
{
ImGui::Text("Script");
ImGui::TableNextColumn();
std::string path = component.Script;
ImGui::Button( path.empty() ? "Create New" : component.Script.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0));
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 512);
path = Nuake::FileSystem::AbsoluteToRelative(std::move(fullPath));
component.LoadScript(path);
}
ImGui::EndDragDropTarget();
}
component.Script = path;
// Double click on file
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0))
{
if(!component.Script.empty())
{
if (component.mWrenScript)
{
Nuake::OS::OpenIn(component.mWrenScript->GetFile()->GetAbsolutePath());
}
}
else
{
// TODO: Turn into command (Undo/Redo)
std::string pathCreation = Nuake::FileDialog::SaveFile("*.wren");
if (!pathCreation.empty())
{
if (!Nuake::String::EndsWith(pathCreation, ".wren"))
{
pathCreation += ".wren";
}
std::string fileName = Nuake::String::ToUpper(Nuake::FileSystem::GetFileNameFromPath(pathCreation));
fileName = Nuake::String::RemoveWhiteSpace(fileName);
if(!Nuake::String::IsDigit(fileName[0]))
{
Nuake::FileSystem::BeginWriteFile(pathCreation);
Nuake::FileSystem::WriteLine(TEMPLATE_SCRIPT_FIRST + fileName + TEMPLATE_SCRIPT_SECOND);
Nuake::FileSystem::EndWriteFile();
path = Nuake::FileSystem::AbsoluteToRelative(pathCreation);
Nuake::FileSystem::Scan();
Nuake::FileSystemUI::m_CurrentDirectory = Nuake::FileSystem::RootDirectory;
component.LoadScript(path);
component.Script = path;
}
else
{
Nuake::Logger::Log("Cannot create script files that starts with a number.","fileSystem", Nuake::CRITICAL);
}
}
}
}
ImGui::TableNextColumn();
ComponentTableReset(component.Script, "");
}
ImGui::TableNextColumn();
{
ImGui::Text("Module");
ImGui::TableNextColumn();
// Here we create a dropdown for every modules
auto& wrenScript = component.mWrenScript;
if (wrenScript)
{
auto modules = wrenScript->GetModules();
std::vector<const char*> modulesC;
for (auto& m : modules)
{
modulesC.push_back(m.c_str());
}
static int currentModule = (int)component.mModule;
ImGui::Combo("##WrenModule", &currentModule, &modulesC[0], modules.size());
component.mModule = currentModule;
}
ImGui::TableNextColumn();
//ComponentTableReset(component.Class, "");
}
}
EndComponentTable();
}

View File

@@ -1,43 +0,0 @@
#pragma once
#include "ComponentPanel.h"
const std::string TEMPLATE_SCRIPT_FIRST = R"(import "Nuake:Engine" for Engine
import "Nuake:ScriptableEntity" for ScriptableEntity
import "Nuake:Input" for Input
import "Nuake:Math" for Vector3, Math
import "Nuake:Scene" for Scene
class )";
const std::string TEMPLATE_SCRIPT_SECOND = R"( is ScriptableEntity {
construct new() {
}
// Called when the scene gets initialized
init() {
// Engine.Log("Hello World!")
}
// Called every update
update(ts) {
}
// Called 90 times per second
fixedUpdate(ts) {
}
// Called on shutdown
exit() {
}
}
)";
class ScriptPanel : ComponentPanel {
public:
ScriptPanel() {}
void Draw(Nuake::Entity entity) override;
};

View File

@@ -0,0 +1,132 @@
#pragma once
#include <src/Core/Core.h>
#include "ComponentPanel.h"
#include "ModelResourceInspector.h"
#include "../Misc/PopupHelper.h"
#include <src/Scene/Entities/ImGuiHelper.h>
#include <src/Scene/Components/SkinnedModelComponent.h>
#include <src/Resource/ResourceLoader.h>
#include <src/Resource/ResourceManager.h>
#include <src/Core/String.h>
#include <src/Resource/ModelLoader.h>
class SkinnedMeshPanel : ComponentPanel
{
private:
Scope<ModelResourceInspector> _modelInspector;
bool _expanded = false;
std::string _importedPathMesh;
public:
SkinnedMeshPanel()
{
CreateScope<ModelResourceInspector>();
}
void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
Nuake::SkinnedModelComponent* componentPtr = componentInstance.try_cast<Nuake::SkinnedModelComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::SkinnedModelComponent& component = *componentPtr;
BeginComponentTable(SKINNED MESH, SkinnedModelComponent);
{
ImGui::Text("Model");
ImGui::TableNextColumn();
std::string label = "None";
const bool isModelNone = component.ModelResource == nullptr;
if (!isModelNone)
{
label = std::to_string(component.ModelResource->ID);
}
if (ImGui::Button(label.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0)))
{
if (!isModelNone)
{
if (!_expanded)
{
//_modelInspector = CreateScope<ModelResourceInspector>(component.ModelResource);
}
_expanded = !_expanded;
}
}
if (_expanded)
{
//_modelInspector->Draw();
}
bool shouldConvert = false;
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Model"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 256);
fullPath = Nuake::FileSystem::AbsoluteToRelative(fullPath);
if (Nuake::String::EndsWith(fullPath, ".mesh"))
{
//component.ModelPath = fullPath;
//component.ModelResource = ResourceLoader::LoadModel(fullPath);
}
else
{
// Convert to .Model
Ref<Nuake::File> resourceFile = FileSystem::GetFile(fullPath);
component.ModelPath = resourceFile;
component.LoadModel((entt::entity)entity.GetHandle(), entity.GetScene());
_importedPathMesh = fullPath;
auto loader = ModelLoader();
auto modelResource = loader.LoadModel(fullPath);
shouldConvert = true;
}
}
ImGui::EndDragDropTarget();
}
//if (PopupHelper::DefineConfirmationDialog("##ConvertAsset", "Convert Asset"))
//{
// // Convert to disk
// auto loader = ModelLoader();
// Ref<Model> modelResource = loader.LoadModel(_importedPathMesh);
// json serializedData = modelResource->SerializeData();
// const std::string exportedMeshPath = _importedPathMesh + ".mesh";
// FileSystem::BeginWriteFile(exportedMeshPath);
// FileSystem::WriteLine(serializedData.dump());
// FileSystem::EndWriteFile();
// ResourceManager::RegisterResource(modelResource);
// // Update component
// component.ModelPath = exportedMeshPath;
// component.ModelResource = modelResource;
//}
//if (shouldConvert)
//{
// PopupHelper::OpenPopup("##ConvertAsset");
//}
ImGui::TableNextColumn();
//ComponentTableReset(component.ModelPath, "");
}
EndComponentTable();
}
};

View File

@@ -1,172 +0,0 @@
#pragma once
#include <src/Core/Core.h>
#include "ComponentPanel.h"
#include "ModelResourceInspector.h"
#include <src/Scene/Entities/ImGuiHelper.h>
#include <src/Scene/Components/SkinnedModelComponent.h>
#include <src/Resource/ResourceLoader.h>
#include <src/Core/String.h>
class SkinnedModelPanel : ComponentPanel
{
private:
Scope<ModelResourceInspector> m_ModelInspector;
bool m_Expanded = false;
std::string m_QueuedModelPath;
public:
SkinnedModelPanel()
{
CreateScope<ModelResourceInspector>();
}
void Draw(Nuake::Entity entity) override
{
using namespace Nuake;
if (!entity.HasComponent<SkinnedModelComponent>())
return;
SkinnedModelComponent& component = entity.GetComponent<SkinnedModelComponent>();
BeginComponentTable(SKINNED MESH, SkinnedModelComponent);
{
ImGui::Text("Model");
ImGui::TableNextColumn();
std::string label = "None";
const bool isModelNone = component.ModelResource == nullptr;
if (!isModelNone)
{
label = std::to_string(component.ModelResource->ID);
}
if (ImGui::Button(label.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0)))
{
}
if (m_Expanded)
{
m_ModelInspector->Draw();
}
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Model"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 256);
fullPath = Nuake::FileSystem::AbsoluteToRelative(fullPath);
if (Nuake::String::EndsWith(fullPath, ".model"))
{
}
else
{
m_QueuedModelPath = fullPath;
ImGui::OpenPopup("Create Skeleton");
}
}
ImGui::EndDragDropTarget();
}
if (ImGui::BeginPopupModal("Create Skeleton", NULL, ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::SetItemDefaultFocus();
ImGui::Text("Would you like to create the skeleton structure in the scene tree?");
ImGui::Separator();
if (ImGui::Button("OK", ImVec2(120, 0)))
{
component.ModelPath = m_QueuedModelPath;
component.LoadModel();
Scene* scene = entity.GetScene();
scene->CreateSkeleton(entity);
ImGui::CloseCurrentPopup();
}
ImGui::SetItemDefaultFocus();
ImGui::SameLine();
if (ImGui::Button("Cancel", ImVec2(120, 0)))
{
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
ImGui::TableNextColumn();
ComponentTableReset(component.ModelPath, "");
if (component.ModelResource)
{
auto& model = component.ModelResource;
ImGui::TableNextColumn();
{
ImGui::Text("Playing");
ImGui::TableNextColumn();
ImGui::Checkbox("##playing", &model->IsPlaying);
ImGui::TableNextColumn();
ComponentTableReset(model->IsPlaying, true);
ImGui::TableNextColumn();
}
if(model->GetCurrentAnimation())
{
ImGui::Text("Animation");
ImGui::TableNextColumn();
uint32_t animIndex = model->GetCurrentAnimationIndex();
uint32_t oldAnimIndex = animIndex;
auto animations = model->GetAnimations();
if (ImGui::BeginCombo("Type", model->GetCurrentAnimation()->GetName().c_str()))
{
for (int n = 0; n < model->GetAnimationsCount(); n++)
{
bool is_selected = (animIndex == n);
std::string animName = animations[n]->GetName();
if (animName.empty())
{
animName = "Empty";
}
if (ImGui::Selectable(animName.c_str(), is_selected))
{
animIndex = n;
}
if (is_selected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
if (animIndex != oldAnimIndex)
{
model->PlayAnimation(animIndex);
}
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetAnimId";
if (ImGui::Button(resetLabel.c_str()))
{
model->PlayAnimation(0);
}
ImGui::PopStyleColor();
}
}
}
EndComponentTable();
}
};

View File

@@ -1,40 +0,0 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Scene/Components/SphereCollider.h>
#include <src/Core/FileSystem.h>
#include <src/Scene/Entities/ImGuiHelper.h>
class SphereColliderPanel : ComponentPanel {
public:
SphereColliderPanel() {}
void Draw(Nuake::Entity entity) override
{
if (!entity.HasComponent<Nuake::SphereColliderComponent>())
return;
auto& component = entity.GetComponent<Nuake::SphereColliderComponent>();
BeginComponentTable(SPHERE COLLIDER, Nuake::SphereColliderComponent);
{
{
ImGui::Text("Size");
ImGui::TableNextColumn();
ImGui::DragFloat("##Radius", &component.Radius, 0.01f, 0.001f);
component.Radius = std::max(component.Radius, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(component.Radius, 0.5f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Is Trigger");
ImGui::TableNextColumn();
ImGui::Checkbox("##isTrigger", &component.IsTrigger);
ImGui::TableNextColumn();
ComponentTableReset(component.IsTrigger, false);
}
}
EndComponentTable();
}
};

View File

@@ -1,89 +0,0 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Core/FileSystem.h>
#include <src/Core/Maths.h>
#include <src/Scene/Components/SpriteComponent.h>
#include <src/Scene/Entities/ImGuiHelper.h>
class SpritePanel : ComponentPanel
{
public:
SpritePanel() = default;
~SpritePanel() = default;
void Draw(Nuake::Entity entity) override
{
if (!entity.HasComponent<Nuake::SpriteComponent>())
{
return;
}
auto& component = entity.GetComponent<Nuake::SpriteComponent>();
BeginComponentTable(SPRITE, Nuake::SpriteComponent);
{
{
ImGui::Text("Sprite");
ImGui::TableNextColumn();
std::string path = component.SpritePath;
ImGui::Button(path.empty() ? "Drag image" : component.SpritePath.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0));
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Image"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 512);
path = Nuake::FileSystem::AbsoluteToRelative(std::move(fullPath));
component.SpritePath = path;
component.LoadSprite();
}
ImGui::EndDragDropTarget();
}
ImGui::TableNextColumn();
ComponentTableReset(component.LockYRotation, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Billboard");
ImGui::TableNextColumn();
ImGui::Checkbox("##billboard", &component.Billboard);
ImGui::TableNextColumn();
ComponentTableReset(component.Billboard, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Lock Y rotation");
ImGui::TableNextColumn();
ImGui::Checkbox("##lockYRotation", &component.LockYRotation);
ImGui::TableNextColumn();
ComponentTableReset(component.LockYRotation, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Position Based");
if (ImGui::BeginItemTooltip())
{
ImGui::Text("Orientation is based on the position of the camera or the orientation of the camera.");
ImGui::EndTooltip();
}
ImGui::TableNextColumn();
ImGui::Checkbox("##positionbased", &component.PositionFacing);
ImGui::TableNextColumn();
ComponentTableReset(component.LockYRotation, false);
}
}
EndComponentTable();
}
};

View File

@@ -27,14 +27,14 @@ public:
ImGui::TableNextColumn();
Vector3 position = component.GetLocalPosition();
ImGuiHelper::DrawVec3("Translation", &position);
ImGuiHelper::DrawVec3("Translation##" + std::to_string(entity.GetHandle()), &position);
if (position != component.GetLocalPosition())
component.SetLocalPosition(position);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetTranslation";
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetTranslation" + std::to_string(entity.GetHandle());
if (ImGui::Button(resetLabel.c_str()))
component.SetLocalPosition(Vector3(0, 0, 0));
@@ -52,7 +52,7 @@ public:
Vector3 eulerDegreesOld = glm::degrees(glm::eulerAngles(currentRotation));
// Draw the ImGui widget for rotation
ImGuiHelper::DrawVec3("Rotation", &eulerDegreesOld);
ImGuiHelper::DrawVec3("Rotation##" + std::to_string(entity.GetHandle()), &eulerDegreesOld);
// Calculate the delta in Euler angles
Vector3 eulerDelta = eulerDegreesOld - glm::degrees(glm::eulerAngles(currentRotation));
@@ -84,7 +84,7 @@ public:
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetRotation";
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetRotation" + std::to_string(entity.GetHandle());
if (ImGui::Button(resetLabel.c_str()))
{
component.SetLocalRotation(Quat(1, 0, 0, 0));
@@ -97,7 +97,7 @@ public:
ImGui::TableNextColumn();
Vector3 localScale = component.GetLocalScale();
ImGuiHelper::DrawVec3("Scale", &localScale);
ImGuiHelper::DrawVec3("Scale##" + std::to_string(entity.GetHandle()), &localScale);
if (localScale != component.GetLocalScale())
component.SetLocalScale(localScale);
@@ -105,7 +105,7 @@ public:
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetScale";
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetScale" + std::to_string(entity.GetHandle());
if (ImGui::Button(resetLabel.c_str()))
component.SetLocalScale(Vector3(1, 1, 1));

View File

@@ -7,6 +7,10 @@
#include <glad/glad.h>
#include "src/UI/NuakeUI.h"
#include "src/UI/UIInputManager.h"
void EditorApplication::OnInit()
{
@@ -45,6 +49,39 @@ void EditorApplication::OnInit()
}
}
m_Window->SetOnWindowFocusedCallback([&](Window& window, bool focused)
{
if (!focused)
{
return;
}
for (auto& layer : m_LayerStack)
{
layer->OnWindowFocused();
}
});
m_Window->SetOnWindowClosedCallback([](Window& window)
{
if (Engine::GetProject())
{
Engine::GetProject()->Save();
}
if (Engine::GetCurrentScene())
{
Engine::GetCurrentScene()->Save();
}
});
m_Window->SetOnDragNDropCallback([&](Window& window, const std::vector<std::string>& paths) {
for (auto& layer : m_LayerStack)
{
layer->OnDragNDrop(paths);
}
});
PushLayer(CreateScope<EditorLayer>());
}

View File

@@ -10,6 +10,15 @@
using namespace NuakeEditor;
class DragNDropModule : public Nuake::IApplicationModule
{
public:
void OnInit() override
{
}
};
class EditorApplication : public Nuake::Application
{
private:

View File

@@ -53,14 +53,18 @@ void EditorLayer::OnUpdate()
m_GizmoDrawer->DrawNavMesh(currentScene, true);
}
if (m_EditorInterface->ShouldDrawCollision())
if (m_EditorInterface->ShouldDrawGizmos())
{
m_GizmoDrawer->DrawGizmos(currentScene, false);
}
if (m_EditorInterface->ShouldDrawShapes())
{
m_GizmoDrawer->DrawShapes(currentScene, false);
}
}
}
}
}
sceneFramebuffer->Unbind();
}
@@ -76,3 +80,13 @@ void EditorLayer::OnDetach()
{
delete m_EditorInterface;
}
void EditorLayer::OnWindowFocused()
{
m_EditorInterface->OnWindowFocused();
}
void EditorLayer::OnDragNDrop(const std::vector<std::string>& paths)
{
m_EditorInterface->OnDragNDrop(paths);
}

View File

@@ -22,6 +22,9 @@ public:
virtual void OnUpdate() override;
virtual void OnDetach() override;
virtual void OnWindowFocused() override;
virtual void OnDragNDrop(const std::vector<std::string>& paths) override;
private:
CommandBuffer mCommandBuffer;
Nuake::EditorInterface* m_EditorInterface;

View File

@@ -8,6 +8,7 @@
#include <src/Scene/Components/SphereCollider.h>
#include <src/Scene/Components/CharacterControllerComponent.h>
#include <src/Scene/Components/BoxCollider.h>
#include "src/Scene/Components/RigidbodyComponent.h"
#include <src/Resource/ModelLoader.h>
#include <src/Rendering/RenderList.h>
@@ -22,7 +23,9 @@
#include <src/Scene/Components/ParticleEmitterComponent.h>
#include <src/Scene/Components/BoneComponent.h>
#include <src/Scene/Components/AudioEmitterComponent.h>
#include <src/Scene/Components/ParentComponent.h>
#include <DetourDebugDraw.h>
#include <src/Scene/Components/BSPBrushComponent.h>
GizmoDrawer::GizmoDrawer(EditorInterface* editor)
@@ -141,6 +144,11 @@ bool GizmoDrawer::IsEntityInSelection(Nuake::Entity entity)
return false;
}
if (!m_Editor->Selection.Entity.IsValid())
{
return false;
}
using namespace Nuake;
const Nuake::Entity selectedEntity = m_Editor->Selection.Entity;
@@ -182,10 +190,10 @@ void GizmoDrawer::DrawAxis(Ref<Scene> scene, bool occluded)
RenderCommand::Enable(RendererEnum::DEPTH_TEST);
{
m_LineShader->Bind();
m_LineShader->SetUniformMat4f("u_View", scene->m_EditorCamera->GetTransform());
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform1f("u_Opacity", occluded ? 0.1f : 0.5f);
m_LineShader->SetUniformVec4("u_Color", {0.0f, 0.0f, 0.0f, 0.0f});
m_LineShader->SetUniform("u_View", scene->m_EditorCamera->GetTransform());
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_Opacity", occluded ? 0.1f : 0.5f);
m_LineShader->SetUniform("u_Color", {0.0f, 0.0f, 0.0f, 0.0f});
m_AxisLineBuffer->Bind();
glLineWidth(1.0f);
Nuake::RenderCommand::DrawLines(0, 6);
@@ -211,29 +219,11 @@ void GizmoDrawer::DrawNavMesh(Ref<Scene> scene, bool occluded)
}
}
void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
void GizmoDrawer::DrawShapes(Ref<Scene> scene, bool occluded)
{
using namespace Nuake;
RenderCommand::Enable(RendererEnum::DEPTH_TEST);
glLineWidth(3.0f);
auto boxColliderView = scene->m_Registry.view<TransformComponent, BoxColliderComponent>();
for (auto e : boxColliderView)
{
auto [transform, box] = scene->m_Registry.get<TransformComponent, BoxColliderComponent>(e);
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
m_LineShader->Bind();
m_LineShader->SetUniform1f("u_Opacity", 1.f);
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix, box.Size));
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_BoxBuffer->Bind();
Nuake::RenderCommand::DrawLines(0, 26);
}
glLineWidth(2.0f);
auto navMeshVolumeView = scene->m_Registry.view<TransformComponent, NavMeshVolumeComponent>();
for (auto e : navMeshVolumeView)
@@ -249,9 +239,26 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
m_LineShader->Bind();
m_LineShader->SetUniform1f("u_Opacity", 0.9f);
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix, volume.VolumeSize));
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_Opacity", 0.9f);
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix, volume.VolumeSize));
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_BoxBuffer->Bind();
Nuake::RenderCommand::DrawLines(0, 26);
}
auto boxColliderView = scene->m_Registry.view<TransformComponent, BoxColliderComponent>();
for (auto e : boxColliderView)
{
auto [transform, box] = scene->m_Registry.get<TransformComponent, BoxColliderComponent>(e);
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
m_LineShader->Bind();
m_LineShader->SetUniform("u_Opacity", 1.f);
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix, box.Size));
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_BoxBuffer->Bind();
Nuake::RenderCommand::DrawLines(0, 26);
@@ -262,9 +269,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
{
auto [transform, sphere] = scene->m_Registry.get<TransformComponent, SphereColliderComponent>(e);
m_LineShader->Bind();
m_LineShader->SetUniform1f("u_Opacity", 1.f);
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])), Vector3(sphere.Radius)));
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_Opacity", 1.f);
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])), Vector3(sphere.Radius)));
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_CircleBuffer->Bind();
Nuake::RenderCommand::DrawLines(0, 128);
@@ -283,14 +290,14 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
Vector3 globalPosition = Vector3(transform.GetGlobalTransform()[3]);
m_LineShader->Bind();
m_LineShader->SetUniform1f("u_Opacity", 1.f);
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), globalPosition), Vector3(emitter.MaxDistance)));
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_Opacity", 1.f);
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), globalPosition), Vector3(emitter.MaxDistance)));
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_CircleBuffer->Bind();
Nuake::RenderCommand::DrawLines(0, 128);
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), globalPosition), Vector3(emitter.MinDistance)));
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), globalPosition), Vector3(emitter.MinDistance)));
Nuake::RenderCommand::DrawLines(0, 128);
}
@@ -311,9 +318,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
m_LineShader->Bind();
m_LineShader->SetUniform1f("u_Opacity", 1.f);
m_LineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_Opacity", 1.f);
m_LineShader->SetUniform("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_CapsuleGizmo[entityId]->Bind();
Nuake::RenderCommand::DrawLines(0, 264);
@@ -336,9 +343,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
m_LineShader->Bind();
m_LineShader->SetUniform1f("u_Opacity", 1.0f);
m_LineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_Opacity", 1.0f);
m_LineShader->SetUniform("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_CylinderGizmo[entityId]->Bind();
Nuake::RenderCommand::DrawLines(0, 264);
@@ -369,23 +376,52 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
gizmoPosition = glm::translate(gizmoPosition, { 0, -cylinderLength / 2.0, 0 });
m_LineShader->Bind();
m_LineShader->SetUniform1f("u_Opacity", 1.0f);
m_LineShader->SetUniformMat4f("u_View", gizmoPosition);
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_Opacity", 1.0f);
m_LineShader->SetUniform("u_View", gizmoPosition);
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_CylinderGizmo[entityId]->Bind();
Nuake::RenderCommand::DrawLines(0, 264);
}
}
auto bspView = scene->m_Registry.view<TransformComponent, BSPBrushComponent>();
for (auto e : bspView)
{
auto [transform, brush] = scene->m_Registry.get<TransformComponent, BSPBrushComponent>(e);
if (brush.target.empty())
{
continue;
}
auto bspView2 = scene->m_Registry.view<TransformComponent, BSPBrushComponent>();
for (auto e2 : bspView2)
{
auto [transform2, brush2] = scene->m_Registry.get<TransformComponent, BSPBrushComponent>(e2);
if (brush2.TargetName.empty())
{
continue;
}
if (brush.target == brush2.TargetName)
{
Vector3 from = transform.GetGlobalTransform()[3];
Vector3 to = transform2.GetGlobalTransform()[3];
scene->m_SceneRenderer->DrawDebugLine(from, to, Color(1, 0, 0, 1), 0.f, 1.0f);
}
}
}
auto particleView = scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
for (auto e : particleView)
{
auto [transform, particle] = scene->m_Registry.get<TransformComponent, ParticleEmitterComponent>(e);
m_LineShader->Bind();
m_LineShader->SetUniform1f("u_Opacity", 1.f);
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])), Vector3(particle.Radius)));
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_Opacity", 1.f);
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])), Vector3(particle.Radius)));
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_CircleBuffer->Bind();
Nuake::RenderCommand::DrawLines(0, 128);
@@ -414,8 +450,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
m_LineShader->Bind();
m_LineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
m_LineShader->SetUniform("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
meshes[mesh.SubMesh]->Bind();
@@ -423,11 +459,42 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
auto camView = scene->m_Registry.view<TransformComponent, CameraComponent>();
for (auto e : camView)
{
auto [transform, camera] = scene->m_Registry.get<TransformComponent, CameraComponent>(e);
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
m_LineShader->Bind();
m_LineShader->SetUniform("u_Opacity", 1.f);
const float aspectRatio = camera.CameraInstance->AspectRatio;
const float fov = camera.CameraInstance->Fov;
Matrix4 clampedPerspective = glm::perspectiveFov(glm::radians(fov), 9.0f * aspectRatio, 9.0f, 0.05f, 3.0f);
m_LineShader->SetUniform("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix * glm::inverse(clampedPerspective));
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
m_BoxBuffer->Bind();
Nuake::RenderCommand::DrawLines(0, 26);
}
}
void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
{
using namespace Nuake;
auto camView = scene->m_Registry.view<TransformComponent, CameraComponent>();
RenderCommand::Enable(RendererEnum::DEPTH_TEST);
glLineWidth(3.0f);
auto flatShader = ShaderManager::GetShader("Resources/Shaders/flat.shader");
flatShader->Bind();
flatShader->SetUniformMat4f("u_View", scene->m_EditorCamera->GetTransform());
flatShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
flatShader->SetUniform4f("u_Color", 0.5f, 0.5f, 0.5f, 1.0f);
flatShader->SetUniform("u_View", scene->m_EditorCamera->GetTransform());
flatShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
flatShader->SetUniform("u_Color", 0.5f, 0.5f, 0.5f, 1.0f);
RenderCommand::Enable(RendererEnum::DEPTH_TEST);
RenderCommand::Enable(RendererEnum::FACE_CULL);
@@ -438,9 +505,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
auto gizmoShader = ShaderManager::GetShader("Resources/Shaders/gizmo.shader");
gizmoShader->Bind();
gizmoShader->SetUniformMat4f("u_View", scene->m_EditorCamera->GetTransform());
gizmoShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
gizmoShader->SetUniform1f("u_Opacity", occluded ? 0.1f : 1.f);
gizmoShader->SetUniform("u_View", scene->m_EditorCamera->GetTransform());
gizmoShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
gizmoShader->SetUniform("u_Opacity", occluded ? 0.1f : 1.f);
RenderCommand::Disable(RendererEnum::FACE_CULL);
const Vector3& cameraPosition = scene->m_EditorCamera->GetTranslation();
@@ -448,11 +515,10 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
const Vector3 gizmoSize = Vector3(Engine::GetProject()->Settings.GizmoSize);
// Camera
auto camView = scene->m_Registry.view<TransformComponent, CameraComponent>();
for (auto e : camView)
{
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/camera.png").get());
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/camera.png").get());
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
auto [transform, camera] = scene->m_Registry.get<TransformComponent, CameraComponent>(e);
auto initialTransform = transform.GetGlobalTransform();
@@ -470,6 +536,7 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
}
// Lights
auto lightView = scene->m_Registry.view<TransformComponent, LightComponent>();
for (auto e : lightView)
{
auto [transform, light] = scene->m_Registry.get<TransformComponent, LightComponent>(e);
@@ -491,8 +558,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
texturePath = "Resources/Gizmos/light.png";
}
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture(texturePath).get());
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture(texturePath).get());
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
auto initialTransform = transform.GetGlobalTransform();
Matrix4 particleTransform = initialTransform;
@@ -512,8 +579,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
auto characterControllerView = scene->m_Registry.view<TransformComponent, CharacterControllerComponent>();
for (auto e : characterControllerView)
{
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/player.png").get());
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/player.png").get());
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
auto [transform, characterControllerComponent] = scene->m_Registry.get<TransformComponent, CharacterControllerComponent>(e);
auto initialTransform = transform.GetGlobalTransform();
@@ -535,8 +602,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
auto boneView = scene->m_Registry.view<TransformComponent, BoneComponent>();
for (auto e : boneView)
{
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/bone.png").get());
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/bone.png").get());
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
auto [transform, boneComponent] = scene->m_Registry.get<TransformComponent, BoneComponent>(e);
auto initialTransform = transform.GetGlobalTransform();
@@ -557,8 +624,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
auto audioView = scene->m_Registry.view<TransformComponent, AudioEmitterComponent>();
for (auto e : audioView)
{
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/sound_emitter.png").get());
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/sound_emitter.png").get());
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
auto [transformComponent, audioEmitterComponent] = scene->m_Registry.get<TransformComponent, AudioEmitterComponent>(e);
auto initialTransform = transformComponent.GetGlobalTransform();
@@ -578,8 +645,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
auto rigidbodyView = scene->m_Registry.view<TransformComponent, RigidBodyComponent>();
for (auto e : rigidbodyView)
{
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/rigidbody.png").get());
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/rigidbody.png").get());
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
auto [transformComponent, rigidbodyComponent] = scene->m_Registry.get<TransformComponent, RigidBodyComponent>(e);
auto initialTransform = transformComponent.GetGlobalTransform();
@@ -599,8 +666,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
auto particleEmitterView = scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
for (auto e : particleEmitterView)
{
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/particles.png").get());
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/particles.png").get());
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
auto [transformComponent, particleEmitter] = scene->m_Registry.get<TransformComponent, ParticleEmitterComponent>(e);
auto initialTransform = transformComponent.GetGlobalTransform();

View File

@@ -53,6 +53,7 @@ public:
GizmoDrawer() = default;
~GizmoDrawer() = default;
void DrawShapes(Ref<Scene> scene, bool occluded);
void DrawGizmos(Ref<Scene> scene, bool occluded);
void DrawAxis(Ref<Scene> scene, bool occluded);
void DrawNavMesh(Ref<Scene> scene, bool occluded);

View File

@@ -6,7 +6,7 @@ void ImGuiTextSTD(const std::string& label, std::string& value)
{
char buffer[256];
memset(buffer, 0, sizeof(buffer));
std::strncpy(buffer, value.c_str(), sizeof(buffer));
strncpy_s(buffer, value.c_str(), sizeof(buffer));
if (ImGui::InputText(label.c_str(), buffer, sizeof(buffer)))
{
@@ -18,7 +18,7 @@ void ImGuiTextMultiline(const std::string& label, std::string& value)
{
char buffer[256];
memset(buffer, 0, sizeof(buffer));
std::strncpy(buffer, value.c_str(), sizeof(buffer));
strncpy_s(buffer, value.c_str(), sizeof(buffer));
if (ImGui::InputTextMultiline(label.c_str(), buffer, sizeof(buffer)))
{
value = std::string(buffer);

View File

@@ -4,8 +4,6 @@
void PopupHelper::OpenPopup(const std::string& id)
{
ImGui::TextWrapped(id.c_str());
ImGui::OpenPopup(id.c_str());
}

View File

@@ -1,10 +1,19 @@
#include "ThumbnailManager.h"
#include <src/Vendors/glm/ext/matrix_clip_space.hpp>
#include <src/FileSystem/FileTypes.h>
#include <src/FileSystem/File.h>
#include <src/Scene/Components/CameraComponent.h>
#include <src/Scene/Components/ModelComponent.h>
#include <src/Rendering/SceneRenderer.h>
#include <src/Resource/ResourceLoader.h>
#include <glad/glad.h>
#include <src/Resource/Prefab.h>
#include <src/Resource/ResourceLoader.h>
#include <src/Vendors/glm/ext/matrix_clip_space.hpp>
#include <glad/glad.h>
#include <Tracy.hpp>
ThumbnailManager::ThumbnailManager()
@@ -39,6 +48,8 @@ bool ThumbnailManager::IsThumbnailLoaded(const std::string& path) const
Ref<Nuake::Texture> ThumbnailManager::GetThumbnail(const std::string& path)
{
ZoneScoped;
if (IsThumbnailLoaded(path))
{
return m_Thumbnails[path];
@@ -71,6 +82,9 @@ void ThumbnailManager::MarkThumbnailAsDirty(const std::string & path)
Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path, Ref<Nuake::Texture> texture)
{
ZoneScopedN("GenerateThumbnail");
ZoneText(path.c_str(), path.size());
using namespace Nuake;
const Matrix4 ortho = glm::orthoLH(-0.6f, 0.6f, -0.6f, 0.6f, -100.0f, 100.0f);
@@ -80,26 +94,26 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
auto file = FileSystem::GetFile(path);
if (file->GetFileType() == FileType::Prefab)
{
Ref<Scene> scene = Scene::New();
auto cam = scene->CreateEntity("Camera");
TransformComponent& camTransform = cam.GetComponent<TransformComponent>();
camTransform.SetLocalPosition({ 0.0f, 0.0f, 2.0f });
auto& previewLight = scene->CreateEntity("_directionalLight").AddComponent<LightComponent>();
previewLight.SetCastShadows(false);
previewLight.Type = LightType::Directional;
scene->GetEnvironment()->CurrentSkyType = SkyType::ProceduralSky;
scene->GetEnvironment()->ProceduralSkybox->SunDirection = { 0.58f, 0.34f, -0.74f };
auto& camComponent = cam.AddComponent<CameraComponent>();
camComponent.CameraInstance->Fov = 45.0f;
camComponent.CameraInstance->AspectRatio = 1.0f;
m_ShadedFramebuffer->SetTexture(texture);
Ref<Prefab> prefab = Prefab::InstanceInScene(path, scene);
scene->Update(0.01f);
scene->Draw(*m_ShadedFramebuffer.get());
//Ref<Scene> scene = Scene::New();
//auto cam = scene->CreateEntity("Camera");
//TransformComponent& camTransform = cam.GetComponent<TransformComponent>();
//camTransform.SetLocalPosition({ 0.0f, 0.0f, 2.0f });
//
//auto& previewLight = scene->CreateEntity("_directionalLight").AddComponent<LightComponent>();
//previewLight.SetCastShadows(false);
//previewLight.Type = LightType::Directional;
//
//scene->GetEnvironment()->CurrentSkyType = SkyType::ProceduralSky;
//scene->GetEnvironment()->ProceduralSkybox->SunDirection = { 0.58f, 0.34f, -0.74f };
//auto& camComponent = cam.AddComponent<CameraComponent>();
//camComponent.CameraInstance->Fov = 45.0f;
//camComponent.CameraInstance->AspectRatio = 1.0f;
//m_ShadedFramebuffer->SetTexture(texture);
//
//Ref<Prefab> prefab = Prefab::InstanceInScene(path, scene.get());
//
//scene->Update(0.01f);
//scene->Draw(*m_ShadedFramebuffer.get());
// Gbuffer pass
//m_Framebuffer->Bind();
@@ -113,9 +127,9 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
// shader->Bind();
//
// auto cam = Engine::GetCurrentScene()->GetCurrentCamera();
// shader->SetUniformMat4f("u_View", view);
// shader->SetUniformMat4f("u_Projection", ortho);
// shader->SetUniformMat4f("u_Model", Matrix4(1.0f));
// shader->SetUniform("u_View", view);
// shader->SetUniform("u_Projection", ortho);
// shader->SetUniform("u_Model", Matrix4(1.0f));
// Renderer::SphereMesh->Draw(shader, true);
//}
//m_Framebuffer->Unbind();
@@ -129,15 +143,15 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
// RenderCommand::Disable(RendererEnum::FACE_CULL);
// auto shader = ShaderManager::GetShader("Resources/Shaders/deferred.shader");
// shader->Bind();
// shader->SetUniformVec3("u_EyePosition", Vector3(1, 0, 0));
// shader->SetUniform1i("LightCount", 0);
// shader->SetUniform("u_EyePosition", Vector3(1, 0, 0));
// shader->SetUniform("LightCount", 0);
// auto dir = Engine::GetCurrentScene()->GetEnvironment()->ProceduralSkybox->GetSunDirection();
// shader->SetUniform3f("u_DirectionalLight.Direction", 0.6, -0.6, 0.6);
// shader->SetUniform3f("u_DirectionalLight.Color", 10.0f, 10.0f, 10.0f);
// shader->SetUniform1i("u_DirectionalLight.Shadow", 0);
// shader->SetUniform1i("u_DisableSSAO", 1);
// shader->SetUniformMat4f("u_View", view);
// shader->SetUniformMat4f("u_Projection", ortho);
// shader->SetUniform("u_DirectionalLight.Direction", 0.6, -0.6, 0.6);
// shader->SetUniform("u_DirectionalLight.Color", 10.0f, 10.0f, 10.0f);
// shader->SetUniform("u_DirectionalLight.Shadow", 0);
// shader->SetUniform("u_DisableSSAO", 1);
// shader->SetUniform("u_View", view);
// shader->SetUniform("u_Projection", ortho);
//
// m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(5);
// m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT0)->Bind(6);
@@ -145,11 +159,11 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
// m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT2)->Bind(8);
// m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT4)->Bind(10);
//
// shader->SetUniform1i("m_Depth", 5);
// shader->SetUniform1i("m_Albedo", 6);
// shader->SetUniform1i("m_Normal", 7);
// shader->SetUniform1i("m_Material", 8);
// shader->SetUniform1i("m_Emissive", 10);
// shader->SetUniform("m_Depth", 5);
// shader->SetUniform("m_Albedo", 6);
// shader->SetUniform("m_Normal", 7);
// shader->SetUniform("m_Material", 8);
// shader->SetUniform("m_Emissive", 10);
//
// Renderer::DrawQuad(Matrix4());
//}
@@ -178,12 +192,8 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
m_ShadedFramebuffer->SetTexture(texture);
ModelComponent& modelComp = scene->CreateEntity("Mesh").AddComponent<ModelComponent>();
modelComp.ModelResource = ResourceLoader::LoadModel(file->GetRelativePath());
AABB aabb = modelComp.ModelResource->GetMeshes()[0]->GetAABB();
Vector3 middlePoint = aabb.Max / 2.0f;
//ModelComponent& modelComp = scene->CreateEntity("Mesh").AddComponent<ModelComponent>();
//modelComp.ModelResource = ResourceLoader::LoadModel(file->GetRelativePath());
scene->Update(0.01f);
scene->Draw(*m_ShadedFramebuffer.get());
}
@@ -201,9 +211,9 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
shader->Bind();
auto cam = Engine::GetCurrentScene()->GetCurrentCamera();
shader->SetUniformMat4f("u_View", view);
shader->SetUniformMat4f("u_Projection", ortho);
shader->SetUniformMat4f("u_Model", Matrix4(1.0f));
shader->SetUniform("u_View", view);
shader->SetUniform("u_Projection", ortho);
shader->SetUniform("u_Model", Matrix4(1.0f));
Ref<Material> material = ResourceLoader::LoadMaterial(path);
material->Bind(shader);
Renderer::SphereMesh->Draw(shader, false);
@@ -219,15 +229,15 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
RenderCommand::Disable(RendererEnum::FACE_CULL);
auto shader = ShaderManager::GetShader("Resources/Shaders/deferred.shader");
shader->Bind();
shader->SetUniformVec3("u_EyePosition", Vector3(1, 0, 0));
shader->SetUniform1i("LightCount", 0);
shader->SetUniform("u_EyePosition", Vector3(1, 0, 0));
shader->SetUniform("LightCount", 0);
auto dir = Engine::GetCurrentScene()->GetEnvironment()->ProceduralSkybox->GetSunDirection();
shader->SetUniform3f("u_DirectionalLight.Direction", 0.6, -0.6, 0.6);
shader->SetUniform3f("u_DirectionalLight.Color", 10.0f, 10.0f, 10.0f);
shader->SetUniform1i("u_DirectionalLight.Shadow", 0);
shader->SetUniform1i("u_DisableSSAO", 1);
shader->SetUniformMat4f("u_View", view);
shader->SetUniformMat4f("u_Projection", ortho);
shader->SetUniform("u_DirectionalLight.Direction", 0.6, -0.6, 0.6);
shader->SetUniform("u_DirectionalLight.Color", 10.0f, 10.0f, 10.0f);
shader->SetUniform("u_DirectionalLight.Shadow", 0);
shader->SetUniform("u_DisableSSAO", 1);
shader->SetUniform("u_View", view);
shader->SetUniform("u_Projection", ortho);
m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(5);
m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT0)->Bind(6);
@@ -235,11 +245,11 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT2)->Bind(8);
m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT4)->Bind(10);
shader->SetUniform1i("m_Depth", 5);
shader->SetUniform1i("m_Albedo", 6);
shader->SetUniform1i("m_Normal", 7);
shader->SetUniform1i("m_Material", 8);
shader->SetUniform1i("m_Emissive", 10);
shader->SetUniform("m_Depth", 5);
shader->SetUniform("m_Albedo", 6);
shader->SetUniform("m_Normal", 7);
shader->SetUniform("m_Material", 8);
shader->SetUniform("m_Emissive", 10);
Renderer::DrawQuad(Matrix4());
}

View File

@@ -5,22 +5,22 @@
void ScriptingContext::Initialize()
{
m_Modules =
modules =
{
CreateRef<EditorNetAPI>()
};
for (auto& m : m_Modules)
for (auto& m : modules)
{
m->RegisterMethods();
}
// Load Nuake assembly DLL
/*auto m_LoadContext2 = Nuake::ScriptingEngineNet::Get().GetHostInstance()->CreateAssemblyLoadContext("NuakeEditorContext");
m_NuakeAssembly = Nuake::ScriptingEngineNet::Get().ReloadEngineAPI(m_LoadContext2);
m_EditorAssembly = m_LoadContext2.LoadAssembly("EditorNet.dll");
/*auto loadContext2 = Nuake::ScriptingEngineNet::Get().GetHostInstance()->CreateAssemblyLoadContext("NuakeEditorContext");
nuakeAssembly = Nuake::ScriptingEngineNet::Get().ReloadEngineAPI(loadContext2);
m_EditorAssembly = loadContext2.LoadAssembly("EditorNet.dll");
for (const auto& netModule : m_Modules)
for (const auto& netModule : modules)
{
for (const auto& [methodName, methodPtr] : netModule->GetMethods())
{

View File

@@ -13,13 +13,13 @@ namespace Coral
class ScriptingContext
{
private:
Coral::HostInstance* m_HostInstance;
Coral::AssemblyLoadContext m_LoadContext;
Coral::HostInstance* hostInstance;
Coral::AssemblyLoadContext loadContext;
std::unordered_map<std::string, Coral::AssemblyLoadContext*> m_LoadedAssemblies;
std::vector<Ref<Nuake::NetAPIModule>> m_Modules;
std::unordered_map<std::string, Coral::AssemblyLoadContext*> loadedAssemblies;
std::vector<Ref<Nuake::NetAPIModule>> modules;
Coral::ManagedAssembly m_NuakeAssembly; // Nuake DLL
Coral::ManagedAssembly nuakeAssembly; // Nuake DLL
Coral::ManagedAssembly m_EditorAssembly; // Editor DLL
public:
static ScriptingContext& Get()

View File

@@ -0,0 +1,2 @@
#pragma once

View File

@@ -10,27 +10,27 @@ public:
float dummyVolume = 1.0f;
void Draw()
{
constexpr int numBus = 6;
if(ImGui::Begin("Audio mixer"))
{
for (int i = 0; i < numBus; i++)
{
const std::string busName = "Bus " + std::to_string(i);
//ImGui::BeginTable(busName.c_str(), 1, 0, ImVec2(300, ImGui::GetContentRegionAvail().y));
//
//ImGui::TableSetupColumn(busName.c_str(), 0, 1.0f);
//ImGui::TableNextColumn ();
//ImGui::TableHeader(busName.c_str());
//ImGui::TableNextColumn();
//
//const float height = ImGui::GetContentRegionAvail().y - 50;
//const std::string id = "##Volume" + std::to_string(i);
//ImGui::VSliderFloat(id.c_str(), ImVec2(50, height), &dummyVolume, -60.0f, 6.0f, "%.3dB", ImGuiSliderFlags_Logarithmic);
//ImGui::TableNextColumn();
//ImGui::EndTable();
}
}
//constexpr int numBus = 6;
//if(ImGui::Begin("Audio mixer"))
//{
// for (int i = 0; i < numBus; i++)
// {
// const std::string busName = "Bus " + std::to_string(i);
// //ImGui::BeginTable(busName.c_str(), 1, 0, ImVec2(300, ImGui::GetContentRegionAvail().y));
// //
// //ImGui::TableSetupColumn(busName.c_str(), 0, 1.0f);
// //ImGui::TableNextColumn ();
// //ImGui::TableHeader(busName.c_str());
// //ImGui::TableNextColumn();
// //
// //const float height = ImGui::GetContentRegionAvail().y - 50;
// //const std::string id = "##Volume" + std::to_string(i);
// //ImGui::VSliderFloat(id.c_str(), ImVec2(50, height), &dummyVolume, -60.0f, 6.0f, "%.3dB", ImGuiSliderFlags_Logarithmic);
// //ImGui::TableNextColumn();
// //ImGui::EndTable();
// }
//}
ImGui::End();
//ImGui::End();
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
#include "src/Vendors/imgui/imgui.h"
#include <src/Vendors/imgui/ImGuizmo.h>
#include "src/Core/FileSystem.h"
#include "src/FileSystem/FileSystem.h"
#include "../Actions/EditorSelection.h"
#include "EditorSelectionPanel.h"
@@ -18,6 +18,7 @@
#include <src/Scripting/ScriptingEngineNet.h>
#include "ProjectSettings/ProjectSettingsWindow.h"
#include "PrefabEditor/PrefabEditorWindow.h"
using namespace NuakeEditor;
@@ -30,14 +31,20 @@ namespace Nuake
class EditorInterface
{
private:
bool m_TitleBarHovered = false;
std::vector<CompilationError> errors;
std::vector<Ref<PrefabEditorWindow>> prefabEditors;
Ref<Scene> SceneSnapshot;
static NuakeEditor::CommandBuffer* mCommandBuffer;
std::string searchQuery = "";
bool isControllingCamera = false;
bool m_DrawGrid = false;
bool m_DrawAxis = true;
bool m_ShowImGuiDemo = false;
bool m_DebugCollisions = true;
bool m_DrawShapes = true;
bool m_DrawGizmos = true;
bool m_DrawCamPreview = false;
bool m_DrawNavMesh = true;
bool m_ShowOverlay = true;
bool m_IsHoveringViewport = false;
@@ -68,39 +75,54 @@ namespace Nuake
AudioWindow* _audioWindow;
FileSystemUI* filesystem;
bool isNewProject = false;
static EditorSelection Selection;
EditorSelectionPanel SelectionPanel;
EditorSelectionPanel* SelectionPanel;
TrenchbroomConfiguratorWindow m_TrenchhbroomConfigurator;
MapImporterWindow m_MapImporter;
ProjectSettingsWindow* m_ProjectSettingsWindow;
Ref<Texture> NuakeTexture;
Ref<Texture> CloseIconTexture;
Ref<Texture> MaximizeTexture;
Ref<Texture> RestoreTexture;
Ref<Texture> MinimizeTexture;
EditorInterface(CommandBuffer& commandBuffer);
static ImFont* bigIconFont;
void BuildFonts();
void DrawTitlebar(float& outHeight);
void Init();
void Draw();
void Update(float ts);
void DrawMenuBar();
bool BeginMenubar(const ImRect& barRectangle);
void EndMenubar();
void SetStatusMessage(const std::string& msg, const Color& color = Color(0.08f, 0.08f, 0.08f, 1.0f)) { m_StatusMessage = msg; m_StatusBarColor = color; }
void DrawViewport();
void DrawStatusBar();
void DrawMenuBars();
void DrawEntityTree(Entity ent);
void DrawEntityTree(Entity ent, bool drawChildrens = true);
void DrawSceneTree();
void DrawLogger();
void DrawProjectSettings();
bool EntityContainsItself(Entity ent1, Entity ent2);
void Overlay();
void OpenPrefabWindow(const std::string& prefabPath);
bool ShouldDrawAxis() const { return m_DrawAxis; }
bool ShouldDrawCollision() const { return m_DebugCollisions; }
bool ShouldDrawShapes() const { return m_DrawShapes; }
bool ShouldDrawGizmos() const { return m_DrawGizmos; }
bool ShouldDrawNavMesh() const { return m_DrawNavMesh; }
bool LoadProject(const std::string& projectPath);
public:
std::string GetEntityTypeName(const Entity& entity) const;
static void PushCommand(ICommand&& command);
public:
void OnWindowFocused();
void OnDragNDrop(const std::vector<std::string>& paths);
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,61 +2,49 @@
#include "../Actions/EditorSelection.h"
#include "src/Scene/Entities/Entity.h"
#include "src/Core/FileSystem.h"
#include "src/FileSystem/FileSystem.h"
#include <src/Resource/Project.h>
#include "../ComponentsPanel/TransformPanel.h"
#include "../ComponentsPanel/LightPanel.h"
#include "../ComponentsPanel/ScriptPanel.h"
#include "../ComponentsPanel/MeshPanel.h"
#include "../ComponentsPanel/QuakeMapPanel.h"
#include "../ComponentsPanel/SkinnedMeshPanel.h"
#include "../ComponentsPanel/CameraPanel.h"
#include "../ComponentsPanel/RigidbodyPanel.h"
#include "../ComponentsPanel/BoxColliderPanel.h"
#include "../ComponentsPanel/CapsuleColliderPanel.h"
#include "../ComponentsPanel/CylinderColliderPanel.h"
#include "../ComponentsPanel/SphereColliderPanel.h"
#include "../ComponentsPanel/MeshColliderPanel.h"
#include "../ComponentsPanel/CharacterControllerPanel.h"
#include "../ComponentsPanel/SpritePanel.h"
#include "../ComponentsPanel/ParticleEmitterPanel.h"
#include "../ComponentsPanel/SkinnedModelPanel.h"
#include "../ComponentsPanel/BonePanel.h"
#include "../ComponentsPanel/AudioEmitterPanel.h"
#include "../ComponentsPanel/NetScriptPanel.h"
#include "../ComponentsPanel/NavMeshVolumePanel.h"
#include <src/Resource/Prefab.h>
namespace Nuake
{
class Scene;
}
class EditorSelectionPanel
{
using DrawComponentTypeFn = std::function<void(Nuake::Entity& entity, entt::meta_any& componentInstance)>;
using DrawFieldTypeFn = std::function<void(entt::meta_data& fieldMeta, entt::meta_any& componentInstance)>;
private:
TransformPanel mTransformPanel;
LightPanel mLightPanel;
ScriptPanel mScriptPanel;
NetScriptPanel mNetScriptPanel;
MeshPanel mMeshPanel;
SkinnedModelPanel mSkinnedModelPanel;
QuakeMapPanel mQuakeMapPanel;
CameraPanel mCameraPanel;
RigidbodyPanel mRigidbodyPanel;
BoxColliderPanel mBoxColliderPanel;
SphereColliderPanel mSphereColliderPanel;
MeshColliderPanel mMeshColliderPanel;
CapsuleColliderPanel mCapsuleColliderPanel;
CylinderColliderPanel mCylinderColliderPanel;
SpritePanel mSpritePanel;
CharacterControllerPanel mCharacterControllerPanel;
ParticleEmitterPanel mParticleEmitterPanel;
BonePanel mBonePanel;
AudioEmitterPanel mAudioEmitterPanel;
NavMeshVolumePanel mNavMeshVolumePanel;
MeshPanel meshPanel;
SkinnedMeshPanel skinnedMeshPanel;
EditorSelection* selection = nullptr;
Ref<Nuake::File> currentFile;
Ref<Nuake::Resource> selectedResource;
Ref<Nuake::Scene> virtualScene;
public:
EditorSelectionPanel();
EditorSelectionPanel(EditorSelection& selection);
void Draw(EditorSelection selection);
void Draw(EditorSelection selection, const std::string& id = "");
void DrawNone();
void DrawEntity(Nuake::Entity entity);
@@ -64,11 +52,48 @@ public:
void DrawFile(Ref<Nuake::File> file);
void DrawResource(Nuake::Resource resource);
void DrawPrefabPanel(Ref<Nuake::Prefab> prefab);
template<class T, auto Func>
void RegisterComponentDrawer()
{
const auto t = entt::type_id<T>();
ComponentTypeDrawers[t.hash()] = std::bind(Func, std::placeholders::_1, std::placeholders::_2);
}
template<class T, auto Func, class O>
void RegisterComponentDrawer(O* o)
{
ComponentTypeDrawers[entt::type_id<T>().hash()] = std::bind(Func, o, std::placeholders::_1, std::placeholders::_2);
}
template<class T, auto Func, class O>
void RegisterTypeDrawer(O* o)
{
FieldTypeDrawers[entt::type_id<T>().hash()] = std::bind(Func, o, std::placeholders::_1, std::placeholders::_2);
}
protected:
// Drawing functions for each component (for writing very specific inspectors for specific components)
std::unordered_map<entt::id_type, DrawComponentTypeFn> ComponentTypeDrawers;
// List of functions to call for each component field type that needs to be drawn
std::unordered_map<entt::id_type, DrawFieldTypeFn> FieldTypeDrawers;
private:
void ResolveFile(Ref<Nuake::File> file);
void DrawMaterialPanel(Ref<Nuake::Material> material);
void DrawProjectPanel(Ref<Nuake::Project> project);
void DrawWrenScriptPanel(Ref<Nuake::WrenScript> wrenFile);
void DrawNetScriptPanel(Ref<Nuake::File> file);
void DrawComponent(Nuake::Entity& entity, entt::meta_any& component);
void DrawComponentContent(entt::meta_any& component);
void DrawFieldTypeFloat(entt::meta_data& field, entt::meta_any& component);
void DrawFieldTypeBool(entt::meta_data& field, entt::meta_any& component);
void DrawFieldTypeVector2(entt::meta_data& field, entt::meta_any& component);
void DrawFieldTypeVector3(entt::meta_data& field, entt::meta_any& component);
void DrawFieldTypeString(entt::meta_data& field, entt::meta_any& component);
void DrawFieldTypeResourceFile(entt::meta_data& field, entt::meta_any& component);
void DrawFieldTypeDynamicItemList(entt::meta_data& field, entt::meta_any& component);
};

View File

@@ -12,15 +12,19 @@
#include <src/Rendering/Textures/Material.h>
#include "../Misc/PopupHelper.h"
#include <src/FileSystem/FileDialog.h>
#include <src/FileSystem/Directory.h>
#include <src/FileSystem/File.h>
#include "src/Scene/Systems/WadConverter.h"
#include "../Misc/ThumbnailManager.h"
#include <Tracy.hpp>
#include <src/Resource/SkyResource.h>
namespace Nuake
{
Ref<Directory> FileSystemUI::m_CurrentDirectory;
// TODO: add filetree in same panel
void FileSystemUI::Draw()
{
@@ -64,6 +68,8 @@ namespace Nuake
void FileSystemUI::DrawDirectory(Ref<Directory> directory, uint32_t drawId)
{
ZoneScoped;
ImGui::PushFont(FontManager::GetFont(Icons));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
const char* icon = ICON_FA_FOLDER;
@@ -226,6 +232,8 @@ namespace Nuake
void FileSystemUI::DrawFile(Ref<File> file, uint32_t drawId)
{
ZoneScoped;
ImGui::PushFont(EditorInterface::bigIconFont);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, {0.f, 0.f});
@@ -254,6 +262,8 @@ namespace Nuake
OS::OpenTrenchbroomMap(file->GetAbsolutePath());
break;
case FileType::NetScript:
case FileType::UI:
case FileType::CSS:
OS::OpenIn(file->GetAbsolutePath());
break;
case FileType::Scene:
@@ -262,8 +272,10 @@ namespace Nuake
case FileType::Solution:
OS::OpenIn(file->GetAbsolutePath());
break;
case FileType::Prefab:
this->Editor->OpenPrefabWindow(file->GetRelativePath());
break;
}
}
Editor->Selection = EditorSelection(file);
@@ -313,6 +325,18 @@ namespace Nuake
{
dragType = "_AudioFile";
}
else if (fileExtension == ".html")
{
dragType = "_UIFile";
}
else if (fileExtension == ".sky")
{
dragType = "_SkyFile";
}
else if (fileExtension == ".env")
{
dragType = "_EnvFile";
}
ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer));
ImGui::Text(file->GetName().c_str());
@@ -373,17 +397,34 @@ namespace Nuake
textureImage = image;
}
}
else if (fileType == FileType::Solution)
{
textureImage = textureMgr->GetTexture("Resources/Images/sln_icon.png");
}
else if (fileType == FileType::Map)
{
textureImage = textureMgr->GetTexture("Resources/Images/trenchbroom_icon.png");
}
else if (fileType == FileType::Env)
{
textureImage = textureMgr->GetTexture("Resources/Images/env_file_icon.png");
}
ImGui::SetCursorPos(prevCursor);
ImGui::Image(reinterpret_cast<ImTextureID>(textureImage->GetID()), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0));
ImGui::PopStyleVar();
auto imguiStyle = ImGui::GetStyle();
auto& imguiStyle = ImGui::GetStyle();
ImVec2 startOffset = ImVec2(imguiStyle.CellPadding.x / 2.0f, 0);
ImVec2 offsetEnd = ImVec2(startOffset.x, imguiStyle.CellPadding.y / 2.0f);
ImU32 rectColor = IM_COL32(255, 255, 255, 16);
ImGui::GetWindowDrawList()->AddRectFilled(prevScreenPos + ImVec2(0, 100) - startOffset, prevScreenPos + ImVec2(100, 150) + offsetEnd, rectColor, 1.0f);
ImU32 rectColor2 = UI::PrimaryCol;
Color fileTypeColor = GetColorByFileType(file->GetFileType());
ImGui::GetWindowDrawList()->AddRectFilled(prevScreenPos + ImVec2(0, 100) - startOffset, prevScreenPos + ImVec2(100, 101) + offsetEnd, IM_COL32(fileTypeColor.r * 255.f, fileTypeColor.g * 255.f, fileTypeColor.b * 255.f, fileTypeColor.a * 255.f), 0.0f);
std::string visibleName = file->GetName();
const uint32_t MAX_CHAR_NAME = 32;
if (file->GetName().size() >= MAX_CHAR_NAME)
@@ -552,7 +593,7 @@ namespace Nuake
}
scene->Path = FileSystem::AbsoluteToRelative(projectPath);
Engine::LoadScene(scene);
Engine::SetCurrentScene(scene);
}
// Rename Popup
@@ -646,34 +687,48 @@ namespace Nuake
RefreshFileBrowser();
}
}
if (ImGui::MenuItem("Wren Script"))
if (ImGui::MenuItem("Sky"))
{
std::string path = FileDialog::SaveFile("*.wren");
if (!String::EndsWith(path, ".wren"))
{
path += ".wren";
}
const std::string path = FileDialog::SaveFile("*.sky");
if (!path.empty())
{
std::string fileName = String::ToUpper(FileSystem::GetFileNameFromPath(path));
fileName = String::RemoveWhiteSpace(fileName);
if(!String::IsDigit(fileName[0]))
std::string finalPath = path;
if (!String::EndsWith(path, ".sky"))
{
finalPath = path + ".sky";
}
FileSystem::BeginWriteFile(path, true);
FileSystem::WriteLine(TEMPLATE_SCRIPT_FIRST + fileName + TEMPLATE_SCRIPT_SECOND);
Ref<SkyResource> sky = CreateRef<SkyResource>(FileSystem::AbsoluteToRelative(finalPath));
sky->IsEmbedded = false;
auto jsonData = sky->Serialize();
FileSystem::BeginWriteFile(finalPath, true);
FileSystem::WriteLine(jsonData.dump(4));
FileSystem::EndWriteFile();
RefreshFileBrowser();
}
else
{
Logger::Log("Cannot create script files that starts with a number.", "filesystem", CRITICAL);
}
if (ImGui::MenuItem("Environment"))
{
const std::string path = FileDialog::SaveFile("*.env");
if (!path.empty())
{
std::string finalPath = path;
if (!String::EndsWith(path, ".env"))
{
finalPath = path + ".env";
}
Ref<Environment> env = CreateRef<Environment>(FileSystem::AbsoluteToRelative(finalPath));
env->IsEmbedded = false;
auto jsonData = env->Serialize();
FileSystem::BeginWriteFile(finalPath, true);
FileSystem::WriteLine(jsonData.dump(4));
FileSystem::EndWriteFile();
RefreshFileBrowser();
}
}
@@ -687,9 +742,80 @@ namespace Nuake
void FileSystemUI::RefreshFileBrowser()
{
Scan();
}
Color FileSystemUI::GetColorByFileType(FileType fileType)
{
switch (fileType)
{
case Nuake::FileType::Unknown:
break;
case Nuake::FileType::Image:
break;
case Nuake::FileType::Material:
break;
case Nuake::FileType::Mesh:
break;
case Nuake::FileType::Script:
return { 1.0, 0.0, 0.0, 1.0 };
break;
case Nuake::FileType::NetScript:
return { 1.0, 0.0, 0.0, 1.0 };
break;
case Nuake::FileType::Project:
return Engine::GetProject()->Settings.PrimaryColor;
break;
case Nuake::FileType::Prefab:
break;
case Nuake::FileType::Scene:
return { 0, 1.0f, 1.0, 1.0 };
break;
case Nuake::FileType::Wad:
break;
case Nuake::FileType::Map:
return { 0.0, 1.0, 0.0, 1.0 };
break;
case Nuake::FileType::Assembly:
break;
case Nuake::FileType::Solution:
break;
case Nuake::FileType::Audio:
return { 0.0, 0.0, 1.0, 1.0 };
break;
case Nuake::FileType::UI:
return { 1.0, 1.0, 0.0, 1.0 };
break;
case Nuake::FileType::CSS:
return { 1.0, 0.0, 1.0, 1.0 };
break;
default:
break;
}
return Color(0, 0, 0, 0);
}
void FileSystemUI::Scan()
{
if (!m_CurrentDirectory)
{
return;
}
std::string previousPath = m_CurrentDirectory->FullPath;
FileSystem::Scan();
if (FileSystem::DirectoryExists(previousPath, true))
{
m_CurrentDirectory = FileSystem::GetDirectory(FileSystem::AbsoluteToRelative(previousPath));
}
else
{
m_CurrentDirectory = FileSystem::RootDirectory;
}
}
float h = 200;
static float sz1 = 300;
@@ -888,6 +1014,11 @@ namespace Nuake
{
for (Ref<Directory>& d : m_CurrentDirectory->Directories)
{
if (d->GetName() == "bin" || d->GetName() == ".vs" || d->GetName() == "obj")
{
continue;
}
if(String::Sanitize(d->Name).find(String::Sanitize(m_SearchKeyword)) != std::string::npos)
{
if (i + 1 % amount != 0)
@@ -907,6 +1038,11 @@ namespace Nuake
{
if(m_SearchKeyword.empty() || f->GetName().find(String::Sanitize(m_SearchKeyword)) != std::string::npos)
{
if (f->GetFileType() == FileType::Unknown || f->GetFileType() == FileType::Assembly)
{
continue;
}
if (i + 1 % amount != 0 || i == 1)
{
ImGui::TableNextColumn();

View File

@@ -1,5 +1,5 @@
#pragma once
#include <src/Core/FileSystem.h>
#include "src/FileSystem/FileSystem.h"
#include <src/Scene/Entities/Entity.h>
#include "EditorInterface.h"
@@ -32,5 +32,9 @@ namespace Nuake {
bool DeletePopup();
void DrawContextMenu();
void RefreshFileBrowser();
Color GetColorByFileType(FileType fileType);
void Scan();
};
}

View File

@@ -1,11 +1,24 @@
#include "MapImporterWindow.h"
#include <imgui/imgui.h>
#include "../Misc/InterfaceFonts.h"
#include <src/UI/ImUI.h>
#include <src/Core/Logger.h>
#include <regex>
#include <src/Threading/JobSystem.h>
#include <Engine.h>
#include <src/Core/Logger.h>
#include <src/FileSystem/File.h>
#include <src/Threading/JobSystem.h>
#include <src/UI/ImUI.h>
#include <src/FileSystem/FileDialog.h>
#include <src/Core/String.h>
#include <src/Resource/Project.h>
#include <imgui/imgui.h>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <regex>
using namespace Nuake;
void MapImporterWindow::Draw()
{
@@ -227,7 +240,7 @@ std::vector<std::string> MapImporterWindow::ScanUsedWads()
std::string MapImporterWindow::GetTransformedWadPath(const std::string& path)
{
const std::string& baseTextureDir = "/textures/";
const std::string& baseTextureDir = "/Textures/";
using namespace Nuake;
if (m_WadToMaterialMap.find(path) != m_WadToMaterialMap.end())
@@ -272,7 +285,7 @@ std::string MapImporterWindow::GetTransformedWadPath(const std::string& path)
if (entry.is_regular_file() && stem == upperInput)
{
std::filesystem::path relativePath = std::filesystem::relative(entry.path(), FileSystem::Root + "/textures/");
std::filesystem::path relativePath = std::filesystem::relative(entry.path(), FileSystem::Root + "/Textures/");
std::filesystem::path pathWithoutExtension = relativePath;
pathWithoutExtension = pathWithoutExtension.parent_path(); // Remove the file name

View File

@@ -1,7 +1,7 @@
#pragma once
#include <src/Core/FileSystem.h>
#include <src/Core/FileSystem.h>
#include "src/FileSystem/FileSystem.h"
#include "src/FileSystem/FileSystem.h"
#include <atomic>
class MapImporterWindow

View File

@@ -7,7 +7,8 @@
#include <src/Rendering/Textures/TextureManager.h>
#include <src/Rendering/Textures/Texture.h>
#include <src/Scene/Entities/ImGuiHelper.h>
#include <src/Core/FileSystem.h>
#include <src/FileSystem/FileDialog.h>
#include "src/FileSystem/FileSystem.h"
#include <src/UI/ImUI.h>
#include <src/Core/Logger.h>
#include <src/Resource/Project.h>
@@ -52,7 +53,7 @@ namespace Nuake
ImGui::PopStyleVar();
}
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.1, 0.1, 0.1, 0.2f));
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.1f, 0.1f, 0.1f, 0.2f));
ImGui::BeginChild("TemplateContainer", { ImGui::GetContentRegionAvail().x - 64.0f, ImGui::GetContentRegionAvail().y }, true, ImGuiChildFlags_AlwaysUseWindowPadding);
{
ImGui::Dummy({ 4, 4 });
@@ -93,7 +94,7 @@ namespace Nuake
if (showTitleEmptyWarning && projectTitle.empty())
{
ImGui::SameLine();
ImGui::TextColored({ 1.0, 0.1, 0.1, 1.0 }, ICON_FA_EXCLAMATION_TRIANGLE);
ImGui::TextColored({ 1.0f, 0.1f, 0.1f, 1.0f }, ICON_FA_EXCLAMATION_TRIANGLE);
Nuake::UI::Tooltip("Title required");
}
@@ -138,28 +139,26 @@ namespace Nuake
ImGui::InputText("##Location", &location); ImGui::SameLine();
if (ImGui::Button((ICON_FA_FOLDER + std::string("##folderOpen")).c_str()))
{
std::string folderPath = Nuake::FileDialog::SaveFile("Project File\0*.project");
std::string folderPath = Nuake::FileDialog::OpenFolder();
folderPath = Nuake::String::ReplaceSlash(folderPath);
if (!folderPath.empty())
{
auto splits = Nuake::String::Split(folderPath, '/');
projectFileName = splits[splits.size() - 1];
if (!Nuake::String::EndsWith(projectFileName, ".project"))
{
projectFileName += ".project";
}
location = "";
for (int i = 0; i < splits.size() - 1; i++)
for (int i = 0; i < splits.size(); i++)
{
location += splits[i] + "/";
}
}
}
projectFileName = Nuake::String::RemoveWhiteSpace(projectTitle) + ".project";
finalLocation = location;
static std::string projectParentPath = location;
projectParentPath = location;
@@ -193,7 +192,12 @@ namespace Nuake
ImGui::Dummy({ 1, ImGui::GetContentRegionAvail().y - 42 });
ImGui::Dummy({ ImGui::GetContentRegionAvail().x - 130, 38 }); ImGui::SameLine();
ImGui::Dummy({ ImGui::GetContentRegionAvail().x - 230 - 16, 38}); ImGui::SameLine();
if (Nuake::UI::SecondaryButton("Cancel", { 100, 38 }))
{
m_Editor->isCreatingNewProject = false;
}
ImGui::SameLine();
if (Nuake::UI::PrimaryButton((ICON_FA_PLUS + std::string(" Create")).c_str(), Nuake::Vector2{ 120, 38 }, Nuake::Color(primaryColor.x, primaryColor.y, primaryColor.z, primaryColor.w)))
{
if (projectTitle.empty())
@@ -230,7 +234,7 @@ namespace Nuake
Nuake::FileSystem::SetRootDirectory(projectParentPath);
auto project = Nuake::Project::New(projectTitle, description, finalLocation);
Nuake::Engine::LoadProject(project);
Nuake::Engine::LoadScene(Nuake::Scene::New());
Nuake::Engine::SetCurrentScene(Nuake::Scene::New());
project->Settings.PrimaryColor = Nuake::Color(primaryColor.x, primaryColor.y, primaryColor.z, primaryColor.w);
project->Save();
@@ -239,7 +243,7 @@ namespace Nuake
window->Maximize();
m_Editor->filesystem->m_CurrentDirectory = Nuake::FileSystem::RootDirectory;
m_Editor->isNewProject = true;
m_HasCreatedProject = true;
}
}
@@ -263,7 +267,6 @@ namespace Nuake
void NewProjectWindow::DrawProjectTemplate(uint32_t i, const std::string& title, const std::string& description)
{
opened = true;
ImGui::ShowDemoWindow(&opened);
ImGui::Dummy({ 4, 4 });
ImGui::SameLine();
opened = true;

View File

@@ -0,0 +1,919 @@
#include "PrefabEditorWindow.h"
#include <src/Core/Input.h>
#include <src/Rendering/Buffers/FrameBuffer.h>
#include <src/Rendering/SceneRenderer.h>
#include <src/Resource/Prefab.h>
#include <src/Scene/Scene.h>
#include <src/Scene/EditorCamera.h>
#include <src/Scene/Entities/Entity.h>
#include <src/Rendering/Textures/Texture.h>
#include <imgui/imgui.h>
#include <imgui/imgui_internal.h>
#include <src/Scene/Components/SpriteComponent.h>
#include <src/Scene/Components/ParticleEmitterComponent.h>
#include <src/Scene/Components/RigidbodyComponent.h>
#include <src/Scene/Components/BoxCollider.h>
#include <src/Scene/Components/SphereCollider.h>
#include <src/Scene/Components/AudioEmitterComponent.h>
#include <src/Scene/Components/PrefabComponent.h>
#include <src/Scene/Components/BSPBrushComponent.h>
#include <src/Scene/Components/NetScriptComponent.h>
#include <src/FileSystem/FileDialog.h>
#include <imgui/ImGuizmo.h>
#include <glm/gtc/type_ptr.hpp>
using namespace Nuake;
PrefabEditorWindow::PrefabEditorWindow(Ref<Prefab> inPrefab) :
prefab(inPrefab),
SelectionPanel(CreateScope<EditorSelectionPanel>(Selection))
{
const Vector2 defaultSize = Vector2{ 640, 360 };
viewportFramebuffer = CreateRef<FrameBuffer>(true, defaultSize);
viewportFramebuffer->SetTexture(CreateRef<Texture>(defaultSize, GL_RGB, GL_RGB16F, GL_FLOAT));
virtualScene = CreateRef<Scene>();
virtualScene->GetEnvironment()->CurrentSkyType = SkyType::ProceduralSky;
virtualScene->GetEnvironment()->ProceduralSkybox->SunDirection = { 0.58f, 0.34f, -0.74f };
prefab = Prefab::InstanceInScene(inPrefab->Path, virtualScene.get());
prefab->Path = inPrefab->Path;
Ref<Texture> outputTexture = CreateRef<Texture>(defaultSize, GL_RGB);
outputTexture->SetParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
outputTexture->SetParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
auto& previewLight = virtualScene->CreateEntity("_directionalLight").AddComponent<LightComponent>();
previewLight.Type = LightType::Directional;
previewLight.SetCastShadows(true);
previewLight.SyncDirectionWithSky = true;
previewLight.Strength = 5.5f;
}
void PrefabEditorWindow::Update(float ts)
{
}
void PrefabEditorWindow::Draw()
{
RenderScene();
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
ImGuiID dockspace_id = ImGui::GetID(prefab->Path.c_str());
ImVec2 dockspace_size;
if (!isInitialized)
{
ImGui::SetNextWindowSize(ImVec2(1280, 720));
}
if(ImGui::Begin(prefab->Path.c_str(), 0, window_flags))
{
dockspace_size = ImGui::GetContentRegionAvail();
ImGui::DockSpace(dockspace_id, dockspace_size, dockspace_flags);
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("File"))
{
if(ImGui::MenuItem("Save", "Ctrl+S"))
{
Save();
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
}
ImGui::End();
// Programmatically dock windows using DockBuilder API
if (!isInitialized)
{
isInitialized = true;
// Create dock layout for the embedded dockspace
ImGui::DockBuilderRemoveNode(dockspace_id); // Clear any existing layout
ImGui::DockBuilderAddNode(dockspace_id, dockspace_flags | ImGuiDockNodeFlags_DockSpace);
ImGui::DockBuilderSetNodeSize(dockspace_id, dockspace_size);
// Split the dockspace into two areas: left and right
ImGuiID dock_left_id = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Left, 0.25f, nullptr, &dockspace_id);
ImGuiID dock_r_id = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 0.66f, nullptr, &dockspace_id);
// Dock windows into the created nodes
ImGui::DockBuilderDockWindow(std::string("Prefab Hierarchy## " + prefab->Path).c_str(), dock_left_id);
ImGui::DockBuilderDockWindow(std::string("Viewport##" + prefab->Path).c_str(), dockspace_id);
ImGui::DockBuilderDockWindow(std::string("Properties##" + prefab->Path).c_str(), dock_r_id);
// Commit the dock layout
ImGui::DockBuilderFinish(dockspace_id);
}
if (ImGui::Begin(std::string("Prefab Hierarchy## " + prefab->Path).c_str()))
{
Ref<Scene> scene = virtualScene;
std::string searchQuery = "";
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 8, 8 });
ImGui::InputTextWithHint("##search", "Search entity", &searchQuery, 0, 0, 0);
ImGui::PopStyleVar();
ImGui::SameLine();
if (UI::PrimaryButton("Add Entity", { ImGui::GetContentRegionAvail().x, 0 }))
{
ImGui::OpenPopup("create_entity_popup");
}
if (ImGui::BeginPopup("create_entity_popup"))
{
Nuake::Entity entity;
if (ImGui::MenuItem("Empty"))
{
entity = scene->CreateEntity("Empty");
}
if (ImGui::BeginMenu("3D"))
{
if (ImGui::MenuItem("Camera"))
{
entity = scene->CreateEntity("Camera");
entity.AddComponent<CameraComponent>();
}
if (ImGui::MenuItem("Model"))
{
entity = scene->CreateEntity("Model");
entity.AddComponent<ModelComponent>();
}
if (ImGui::MenuItem("Skinned Model"))
{
entity = scene->CreateEntity("Skinned Model");
entity.AddComponent<SkinnedModelComponent>();
}
if (ImGui::MenuItem("Sprite"))
{
entity = scene->CreateEntity("Sprite");
entity.AddComponent<SpriteComponent>();
}
if (ImGui::MenuItem("Particle Emitter"))
{
entity = scene->CreateEntity("Particle Emitter");
entity.AddComponent<ParticleEmitterComponent>();
}
if (ImGui::MenuItem("Light"))
{
entity = scene->CreateEntity("Light");
entity.AddComponent<LightComponent>();
}
if (ImGui::MenuItem("Quake Map"))
{
entity = scene->CreateEntity("Quake Map");
entity.AddComponent<QuakeMapComponent>();
}
if (ImGui::MenuItem("NavMesh Volume"))
{
entity = scene->CreateEntity("NavMesh Volume");
entity.AddComponent<NavMeshVolumeComponent>();
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Physics"))
{
if (ImGui::MenuItem("Character Controller"))
{
entity = scene->CreateEntity("Character Controller");
entity.AddComponent<CharacterControllerComponent>();
}
if (ImGui::MenuItem("Rigid Body"))
{
entity = scene->CreateEntity("Rigid Body");
entity.AddComponent<RigidBodyComponent>();
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Colliders"))
{
if (ImGui::MenuItem("Box Collider"))
{
entity = scene->CreateEntity("Box Collider");
entity.AddComponent<BoxColliderComponent>();
}
if (ImGui::MenuItem("Sphere Collider"))
{
entity = scene->CreateEntity("Sphere Collider");
entity.AddComponent<SphereColliderComponent>();
}
if (ImGui::MenuItem("Capsule Collider"))
{
entity = scene->CreateEntity("Capsule Collider");
entity.AddComponent<CapsuleColliderComponent>();
}
if (ImGui::MenuItem("Cylinder Collider"))
{
entity = scene->CreateEntity("Cylinder Collider");
entity.AddComponent<CylinderColliderComponent>();
}
if (ImGui::MenuItem("Mesh Collider"))
{
entity = scene->CreateEntity("Mesh Collider");
entity.AddComponent<MeshColliderComponent>();
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Audio"))
{
if (ImGui::MenuItem("Audio Emitter"))
{
entity = scene->CreateEntity("Audio Emitter");
entity.AddComponent<AudioEmitterComponent>();
}
ImGui::EndMenu();
}
if (entity.IsValid())
{
if (Selection.Type == EditorSelectionType::Entity && Selection.Entity.IsValid())
{
Selection.Entity.AddChild(entity);
}
else
{
auto& camera = virtualScene->m_EditorCamera;
Vector3 newEntityPos = camera->Translation + camera->Direction;
entity.GetComponent<TransformComponent>().SetLocalPosition(newEntityPos);
}
Selection = EditorSelection(entity);
}
ImGui::EndPopup();
}
// Draw a tree of entities.
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(26.f / 255.0f, 26.f / 255.0f, 26.f / 255.0f, 1));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 4, 4 });
if (ImGui::BeginChild("Scene tree", ImGui::GetContentRegionAvail(), false))
{
if (ImGui::BeginTable("entity_table", 4, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_SizingStretchProp))
{
ImGui::TableSetupColumn(" Label", ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_IndentDisable | ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Script", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_IndentDisable | ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Visibility ", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_IndentDisable | ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0));
std::vector<Nuake::Entity> entities = scene->GetAllEntities();
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanFullWidth;
std::string name = prefab->Root.GetComponent<NameComponent>().Name;
// If selected add selected flag.
if (Selection.Type == EditorSelectionType::Entity && Selection.Entity == prefab->Root)
base_flags |= ImGuiTreeNodeFlags_Selected;
DrawEntityTree(prefab->Root);
ImGui::PopStyleVar();
}
ImGui::EndTable();
if (QueueDeletion.GetHandle() != -1)
{
virtualScene->DestroyEntity(QueueDeletion);
// Clear Selection
Selection = EditorSelection();
QueueDeletion = Nuake::Entity{ (entt::entity)-1, scene.get() };
}
}
ImGui::EndChild();
ImGui::PopStyleVar();
ImGui::PopStyleColor();
}
ImGui::End();
SelectionPanel->Draw(Selection, prefab->Path);
DrawViewportWindow();
}
void PrefabEditorWindow::DrawViewportWindow()
{
//viewportFramebuffer->Bind();
////RenderCommand::SetClearColor(Color(1, 0, 0, 1));
//viewportFramebuffer->Clear();
//viewportFramebuffer->Unbind();
//RenderScene();
if (ImGui::Begin(std::string("Viewport##" + prefab->Path).c_str()))
{
DrawOverlay();
ImGuizmo::BeginFrame();
ImGuizmo::SetOrthographic(false);
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
Vector2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
if (viewportFramebuffer->GetSize() != viewportPanelSize)
viewportFramebuffer->QueueResize(viewportPanelSize);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));\
viewportFramebuffer->QueueResize(viewportPanelSize);
ImGui::Image((void*)viewportFramebuffer->GetTexture(GL_COLOR_ATTACHMENT0)->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0));
ImGui::PopStyleVar();
const Vector2& mousePos = Input::GetMousePosition();
ImVec2 imagePos = ImGui::GetWindowPos() + ImGui::GetCursorPos();
const ImVec2& windowPos = ImGui::GetWindowPos();
const auto windowPosNuake = Vector2(windowPos.x, windowPos.y);
const ImVec2& windowSize = ImGui::GetWindowSize();
const bool isInsideWidth = mousePos.x > windowPos.x && mousePos.x < windowPos.x + windowSize.x;
const bool isInsideHeight = mousePos.y > windowPos.y && mousePos.y < windowPos.y + windowSize.y;
isHoveringViewport = isInsideWidth && isInsideHeight;
ImGuizmo::SetDrawlist();
ImGuizmo::AllowAxisFlip(true);
ImGuizmo::SetRect(imagePos.x, imagePos.y + 0.0f, viewportPanelSize.x, viewportPanelSize.y);
auto& editorCam = virtualScene->m_EditorCamera;
isControllingCamera = editorCam->Update(Engine::GetTimestep(), isHoveringViewport);
if (Selection.Type == EditorSelectionType::Entity && !Engine::IsPlayMode())
{
if (!Selection.Entity.IsValid())
{
Selection = EditorSelection();
}
else
{
TransformComponent& tc = Selection.Entity.GetComponent<TransformComponent>();
Matrix4 transform = tc.GetGlobalTransform();
const auto& editorCam = virtualScene->GetCurrentCamera();
Matrix4 cameraView = editorCam->GetTransform();
Matrix4 cameraProjection = editorCam->GetPerspective();
static Vector3 camPreviousPos = virtualScene->m_EditorCamera->Translation;
static Vector3 camNewPos = Vector3(0, 0, 0);
Vector3 camDelta = camNewPos - camPreviousPos;
Vector3 previousGlobalPos = transform[3];
// Imguizmo calculates the delta from the gizmo,
ImGuizmo::Manipulate(
glm::value_ptr(cameraView),
glm::value_ptr(cameraProjection),
CurrentOperation, CurrentMode,
glm::value_ptr(transform), NULL,
UseSnapping ? &CurrentSnapping.x : NULL
);
if (ImGuizmo::IsUsing())
{
// Since imguizmo returns a transform in global space and we want the local transform,
// we need to multiply by the inverse of the parent's global transform in order to revert
// the changes from the parent transform.
Matrix4 localTransform = Matrix4(transform);
Vector3 newGlobalPos = transform[3];
if (ImGui::IsKeyDown(ImGuiKey_LeftShift))
{
Vector3 positionDelta = newGlobalPos - previousGlobalPos;
virtualScene->m_EditorCamera->Translation += positionDelta;
camNewPos = virtualScene->m_EditorCamera->Translation;
}
ParentComponent& parent = Selection.Entity.GetComponent<ParentComponent>();
if (parent.HasParent)
{
const auto& parentTransformComponent = parent.Parent.GetComponent<TransformComponent>();
const Matrix4& parentTransform = parentTransformComponent.GetGlobalTransform();
localTransform = glm::inverse(parentTransform) * localTransform;
}
// Decompose local transform
float decomposedPosition[3];
float decomposedEuler[3];
float decomposedScale[3];
ImGuizmo::DecomposeMatrixToComponents(glm::value_ptr(localTransform), decomposedPosition, decomposedEuler, decomposedScale);
const auto& localPosition = Vector3(decomposedPosition[0], decomposedPosition[1], decomposedPosition[2]);
const auto& localScale = Vector3(decomposedScale[0], decomposedScale[1], decomposedScale[2]);
localTransform[0] /= localScale.x;
localTransform[1] /= localScale.y;
localTransform[2] /= localScale.z;
const auto& rotationMatrix = Matrix3(localTransform);
const Quat& localRotation = glm::normalize(Quat(rotationMatrix));
const Matrix4& rotationMatrix4 = glm::mat4_cast(localRotation);
const Matrix4& scaleMatrix = glm::scale(Matrix4(1.0f), localScale);
const Matrix4& translationMatrix = glm::translate(Matrix4(1.0f), localPosition);
const Matrix4& newLocalTransform = translationMatrix * rotationMatrix4 * scaleMatrix;
tc.Translation = localPosition;
if (CurrentOperation != ImGuizmo::SCALE)
{
tc.Rotation = localRotation;
}
tc.Scale = localScale;
tc.LocalTransform = newLocalTransform;
tc.Dirty = true;
}
}
}
if (ImGui::IsWindowHovered() && isHoveringViewport && !isViewportFocused && ImGui::GetIO().WantCaptureMouse)
{
ImGui::FocusWindow(ImGui::GetCurrentWindow());
}
isViewportFocused = ImGui::IsWindowFocused();
if (ImGui::GetIO().WantCaptureMouse && isHoveringViewport && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && isViewportFocused)
{
auto& gbuffer = virtualScene->m_SceneRenderer->GetGBuffer();
auto pixelPos = (Input::GetMousePosition() - windowPosNuake);
pixelPos.y = gbuffer.GetSize().y - pixelPos.y; // imgui coords are inverted on the Y axi
gbuffer.Bind();
if (const int result = gbuffer.ReadPixel(3, pixelPos); result > 0)
{
auto ent = Nuake::Entity{ (entt::entity)(result - 1), virtualScene.get() };
if (ent.IsValid())
{
Selection = EditorSelection(ent);
virtualScene->m_SceneRenderer->mOutlineEntityID = (uint32_t)ent.GetHandle();
}
}
else
{
Selection = EditorSelection(); // None
}
gbuffer.Unbind();
}
}
ImGui::End();
}
void PrefabEditorWindow::DrawOverlay()
{
if (Engine::GetGameState() == GameState::Playing)
{
return;
}
// FIXME-VIEWPORT: Select a default viewport
const float DISTANCE = 10.0f;
int corner = 0;
ImGuiIO& io = ImGui::GetIO();
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
window_flags |= ImGuiWindowFlags_NoMove;
ImGuiViewport* viewport = ImGui::GetWindowViewport();
ImVec2 work_area_pos = ImGui::GetCurrentWindow()->Pos; // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any!
ImVec2 work_area_size = ImGui::GetCurrentWindow()->Size;
ImVec2 window_pos = ImVec2((corner & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE));
ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 32.0f);
if (ImGui::Begin("ActionBar2", 0, window_flags))
{
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 2));
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 100);
bool selectedMode = CurrentOperation == ImGuizmo::OPERATION::TRANSLATE;
if (selectedMode)
{
Color color = Engine::GetProject()->Settings.PrimaryColor;
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
}
if (ImGui::Button(ICON_FA_ARROWS_ALT , ImVec2(30, 28)) || (ImGui::Shortcut(ImGuiKey_W, 0, ImGuiInputFlags_RouteGlobalLow) && !ImGui::IsAnyItemActive() && !isControllingCamera))
{
CurrentOperation = ImGuizmo::OPERATION::TRANSLATE;
}
UI::Tooltip("Translate");
if (selectedMode)
{
ImGui::PopStyleColor();
}
ImGui::SameLine();
selectedMode = CurrentOperation == ImGuizmo::OPERATION::ROTATE;
if (selectedMode)
{
Color color = Engine::GetProject()->Settings.PrimaryColor;
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
}
if (ImGui::Button(ICON_FA_SYNC_ALT, ImVec2(30, 28)) || (ImGui::Shortcut(ImGuiKey_E, 0, ImGuiInputFlags_RouteGlobalLow) && !ImGui::IsAnyItemActive() && !isControllingCamera))
{
CurrentOperation = ImGuizmo::OPERATION::ROTATE;
}
UI::Tooltip("Rotate");
if (selectedMode)
{
ImGui::PopStyleColor();
}
ImGui::SameLine();
selectedMode = CurrentOperation == ImGuizmo::OPERATION::SCALE;
if (selectedMode)
{
Color color = Engine::GetProject()->Settings.PrimaryColor;
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
}
if (ImGui::Button(ICON_FA_EXPAND_ALT, ImVec2(30, 28)) || (ImGui::Shortcut(ImGuiKey_R, 0, ImGuiInputFlags_RouteGlobalLow) && !ImGui::IsAnyItemActive() && !isControllingCamera))
{
CurrentOperation = ImGuizmo::OPERATION::SCALE;
}
UI::Tooltip("Scale");
if (selectedMode)
{
ImGui::PopStyleColor();
}
ImGui::SameLine();
selectedMode = CurrentMode == ImGuizmo::MODE::WORLD;
if (selectedMode)
{
Color color = Engine::GetProject()->Settings.PrimaryColor;
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
}
if (ImGui::Button(ICON_FA_GLOBE, ImVec2(30, 28)))
{
CurrentMode = ImGuizmo::MODE::WORLD;
}
UI::Tooltip("Global Transformation");
if (selectedMode)
{
ImGui::PopStyleColor();
}
ImGui::SameLine();
selectedMode = CurrentMode == ImGuizmo::MODE::LOCAL;
if (selectedMode)
{
Color color = Engine::GetProject()->Settings.PrimaryColor;
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
}
if (ImGui::Button(ICON_FA_CUBE, ImVec2(30, 28)))
{
CurrentMode = ImGuizmo::MODE::LOCAL;
}
UI::Tooltip("Local Transformation");
if (selectedMode)
{
ImGui::PopStyleColor();
}
ImGui::SameLine();
ImGui::SameLine();
ImGui::PushItemWidth(75);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 6, 6 });
ImGui::DragFloat("##snapping", &CurrentSnapping.x, 0.01f, 0.0f, 100.0f);
CurrentSnapping = { CurrentSnapping.x, CurrentSnapping.x, CurrentSnapping.z };
ImGui::PopStyleVar();
ImGui::PopItemWidth();
UI::Tooltip("Snapping");
ImGui::PopStyleVar();
ImGui::PopStyleVar();
ImGui::PopStyleColor();
}
ImGui::PopStyleVar();
ImGui::End();
int corner2 = 1;
work_area_pos = ImGui::GetCurrentWindow()->Pos; // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any!
work_area_size = ImGui::GetCurrentWindow()->Size;
window_pos = ImVec2((corner2 & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner2 & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE));
window_pos_pivot = ImVec2((corner2 & 1) ? 1.0f : 0.0f, (corner2 & 2) ? 1.0f : 0.0f);
ImGui::SetNextWindowPos(window_pos + ImVec2(0, 40), ImGuiCond_Always, window_pos_pivot);
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 32.0f);
ImGui::SetNextWindowSize(ImVec2(16, ImGui::GetContentRegionAvail().y - DISTANCE * 2.0 - 40.0));
if (ImGui::Begin("Controls2", 0, window_flags))
{
const auto& editorCam = virtualScene->m_EditorCamera;
const float camSpeed = editorCam->Speed;
const float maxSpeed = 50.0f;
const float minSpeed = 0.05f;
const float normalizedSpeed = glm::clamp((camSpeed / maxSpeed), 0.0f, 1.0f);
ImVec2 start = ImGui::GetWindowPos() - ImVec2(0.0, 4.0);
ImVec2 end = start + ImGui::GetWindowSize() - ImVec2(0, 16.0);
ImVec2 startOffset = ImVec2(start.x, end.y - (normalizedSpeed * (ImGui::GetWindowHeight() - 20.0)));
ImGui::GetWindowDrawList()->AddRectFilled(startOffset + ImVec2(0, 10.0), end + ImVec2(0.0, 20.0), IM_COL32(255, 255, 255, 180), 8.0f, ImDrawFlags_RoundCornersAll);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 100);
ImGui::PopStyleVar();
}
ImGui::PopStyleVar();
ImGui::End();
}
void PrefabEditorWindow::RenderScene()
{
virtualScene->Update(Engine::GetTimestep());
Ref<SceneRenderer> sceneRenderer = virtualScene->m_SceneRenderer;
Ref<EditorCamera> editorCam = virtualScene->m_EditorCamera;
editorCam->OnWindowResize(viewportFramebuffer->GetSize().x, viewportFramebuffer->GetSize().y);
virtualScene->Draw(*viewportFramebuffer.get());
sceneRenderer->BeginRenderScene(editorCam->GetPerspective(), editorCam->GetTransform(), editorCam->Translation);
sceneRenderer->RenderScene(*virtualScene, *viewportFramebuffer.get(), true);
}
void PrefabEditorWindow::DrawEntityTree(Nuake::Entity e)
{
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{ 0.0f, 0.0f });
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_FramePadding | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAllColumns;
NameComponent& nameComponent = e.GetComponent<NameComponent>();
std::string name = nameComponent.Name;
ParentComponent& parent = e.GetComponent<ParentComponent>();
if (Selection.Type == EditorSelectionType::Entity && Selection.Entity == e)
base_flags |= ImGuiTreeNodeFlags_Selected;
ImGui::TableNextColumn();
// Write in normal font.
// ImGui::PushFont(normalFont);
// If has no childrens draw tree node leaf
if (parent.Children.size() <= 0)
{
base_flags |= ImGuiTreeNodeFlags_Leaf;
}
if (nameComponent.IsPrefab && e.HasComponent<PrefabComponent>())
{
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 255, 0, 255));
}
else if (e.HasComponent<BSPBrushComponent>())
{
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 120));
}
//if (!m_IsRenaming && m_ShouldUnfoldEntityTree && Selection.Type == EditorSelectionType::Entity && e.GetScene()->EntityIsParent(Selection.Entity, e))
//{
// ImGui::SetNextItemOpen(true);
//}
auto cursorPos = ImGui::GetCursorPos();
ImGui::SetNextItemAllowOverlap();
bool open = ImGui::TreeNodeEx(name.c_str(), base_flags);
if (isRenaming)
{
if (Selection.Type == EditorSelectionType::Entity && Selection.Entity == e)
{
ImGui::SetCursorPosY(cursorPos.y);
ImGui::Indent();
ImGui::InputText("##renamingEntity", &name);
ImGui::Unindent();
if (Input::IsKeyDown(Key::ENTER))
{
nameComponent.Name = name;
isRenaming = false;
}
}
}
bool isDragging = false;
if (nameComponent.IsPrefab && e.HasComponent<PrefabComponent>() || e.HasComponent<BSPBrushComponent>())
{
ImGui::PopStyleColor();
}
else if (!isRenaming && ImGui::BeginDragDropSource())
{
ImGui::SetDragDropPayload("ENTITYPrefab", (void*)&e, sizeof(Nuake::Entity));
ImGui::Text(name.c_str());
ImGui::EndDragDropSource();
}
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITYPrefab"))
{
Nuake::Entity payload_entity = *(const Nuake::Entity*)payload->Data;
// Check if entity is already parent.
ParentComponent& parentPayload = payload_entity.GetComponent<ParentComponent>();
if (!payload_entity.EntityContainsItself(payload_entity, e) && parentPayload.Parent != e && std::count(parent.Children.begin(), parent.Children.end(), payload_entity) == 0)
{
if (parentPayload.HasParent)
{
// Erase remove idiom.
ParentComponent& childOfParent = parentPayload.Parent.GetComponent<ParentComponent>();
childOfParent.Children.erase(std::remove(childOfParent.Children.begin(), childOfParent.Children.end(), payload_entity), childOfParent.Children.end());
}
parentPayload.Parent = e;
parentPayload.HasParent = true;
parent.Children.push_back(payload_entity);
}
}
else if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_NetScript"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 512);
std::string path = Nuake::FileSystem::AbsoluteToRelative(std::move(fullPath));
if (e.HasComponent<NetScriptComponent>())
{
e.GetComponent<NetScriptComponent>().ScriptPath = path;
}
else
{
e.AddComponent<NetScriptComponent>().ScriptPath = path;
}
}
ImGui::EndDragDropTarget();
}
if (!isDragging && ImGui::IsItemHovered() && ImGui::IsMouseReleased(0))
{
// We selected another another that we werent renaming
if (Selection.Entity != e)
{
isRenaming = false;
}
Selection = EditorSelection(e);
}
if (!isDragging && (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) || Input::IsKeyPressed(Key::F2))
{
isRenaming = true;
}
if (!isRenaming && Selection.Type == EditorSelectionType::Entity && Input::IsKeyPressed(Key::DELETE_KEY))
{
QueueDeletion = Selection.Entity;
}
if (ImGui::BeginPopupContextItem())
{
Selection = EditorSelection(e);
Nuake::Entity entity = Selection.Entity;
if (entity.HasComponent<CameraComponent>())
{
// Moves the editor camera to the camera position and direction.
if (ImGui::Selectable("Focus camera"))
{
Ref<EditorCamera> editorCam = virtualScene->m_EditorCamera;
Vector3 camDirection = entity.GetComponent<CameraComponent>().CameraInstance->GetDirection();
camDirection.z *= -1.0f;
editorCam->SetTransform(glm::inverse(entity.GetComponent<TransformComponent>().GetGlobalTransform()));
}
ImGui::Separator();
}
if (ImGui::Selectable("Remove"))
{
QueueDeletion = e;
}
if (entity.GetComponent<ParentComponent>().HasParent && ImGui::Selectable("Move to root"))
{
auto& parentComp = Selection.Entity.GetComponent<ParentComponent>();
if (parentComp.HasParent)
{
auto& parentParentComp = parentComp.Parent.GetComponent<ParentComponent>();
parentParentComp.RemoveChildren(entity);
parentComp.HasParent = false;
}
}
if (ImGui::Selectable("Save entity as a new prefab"))
{
Ref<Prefab> newPrefab = Prefab::CreatePrefabFromEntity(Selection.Entity);
std::string savePath = Nuake::FileDialog::SaveFile("*.prefab");
if (!String::EndsWith(savePath, ".prefab"))
{
savePath += ".prefab";
}
if (!savePath.empty())
{
newPrefab->SaveAs(savePath);
Selection.Entity.AddComponent<PrefabComponent>().PrefabInstance = newPrefab;
}
}
ImGui::EndPopup();
}
ImGui::TableNextColumn();
ImGui::TextColored(ImVec4(0.5, 0.5, 0.5, 1.0), "");
ImGui::TableNextColumn();
{
bool hasScript = e.HasComponent<NetScriptComponent>();
if (hasScript)
{
std::string scrollIcon = std::string(ICON_FA_SCROLL) + "##" + name;
ImGui::PushStyleColor(ImGuiCol_Button, { 0, 0, 0, 0 });
if (ImGui::Button(scrollIcon.c_str(), { 40, 0 }))
{
auto& scriptComponent = e.GetComponent<NetScriptComponent>();
if (!scriptComponent.ScriptPath.empty() && FileSystem::FileExists(scriptComponent.ScriptPath))
{
OS::OpenIn(FileSystem::RelativeToAbsolute(scriptComponent.ScriptPath));
}
}
ImGui::PopStyleColor();
}
}
ImGui::TableNextColumn();
{
bool& isVisible = e.GetComponent<VisibilityComponent>().Visible;
std::string visibilityIcon = isVisible ? ICON_FA_EYE : ICON_FA_EYE_SLASH;
ImGui::PushStyleColor(ImGuiCol_Button, { 0, 0, 0, 0 });
if (ImGui::Button(visibilityIcon.c_str(), { 40, 0 }))
{
isVisible = !isVisible;
}
ImGui::PopStyleColor();
}
if (open)
{
// Caching list to prevent deletion while iterating.
std::vector<Nuake::Entity> childrens = parent.Children;
for (auto& c : childrens)
DrawEntityTree(c);
ImGui::TreePop();
}
ImGui::PopStyleVar();
//ImGui::PopFont();
}
void PrefabEditorWindow::Save()
{
Ref<Prefab> newPrefab = Prefab::CreatePrefabFromEntity(prefab->Root);
newPrefab->Path = prefab->Path;
newPrefab->SaveAs(newPrefab->Path);
}

View File

@@ -0,0 +1,53 @@
#pragma once
#include "src/Core/Core.h"
#include "src/Core/Maths.h"
#include "../EditorSelectionPanel.h"
#include <src/Vendors/imgui/ImGuizmo.h>
namespace Nuake
{
class Prefab;
class Scene;
class FrameBuffer;
class Texture;
class Entity;
}
class PrefabEditorWindow
{
public:
PrefabEditorWindow(Ref<Nuake::Prefab> prefab);
~PrefabEditorWindow() {
ASSERT(false);
};
void Update(float ts);
void Draw();
private:
Ref<Nuake::Prefab> prefab;
Ref<Nuake::Scene> virtualScene;
Ref<Nuake::FrameBuffer> viewportFramebuffer;
Ref<Nuake::Texture> viewportTexture;
bool isViewportFocused;
bool isHoveringViewport;
bool isRenaming;
bool isInitialized = false;
Scope<EditorSelectionPanel> SelectionPanel;
EditorSelection Selection;
Nuake::Entity QueueDeletion;
ImGuizmo::OPERATION CurrentOperation = ImGuizmo::TRANSLATE;
ImGuizmo::MODE CurrentMode = ImGuizmo::WORLD;
bool UseSnapping = true;
Nuake::Vector3 CurrentSnapping = Nuake::Vector3{ 0.0f, 0.0f, 0.0f };
bool isControllingCamera = false;
private:
void DrawViewportWindow();
void DrawOverlay();
void RenderScene();
void DrawEntityTree(Nuake::Entity e);
void Save();
};

View File

@@ -1,9 +1,12 @@
#include "ProjectInterface.h"
#include <src/Vendors/imgui/imgui.h>
#include "Engine.h"
#include "src/Core/FileSystem.h"
#include <src/FileSystem/FileDialog.h>
#include "src/FileSystem/FileSystem.h"
#include <src/Scripting/ScriptingEngineNet.h>
#include <src/Scripting/ScriptingEngineNet.h>
#include <src/Vendors/imgui/imgui.h>
//#include "ImGuiTextHelper.h"
namespace Nuake {

View File

@@ -1,7 +1,8 @@
#include "ProjectSettingsWindow.h"
#include <imgui/imgui.h>
#include "../../Misc/InterfaceFonts.h"
#include <src/Core/FileSystem.h>
#include <src/FileSystem/FileDialog.h>
#include "src/FileSystem/FileSystem.h"
#include "../EditorInterface.h"
#include "../../Commands/Commands/Commands.h"
#include <src/Audio/AudioManager.h>
@@ -14,9 +15,9 @@ ProjectSettingsCategoryWindowGeneral::ProjectSettingsCategoryWindowGeneral(Ref<N
void ProjectSettingsCategoryWindowGeneral::Draw()
{
using namespace Nuake;
//ImGui::InputText("Project Name", &m_Project->Name);
//ImGui::InputTextMultiline("Project Description", &m_Project->Description);
ImGui::InputText("Project Name", &m_Project->Name);
ImGui::InputTextMultiline("Project Description", &m_Project->Description);
if (ImGui::Button("Locate"))
{
@@ -28,9 +29,10 @@ void ProjectSettingsCategoryWindowGeneral::Draw()
}
}
ImGui::ColorEdit4("Primary Color", &m_Project->Settings.PrimaryColor.r);
ImGui::SameLine();
ImGui::InputText("Trenchbroom Path", &m_Project->TrenchbroomPath);
//ImGui::InputText("Trenchbroom Path", &m_Project->TrenchbroomPath);
ImGui::ColorEdit4("Primary Color", &m_Project->Settings.PrimaryColor.r);
}
ProjectSettingsWindow::ProjectSettingsWindow()
@@ -63,7 +65,7 @@ void ProjectSettingsWindow::Draw()
return;
}
ImGui::SetNextWindowSizeConstraints({600, 300}, {1280, 720});
ImGui::SetNextWindowSizeConstraints({800, 400}, {1280, 720});
if (ImGui::Begin("Project Settings", &m_DisplayWindow, ImGuiWindowFlags_NoDocking))
{
ImVec4* colors = ImGui::GetStyle().Colors;
@@ -121,7 +123,7 @@ ProjectSettingsCategoryWindowViewport::ProjectSettingsCategoryWindowViewport(Ref
void ProjectSettingsCategoryWindowViewport::Draw()
{
ImGui::DragFloat("Outline Radius", &m_Project->Settings.OutlineRadius, 0.1f, 1.0f, 10.0f);
ImGui::DragFloat("Outline Radius", &m_Project->Settings.OutlineRadius, 0.1f, 1.0f, 90.0f);
ImGui::DragFloat("Gizmo Size", &m_Project->Settings.GizmoSize, 0.01f, 0.05f, 0.5f);
ImGui::Separator();
ImGui::Checkbox("Smooth Camera", &m_Project->Settings.SmoothCamera);
@@ -182,11 +184,11 @@ void ProjectSettingsCategoryPhysics::Draw()
Engine::SetPhysicsStep(Engine::GetProject()->Settings.PhysicsStep);
}
ImGui::DragInt("Maximum SubSteps", &Engine::GetProject()->Settings.MaxPhysicsSubStep, 1.0f, 8.0f, 128);
ImGui::DragInt("Maximum SubSteps", &Engine::GetProject()->Settings.MaxPhysicsSubStep, 1, 8, 128);
ImGui::DragInt("Maximum Bodies", &Engine::GetProject()->Settings.MaxPhysicsBodies, 1.0f, 256.0f, 8000);
ImGui::DragInt("Maximum Body Pair", &Engine::GetProject()->Settings.MaxPhysicsBodyPair, 1.0f, 256.0f, 4096.0f);
ImGui::DragInt("Maximum Contact Constraint", &Engine::GetProject()->Settings.MaxPhysicsContactConstraints, 1.0f, 256.0f, 4096.0f);
ImGui::DragInt("Maximum Bodies", &Engine::GetProject()->Settings.MaxPhysicsBodies, 1.0f, 256, 8000);
ImGui::DragInt("Maximum Body Pair", &Engine::GetProject()->Settings.MaxPhysicsBodyPair, 1.0f, 256, 4096);
ImGui::DragInt("Maximum Contact Constraint", &Engine::GetProject()->Settings.MaxPhysicsContactConstraints, 1.0f, 256, 4096);
}
ProjectSettingsCategoryAudio::ProjectSettingsCategoryAudio(Ref<Nuake::Project> project) :

View File

@@ -1,11 +1,13 @@
#include "TrenchbroomConfiguratorWindow.h"
#include <Engine.h>
#include <src/Resource/Project.h>
#include <src/UI/ImUI.h>
#include <src/Core/OS.h>
#include <src/Rendering/Textures/TextureManager.h>
#include <src/Resource/Prefab.h>
void TrenchbroomConfiguratorWindow::Update()
{

View File

@@ -9,12 +9,12 @@ void UIDemoWindow::Draw()
{
using namespace Nuake;
UI::BeginWindow("UI Demo");
{
UI::PrimaryButton("Primary Button");
UI::SecondaryButton("Secondary Button");
UI::FloatSlider("Float slider", floatSlider);
UI::CheckBox("Checkbox", checkbox);
}
UI::EndWindow();
//UI::BeginWindow("UI Demo");
//{
// UI::PrimaryButton("Primary Button");
// UI::SecondaryButton("Secondary Button");
// UI::FloatSlider("Float slider", floatSlider);
// UI::CheckBox("Checkbox", checkbox);
//}
//UI::EndWindow();
}

View File

@@ -5,7 +5,8 @@
#include "../Misc/InterfaceFonts.h"
#include <Engine.h>
#include <src/Core/FileSystem.h>
#include <src/FileSystem/FileDialog.h>
#include "src/FileSystem/FileSystem.h"
#include <src/Resource/Project.h>
#include <src/Core/Logger.h>
#include <src/Rendering/Textures/TextureManager.h>
@@ -80,6 +81,11 @@ namespace Nuake
ParseRecentFile();
if (_Projects.size() > 0)
{
SelectedProject = 0;
}
// Load Nuake logo
_NuakeLogo = TextureManager::Get()->GetTexture(NUAKE_LOGO_PATH);
}
@@ -109,8 +115,41 @@ namespace Nuake
Engine::GetCurrentWindow()->SetTitle("Nuake Engine - Editing " + project->Name);
}
void WelcomeWindow::ImportProject(const std::string& file)
{
if (file != "" && String::EndsWith(file, ".project"))
{
// Prevent importing the same project twice in the list
bool alreadyContainsProject = false;
for (auto& p : _Projects)
{
if (p.Path == file)
{
alreadyContainsProject = true;
}
}
if (!alreadyContainsProject)
{
_Projects.push_back(ProjectPreview(file));
SaveRecentFile();
}
}
}
void WelcomeWindow::Draw()
{
if (!queuedRemovalPath.empty())
{
std::erase_if(_Projects, [&](ProjectPreview preview)
{
return preview.Path == queuedRemovalPath;
});
queuedRemovalPath = "";
SaveRecentFile();
}
// Make viewport fullscreen
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->Pos);
@@ -144,6 +183,7 @@ namespace Nuake
DrawRightControls();
ImGui::SameLine();
DrawRecentProjectsSection();
ImGui::End();
@@ -157,36 +197,30 @@ namespace Nuake
ImVec2 projectsWindowSize = ImGui::GetContentRegionAvail();
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0));
ImGui::BeginChild("Projects", projectsWindowSize, false);
ImGui::BeginChild("Projects", projectsWindowSize);
{
//ImGui::Dummy({ 4, 4 });
//ImGui::SameLine();
//{
// auto font = UIFont(Bold);
// ImGui::Text("Recent Projects");
//}
ImGui::PopStyleColor();
for (uint32_t i = 0; i < std::size(_Projects); i++)
{
DrawProjectItem(i);
}
const float itemHeight = 100.0f;
ImGui::Dummy({ 1, 4 });
ImGui::SameLine();
const float itemHeight = 60.0f;
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
if (ImGui::Button("Import an existing project", ImVec2(ImGui::GetContentRegionAvail().x, itemHeight)))
if (UI::SecondaryButton("Import or Drag a Project", Vector2(ImGui::GetContentRegionAvail().x - 8, itemHeight)))
{
const std::string path = FileDialog::OpenFile("Project file(.project)\0*.project\0");
if (path != "" && String::EndsWith(path, ".project"))
{
// Prevent importing the same project twice in the list
bool alreadyContainsProject = false;
for (auto& p : _Projects)
{
if (p.Path == path)
{
alreadyContainsProject = true;
}
}
if (!alreadyContainsProject)
{
_Projects.push_back(ProjectPreview(path));
}
}
ImportProject(path);
}
ImGui::PopStyleColor();
}
@@ -195,8 +229,10 @@ namespace Nuake
void WelcomeWindow::DrawProjectItem(const uint32_t itemIndex)
{
ImGui::Dummy({ 4, 4 });
ImGui::SameLine();
const ProjectPreview& project = _Projects[itemIndex];
const uint32_t itemHeight = 120;
const uint32_t itemHeight = 56;
const float cursorYStart = ImGui::GetCursorPosY();
const std::string selectableName = "##" + std::to_string(itemIndex);
@@ -210,7 +246,24 @@ namespace Nuake
draw_list->ChannelsSetCurrent(1);
//ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0, 0, 0, 0));
bool result = ImGui::Selectable(selectableName.c_str(), SelectedProject == itemIndex, ImGuiSelectableFlags_AllowOverlap | ImGuiSelectableFlags_AllowDoubleClick, ImVec2(ImGui::GetContentRegionAvail().x, itemHeight));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 8.0f);
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.25, 0.25, 0.5, 0.0));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.25, 0.25, 0.5, 0.0));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.25, 0.25, 0.5, 0.0));
bool result = ImGui::Selectable(selectableName.c_str(), SelectedProject == itemIndex, ImGuiSelectableFlags_AllowOverlap | ImGuiSelectableFlags_AllowDoubleClick, ImVec2(ImGui::GetContentRegionAvail().x - 12, itemHeight));
ImGui::PopStyleVar();
if (ImGui::BeginPopupContextWindow(selectableName.c_str()))
{
if (ImGui::MenuItem("Remove from list"))
{
queuedRemovalPath = _Projects[itemIndex].Path;
}
ImGui::EndPopup();
}
if (result)
{
SelectedProject = itemIndex;
@@ -220,12 +273,23 @@ namespace Nuake
{
SaveRecentFile();
queuedProjectPath = _Projects[SelectedProject].Path;
queuedProjectPath = _Projects[itemIndex].Path;
}
//ImGui::PopStyleColor();
ImU32 color = IM_COL32(63, 63, 66, 128);
if (isSelected)
{
color = IM_COL32(63, 69, 79, 255);
}
else if (ImGui::IsItemHovered())
{
color = IM_COL32(20, 20, 20, 128);
}
draw_list->ChannelsMerge();
if (isSelected && ImGui::IsKeyPressed(ImGuiKey_Delete))
{
queuedRemovalPath = _Projects[SelectedProject].Path;
}
if (result)
{
@@ -233,33 +297,62 @@ namespace Nuake
}
//ImGui::PopStyleColor();
const ImVec2 padding = ImVec2(25.0f, 20.0f);
const ImVec2 iconSize = ImVec2(100, 100);
ImGui::SetCursorPos(ImVec2(padding.x / 2.0, padding.y / 2.0) + ImVec2(0, cursorYStart));
draw_list->ChannelsSetCurrent(0);
ImVec2 p_min = ImGui::GetItemRectMin();
ImVec2 p_max = ImGui::GetItemRectMax();
ImGui::GetWindowDrawList()->AddRectFilled(p_min, p_max, color, 4.0f);
draw_list->ChannelsMerge();
ImGui::PopStyleColor(3);
const ImVec2 padding = ImVec2(16.0f, 0.0f);
const ImVec2 iconSize = ImVec2(54, 54.0f);
ImGui::SetCursorPos(ImVec2(padding.x / 2.0, padding.y / 2.0) + ImVec2(4, cursorYStart));
if (project.ProjectIcon)
{
ImGui::Image((ImTextureID)project.ProjectIcon->GetID(), iconSize, ImVec2(0, 1), ImVec2(1, 0));
}
else
{
ImGui::Image((void*)Nuake::TextureManager::Get()->GetTexture("Resources/Images/cube.png")->GetID(), iconSize, ImVec2(0, 1), ImVec2(1, 0));
}
ImGui::SameLine();
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
ImGui::SetCursorPosX(padding.x + iconSize.x);
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
ImGui::SetCursorPosY(cursorYStart + padding.y);
ImGui::SetCursorPosY(cursorYStart + 8.0f);
{
UIFont boldfont = UIFont(Fonts::Normal);
if (isSelected)
{
ImGui::TextColored(ImVec4(119.0f / 255.0f, 187.0f / 255.0f, 1, 255.0f), project.Name.c_str());
}
else
{
UIFont boldfont = UIFont(Fonts::LargeBold);
ImGui::Text(project.Name.c_str());
}
ImGui::SetCursorPosY(cursorYStart + padding.y + 34.f);
{
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
UIFont boldfont = UIFont(Fonts::Bold);
ImGui::Text(project.Description.c_str());
}
ImGui::SetCursorPosY(cursorYStart + itemHeight + 32.0f);
ImGui::SetCursorPosY(cursorYStart + 28.f);
{
ImGui::SetCursorPosX(padding.x + iconSize.x);
UIFont boldfont = UIFont(Fonts::Normal);
if (isSelected)
{
ImGui::TextColored(ImVec4(119.0f / 255.0f, 187.0f / 255.0f, 1, 255.0f), (ICON_FA_INFO_CIRCLE + std::string(" ") + project.Description).c_str());
}
else
{
ImGui::TextColored(ImVec4(1, 1, 1, 0.4), (ICON_FA_INFO_CIRCLE + std::string(" ") + project.Description).c_str());
}
}
ImGui::SetCursorPosY(cursorYStart + itemHeight + 4.0f);
ImGui::Dummy({ 4, 2 });
}
void WelcomeWindow::DrawRightControls()
@@ -275,56 +368,17 @@ namespace Nuake
const ImVec2 buttonSize = ImVec2(ImGui::GetContentRegionAvail().x, buttonHeight);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.14f, 0.5f));
const std::string buttonLabel = std::string(ICON_FA_FOLDER_PLUS) + " New Game Project...";
const std::string buttonLabel = std::string(ICON_FA_FOLDER_PLUS) + " New Project...";
if (Nuake::UI::PrimaryButton(buttonLabel.c_str(), { buttonSize.x, buttonSize.y }))
{
_Editor->isCreatingNewProject = true;
//
//std::string selectedProject = FileDialog::SaveFile("Project file\0*.project");
//
//if (!selectedProject.empty())
//{
// if(!String::EndsWith(selectedProject, ".project"))
// selectedProject += ".project";
//
// auto backslashSplits = String::Split(selectedProject, '\\');
// auto fileName = backslashSplits[backslashSplits.size() - 1];
// std::string finalPath = String::Split(selectedProject, '.')[0];
// if (String::EndsWith(fileName, ".project"))
// {
// // We need to create a folder
// if (const auto& dirPath = finalPath;
// !std::filesystem::create_directory(dirPath))
// {
// // Should we continue?
// Logger::Log("Failed creating project directory: " + dirPath);
// }
// finalPath += "\\" + fileName;
// }
// auto project = Project::New(String::Split(fileName, '.')[0], "no description", finalPath);
// Engine::LoadProject(project);
// Engine::LoadScene(Scene::New());
// project->Save();
// auto projectPreview = ProjectPreview();
// projectPreview.Name = project->Name;
// projectPreview.Description = project->Description;
// projectPreview.Path = project->FullPath;
// projectPreview.ProjectIcon = nullptr;
// _Projects.push_back(projectPreview);
//}
}
ImGui::PopStyleVar(2);
ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.16f, 0.5f));
const std::string buttonLabelOpen = std::string(ICON_FA_FOLDER_OPEN) + " Load Selected Project";
const std::string buttonLabelOpen = std::string(ICON_FA_FOLDER_OPEN) + " Load Project";
bool hasProjectSelected = false;
if (SelectedProject < std::size(_Projects) && SelectedProject >= 0)
@@ -358,7 +412,7 @@ namespace Nuake
const std::string buttonLabelDoc = std::string(ICON_FA_EXTERNAL_LINK_SQUARE_ALT) + " Documentation";
if (Nuake::UI::SecondaryButton(buttonLabelDoc, { buttonSize.x, buttonSize.y }))
{
OS::OpenURL("https://nuake.readthedocs.io/en/latest/index.html");
OS::OpenURL("https://docs.readthedocs.io/en/latest/index.html");
}
ImGui::PopStyleVar(2);
}

View File

@@ -42,6 +42,8 @@ namespace Nuake
int32_t SelectedProject = -1;
std::vector<ProjectPreview> _Projects;
std::string queuedProjectPath;
std::string queuedRemovalPath;
public:
WelcomeWindow(Nuake::EditorInterface* editor);
~WelcomeWindow() = default;
@@ -50,6 +52,9 @@ namespace Nuake
bool IsProjectQueued() const { return !queuedProjectPath.empty(); };
void LoadQueuedProject();
void ImportProject(const std::string& file);
private:
void DrawRecentProjectsSection();
void DrawProjectItem(const uint32_t projectPreview);

5
Editor/test.html Normal file
View File

@@ -0,0 +1,5 @@
<div>
<div class="main">
<p>Hello</p>
</div>
</div>

View File

@@ -1,63 +1,125 @@
#include "Engine.h"
#include "src/Scene/Scene.h"
#include "src/Resource/Project.h"
#include "src/Physics/PhysicsManager.h"
#include <GLFW/glfw3.h>
#include "src/AI/NavManager.h"
#include "src/Audio/AudioManager.h"
#include "src/Core/FileSystem.h"
#include "src/FileSystem/FileSystem.h"
#include "src/Core/Input.h"
#include "src/Rendering/Renderer.h"
#include "src/Rendering/Renderer2D.h"
#include "src/Scripting/ScriptingEngine.h"
#include "src/Scripting/ScriptingEngineNet.h"
#include "src/Threading/JobSystem.h"
#include "src/Core/RegisterCoreTypes.h"
#include "src/Modules/Modules.h"
#include "src/Subsystems/EngineSubsystemScriptable.h"
#include <GLFW/glfw3.h>
#include <imgui/imgui_impl_glfw.h>
#include <imgui/imgui_impl_opengl3.h>
#include <Tracy.hpp>
namespace Nuake
{
Ref<Project> Engine::currentProject;
Ref<Window> Engine::currentWindow;
std::string Engine::queuedScene = "";
Ref<Project> Engine::s_CurrentProject;
Ref<Window> Engine::s_CurrentWindow;
GameState Engine::gameState = GameState::Stopped;
GameState Engine::s_GameState = GameState::Stopped;
float Engine::s_LastFrameTime = 0.0f;
float Engine::s_FixedUpdateRate = 1.0f / 90.0f;
float Engine::s_FixedUpdateDifference = 0.f;
float Engine::s_Time = 0.f;
Timestep Engine::s_TimeStep = 0.f;
float Engine::s_TimeScale = 1.0f;
float Engine::lastFrameTime = 0.0f;
float Engine::fixedUpdateRate = 1.0f / 90.0f;
float Engine::fixedUpdateDifference = 0.f;
float Engine::time = 0.f;
Timestep Engine::timeStep = 0.f;
float Engine::timeScale = 1.0f;
void Engine::Init()
{
//Window::Get()->OnWindowSetScene().AddStatic(&Engine::OnWindowSetScene);
ScriptingEngineNet::Get().OnGameAssemblyLoaded().AddStatic(&Engine::OnScriptingEngineGameAssemblyLoaded);
AudioManager::Get().Initialize();
PhysicsManager::Get().Init();
NavManager::Get().Initialize();
// Creates the window
s_CurrentWindow = Window::Get();
currentWindow = Window::Get();
Input::Init();
Renderer2D::Init();
Logger::Log("Engine initialized");
RegisterCoreTypes::RegisterCoreComponents();
Modules::StartupModules();
InitializeCoreSubsystems();
}
void Engine::Tick()
{
ZoneScoped;
JobSystem::Get().Update();
s_Time = static_cast<float>(glfwGetTime());
s_TimeStep = s_Time - s_LastFrameTime;
s_LastFrameTime = s_Time;
time = static_cast<float>(glfwGetTime());
timeStep = time - lastFrameTime;
lastFrameTime = time;
if (Engine::IsPlayMode())
{
if (!queuedScene.empty())
{
Ref<Scene> nextScene = Scene::New();
if (FileSystem::FileExists(queuedScene))
{
const std::string& fileContent = FileSystem::ReadFile(queuedScene);
nextScene->Path = queuedScene;
nextScene->Deserialize(json::parse(fileContent));
// Uninit current scene
GetCurrentScene()->OnExit();
// Set new scene
SetCurrentScene(nextScene);
// Init new scene
PhysicsManager::Get().ReInit();
GetCurrentScene()->OnInit();
queuedScene = "";
}
}
}
float scaledTimeStep = timeStep * timeScale;
// Tick all subsystems
if (Engine::IsPlayMode())
{
for (auto subsystem : subsystems)
{
if (subsystem == nullptr)
continue;
if (subsystem->CanEverTick())
{
subsystem->Tick(scaledTimeStep);
}
}
}
// Dont update if no scene is loaded.
if (s_CurrentWindow->GetScene())
if (currentWindow->GetScene())
{
float scaledTimeStep = s_TimeStep * s_TimeScale;
s_CurrentWindow->Update(scaledTimeStep);
currentWindow->Update(scaledTimeStep);
// Play mode update all the entities, Editor does not.
if (!Engine::IsPlayMode())
@@ -65,33 +127,34 @@ namespace Nuake
GetCurrentScene()->EditorUpdate(scaledTimeStep);
}
s_FixedUpdateDifference += s_TimeStep;
fixedUpdateDifference += timeStep;
// Fixed update
while (s_FixedUpdateDifference >= s_FixedUpdateRate)
while (fixedUpdateDifference >= fixedUpdateRate)
{
s_CurrentWindow->FixedUpdate(s_FixedUpdateRate * s_TimeScale);
currentWindow->FixedUpdate(fixedUpdateRate * timeScale);
s_FixedUpdateDifference -= s_FixedUpdateRate;
fixedUpdateDifference -= fixedUpdateRate;
}
Input::Update();
AudioManager::Get().AudioUpdate();
}
}
void Engine::EnterPlayMode()
{
s_LastFrameTime = (float)glfwGetTime(); // Reset timestep timer.
lastFrameTime = (float)glfwGetTime(); // Reset timestep timer.
// Dont trigger init if already in player mode.
if (GetGameState() == GameState::Playing)
if (GetGameState() == GameState::Playing || GetGameState() == GameState::Loading)
{
Logger::Log("Cannot enter play mode if is already in play mode.", "engine", WARNING);
Logger::Log("Cannot enter play mode if is already in play mode or is loading.", "engine", WARNING);
return;
}
SetGameState(GameState::Loading);
PhysicsManager::Get().ReInit();
if (GetCurrentScene()->OnInit())
@@ -108,22 +171,28 @@ namespace Nuake
void Engine::ExitPlayMode()
{
// Dont trigger exit if already not in play mode.
if (s_GameState != GameState::Stopped)
if (gameState != GameState::Stopped)
{
GetCurrentScene()->OnExit();
Input::ShowMouse();
s_GameState = GameState::Stopped;
gameState = GameState::Stopped;
}
}
void Engine::Draw()
{
ZoneScoped;
RenderCommand::Clear();
// Start imgui frame
{
ZoneScopedN("ImGui New Frame");
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
// Draw scene
Window::Get()->Draw();
@@ -131,6 +200,7 @@ namespace Nuake
void Engine::EndDraw()
{
ZoneScoped;
Window::Get()->EndDraw();
}
@@ -141,34 +211,146 @@ namespace Nuake
Ref<Scene> Engine::GetCurrentScene()
{
if (s_CurrentWindow)
if (currentWindow)
{
return s_CurrentWindow->GetScene();
return currentWindow->GetScene();
}
return nullptr;
}
bool Engine::LoadScene(Ref<Scene> scene)
bool Engine::SetCurrentScene(Ref<Scene> scene)
{
return s_CurrentWindow->SetScene(scene);
return currentWindow->SetScene(scene);
}
bool Engine::QueueSceneSwitch(const std::string& scenePath)
{
if (!IsPlayMode())
{
return false;
}
queuedScene = scenePath;
return true;
}
Ref<Project> Engine::GetProject()
{
return s_CurrentProject;
return currentProject;
}
Ref<EngineSubsystemScriptable> Engine::GetScriptedSubsystem(const std::string& subsystemName)
{
if (scriptedSubsystemMap.contains(subsystemName))
{
return scriptedSubsystemMap[subsystemName];
}
return nullptr;
}
Ref<EngineSubsystemScriptable> Engine::GetScriptedSubsystem(const int subsystemId)
{
if (subsystemId >= subsystems.size())
{
return nullptr;
}
return std::reinterpret_pointer_cast<EngineSubsystemScriptable>(subsystems[subsystemId]);
}
void Engine::OnWindowSetScene(Ref<Scene> oldScene, Ref<Scene> newScene)
{
// Inform the subsystems that we are going to destroy/swap out the old scene
for (auto subsystem : subsystems)
{
if (subsystem == nullptr)
continue;
subsystem->OnScenePreDestroy(oldScene);
}
// Hook into when the internal pieces of the scene are just about to be ready and when the scene is finally
// ready to present (ie, all initialized and loaded).
if (newScene != nullptr)
{
newScene->OnPreInitialize().AddStatic(&Engine::OnScenePreInitialize, newScene);
newScene->OnPostInitialize().AddStatic(&Engine::OnScenePostInitialize, newScene);
}
}
void Engine::InitializeCoreSubsystems()
{
}
void Engine::OnScriptingEngineGameAssemblyLoaded()
{
if (!Engine::IsPlayMode() && Engine::GetGameState() != GameState::Loading)
{
return;
}
subsystems.clear();
scriptedSubsystemMap.clear();
const Coral::ManagedAssembly& gameAssembly = ScriptingEngineNet::Get().GetGameAssembly();
const auto scriptTypeEngineSubsystem = gameAssembly.GetType("Nuake.Net.EngineSubsystem");
const auto& types = gameAssembly.GetTypes();
for (const auto& type : types)
{
// Initialize all subsystems
if (type->IsSubclassOf(scriptTypeEngineSubsystem))
{
const std::string typeName = std::string(type->GetFullName());
Logger::Log("Creating Scripted Subsystem " + typeName);
Coral::ManagedObject scriptedSubsystem = type->CreateInstance();
scriptedSubsystem.SetPropertyValue("EngineSubsystemID", subsystems.size());
Ref<EngineSubsystemScriptable> subsystemScript = CreateRef<EngineSubsystemScriptable>(scriptedSubsystem);
subsystems.push_back(subsystemScript);
scriptedSubsystemMap[typeName] = subsystemScript;
subsystemScript->Initialize();
}
}
}
void Engine::OnScenePreInitialize(Ref<Scene> scene)
{
for (auto subsystem : subsystems)
{
if (subsystem == nullptr)
continue;
subsystem->OnScenePreInitialize(scene);
}
}
void Engine::OnScenePostInitialize(Ref<Scene> scene)
{
for (auto subsystem : subsystems)
{
if (subsystem == nullptr)
continue;
subsystem->OnScenePostInitialize(scene);
}
}
bool Engine::LoadProject(Ref<Project> project)
{
s_CurrentProject = project;
currentProject = project;
if (!Engine::LoadScene(s_CurrentProject->DefaultScene))
if (!Engine::SetCurrentScene(currentProject->DefaultScene))
{
return false;
}
FileSystem::SetRootDirectory(FileSystem::GetParentPath(project->FullPath));
ScriptingEngineNet::Get().Initialize();
ScriptingEngineNet::Get().LoadProjectAssembly(project);
return true;
@@ -176,6 +358,6 @@ namespace Nuake
Ref<Window> Engine::GetCurrentWindow()
{
return s_CurrentWindow;
return currentWindow;
}
}

View File

@@ -1,19 +1,20 @@
#pragma once
#include "src/Core/Core.h"
#include "src/Window.h"
#include "src/Scene/Scene.h"
#include "src/Resource/Project.h"
#include "src/Core/Logger.h"
/* TODOS:
*/
#include "src/Window.h"
// Welcome to the Nuake source code.
namespace Nuake
{
class Project;
class Scene;
class EngineSubsystem;
class EngineSubsystemScriptable;
enum GameState
{
Loading,
Playing,
Paused,
Stopped
@@ -21,19 +22,6 @@ namespace Nuake
class Engine
{
private:
static Ref<Window> s_CurrentWindow;
static Ref<Project> s_CurrentProject;
static Ref<Scene> s_CurrentScene;
static GameState s_GameState;
static float s_LastFrameTime;
static float s_FixedUpdateRate;
static float s_FixedUpdateDifference;
static float s_Time;
static Timestep s_TimeStep;
static float s_TimeScale;
public:
static void Init(); // Initialize the engine.
static void Tick(); // Updates everything, called every frame.
@@ -46,23 +34,57 @@ namespace Nuake
static void Draw(); // Start new frame
static void EndDraw(); // Swap buffer
static void SetGameState(GameState gameState) { s_GameState = gameState; }
static GameState GetGameState() { return s_GameState; }
static bool IsPlayMode() { return s_GameState == GameState::Playing; }
static void SetGameState(GameState state) { gameState = state; }
static GameState GetGameState() { return gameState; }
static bool IsPlayMode() { return gameState == GameState::Playing; }
static inline float GetTime() { return s_Time; }
static inline Timestep GetTimestep() { return s_TimeStep; }
static inline void SetPhysicsStep(int amount) { s_FixedUpdateRate = 1.0f / static_cast<float>(amount); }
static inline void SetTimeScale(float timeScale) { s_TimeScale = timeScale; }
static inline float GetTimeScale() { return s_TimeScale; }
static inline float GetTime() { return time; }
static inline Timestep GetTimestep() { return timeStep; }
static inline void SetPhysicsStep(int amount) { fixedUpdateRate = 1.0f / static_cast<float>(amount); }
static inline float GetFixedTimeStep() { return fixedUpdateRate; }
static inline void SetTimeScale(float timeScale) { timeScale = timeScale; }
static inline float GetTimeScale() { return timeScale; }
static Ref<Window> GetCurrentWindow();
static bool LoadScene(Ref<Scene> scene);
static bool SetCurrentScene(Ref<Scene> scene);
static bool QueueSceneSwitch(const std::string& scene);
static Ref<Scene> GetCurrentScene();
static bool LoadProject(Ref<Project> project);
static Ref<Project> GetProject();
static Ref<EngineSubsystemScriptable> GetScriptedSubsystem(const std::string& subsystemName);
static Ref<EngineSubsystemScriptable> GetScriptedSubsystem(const int subsystemId);
protected:
static void OnWindowSetScene(Ref<Scene> oldScene, Ref<Scene> newScene);
static void InitializeCoreSubsystems();
static void OnScriptingEngineUninitialize();
static void OnScriptingEngineGameAssemblyLoaded();
static void OnScenePreInitialize(Ref<Scene> scene);
static void OnScenePostInitialize(Ref<Scene> scene);
private:
static Ref<Window> currentWindow;
static Ref<Project> currentProject;
static Ref<Scene> currentScene;
static std::string queuedScene;
static inline std::vector<Ref<EngineSubsystem>> subsystems;
static inline std::unordered_map<std::string, Ref<EngineSubsystemScriptable>> scriptedSubsystemMap;
static GameState gameState;
static float lastFrameTime;
static float fixedUpdateRate;
static float fixedUpdateDifference;
static float time;
static Timestep timeStep;
static float timeScale;
};
}

View File

@@ -11,12 +11,15 @@ project 'assimp'
warnings 'Off'
optimize 'Speed'
cppdialect "C++20"
includedirs {
'build/',
'build/assimp',
'assimp/',
'assimp/contrib/irrXML/',
'assimp/contrib/unzip/',
'assimp/contrib/utf8cpp/source',
'assimp/contrib/zlib/',
'assimp/contrib/rapidjson/include/',
'assimp/code',
@@ -32,6 +35,7 @@ project 'assimp'
'assimp/code/Common/**',
'assimp/code/PostProcessing/**',
'assimp/code/Material/**',
'assimp/code/Geometry/**',
'assimp/code/CApi/**',
-- Importers
'assimp/code/AssetLib/Collada/**',
@@ -99,7 +103,8 @@ project 'assimp'
'ASSIMP_BUILD_NO_X_IMPORTER',
'ASSIMP_BUILD_NO_X3D_IMPORTER',
'ASSIMP_BUILD_NO_XGL_IMPORTER',
'ASSIMP_BUILD_NO_IQM_IMPORTER'
'ASSIMP_BUILD_NO_IQM_IMPORTER',
'ASSIMP_BUILD_NO_USD_IMPORTER'
}
-- Exporters
defines {
@@ -120,6 +125,13 @@ project 'assimp'
'ASSIMP_BUILD_NO_ASSJSON_EXPORTER'
}
-- When building any Visual Studio solution
filter { "system:windows", "action:vs*"}
flags
{
"MultiProcessorCompile",
}
filter "configurations:Debug"
runtime "Debug"
symbols "on"

View File

@@ -3,8 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@@ -60,14 +59,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_CONFIG_H_INC
#define AI_CONFIG_H_INC
// ###########################################################################
// LIBRARY SETTINGS
// General, global settings
// ###########################################################################
// ###########################################################################
// LIBRARY SETTINGS
// General, global settings
// ###########################################################################
// ---------------------------------------------------------------------------
/** @brief Enables time measurements.
// ---------------------------------------------------------------------------
/** @brief Enables time measurements.
*
* If enabled, measures the time needed for each part of the loading
* process (i.e. IO time, importing, postprocessing, ..) and dumps
@@ -79,46 +77,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_GLOB_MEASURE_TIME \
"GLOB_MEASURE_TIME"
// ---------------------------------------------------------------------------
/** @brief Global setting to disable generation of skeleton dummy meshes
// ---------------------------------------------------------------------------
/** @brief Global setting to disable generation of skeleton dummy meshes
*
* Skeleton dummy meshes are generated as a visualization aid in cases which
* the input data contains no geometry, but only animation data.
* Property data type: bool. Default value: false
*/
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#define AI_CONFIG_IMPORT_NO_SKELETON_MESHES \
"IMPORT_NO_SKELETON_MESHES"
# if 0 // not implemented yet
// ---------------------------------------------------------------------------
/** @brief Set Assimp's multithreading policy.
*
* This setting is ignored if Assimp was built without boost.thread
* support (ASSIMP_BUILD_NO_THREADING, which is implied by ASSIMP_BUILD_BOOST_WORKAROUND).
* Possible values are: -1 to let Assimp decide what to do, 0 to disable
* multithreading entirely and any number larger than 0 to force a specific
* number of threads. Assimp is always free to ignore this settings, which is
* merely a hint. Usually, the default value (-1) will be fine. However, if
* Assimp is used concurrently from multiple user threads, it might be useful
* to limit each Importer instance to a specific number of cores.
*
* For more information, see the @link threading Threading page@endlink.
* Property type: int, default value: -1.
*/
#define AI_CONFIG_GLOB_MULTITHREADING \
"GLOB_MULTITHREADING"
#endif
// ###########################################################################
// POST PROCESSING SETTINGS
// Various stuff to fine-tune the behavior of a specific post processing step.
// ###########################################################################
// ---------------------------------------------------------------------------
/** @brief Maximum bone count per mesh for the SplitbyBoneCount step.
*
@@ -127,17 +101,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* compile-time.
* Property data type: integer.
*/
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#define AI_CONFIG_PP_SBBC_MAX_BONES \
"PP_SBBC_MAX_BONES"
// default limit for bone count
#if (!defined AI_SBBC_DEFAULT_MAX_BONES)
# define AI_SBBC_DEFAULT_MAX_BONES 60
#endif
// ---------------------------------------------------------------------------
/** @brief Specifies the maximum angle that may be between two vertex tangents
* that their tangents and bi-tangents are smoothed.
@@ -149,13 +121,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE \
"PP_CT_MAX_SMOOTHING_ANGLE"
// ---------------------------------------------------------------------------
/** @brief Source UV channel for tangent space computation.
// ---------------------------------------------------------------------------
/** @brief Source UV channel for tangent space computation.
*
* The specified channel must exist or an error will be raised.
* Property type: integer. Default value: 0
*/
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#define AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX \
"PP_CT_TEXTURE_CHANNEL_INDEX"
@@ -174,9 +146,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE \
"PP_GSN_MAX_SMOOTHING_ANGLE"
// ---------------------------------------------------------------------------
/** @brief Sets the colormap (= palette) to be used to decode embedded
// ---------------------------------------------------------------------------
/** @brief Sets the colormap (= palette) to be used to decode embedded
* textures in MDL (Quake or 3DGS) files.
*
* This must be a valid path to a file. The file is 768 (256*3) bytes
@@ -188,8 +159,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_IMPORT_MDL_COLORMAP \
"IMPORT_MDL_COLORMAP"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_RemoveRedundantMaterials step to
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_RemoveRedundantMaterials step to
* keep materials matching a name in a given list.
*
* This is a list of 1 to n strings, ' ' serves as delimiter character.
@@ -210,8 +181,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_RRM_EXCLUDE_LIST \
"PP_RRM_EXCLUDE_LIST"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PreTransformVertices step to
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PreTransformVertices step to
* keep the scene hierarchy. Meshes are moved to worldspace, but
* no optimization is performed (read: meshes with equal materials are not
* joined. The total number of meshes won't change).
@@ -225,8 +196,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_PTV_KEEP_HIERARCHY \
"PP_PTV_KEEP_HIERARCHY"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PreTransformVertices step to normalize
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PreTransformVertices step to normalize
* all vertex components into the [-1,1] range. That is, a bounding box
* for the whole scene is computed, the maximum component is taken and all
* meshes are scaled appropriately (uniformly of course!).
@@ -235,8 +206,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_PTV_NORMALIZE \
"PP_PTV_NORMALIZE"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PreTransformVertices step to use
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PreTransformVertices step to use
* a users defined matrix as the scene root node transformation before
* transforming vertices.
* Property type: bool. Default value: false.
@@ -244,8 +215,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION \
"PP_PTV_ADD_ROOT_TRANSFORMATION"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PreTransformVertices step to use
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PreTransformVertices step to use
* a users defined matrix as the scene root node transformation before
* transforming vertices. This property correspond to the 'a1' component
* of the transformation matrix.
@@ -254,6 +225,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION \
"PP_PTV_ROOT_TRANSFORMATION"
// ---------------------------------------------------------------------------
/** @brief Set epsilon to check the identity of the matrix 4x4.
*
* This is used by aiMatrix4x4t<TReal>::IsIdentity(const TReal epsilon).
* @note The default value is 10e-3f for backward compatibility of legacy code.
* Property type: Float.
*/
#define AI_CONFIG_CHECK_IDENTITY_MATRIX_EPSILON \
"CHECK_IDENTITY_MATRIX_EPSILON"
// default value for AI_CONFIG_CHECK_IDENTITY_MATRIX_EPSILON
#if (!defined AI_CONFIG_CHECK_IDENTITY_MATRIX_EPSILON_DEFAULT)
# define AI_CONFIG_CHECK_IDENTITY_MATRIX_EPSILON_DEFAULT 10e-3f
#endif
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_FindDegenerates step to
* remove degenerated primitives from the import - immediately.
@@ -267,17 +253,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_FD_REMOVE \
"PP_FD_REMOVE"
// ---------------------------------------------------------------------------
/**
// ---------------------------------------------------------------------------
/**
* @brief Configures the #aiProcess_FindDegenerates to check the area of a
* trinagle to be greates than e-6. If this is not the case the triangle will
* triangle to be greater than e-6. If this is not the case the triangle will
* be removed if #AI_CONFIG_PP_FD_REMOVE is set to true.
*/
#define AI_CONFIG_PP_FD_CHECKAREA \
"PP_FD_CHECKAREA"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes
* matching a name in a given list.
*
* This is a list of 1 to n strings, ' ' serves as delimiter character.
@@ -297,8 +283,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_OG_EXCLUDE_LIST \
"PP_OG_EXCLUDE_LIST"
// ---------------------------------------------------------------------------
/** @brief Set the maximum number of triangles in a mesh.
// ---------------------------------------------------------------------------
/** @brief Set the maximum number of triangles in a mesh.
*
* This is used by the "SplitLargeMeshes" PostProcess-Step to determine
* whether a mesh must be split or not.
@@ -308,7 +294,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_SLM_TRIANGLE_LIMIT \
"PP_SLM_TRIANGLE_LIMIT"
// default value for AI_CONFIG_PP_SLM_TRIANGLE_LIMIT
// default value for AI_CONFIG_PP_SLM_TRIANGLE_LIMIT
#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES)
# define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000
#endif
@@ -324,7 +310,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_SLM_VERTEX_LIMIT \
"PP_SLM_VERTEX_LIMIT"
// default value for AI_CONFIG_PP_SLM_VERTEX_LIMIT
// default value for AI_CONFIG_PP_SLM_VERTEX_LIMIT
#if (!defined AI_SLM_DEFAULT_MAX_VERTICES)
# define AI_SLM_DEFAULT_MAX_VERTICES 1000000
#endif
@@ -338,7 +324,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_LBW_MAX_WEIGHTS \
"PP_LBW_MAX_WEIGHTS"
// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS
// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS
#if (!defined AI_LMW_MAX_WEIGHTS)
# define AI_LMW_MAX_WEIGHTS 0x4
#endif // !! AI_LMW_MAX_WEIGHTS
@@ -352,7 +338,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_DB_THRESHOLD \
"PP_DB_THRESHOLD"
// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS
// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS
#if (!defined AI_DEBONE_THRESHOLD)
# define AI_DEBONE_THRESHOLD 1.0f
#endif // !! AI_DEBONE_THRESHOLD
@@ -366,14 +352,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_DB_ALL_OR_NONE \
"PP_DB_ALL_OR_NONE"
/** @brief Default value for the #AI_CONFIG_PP_ICL_PTCACHE_SIZE property
/** @brief Default value for the #AI_CONFIG_PP_ICL_PTCACHE_SIZE property
*/
#ifndef PP_ICL_PTCACHE_SIZE
# define PP_ICL_PTCACHE_SIZE 12
#endif
// ---------------------------------------------------------------------------
/** @brief Set the size of the post-transform vertex cache to optimize the
// ---------------------------------------------------------------------------
/** @brief Set the size of the post-transform vertex cache to optimize the
* vertices for. This configures the #aiProcess_ImproveCacheLocality step.
*
* The size is given in vertices. Of course you can't know how the vertex
@@ -385,8 +371,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define AI_CONFIG_PP_ICL_PTCACHE_SIZE "PP_ICL_PTCACHE_SIZE"
// ---------------------------------------------------------------------------
/** @brief Enumerates components of the aiScene and aiMesh data structures
// ---------------------------------------------------------------------------
/** @brief Enumerates components of the aiScene and aiMesh data structures
* that can be excluded from the import using the #aiProcess_RemoveComponent step.
*
* See the documentation to #aiProcess_RemoveComponent for more details.
@@ -474,8 +460,8 @@ enum aiComponent
#define AI_CONFIG_PP_RVC_FLAGS \
"PP_RVC_FLAGS"
// ---------------------------------------------------------------------------
/** @brief Input parameter to the #aiProcess_SortByPType step:
// ---------------------------------------------------------------------------
/** @brief Input parameter to the #aiProcess_SortByPType step:
* Specifies which primitive types are removed by the step.
*
* This is a bitwise combination of the aiPrimitiveType flags.
@@ -486,8 +472,8 @@ enum aiComponent
#define AI_CONFIG_PP_SBP_REMOVE \
"PP_SBP_REMOVE"
// ---------------------------------------------------------------------------
/** @brief Input parameter to the #aiProcess_FindInvalidData step:
// ---------------------------------------------------------------------------
/** @brief Input parameter to the #aiProcess_FindInvalidData step:
* Specifies the floating-point accuracy for animation values. The step
* checks for animation tracks where all frame values are absolutely equal
* and removes them. This tweakable controls the epsilon for floating-point
@@ -498,15 +484,15 @@ enum aiComponent
#define AI_CONFIG_PP_FID_ANIM_ACCURACY \
"PP_FID_ANIM_ACCURACY"
// ---------------------------------------------------------------------------
/** @brief Input parameter to the #aiProcess_FindInvalidData step:
// ---------------------------------------------------------------------------
/** @brief Input parameter to the #aiProcess_FindInvalidData step:
* Set to true to ignore texture coordinates. This may be useful if you have
* to assign different kind of textures like one for the summer or one for the winter.
*/
#define AI_CONFIG_PP_FID_IGNORE_TEXTURECOORDS \
"PP_FID_IGNORE_TEXTURECOORDS"
// TransformUVCoords evaluates UV scalings
// TransformUVCoords evaluates UV scalings
#define AI_UVTRAFO_SCALING 0x1
// TransformUVCoords evaluates UV rotations
@@ -529,8 +515,8 @@ enum aiComponent
#define AI_CONFIG_PP_TUV_EVALUATE \
"PP_TUV_EVALUATE"
// ---------------------------------------------------------------------------
/** @brief A hint to assimp to favour speed against import quality.
// ---------------------------------------------------------------------------
/** @brief A hint to assimp to favour speed against import quality.
*
* Enabling this option may result in faster loading, but it needn't.
* It represents just a hint to loaders and post-processing steps to use
@@ -541,14 +527,13 @@ enum aiComponent
#define AI_CONFIG_FAVOUR_SPEED \
"FAVOUR_SPEED"
// ###########################################################################
// IMPORTER SETTINGS
// Various stuff to fine-tune the behaviour of specific importer plugins.
// ###########################################################################
// ###########################################################################
// IMPORTER SETTINGS
// Various stuff to fine-tune the behaviour of specific importer plugins.
// ###########################################################################
// ---------------------------------------------------------------------------
/** @brief Importers which parse JSON may use this to obtain a pointer to a
// ---------------------------------------------------------------------------
/** @brief Importers which parse JSON may use this to obtain a pointer to a
* rapidjson::IRemoteSchemaDocumentProvider.
*
* The default value is nullptr
@@ -557,8 +542,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_SCHEMA_DOCUMENT_PROVIDER \
"IMPORT_SCHEMA_DOCUMENT_PROVIDER"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will merge all geometry layers present
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will merge all geometry layers present
* in the source file or take only the first.
*
* The default value is true (1)
@@ -567,8 +552,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS \
"IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read all materials present in the
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read all materials present in the
* source file or take only the referenced materials.
*
* This is void unless IMPORT_FBX_READ_MATERIALS=1.
@@ -579,8 +564,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS \
"IMPORT_FBX_READ_ALL_MATERIALS"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read materials.
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read materials.
*
* The default value is true (1)
* Property type: bool
@@ -588,8 +573,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_READ_MATERIALS \
"IMPORT_FBX_READ_MATERIALS"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read embedded textures.
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read embedded textures.
*
* The default value is true (1)
* Property type: bool
@@ -597,8 +582,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_READ_TEXTURES \
"IMPORT_FBX_READ_TEXTURES"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read cameras.
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read cameras.
*
* The default value is true (1)
* Property type: bool
@@ -606,8 +591,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_READ_CAMERAS \
"IMPORT_FBX_READ_CAMERAS"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read light sources.
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read light sources.
*
* The default value is true (1)
* Property type: bool
@@ -615,8 +600,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_READ_LIGHTS \
"IMPORT_FBX_READ_LIGHTS"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read animations.
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read animations.
*
* The default value is true (1)
* Property type: bool
@@ -624,8 +609,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS \
"IMPORT_FBX_READ_ANIMATIONS"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read weights.
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will read weights.
*
* The default value is true (1)
* Property type: bool
@@ -633,8 +618,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_READ_WEIGHTS \
"IMPORT_FBX_READ_WEIGHTS"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will act in strict mode in which only
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will act in strict mode in which only
* FBX 2013 is supported and any other sub formats are rejected. FBX 2013
* is the primary target for the importer, so this format is best
* supported and well-tested.
@@ -645,8 +630,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_STRICT_MODE \
"IMPORT_FBX_STRICT_MODE"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will preserve pivot points for
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will preserve pivot points for
* transformations (as extra nodes). If set to false, pivots and offsets
* will be evaluated whenever possible.
*
@@ -656,8 +641,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS \
"IMPORT_FBX_PRESERVE_PIVOTS"
// ---------------------------------------------------------------------------
/** @brief Specifies whether the importer will drop empty animation curves or
// ---------------------------------------------------------------------------
/** @brief Specifies whether the importer will drop empty animation curves or
* animation curves which match the bind pose transformation over their
* entire defined range.
*
@@ -667,8 +652,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \
"IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will use the legacy embedded texture naming.
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will use the legacy embedded texture naming.
*
* The default value is false (0)
* Property type: bool
@@ -676,8 +661,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING \
"AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
// ---------------------------------------------------------------------------
/** @brief Set wether the importer shall not remove empty bones.
// ---------------------------------------------------------------------------
/** @brief Set wether the importer shall not remove empty bones.
*
* Empty bone are often used to define connections for other models.
*/
@@ -685,12 +670,25 @@ enum aiComponent
"AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
// ---------------------------------------------------------------------------
/** @brief Set wether the FBX importer shall convert the unit from cm to m.
// ---------------------------------------------------------------------------
/** @brief Set wether the FBX importer shall convert the unit from cm to m.
*/
#define AI_CONFIG_FBX_CONVERT_TO_M \
"AI_CONFIG_FBX_CONVERT_TO_M"
// ---------------------------------------------------------------------------
/** @brief Set whether the FBX importer shall ignore the provided axis configuration
*
* If this property is set to true, the axis directions provided in the FBX file
* will be ignored and the file will be loaded as is.
*
* Set to true for Assimp 5.3.x and earlier behavior
* Equivalent to AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION \
"AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION"
// ---------------------------------------------------------------------------
/** @brief Will enable the skeleton struct to store bone data.
*
@@ -700,8 +698,8 @@ enum aiComponent
#define AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER \
"AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER"
// ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported
// ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported
*
* ASSIMP does not support vertex keyframes (only bone animation is supported).
* The library reads only one frame of models with vertex animations.
@@ -722,16 +720,16 @@ enum aiComponent
#define AI_CONFIG_IMPORT_SMD_KEYFRAME "IMPORT_SMD_KEYFRAME"
#define AI_CONFIG_IMPORT_UNREAL_KEYFRAME "IMPORT_UNREAL_KEYFRAME"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read animations.
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read animations.
*
* The default value is true (1)
* Property type: bool
*/
#define AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATIONS "IMPORT_MDL_HL1_READ_ANIMATIONS"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read animation events.
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read animation events.
* \note This property requires AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATIONS to be set to true.
*
* The default value is true (1)
@@ -739,8 +737,14 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATION_EVENTS "IMPORT_MDL_HL1_READ_ANIMATION_EVENTS"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read blend controllers.
// ---------------------------------------------------------------------------
/** @brief Set whether you want to convert the HS1 coordinate system in a special way.
* The default value is true (S1)
* Property type: bool
*/
#define AI_CONFIG_IMPORT_MDL_HL1_TRANSFORM_COORD_SYSTEM "TRANSFORM COORDSYSTEM FOR HS! MODELS"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read blend controllers.
* \note This property requires AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATIONS to be set to true.
*
* The default value is true (1)
@@ -748,8 +752,8 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_MDL_HL1_READ_BLEND_CONTROLLERS "IMPORT_MDL_HL1_READ_BLEND_CONTROLLERS"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read sequence transition graph.
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read sequence transition graph.
* \note This property requires AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATIONS to be set to true.
*
* The default value is true (1)
@@ -757,47 +761,47 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_MDL_HL1_READ_SEQUENCE_TRANSITIONS "IMPORT_MDL_HL1_READ_SEQUENCE_TRANSITIONS"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read attachments info.
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read attachments info.
*
* The default value is true (1)
* Property type: bool
*/
#define AI_CONFIG_IMPORT_MDL_HL1_READ_ATTACHMENTS "IMPORT_MDL_HL1_READ_ATTACHMENTS"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read bone controllers info.
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read bone controllers info.
*
* The default value is true (1)
* Property type: bool
*/
#define AI_CONFIG_IMPORT_MDL_HL1_READ_BONE_CONTROLLERS "IMPORT_MDL_HL1_READ_BONE_CONTROLLERS"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read hitboxes info.
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read hitboxes info.
*
* The default value is true (1)
* Property type: bool
*/
#define AI_CONFIG_IMPORT_MDL_HL1_READ_HITBOXES "IMPORT_MDL_HL1_READ_HITBOXES"
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read miscellaneous global model info.
// ---------------------------------------------------------------------------
/** @brief Set whether the MDL (HL1) importer will read miscellaneous global model info.
*
* The default value is true (1)
* Property type: bool
*/
#define AI_CONFIG_IMPORT_MDL_HL1_READ_MISC_GLOBAL_INFO "IMPORT_MDL_HL1_READ_MISC_GLOBAL_INFO"
// ---------------------------------------------------------------------------
/** Smd load multiple animations
// ---------------------------------------------------------------------------
/** Smd load multiple animations
*
* Property type: bool. Default value: true.
*/
#define AI_CONFIG_IMPORT_SMD_LOAD_ANIMATION_LIST "IMPORT_SMD_LOAD_ANIMATION_LIST"
// ---------------------------------------------------------------------------
/** @brief Configures the AC loader to collect all surfaces which have the
// ---------------------------------------------------------------------------
/** @brief Configures the AC loader to collect all surfaces which have the
* "Backface cull" flag set in separate meshes.
*
* Property type: bool. Default value: true.
@@ -805,8 +809,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL \
"IMPORT_AC_SEPARATE_BFCULL"
// ---------------------------------------------------------------------------
/** @brief Configures whether the AC loader evaluates subdivision surfaces (
// ---------------------------------------------------------------------------
/** @brief Configures whether the AC loader evaluates subdivision surfaces (
* indicated by the presence of the 'subdiv' attribute in the file). By
* default, Assimp performs the subdivision using the standard
* Catmull-Clark algorithm
@@ -816,8 +820,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION \
"IMPORT_AC_EVAL_SUBDIVISION"
// ---------------------------------------------------------------------------
/** @brief Configures the UNREAL 3D loader to separate faces with different
// ---------------------------------------------------------------------------
/** @brief Configures the UNREAL 3D loader to separate faces with different
* surface flags (e.g. two-sided vs. single-sided).
*
* * Property type: bool. Default value: true.
@@ -825,8 +829,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS \
"UNREAL_HANDLE_FLAGS"
// ---------------------------------------------------------------------------
/** @brief Configures the terragen import plugin to compute uv's for
// ---------------------------------------------------------------------------
/** @brief Configures the terragen import plugin to compute uv's for
* terrains, if not given. Furthermore a default texture is assigned.
*
* UV coordinates for terrains are so simple to compute that you'll usually
@@ -838,8 +842,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_TER_MAKE_UVS \
"IMPORT_TER_MAKE_UVS"
// ---------------------------------------------------------------------------
/** @brief Configures the ASE loader to always reconstruct normal vectors
// ---------------------------------------------------------------------------
/** @brief Configures the ASE loader to always reconstruct normal vectors
* basing on the smoothing groups loaded from the file.
*
* Some ASE files have carry invalid normals, other don't.
@@ -848,8 +852,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS \
"IMPORT_ASE_RECONSTRUCT_NORMALS"
// ---------------------------------------------------------------------------
/** @brief Configures the M3D loader to detect and process multi-part
// ---------------------------------------------------------------------------
/** @brief Configures the M3D loader to detect and process multi-part
* Quake player models.
*
* These models usually consist of 3 files, lower.md3, upper.md3 and
@@ -860,8 +864,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART \
"IMPORT_MD3_HANDLE_MULTIPART"
// ---------------------------------------------------------------------------
/** @brief Tells the MD3 loader which skin files to load.
// ---------------------------------------------------------------------------
/** @brief Tells the MD3 loader which skin files to load.
*
* When loading MD3 files, Assimp checks whether a file
* [md3_file_name]_[skin_name].skin is existing. These files are used by
@@ -872,8 +876,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_MD3_SKIN_NAME \
"IMPORT_MD3_SKIN_NAME"
// ---------------------------------------------------------------------------
/** @brief Specify if to try load Quake 3 shader files. This also controls
// ---------------------------------------------------------------------------
/** @brief Specify if to try load Quake 3 shader files. This also controls
* original surface name handling: when disabled it will be used unchanged.
*
* Property type: bool. Default value: true.
@@ -881,8 +885,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_MD3_LOAD_SHADERS \
"IMPORT_MD3_LOAD_SHADERS"
// ---------------------------------------------------------------------------
/** @brief Specify the Quake 3 shader file to be used for a particular
// ---------------------------------------------------------------------------
/** @brief Specify the Quake 3 shader file to be used for a particular
* MD3 file. This can also be a search path.
*
* By default Assimp's behaviour is as follows: If a MD3 file
@@ -899,8 +903,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_MD3_SHADER_SRC \
"IMPORT_MD3_SHADER_SRC"
// ---------------------------------------------------------------------------
/** @brief Configures the LWO loader to load just one layer from the model.
// ---------------------------------------------------------------------------
/** @brief Configures the LWO loader to load just one layer from the model.
*
* LWO files consist of layers and in some cases it could be useful to load
* only one of them. This property can be either a string - which specifies
@@ -913,8 +917,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY \
"IMPORT_LWO_ONE_LAYER_ONLY"
// ---------------------------------------------------------------------------
/** @brief Configures the MD5 loader to not load the MD5ANIM file for
// ---------------------------------------------------------------------------
/** @brief Configures the MD5 loader to not load the MD5ANIM file for
* a MD5MESH file automatically.
*
* The default strategy is to look for a file with the same name but the
@@ -927,8 +931,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD \
"IMPORT_MD5_NO_ANIM_AUTOLOAD"
// ---------------------------------------------------------------------------
/** @brief Defines the begin of the time range for which the LWS loader
// ---------------------------------------------------------------------------
/** @brief Defines the begin of the time range for which the LWS loader
* evaluates animations and computes aiNodeAnim's.
*
* Assimp provides full conversion of LightWave's envelope system, including
@@ -948,8 +952,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_LWS_ANIM_END \
"IMPORT_LWS_ANIM_END"
// ---------------------------------------------------------------------------
/** @brief Defines the output frame rate of the IRR loader.
// ---------------------------------------------------------------------------
/** @brief Defines the output frame rate of the IRR loader.
*
* IRR animations are difficult to convert for Assimp and there will
* always be a loss of quality. This setting defines how many keys per second
@@ -959,8 +963,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_IRR_ANIM_FPS \
"IMPORT_IRR_ANIM_FPS"
// ---------------------------------------------------------------------------
/** @brief Ogre Importer will try to find referenced materials from this file.
// ---------------------------------------------------------------------------
/** @brief Ogre Importer will try to find referenced materials from this file.
*
* Ogre meshes reference with material names, this does not tell Assimp the file
* where it is located in. Assimp will try to find the source file in the following
@@ -972,8 +976,8 @@ enum aiComponent
#define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE \
"IMPORT_OGRE_MATERIAL_FILE"
// ---------------------------------------------------------------------------
/** @brief Ogre Importer detect the texture usage from its filename.
// ---------------------------------------------------------------------------
/** @brief Ogre Importer detect the texture usage from its filename.
*
* Ogre material texture units do not define texture type, the textures usage
* depends on the used shader or Ogre's fixed pipeline. If this config property
@@ -998,10 +1002,10 @@ enum aiComponent
* Android application without having to keep the internal directory and asset
* manager pointer.
*/
#define AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT "AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT"
#define AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT "AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT"
// ---------------------------------------------------------------------------
/** @brief Specifies whether the IFC loader skips over IfcSpace elements.
// ---------------------------------------------------------------------------
/** @brief Specifies whether the IFC loader skips over IfcSpace elements.
*
* IfcSpace elements (and their geometric representations) are used to
* represent, well, free space in a building storey.<br>
@@ -1009,8 +1013,8 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS "IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS"
// ---------------------------------------------------------------------------
/** @brief Specifies whether the IFC loader will use its own, custom triangulation
// ---------------------------------------------------------------------------
/** @brief Specifies whether the IFC loader will use its own, custom triangulation
* algorithm to triangulate wall and floor meshes.
*
* If this property is set to false, walls will be either triangulated by
@@ -1024,8 +1028,8 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION"
// ---------------------------------------------------------------------------
/** @brief Set the tessellation conic angle for IFC smoothing curves.
// ---------------------------------------------------------------------------
/** @brief Set the tessellation conic angle for IFC smoothing curves.
*
* This is used by the IFC importer to determine the tessellation parameter
* for smoothing curves.
@@ -1035,7 +1039,7 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE "IMPORT_IFC_SMOOTHING_ANGLE"
// default value for AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE
// default value for AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE
#if (!defined AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE)
# define AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE 10.0f
#endif
@@ -1051,7 +1055,7 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION "IMPORT_IFC_CYLINDRICAL_TESSELLATION"
// default value for AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION
// default value for AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION
#if (!defined AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION)
# define AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION 32
#endif
@@ -1065,8 +1069,17 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
// ---------------------------------------------------------------------------
/** @brief Specifies whether the Collada loader should use Collada names.
// ---------------------------------------------------------------------------
/** @brief Specifies whether the Collada loader will ignore the provided unit size.
*
* If this property is set to true, the unit size provided in the file header will
* be ignored and the file will be loaded without scaling the assets.
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE "IMPORT_COLLADA_IGNORE_UNIT_SIZE"
// ---------------------------------------------------------------------------
/** @brief Specifies whether the Collada loader should use Collada names.
*
* If this property is set to true, the Collada names will be used as the node and
* mesh names. The default is to use the id tag (resp. sid tag, if no id tag is present)
@@ -1075,25 +1088,61 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES "IMPORT_COLLADA_USE_COLLADA_NAMES"
// ---------- All the Export defines ------------
// ---------- All the Export defines ------------
/** @brief Specifies the xfile use double for real values of float
/** @brief Specifies the xfile use double for real values of float
*
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
/** @brief Specifies whether the assimp export shall be able to export point clouds
/** @brief Specifies whether the assimp export shall be able to export point clouds
*
* When this flag is not defined the render data has to contain valid faces.
* Point clouds are only a collection of vertices which have nor spatial organization
* by a face and the validation process will remove them. Enabling this feature will
* switch off the flag and enable the functionality to export pure point clouds.
*
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS"
/**
/** @brief Specifies whether to use the deprecated KHR_materials_pbrSpecularGlossiness extension
*
* When this flag is undefined any material with specularity will use the new KHR_materials_specular
* extension. Enabling this flag will revert to the deprecated extension. Note that exporting
* KHR_materials_pbrSpecularGlossiness with extensions other than KHR_materials_unlit is unsupported,
* including the basic pbrMetallicRoughness spec.
*
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_USE_GLTF_PBR_SPECULAR_GLOSSINESS "USE_GLTF_PBR_SPECULAR_GLOSSINESS"
/** @brief Specifies whether to apply a limit on the number of four bones per vertex in skinning
*
* When this flag is not defined, all bone weights and indices are limited to a
* maximum of four bones for each vertex (attributes JOINT_0 and WEIGHT_0 only).
* By enabling this flag, the number of bones per vertex is unlimited.
* In both cases, indices and bone weights are sorted by weight in descending order.
* In the case of the limit of up to four bones, a maximum of the four largest values are exported.
* Weights are not normalized.
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX \
"USE_UNLIMITED_BONES_PER VERTEX"
/** @brief Specifies whether to write the value referenced to opacity in TransparencyFactor of each material.
*
* When this flag is not defined, the TransparencyFactor value of each meterial is 1.0.
* By enabling this flag, the value is 1.0 - opacity;
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_EXPORT_FBX_TRANSPARENCY_FACTOR_REFER_TO_OPACITY \
"EXPORT_FBX_TRANSPARENCY_FACTOR_REFER_TO_OPACITY"
/**
* @brief Specifies the blob name, assimp uses for exporting.
*
* Some formats require auxiliary files to be written, that need to be linked back into
@@ -1110,8 +1159,8 @@ enum aiComponent
*/
#define AI_CONFIG_EXPORT_BLOB_NAME "EXPORT_BLOB_NAME"
/**
* @brief Specifies a gobal key factor for scale, float value
/**
* @brief Specifies a global key factor for scale, float value
*/
#define AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY "GLOBAL_SCALE_FACTOR"
@@ -1126,12 +1175,11 @@ enum aiComponent
#endif // AI_CONFIG_APP_SCALE_KEY
// ---------- All the Build/Compile-time defines ------------
// ---------- All the Build/Compile-time defines ------------
/** @brief Specifies if double precision is supported inside assimp
/** @brief Specifies if double precision is supported inside assimp
*
* Property type: Bool. Default value: undefined.
*/
#endif // !! AI_CONFIG_H_INC

View File

@@ -0,0 +1,91 @@
group "Dependencies"
project "Freetype"
location "freetype"
kind "StaticLib"
staticruntime "on"
language "C"
targetdir ("freetype/bin/" .. outputdir .. "/%{prj.name}")
objdir ("freetype/bin-obj/" .. outputdir .. "/%{prj.name}")
includedirs {
'freetype/include/',
'freetype/',
"freetype/include/config/"
}
defines { "FT2_BUILD_LIBRARY" }
files {
"freetype/src/autofit/autofit.c",
"freetype/src/base/ftbase.c",
"freetype/src/base/ftbbox.c",
"freetype/src/base/ftbdf.c",
"freetype/src/base/ftbitmap.c",
"freetype/src/base/ftcid.c",
"freetype/src/base/ftfstype.c",
"freetype/src/base/ftgasp.c",
"freetype/src/base/ftglyph.c",
"freetype/src/base/ftgxval.c",
"freetype/src/base/ftinit.c",
"freetype/src/base/ftmm.c",
"freetype/src/base/ftotval.c",
"freetype/src/base/ftpatent.c",
"freetype/src/base/ftpfr.c",
"freetype/src/base/ftstroke.c",
"freetype/src/base/ftsynth.c",
"freetype/src/base/ftsystem.c",
"freetype/src/base/fttype1.c",
"freetype/src/base/ftwinfnt.c",
"freetype/src/bdf/bdf.c",
"freetype/src/cache/ftcache.c",
"freetype/src/cff/cff.c",
"freetype/src/cid/type1cid.c",
"freetype/src/gzip/ftgzip.c",
"freetype/src/lzw/ftlzw.c",
"freetype/src/pcf/pcf.c",
"freetype/src/pfr/pfr.c",
"freetype/src/psaux/psaux.c",
"freetype/src/pshinter/pshinter.c",
"freetype/src/psnames/psmodule.c",
"freetype/src/raster/raster.c",
"freetype/src/sfnt/sfnt.c",
"freetype/src/smooth/smooth.c",
"freetype/src/truetype/truetype.c",
"freetype/src/type1/type1.c",
"freetype/src/type42/type42.c",
"freetype/src/winfonts/winfnt.c",
"freetype/src/winfonts/winfnt.c",
"freetype/src/sdf/sdf.c"
}
filter "system:windows"
systemversion "latest"
-- warning C4244: 'function': conversion from '__int64' to 'const unsigned int', possible loss of data
-- warning C4996: 'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead
-- warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead.
-- warning C4267: '=': conversion from 'size_t' to 'FT_Int', possible loss of data
-- warning C4312: 'type cast': conversion from 'unsigned long' to 'void *' of greater size
disablewarnings { "4996", "4267", "4244", "4312" }
defines
{
}
filter "configurations:Debug"
files { "freetype/src/base/ftdebug.c" }
runtime "Debug"
symbols "on"
filter "configurations:Release"
files { "freetype/src/base/ftdebug.c" }
runtime "Release"
optimize "on"
filter "configurations:Dist"
files { "freetype/src/base/ftdebug.c" }
runtime "Release"
optimize "on"
group ""

View File

@@ -10,14 +10,19 @@ project "GLFW"
files
{
"glfw/include/GLFW/glfw3.h",
--"glfw/include/GLFW/glfw3native.h",
"glfw/include/GLFW/glfw3native.h",
"glfw/src/glfw_config.h",
"glfw/src/context.c",
"glfw/src/init.c",
"glfw/src/input.c",
"glfw/src/monitor.c",
"glfw/src/vulkan.c",
"glfw/src/window.c"
"glfw/src/window.c",
"glfw/src/platform.c",
"glfw/src/null_init.c",
"glfw/src/null_joystick.c",
"glfw/src/null_monitor.c",
"glfw/src/null_window.c",
"glfw/src/vulkan.c"
}
filter "system:windows"
@@ -31,6 +36,7 @@ project "GLFW"
"glfw/src/win32_time.c",
"glfw/src/win32_thread.c",
"glfw/src/win32_window.c",
"glfw/src/win32_module.c",
"glfw/src/wgl_context.c",
"glfw/src/egl_context.c",
"glfw/src/osmesa_context.c"
@@ -41,6 +47,8 @@ project "GLFW"
"_GLFW_WIN32",
}
disablewarnings { "4996" }
filter "system:linux"
staticruntime "On"
@@ -54,6 +62,7 @@ project "GLFW"
"glfw/src/xkb_unicode.c",
"glfw/src/posix_time.c",
"glfw/src/posix_thread.c",
"glfw/src/posix_module.c",
"glfw/src/glx_context.c",
"glfw/src/egl_context.c",
"glfw/src/osmesa_context.c",

View File

@@ -36,6 +36,14 @@ project 'JoltPhysics'
prebuildcommands {
"cp %{prj.location}./Jolt.cpp %{prj.location}/"
}
-- When building any Visual Studio solution
filter { "system:windows", "action:vs*"}
flags
{
"MultiProcessorCompile",
}
filter "configurations:Debug"
cppdialect "C++17"
runtime "Debug"

View File

@@ -0,0 +1,86 @@
project '*'
includedirs {
'yoga/yoga/'
}
group "Dependencies"
project 'msdf-gen'
kind "StaticLib"
staticruntime "on"
warnings 'Off'
optimize 'Speed'
cppdialect "C++20"
includedirs {
'msdf-atlas-gen/include',
'freetype/include'
}
files {
'msdf-atlas-gen/msdfgen/*.h',
'msdf-atlas-gen/msdfgen/*.cpp',
'msdf-atlas-gen/msdfgen/*.hpp',
'msdf-atlas-gen/msdfgen/Core/*.h',
'msdf-atlas-gen/msdfgen/Core/*.hpp',
'msdf-atlas-gen/msdfgen/Core/*.cpp',
'msdf-atlas-gen/msdfgen/lib/*.cpp',
'msdf-atlas-gen/msdfgen/ext/*.h',
'msdf-atlas-gen/msdfgen/ext/*.cpp'
}
defines {
}
-- When building any Visual Studio solution
filter { "system:windows", "action:vs*"}
flags
{
"MultiProcessorCompile",
}
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter "configurations:Release"
runtime "Release"
optimize "on"
project 'msdf-atlas-gen'
kind "StaticLib"
staticruntime "on"
warnings 'Off'
optimize 'Speed'
cppdialect "C++20"
includedirs {
'msdf-atlas-gen/include',
'msdf-atlas-gen/msdfgen',
'msdf-atlas-gen/msdfgen/include'
}
files {
'msdf-atlas-gen/msdf-atlas-gen/*.h',
'msdf-atlas-gen/msdf-atlas-gen/*.cpp',
'msdf-atlas-gen/msdf-atlas-gen/*.hpp',
}
links {
'msdf-gen'
}
defines {
}
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter "configurations:Release"
runtime "Release"
optimize "on"
group ""

View File

@@ -67,7 +67,6 @@ project "Detour"
defines {"DEBUG"}
symbols "On"
postbuildcommands {}
flags {"staticruntime"} -- this is what worked for me
-- linux library cflags and libs
filter {"system:linux", "toolset:gcc"}

View File

@@ -0,0 +1,30 @@
group "Dependencies"
project 'Tracy'
location "tracy"
kind "StaticLib"
staticruntime "on"
warnings 'Off'
includedirs {
"tracy/public/tracy"
}
files {
"tracy/public/tracy/Tracy.hpp",
"tracy/public/TracyClient.cpp"
}
defines {
"TRACY_ENABLE",
"TRACY_ON_DEMAND",
}
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter "configurations:Release"
runtime "Release"
optimize "on"
group ""

Submodule Nuake/dependencies/vma added at 5a53a19894

View File

@@ -0,0 +1,43 @@
project '*'
includedirs {
'yoga/yoga/'
}
group "Dependencies"
project 'yoga'
kind "StaticLib"
staticruntime "on"
warnings 'Off'
optimize 'Speed'
cppdialect "C++20"
includedirs {
'yoga/'
}
files {
'yoga/yoga/*.cpp',
'yoga/yoga/*.h',
'yoga/yoga/**/*.cpp',
'yoga/yoga/**/*.h',
}
defines {
}
-- When building any Visual Studio solution
filter { "system:windows", "action:vs*"}
flags
{
"MultiProcessorCompile",
}
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter "configurations:Release"
runtime "Release"
optimize "on"
group ""

View File

@@ -3,6 +3,8 @@
#include <filesystem>
#include <Tracy.hpp>
namespace Nuake {
Application::Application(const ApplicationSpecification& appSpecification)
@@ -33,8 +35,11 @@ namespace Nuake {
{
while (!m_Window->ShouldClose())
{
ZoneScoped;
for (auto& layer : m_LayerStack)
{
ZoneScopedN("Layer Update");
layer->OnUpdate();
}
@@ -42,9 +47,12 @@ namespace Nuake {
{
for (auto& layer : m_LayerStack)
{
ZoneScopedN("Layer Draw");
layer->OnDraw();
}
}
FrameMark;
}
}

View File

@@ -17,6 +17,8 @@ namespace Nuake {
virtual void OnDraw() {};
virtual void OnWindowFocused() {};
virtual void OnDragNDrop(const std::vector<std::string>&) {};
// TODO: OnEvent
inline const std::string& GetName() const { return m_Name; }

View File

@@ -1,6 +1,6 @@
#include "AudioManager.h"
#include "src/Core/Logger.h"
#include "src/Core/FileSystem.h"
#include "src/FileSystem/FileSystem.h"
#include <soloud.h>
#include "soloud_speech.h"
@@ -11,8 +11,7 @@
namespace Nuake {
AudioManager::AudioManager() :
m_AudioThreadRunning(true)
AudioManager::AudioManager()
{
}
@@ -20,9 +19,6 @@ namespace Nuake {
{
Deinitialize();
m_AudioThreadRunning = false;
m_AudioThread.join();
m_Soloud->deinit();
}
@@ -32,20 +28,11 @@ namespace Nuake {
// TODO: Sample rate, back end, buffer size, flags.
#ifdef NK_WIN
m_Soloud->init();
m_Soloud->init(SoLoud::Soloud::LEFT_HANDED_3D);
#else
m_Soloud->init(SoLoud::Soloud::CLIP_ROUNDOFF, SoLoud::Soloud::ALSA);
#endif
if (m_AudioThread.joinable())
{
m_AudioThreadRunning = false;
m_AudioThread.join();
}
m_AudioThreadRunning = true;
m_AudioThread = std::thread(&AudioManager::AudioThreadLoop, this);
Logger::Log("Audio manager initialized", "audio", VERBOSE);
}
@@ -68,6 +55,7 @@ namespace Nuake {
m_ListenerUp.x, m_ListenerUp.y, m_ListenerUp.z
);
m_Soloud->update3dAudio();
}
}
@@ -79,9 +67,6 @@ namespace Nuake {
void AudioManager::QueueWavAudio(const AudioRequest& request)
{
// Acquire mutex lock and push to queue
const std::lock_guard<std::mutex> lock(m_AudioQueueMutex);
// Check if file exists and load
const bool fileExists = FileSystem::FileExists(request.audioFile, true);
if (fileExists && !IsWavLoaded(request.audioFile))
@@ -94,9 +79,6 @@ namespace Nuake {
void AudioManager::UpdateVoice(const AudioRequest& request)
{
// Acquire mutex lock
const std::lock_guard<std::mutex> lock(m_AudioQueueMutex);
auto& audioClip = m_ActiveClips[request.audioFile];
if (IsVoiceActive(request.audioFile))
{
@@ -125,8 +107,6 @@ namespace Nuake {
void AudioManager::StopVoice(const std::string& filePath)
{
const std::lock_guard<std::mutex> lock(m_AudioQueueMutex);
if (!IsVoiceActive(filePath))
{
return; // We can't stop a voice that isn't active.
@@ -153,7 +133,7 @@ namespace Nuake {
void AudioManager::LoadWavAudio(const std::string& filePath)
{
const bool STREAMING = true;
const bool STREAMING = false;
if (STREAMING)
{
Ref<SoLoud::WavStream> wavStream = CreateRef<SoLoud::WavStream>();
@@ -166,46 +146,44 @@ namespace Nuake {
wav->load(filePath.c_str());
m_WavSamples[filePath] = wav;
}
}
void AudioManager::AudioThreadLoop()
void AudioManager::AudioUpdate()
{
while(m_AudioThreadRunning)
{
// Acquire mutex lock
const std::lock_guard<std::mutex> lock(m_AudioQueueMutex);
// Check if we have audio queued
if (m_Soloud->getGlobalVolume() != m_GlobalVolume)
{
m_Soloud->setGlobalVolume(m_GlobalVolume);
}
while (!m_AudioQueue.empty())
{
AudioRequest& audioRequest = m_AudioQueue.front();
Ref<SoLoud::AudioSource> audio = m_WavSamples[audioRequest.audioFile];
SoLoud::handle soloudHandle;
SoLoud::handle handle;
if (!audioRequest.spatialized)
{
soloudHandle = m_Soloud->play(*audio);
m_Soloud->setVolume(soloudHandle, audioRequest.volume);
m_Soloud->setPan(soloudHandle, audioRequest.pan);
handle = m_Soloud->play(*audio);
m_Soloud->setVolume(handle, audioRequest.volume);
m_Soloud->setPan(handle, audioRequest.pan);
}
else
{
const Vector3& position = audioRequest.position;
soloudHandle = m_Soloud->play3d(*audio, position.x, position.y, position.z);
m_Soloud->set3dSourceMinMaxDistance(soloudHandle, audioRequest.MinDistance, audioRequest.MaxDistance);
m_Soloud->set3dSourceAttenuation(soloudHandle, SoLoud::AudioSource::ATTENUATION_MODELS::EXPONENTIAL_DISTANCE, audioRequest.AttenuationFactor);
handle = m_Soloud->play3d(*audio, position.x, position.y, position.z);
m_Soloud->set3dSourceMinMaxDistance(handle, audioRequest.MinDistance, audioRequest.MaxDistance);
m_Soloud->set3dSourceAttenuation(handle, SoLoud::AudioSource::ATTENUATION_MODELS::EXPONENTIAL_DISTANCE, audioRequest.AttenuationFactor);
}
m_Soloud->setRelativePlaySpeed(soloudHandle, audioRequest.speed);
m_Soloud->setLooping(soloudHandle, audioRequest.Loop);
m_Soloud->setRelativePlaySpeed(handle, audioRequest.speed);
m_Soloud->setLooping(handle, audioRequest.Loop);
m_ActiveClips[audioRequest.audioFile] = soloudHandle;
m_ActiveClips[audioRequest.audioFile] = handle;
m_AudioQueue.pop();
}
}
}
void AudioManager::CleanupInactiveVoices()
{

View File

@@ -39,10 +39,7 @@ namespace Nuake
Ref<SoLoud::Soloud> m_Soloud;
bool m_AudioThreadRunning;
std::thread m_AudioThread;
std::mutex m_AudioQueueMutex;
std::atomic<bool> m_AudioQueued = { false };
bool m_AudioQueued = false;
std::queue<AudioRequest> m_AudioQueue;
Vector3 m_ListenerPosition;
@@ -87,8 +84,9 @@ namespace Nuake
bool IsVoiceActive(const std::string & voice) const;
void LoadWavAudio(const std::string& filePath);
void AudioUpdate();
private:
void AudioThreadLoop();
void CleanupInactiveVoices();
};

View File

@@ -6,6 +6,7 @@
#include <vector>
#include <queue>
#include <stdexcept>
#include <cassert>
#define ASSERT(x) if (!(x)) assert(false)

View File

@@ -1,404 +0,0 @@
#include "FileSystem.h"
#include "Engine.h"
#include "OS.h"
#include <GLFW/glfw3.h>
#ifdef NK_WIN
#define GLFW_EXPOSE_NATIVE_WIN32
#include "GLFW/glfw3native.h"
#include <commdlg.h>
#endif
#ifdef NK_LINUX
#include "gtk/gtk.h"
#endif
#include <fstream>
#include <iostream>
#include <ShlObj.h>
namespace Nuake
{
namespace fs = std::filesystem;
std::string FileDialog::OpenFile(const char* filter)
{
std::string filePath;
#ifdef NK_WIN
OPENFILENAMEA ofn;
CHAR szFile[260] = { 0 };
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle());
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = filter;
ofn.nFilterIndex = 1;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
if (GetOpenFileNameA(&ofn) == TRUE)
{
filePath = std::string(ofn.lpstrFile);
}
#endif
#ifdef NK_LINUX
GtkWidget *dialog;
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
gint res;
dialog = gtk_file_chooser_dialog_new("Open File",
NULL,
action,
"_Cancel",
GTK_RESPONSE_CANCEL,
"_Open",
GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
if (filter) {
GtkFileFilter *file_filter = gtk_file_filter_new();
gtk_file_filter_set_name(file_filter, "Filter Name");
gtk_file_filter_add_pattern(file_filter, filter);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter);
}
res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT) {
char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
filePath = filename;
g_free(filename);
}
gtk_widget_destroy(dialog);
#endif
return filePath;
}
std::string FileDialog::SaveFile(const char* filter)
{
#ifdef NK_WIN
OPENFILENAMEA ofn;
CHAR szFile[260] = { 0 };
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle());
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = filter;
ofn.nFilterIndex = 1;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT;
if (GetSaveFileNameA(&ofn) == TRUE)
{
return ofn.lpstrFile;
}
#endif
#ifdef NK_LINUX
GtkWidget *dialog;
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
gint res;
gtk_init(NULL, NULL);
dialog = gtk_file_chooser_dialog_new("Save File",
NULL,
action,
"_Cancel",
GTK_RESPONSE_CANCEL,
"_Save",
GTK_RESPONSE_ACCEPT,
NULL);
GtkFileFilter *file_filter = gtk_file_filter_new();
gtk_file_filter_set_name(file_filter, filter);
gtk_file_filter_add_pattern(file_filter, "*.*"); // You can customize this pattern
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter);
res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT)
{
char *filename;
GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);
filename = gtk_file_chooser_get_filename(chooser);
std::string result(filename);
g_free(filename);
gtk_widget_destroy(dialog);
return result;
}
else
{
gtk_widget_destroy(dialog);
return std::string();
}
#endif
return std::string();
}
std::string FileDialog::OpenFolder()
{
std::string folderPath;
#ifdef NK_WIN
BROWSEINFOA bi;
CHAR szFolder[260] = { 0 };
ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.lpszTitle = "Select a Folder";
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
bi.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle());
bi.pszDisplayName = szFolder;
LPITEMIDLIST pidl = SHBrowseForFolderA(&bi);
if (pidl != NULL)
{
SHGetPathFromIDListA(pidl, szFolder);
folderPath = std::string(szFolder);
CoTaskMemFree(pidl);
}
#endif
#ifdef NK_LINUX
GtkWidget* dialog;
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
gint res;
dialog = gtk_file_chooser_dialog_new("Select Folder",
NULL,
action,
"_Cancel",
GTK_RESPONSE_CANCEL,
"_Select",
GTK_RESPONSE_ACCEPT,
NULL);
res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT) {
char* foldername = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
folderPath = foldername;
g_free(foldername);
}
gtk_widget_destroy(dialog);
#endif
return folderPath;
}
std::string FileSystem::Root = "";
Ref<Directory> FileSystem::RootDirectory;
void FileSystem::ScanDirectory(Ref<Directory> directory)
{
for (const auto& entry : std::filesystem::directory_iterator(directory->FullPath))
{
if (entry.is_directory())
{
Ref<Directory> newDir = CreateRef<Directory>();
newDir->FullPath = entry.path().string();
newDir->Name = entry.path().filename().string();
newDir->Parent = directory;
ScanDirectory(newDir);
directory->Directories.push_back(newDir);
}
else if (entry.is_regular_file())
{
std::filesystem::path currentPath = entry.path();
std::string absolutePath = currentPath.string();
std::string name = currentPath.filename().string();
std::string extension = currentPath.extension().string();
Ref<File> newFile = CreateRef<File>(directory, absolutePath, name, extension);
directory->Files.push_back(newFile);
}
}
}
bool FileSystem::DirectoryExists(const std::string& path, bool absolute)
{
const std::string& finalPath = absolute ? path : Root + path;
return std::filesystem::exists(finalPath) && std::filesystem::is_directory(finalPath);
}
bool FileSystem::MakeDirectory(const std::string& path, bool absolute)
{
return std::filesystem::create_directories(absolute ? path : FileSystem::Root + path);
}
bool FileSystem::FileExists(const std::string& path, bool absolute)
{
std::string fullPath = absolute ? path : FileSystem::Root + path;
return std::filesystem::exists(fullPath);
}
void FileSystem::SetRootDirectory(const std::string path)
{
Root = path;
Scan();
}
void FileSystem::Scan()
{
RootDirectory = CreateRef<Directory>(Root);
ScanDirectory(RootDirectory);
}
std::string FileSystem::AbsoluteToRelative(const std::string& path)
{
const fs::path rootPath(Root);
const fs::path absolutePath(path);
return fs::relative(absolutePath, rootPath).generic_string();
}
std::string FileSystem::RelativeToAbsolute(const std::string& path)
{
return Root + path;
}
std::string FileSystem::GetParentPath(const std::string& fullPath)
{
std::filesystem::path pathObj(fullPath);
auto returnvalue = pathObj.parent_path().string();
return returnvalue + "/";
}
std::string FileSystem::ReadFile(const std::string& path, bool absolute)
{
std::string finalPath = path;
if (!absolute)
finalPath = Root + path;
std::ifstream myReadFile(finalPath, std::ios::in | std::ios::binary);
std::string fileContent = "";
std::string allFile = "";
char bom[3];
myReadFile.read(bom, 3);
// Check for UTF-8 BOM (EF BB BF)
if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF)
{
myReadFile.seekg(3);
}
else
{
myReadFile.seekg(0);
}
// Use a while loop together with the getline() function to read the file line by line
while (getline(myReadFile, fileContent))
{
allFile.append(fileContent + "\n");
}
// Close the file
myReadFile.close();
return allFile;
}
std::ofstream FileSystem::fileWriter;
bool FileSystem::BeginWriteFile(const std::string path, bool absolute)
{
fileWriter = std::ofstream();
fileWriter.open(absolute ? path : FileSystem::Root + path);
return false;
}
bool FileSystem::WriteLine(const std::string line)
{
fileWriter << line.c_str();
return true;
}
void FileSystem::EndWriteFile()
{
fileWriter.close();
}
uintmax_t FileSystem::DeleteFileFromPath(const std::string& path)
{
return std::remove(path.c_str());
}
uintmax_t FileSystem::DeleteFolder(const std::string& path)
{
return std::filesystem::remove_all(path.c_str());
}
std::string FileSystem::GetConfigFolderPath()
{
std::string subFolderPath = OS::GetConfigFolderPath().append("/Nuake/");
if (!DirectoryExists(subFolderPath, true))
{
MakeDirectory(subFolderPath);
}
return subFolderPath;
}
Ref<Directory> FileSystem::GetFileTree()
{
return RootDirectory;
}
Ref<File> FileSystem::GetFile(const std::string& path)
{
// Note, Might be broken on other platforms.
auto splits = String::Split(path, '/');
int currentDepth = -1;
std::string currentDirName = ".";
Ref<Directory> currentDirComparator = RootDirectory;
while (currentDirName == currentDirComparator->Name)
{
currentDepth++;
currentDirName = splits[currentDepth];
// Find next directory
for (auto& d : currentDirComparator->Directories)
{
if (d->Name == currentDirName)
{
currentDirComparator = d;
}
}
// Find in files if can't find in directories.
for (auto& f : currentDirComparator->Files)
{
if (f->GetName() == currentDirName)
{
return f;
}
}
}
return nullptr;
}
std::string FileSystem::GetFileNameFromPath(const std::string& path)
{
const auto& split = String::Split(path, '/');
return String::Split(split[split.size() - 1], '.')[0];
}
Directory::Directory(const std::string& path)
{
Files = std::vector<Ref<File>>();
Directories = std::vector<Ref<Directory>>();
Name = FileSystem::AbsoluteToRelative(path);
FullPath = path;
}
}

View File

@@ -1,248 +0,0 @@
#pragma once
#include "Core.h"
#include "String.h"
#include <string>
#include <filesystem>
#include <iostream>
#include <fstream>
namespace Nuake
{
class FileDialog
{
public:
static std::string OpenFile(const char* filter);
static std::string SaveFile(const char* filter);
static std::string OpenFolder();
};
class Directory;
class File;
class FileSystem
{
public:
static std::string Root;
static Ref<Directory> RootDirectory;
static void SetRootDirectory(const std::string path);
static void Scan();
static std::string AbsoluteToRelative(const std::string& path);
static std::string RelativeToAbsolute(const std::string& path);
static std::string GetParentPath(const std::string& fullPath);
static Ref<Directory> GetFileTree();
static Ref<File> GetFile(const std::string& path);
static std::string GetFileNameFromPath(const std::string& path);
static void ScanDirectory(Ref<Directory> directory);
static void GetDirectories();
static bool MakeDirectory(const std::string& path, bool absolute = false);
static bool DirectoryExists(const std::string& path, bool absolute = false);
static bool FileExists(const std::string& path, bool absolute = false);
static std::string ReadFile(const std::string& path, bool absolute = false);
static std::ofstream fileWriter;
static bool BeginWriteFile(const std::string path, bool absolute = false);
static bool WriteLine(const std::string line);
static void EndWriteFile();
static uintmax_t DeleteFileFromPath(const std::string& path);
static uintmax_t DeleteFolder(const std::string& path);
static std::string GetConfigFolderPath();
};
enum class FileType
{
Unkown,
Image,
Material,
Mesh,
Script,
NetScript,
Project,
Prefab,
Scene,
Wad,
Map,
Assembly,
Solution,
Audio
};
class File
{
private:
std::string Type;
std::string Name;
std::string RelativePath;
std::string AbsolutePath;
Ref<Directory> Parent;
public:
std::string GetExtension() const { return Type; }
std::string GetName() const { return Name; }
std::string GetRelativePath() const { return RelativePath; }
std::string GetAbsolutePath() const { return AbsolutePath; }
Ref<Directory> GetParent() const { return Parent; }
FileType GetFileType() const
{
std::string ext = GetExtension();
if (ext == ".png" || ext == ".jpg")
{
return FileType::Image;
}
if (ext == ".ogg" || ext == ".wav")
{
return FileType::Audio;
}
if (ext == ".material")
{
return FileType::Material;
}
if (ext == ".scene")
{
return FileType::Scene;
}
if (ext == ".project")
{
return FileType::Project;
}
if (ext == ".script")
{
return FileType::Script;
}
if (ext == ".prefab")
{
return FileType::Prefab;
}
if (ext == ".wad")
{
return FileType::Wad;
}
if (ext == ".map")
{
return FileType::Map;
}
if (ext == ".dll")
{
return FileType::Assembly;
}
if (ext == ".cs")
{
return FileType::NetScript;
}
if (ext == ".sln")
{
return FileType::Solution;
}
if (ext == ".mesh")
{
return FileType::Mesh;
}
return FileType::Unkown;
}
std::string GetFileTypeAsString() const
{
std::string ext = GetExtension();
if (ext == ".png" || ext == "jpg")
{
return "Image";
}
if (ext == ".material")
{
return "Material";
}
if (ext == ".scene")
{
return "Scene";
}
if (ext == ".project")
{
return "Project";
}
if (ext == ".script")
{
return "Script";
}
if (ext == ".prefab")
{
return "Prefab";
}
if (ext == ".wad")
{
return "Wad";
}
if (ext == ".map")
{
return "Map";
}
if (ext == ".map")
{
return "Assembly";
}
if (ext == ".cs")
{
return "C# Script";
}
return "File";
}
std::string Read()
{
return FileSystem::ReadFile(AbsolutePath, true);
}
bool IsValid()
{
return FileSystem::FileExists(AbsolutePath, true);
}
File(Ref<Directory> parentDir, const std::string& absolutePath, const std::string& name, const std::string& type)
{
AbsolutePath = absolutePath;
Parent = parentDir;
RelativePath = FileSystem::AbsoluteToRelative(absolutePath);
Name = name;
Type = type;
}
};
class Directory
{
public:
std::string Name;
std::string FullPath;
Ref<Directory> Parent;
std::vector<Ref<Directory>> Directories;
std::vector<Ref<File>> Files;
Directory(const std::string& path);
Directory() = default;
~Directory() = default;
};
}

View File

@@ -3,15 +3,21 @@
#include <imgui/imgui_impl_glfw.h>
#include <GLFW/glfw3.h>
#include <Tracy.hpp>
namespace Nuake
{
Input* Input::s_Instance;
Vector2 Input::s_ViewportPos = Vector2(0,0);
Vector2 Input::s_ViewportSize = Vector2(0, 0);
std::map<int, bool> Input::m_Keys = std::map<int, bool>();
bool Input::m_MouseButtons[5] = { false, false, false, false, false };
float Input::XScroll = 0.0f;
float Input::YScroll = 0.0f;
Vector2 Input::ViewportPosition = Vector2(0, 0);;
Vector2 Input::ViewportSize = Vector2(0, 0);
void Input::ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
{
XScroll = (float)xoffset;
@@ -74,6 +80,7 @@ namespace Nuake
{
auto window = Window::Get()->GetHandle();
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouse;
}
bool Input::IsMouseHidden()
@@ -86,6 +93,7 @@ namespace Nuake
{
auto window = Window::Get()->GetHandle();
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
}
// Action
@@ -149,14 +157,108 @@ namespace Nuake
return Vector2(xpos, ypos);
}
void Input::SetEditorViewportSize(const Vector2& position, const Vector2& size)
{
s_ViewportPos = position;
s_ViewportSize = size;
}
Vector2 Input::GetEditorViewportMousePosition()
{
if (s_ViewportPos == s_ViewportSize)
{
return GetMousePosition();
}
auto window = Window::Get()->GetHandle();
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
Vector2 absolutePosition = { xpos, ypos };
Vector2 offset = absolutePosition - ViewportPosition;
return Vector2(xpos , ypos);
}
void Input::SetMousePosition(const Vector2& position)
{
auto window = Window::Get()->GetHandle();
glfwSetCursorPos(window, position.x, position.y);
}
float Input::GetViewportMouseY()
{
return glm::clamp(GetMouseY() - ViewportPosition.y, 0.0f, ViewportSize.y);
}
float Input::GetViewportMouseX()
{
return glm::clamp(GetMouseX() - ViewportPosition.x, 0.0f, ViewportSize.x);
}
Vector2 Input::GetViewportMousePosition()
{
return glm::clamp(GetMousePosition() - ViewportPosition, { 0, 0 }, ViewportSize);
}
Vector2 Input::GetViewportSize()
{
return ViewportSize;
}
void Input::SetViewportDimensions(const Vector2& pos, const Vector2& size)
{
ViewportPosition = pos;
ViewportSize = size;
}
#pragma endregion
bool Input::IsControllerPresent(int id)
{
if (id > GLFW_JOYSTICK_LAST)
{
return 0;
}
return glfwJoystickPresent(GLFW_JOYSTICK_1 + id);
}
std::string Input::GetControllerName(int id)
{
if (IsControllerPresent(id))
{
return glfwGetJoystickName(id);
}
return "Controller Disconnected";
}
bool Input::IsControllerButtonPressed(int id, ControllerInput input)
{
GLFWgamepadstate state;
if (glfwGetGamepadState(GLFW_JOYSTICK_1 + id, &state))
{
if (state.buttons[static_cast<int>(input)])
{
return true;
}
}
return false;
}
float Input::GetControllerAxis(int id, ControllerAxis axis)
{
GLFWgamepadstate state;
if (glfwGetGamepadState(GLFW_JOYSTICK_1 + id, &state))
{
return state.axes[static_cast<int>(axis)];
}
return 0.0f;
}
bool Input::Init()
{
//auto window = Application::Get().GetWindow()->GetNative();
@@ -167,6 +269,8 @@ namespace Nuake
void Input::Update()
{
ZoneScoped;
// Reset all input to false.
for (auto& k : m_Keys)
{

View File

@@ -1,6 +1,7 @@
#pragma once
#include "src/Core/Maths.h"
#include <string>
#include <map>
#include <utility>
@@ -65,7 +66,7 @@ namespace Nuake
TAB = 258,
BACKSPACE = 259,
INSERT = 260,
DELETE = 261,
DELETE_KEY = 261,
RIGHT = 262,
LEFT = 263,
DOWN = 264,
@@ -132,11 +133,43 @@ namespace Nuake
MENU = 348
};
enum class ControllerInput
{
A = 0,
B,
X,
Y,
LEFT_BUMPER,
RIGHT_BUMPER,
BACK,
START,
GUIDE,
LEFT_THUMB,
RIGHT_THUMB,
DPAD_UP,
DPAD_RIGHT,
DPAD_DOWN,
DPAD_LEFT
};
enum class ControllerAxis
{
LEFT_X = 0,
LEFT_Y,
RIGHT_X,
RIGHT_Y,
LEFT_TRIGGER,
RIGHT_TRIGGER
};
class Input
{
private:
static bool m_MouseButtons[5];
static std::map<int, bool> m_Keys;
static Vector2 ViewportPosition;
static Vector2 ViewportSize;
public:
static bool IsKeyPressed(Key keycode);
static bool IsKeyDown(Key keycode);
@@ -153,11 +186,29 @@ namespace Nuake
static bool IsMouseButtonDown(int button);
static bool IsMouseButtonReleased(int button);
// Get mouse position relative to window
static float GetMouseX();
static float GetMouseY();
static Vector2 GetMousePosition();
static void SetEditorViewportSize(const Vector2& position, const Vector2& size);
static Vector2 GetEditorViewportMousePosition();
static void SetMousePosition(const Vector2& position);
// Get mouse position relative to viewport
static float GetViewportMouseY();
static float GetViewportMouseX();
static Vector2 GetViewportMousePosition();
static Vector2 GetViewportSize();
static void SetViewportDimensions(const Vector2& pos, const Vector2& size);
// Controller
static bool IsControllerPresent(int id);
static std::string GetControllerName(int id);
static bool IsControllerButtonPressed(int id, ControllerInput input);
static float GetControllerAxis(int id, ControllerAxis axis);
static bool Init();
static void Update();
@@ -165,5 +216,7 @@ namespace Nuake
private:
static Input* s_Instance;
static Vector2 s_ViewportPos;
static Vector2 s_ViewportSize;
};
}

View File

@@ -0,0 +1,134 @@
#pragma once
#include <functional>
#include <vector>
#define DECLARE_MULTICAST_DELEGATE(multicastDelegateName, ...) typedef MulticastDelegate<__VA_ARGS__> multicastDelegateName;
struct DelegateHandle
{
size_t id = InvalidHandle;
static inline size_t InvalidHandle = static_cast<size_t>(-1);
bool IsValid() const { return id != InvalidHandle; }
void Reset() { id = InvalidHandle; }
// Comparison operators for convenience
bool operator==(const DelegateHandle& other) const { return id == other.id; }
bool operator!=(const DelegateHandle& other) const { return id != other.id; }
};
template<typename... Args>
class MulticastDelegate
{
public:
// Add a callable with bound variables (supports no arguments as well)
template<typename Callable, typename... BoundArgs>
DelegateHandle AddStatic(Callable&& func, BoundArgs&&... boundArgs)
{
size_t id = GetNextID();
auto boundFunction = [=](Args... args) {
if constexpr (sizeof...(Args) > 0)
{
func(boundArgs..., std::forward<Args>(args)...);
}
else
{
func(boundArgs...);
}
};
SetDelegate(id, boundFunction);
return DelegateHandle{ id };
}
template<typename Obj, typename Callable, typename... BoundArgs>
DelegateHandle AddRaw(Obj* object, Callable&& func, BoundArgs&&... boundArgs)
{
size_t id = GetNextID();
auto boundFunction = [=](Args... args) {
if constexpr (sizeof...(Args) > 0)
{
(object->*func)(boundArgs..., std::forward<Args>(args)...);
}
else
{
(object->*func)(boundArgs...);
}
};
SetDelegate(id, boundFunction);
return DelegateHandle{ id };
}
// Remove a callable using the token returned by Add()
void Remove(DelegateHandle& handle)
{
ASSERT(handle.IsValid());
if (handle.IsValid() && handle.id < delegates.size())
{
delegates[handle.id].active = false;
// Mark this slot as reusable
freeIDs.push_back(handle.id);
}
// Invalidate the handle
handle.Reset();
}
// Clear all delegates
void Clear()
{
delegates.clear();
freeIDs.clear();
nextID = 0;
}
// Invoke all callables
void Broadcast(Args... args)
{
for (auto& delegate : delegates)
{
if (delegate.active)
{
delegate.function(std::forward<Args>(args)...);
}
}
}
private:
struct Delegate
{
bool active = false;
std::function<void(Args...)> function;
};
// A vector of delegates with active state
std::vector<Delegate> delegates;
// List of reusable slots
std::vector<size_t> freeIDs;
size_t nextID = 0;
// Get the next available ID, either by reusing a free slot or by creating a new one
size_t GetNextID()
{
if (!freeIDs.empty())
{
size_t id = freeIDs.back();
freeIDs.pop_back();
return id;
}
return nextID++;
}
// Set the delegate in the vector, makes the array larger if necessary
void SetDelegate(size_t id, const std::function<void(Args...)>& func)
{
if (id >= delegates.size())
delegates.resize(id + 1);
delegates[id] = { true, func };
}
};

View File

@@ -1,7 +1,9 @@
#include "OS.h"
#include "src/Window.h"
#include "Engine.h"
#include "src/Resource/Project.h"
#include "src/Window.h"
#include "src/Core/String.h"
#ifdef NK_WIN
#define GLFW_EXPOSE_NATIVE_WIN32
@@ -18,13 +20,17 @@
#include <X11/Xlib.h>
#endif
#include "src/FileSystem/File.h"
#include "src/FileSystem/Directory.h"
#include "GLFW/glfw3.h"
#include "GLFW/glfw3native.h"
#include "imgui/imgui.h"
#include <chrono>
#include <imgui/imgui.h>
#include <Subprocess.hpp>
#include <codecvt>
#include <filesystem>
#include <Subprocess.hpp>
namespace Nuake {

View File

@@ -1,7 +1,7 @@
#pragma once
#include <string>
#include "FileSystem.h"
#include "src/FileSystem/FileSystem.h"
namespace Nuake
{

View File

@@ -0,0 +1,5 @@
#include "ClassDB.h"
namespace Nuake
{
}

View File

@@ -0,0 +1,14 @@
#pragma once
namespace Nuake
{
class ClassDB
{
public:
template<class T>
static void RegisterComponent(T klass)
{
T::InternalInitializeClass();
}
};
}

View File

@@ -0,0 +1,173 @@
#pragma once
#include <entt/entt.hpp>
#include <type_traits>
#define NK_HASHED_STATIC_STR(name) inline static constexpr entt::hashed_string name = entt::hashed_string(#name);
#define NK_ENUM_BITWISE_IMPL(enumClassName) \
inline enumClassName operator|(enumClassName lhs, enumClassName rhs) \
{ \
return static_cast<enumClassName>(ToUnderlying(lhs) | ToUnderlying(rhs)); \
} \
\
inline enumClassName operator&(enumClassName lhs, enumClassName rhs) \
{ \
return static_cast<enumClassName>(ToUnderlying(lhs) & ToUnderlying(rhs)); \
}
namespace Nuake
{
struct HashedFnName
{
NK_HASHED_STATIC_STR(GetComponentName)
NK_HASHED_STATIC_STR(AddToEntity)
NK_HASHED_STATIC_STR(RemoveFromEntity)
NK_HASHED_STATIC_STR(ActionName)
};
struct HashedFieldPropName
{
NK_HASHED_STATIC_STR(FloatStep)
NK_HASHED_STATIC_STR(FloatMin)
NK_HASHED_STATIC_STR(FloatMax)
NK_HASHED_STATIC_STR(ResourceFileType)
};
struct HashedName
{
NK_HASHED_STATIC_STR(DisplayName)
};
enum class ComponentTypeTrait : uint16_t
{
None = 0,
// Exposes the component to be added via the inspector
InspectorExposed = 1 << 0,
};
enum class ComponentFuncTrait : uint16_t
{
None = 0,
// Exposes the component to be added via the inspector
Action = 1 << 0,
};
enum class ComponentFieldTrait : uint16_t
{
None = 0,
// Stops field from showing up in the editor inspector
Internal = 1 << 0,
// Marks the field as temporary (ie, do not serialize)
Transient = 1 << 1,
};
template <typename Enum>
constexpr std::underlying_type_t<Enum> ToUnderlying(Enum e)
{
return static_cast<std::underlying_type_t<Enum>>(e);
}
NK_ENUM_BITWISE_IMPL(ComponentTypeTrait);
NK_ENUM_BITWISE_IMPL(ComponentFuncTrait);
NK_ENUM_BITWISE_IMPL(ComponentFieldTrait);
}
#define NUAKECOMPONENT(klass, componentName) \
public: \
static std::string ClassName() \
{ \
static std::string className = #klass; \
return className; \
} \
\
static std::string ComponentName() \
{ \
static std::string name = componentName; \
return name; \
} \
\
static void AddToEntity(entt::entity entity, entt::registry* enttRegistry) \
{ \
enttRegistry->emplace_or_replace<klass>(entity); \
} \
\
static void RemoveFromEntity(entt::entity entity, entt::registry* enttRegistry) \
{ \
enttRegistry->erase<klass>(entity); \
} \
\
\
static void (*GetInitializeComponentClass())() \
{ \
return &klass::InitializeComponentClass; \
} \
\
inline static auto ComponentFactory = entt::meta<klass>(); \
static void InternalInitializeClass() \
{ \
static bool initialized = false; \
if (initialized) \
return; \
\
ComponentFactory.type(entt::hashed_string(#klass)) \
.traits(ComponentTypeTrait::InspectorExposed); \
ComponentFactory.func<&klass::ComponentName>(HashedFnName::GetComponentName); \
ComponentFactory.func<&klass::AddToEntity>(HashedFnName::AddToEntity); \
ComponentFactory.func<&klass::RemoveFromEntity>(HashedFnName::RemoveFromEntity); \
\
if (klass::GetInitializeComponentClass() != Component::GetInitializeComponentClass()) \
{ \
GetInitializeComponentClass()(); \
} \
\
initialized = true; \
\
} \
\
template<auto Data> \
static auto BindComponentField(const char* varName, const char* displayName) \
{ \
return ComponentFactory \
.data<Data>(entt::hashed_string(varName)) \
.prop(HashedName::DisplayName, displayName); \
} \
\
template<auto Getter, auto Setter> \
static auto BindComponentProperty(const char* varName, const char* displayName) \
{ \
return ComponentFactory \
.data<Getter, Setter>(entt::hashed_string(varName)) \
.prop(HashedName::DisplayName, displayName); \
} \
\
static auto FieldFloatLimits(float stepSize, float min, float max) \
{ \
return ComponentFactory \
.prop(HashedFieldPropName::FloatStep, stepSize) \
.prop(HashedFieldPropName::FloatMin, min) \
.prop(HashedFieldPropName::FloatMax, max); \
} \
\
static auto ResourceFileRestriction(const char* fileType) \
{ \
return ComponentFactory \
.prop(HashedFieldPropName::ResourceFileType, fileType); \
} \
\
template <typename... Enums> \
static auto SetFlags(Enums... enums) \
{ \
static_assert((std::is_enum_v<Enums> && ...), "All arguments must be of enum class type"); \
return ComponentFactory.traits((enums | ...)); \
} \
\
template<auto Func> \
static void BindAction(const char* funcName, const char* actionName) \
{ \
ComponentFactory \
.func<Func>(entt::hashed_string(funcName)) \
.prop(HashedName::DisplayName, actionName); \
SetFlags(ComponentFuncTrait::Action); \
}

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