Compare commits

..

438 Commits

Author SHA1 Message Date
William Moberg d1b6fb1259 Tiny logic alteration so we don't get false warnings in debug. 2016-01-19 16:59:02 +01:00
William Moberg 017ad96bbe Fixed some errors in Tests. 2016-01-19 15:20:29 +01:00
William Moberg 713ebbe18c Can add any objects that inherit from AABB into the Octree. 2016-01-19 14:50:46 +01:00
William Moberg 621d935d7a Octree returns correct boxes when testing along an axis by searching through the correct child subtrees. 2016-01-18 18:24:11 +01:00
William Moberg b2358a1854 Added bool in Physics to toggle gravity for entities. 2016-01-18 18:16:24 +01:00
William Moberg bf3f8aea89 Merge pull request #36 from teamfisk/PlayerMovement
Player movement
2016-01-18 13:32:42 +01:00
William Moberg 0669d91767 CollisionSystem loops over Collidable components. 2016-01-18 13:29:10 +01:00
William Moberg 942064c450 Removed class PlayerSystem and associated files. 2016-01-18 13:07:04 +01:00
Jace fb7e0498a8 Merge pull request #35 from teamfisk/DisableMemoryPool
Possible to disable the MemoryPool allocation in Config files.
2016-01-18 10:46:53 +01:00
William Moberg a346a329b3 Added an option to disable the Pool allocation in Config.ini, in case there is a mess with the MemoryPool. 2016-01-18 10:16:35 +01:00
Jace f281d220de Working Spawner, SpawnPoint, PlayerSpawn and Team components, along with their systems. 2016-01-17 01:00:48 +01:00
Jace 6385a98eca Added runtime type size check to ComponentWrapper to avoid corruption when types don't match 2016-01-17 00:59:26 +01:00
Jace d8a24bbfde Renamed all instances of "Property" to "Field" in ComponentWrapper to maintain consistent naming with ComponentInfo 2016-01-17 00:38:25 +01:00
Jace 9ec32464bc Added enum support to entity file format, see "Team" component for an example. Use ComponentInfo::Enum to convert enum string keys to its corresponding integer representation at runtime. 2016-01-16 23:12:24 +01:00
Jace f65ac65e30 Updated component defaults files to match component schema and made schema validation strict. 2016-01-16 17:03:57 +01:00
Jace b2213dbe9a Merge remote-tracking branch 'origin/master' into PlayerMovement
# Conflicts:
#	include/Engine/Collision/Collision.h
#	include/Engine/Collision/CollisionSystem.h
#	include/Engine/Collision/TriggerSystem.h
#	resources/Schema/Components.xsd
#	resources/Schema/Entities/CollisionTestLevel.xml
#	resources/Schema/Types/Entity.xsd
#	src/Engine/Collision/Collision.cpp
#	src/Game/Game.cpp
2016-01-15 20:28:43 +01:00
Jace bbabc84127 Fixed default values for CPlayerSpawn 2016-01-15 20:26:30 +01:00
Jace 8bd5a428b9 EntityFileParser now ignores component fields not present in component definition instead of crashing. 2016-01-15 20:25:48 +01:00
Jace db1b972cd1 Spawner, SpawnPoint and PlayerSpawn components, and base work on their systems 2016-01-15 18:32:47 +01:00
Jace 97e12ff550 Made EntityFileParser::MergeEntities return the base entity that was created, and also take an optional parent entity to create it under. 2016-01-15 18:31:32 +01:00
stiffly d28583ca9e Fixes for #34 (Licenses) 2016-01-15 17:20:11 +01:00
Jace 0469460029 Input binding format changed to allow custom values for bindings. Relevant code must clamp input values to prevent speedhaxx! 2016-01-15 16:32:04 +01:00
Jace 7b2a21f0b0 Merge pull request #34 from teamfisk/Sound
Sound
2016-01-15 16:26:55 +01:00
stiffly 5c45dbdd10 Merge remote-tracking branch 'origin/master' into Sound
# Conflicts:
#	resources/Schema/Types/Entity.xsd
2016-01-15 16:25:32 +01:00
Jace ce8dcd3022 Merge pull request #33 from teamfisk/Forward+
Forward+
2016-01-15 16:20:53 +01:00
Jace a2e19013c6 Merge pull request #32 from teamfisk/AsyncResourceLoad
Async resource load
2016-01-15 16:20:36 +01:00
William Moberg c09fe4ae55 Added a bool option to disable threads in in the configfile regarding resource loading. 2016-01-15 16:18:39 +01:00
stiffly be33dfbd69 Forgot to change the velocity for the emitters as well... 2016-01-15 16:10:02 +01:00
stiffly 63704b2e6b Now calculating the velocity for the listener correctly. 2016-01-15 15:43:20 +01:00
Tleety 3de853ac8b Frustum culling now works correctly for all resolutions 2016-01-15 15:38:14 +01:00
William Moberg f5ea4d513c ResourceManager::Load never returns null, throws exceptions instead. 2016-01-15 15:25:01 +01:00
stiffly d9dd7f535f When changing camera listener is updated. Also fixed some crashes in RenderSystem when there were no cameras available. 2016-01-15 13:45:08 +01:00
William Moberg 76f90ab031 The main thread is not mutex blocked while child threads load anymore. 2016-01-15 11:29:46 +01:00
stiffly 3e2cb33bc0 Played around with new map MapVersion1. Was fun ヽ(´▽`)/ 2016-01-15 11:23:29 +01:00
Tleety 14bc850fab Merge remote-tracking branch 'origin/master' into Forward+ 2016-01-15 11:02:27 +01:00
Tleety ecf524eb4e Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	include/Engine/Rendering/PickingPass.h
#	include/Engine/Rendering/Renderer.h
#	resources/Schema/Entities/Test.xml
#	src/Engine/Rendering/DrawScenePass.cpp
#	src/Engine/Rendering/PickingPass.cpp
#	src/Engine/Rendering/RenderQueueFactory.cpp
#	src/Engine/Rendering/Renderer.cpp
2016-01-15 11:01:58 +01:00
William Moberg 4cf6dcfc14 Merge branch 'master' into AsyncResourceLoad
# Conflicts:
#	include/Engine/Rendering/RawModel.h
#	src/Engine/Rendering/RenderQueueFactory.cpp
2016-01-15 10:10:57 +01:00
stiffly 32634f742e Merge remote-tracking branch 'origin/master' into Sound 2016-01-15 09:53:39 +01:00
stiffly e248b37ea8 Merge remote-tracking branch 'origin/master' into Sound
# Conflicts:
#	src/Game/Game.cpp
2016-01-15 09:52:52 +01:00
Jace 567173c565 Merge branch 'master' into PlayerMovement
# Conflicts:
#	src/Engine/Rendering/RenderSystem.cpp
#	src/Game/Game.cpp
2016-01-14 18:24:34 +01:00
Jace 5e721325a4 Merge fixes 2016-01-14 18:20:51 +01:00
Jace 627108c6ee Fixes for #30
# Conflicts:
#	src/Game/Game.cpp
2016-01-14 18:15:38 +01:00
Jace 3a4f378ac5 Merge remote-tracking branch 'origin/master' into PlayerMovement
# Conflicts:
#	src/Game/Game.cpp
2016-01-14 17:07:39 +01:00
Jace 6ad1839def Initial work on PlayerMovementSystem 2016-01-14 17:03:48 +01:00
Jace 986af01091 Fixed editor component fields with the same name across components being treated as the same value 2016-01-14 17:02:13 +01:00
Jace 99406c32cf Better error handling for EntityFilePreprocessor 2016-01-14 17:01:39 +01:00
Viktor Ljung a8f7d5f6b9 Merge pull request #30 from teamfisk/Rendering
Rendering Scenes
2016-01-14 16:43:35 +01:00
William Moberg 71047b08ec Async load works, using exceptions for special resources. 2016-01-14 16:27:45 +01:00
Jace d34470256b EntityWrapper to uniquely identify entities and make using them a little easier 2016-01-14 15:43:19 +01:00
Jace 28392def79 Made string passing in World a little more effective 2016-01-14 15:42:55 +01:00
viktorljung c99a8685bb Removed Debug scene 2016-01-14 15:40:13 +01:00
stiffly b80ecc29d8 Added comments and cleaned up in Game.cpp/h 2016-01-14 15:32:53 +01:00
viktorljung 143648860b Added world pointer to PickData 2016-01-14 15:32:41 +01:00
viktorljung 96371a08c8 Changed Picking colors from vec2 to ivec2. Picking now working for multiple scenes (Solution not perfect in the editor, yet) 2016-01-14 15:26:06 +01:00
stiffly c916185a7c Does not crash when removing soundemitter component. 2016-01-14 15:06:26 +01:00
Jace 71d936f8d1 Start of a movement system with collisions against AABBs 2016-01-14 14:54:12 +01:00
stiffly 7f0ff6c4d7 Added a sound testing level. 2016-01-14 14:20:34 +01:00
stiffly 773a417a90 Merge branch 'master' into Sound 2016-01-14 14:19:48 +01:00
stiffly cca64dca24 Refactoring and commenting. 2016-01-14 13:54:38 +01:00
viktorljung e7f02f14a0 Added Transform.h that holds all the AbsoluteTransformation functions. Camera now working better with scenes. Changed Modeljob Matrix to only hold the model matrix instad of all matrix info 2016-01-14 11:12:02 +01:00
William Moberg 9f185a1e35 Wrecked the last commit. Async loading works now. 2016-01-13 18:51:45 +01:00
William Moberg a143ae7c85 Changed to relative #include paths. 2016-01-13 15:53:55 +01:00
Jace d6ef527f25 Basic collisions using Octree. Seems buggy over octree boundaries. 2016-01-13 15:34:43 +01:00
Jace 8ed4ba1219 Added missing include for Octree 2016-01-13 12:16:35 +01:00
Jace 311475cbb6 Renamed all OctTree to Octree (More OCD) 2016-01-13 12:15:36 +01:00
Jace 8164a955d6 Renamed OctTree files to Octree (OCD to the max) 2016-01-13 12:15:09 +01:00
William Moberg a58cc33ed0 WIP, multithreaded loading based on exceptions, very slow probably. 2016-01-13 10:58:31 +01:00
William Moberg 704e8825c4 Merge pull request #29 from teamfisk/Networking
Networking
2016-01-12 17:48:33 +01:00
Jocke 2284399538 Removed Close method from Client, Server and Network.
Removed legacy variable m_ThreadIsRunning in Client.h and Server.h.
Removed m_EventBroker->Unsubscribe(m_EInputCommand) in Client destructor.
2016-01-12 17:47:03 +01:00
viktorljung 0f17f9a888 Merge remote-tracking branch 'origin/master' into Rendering
# Conflicts:
#	include/Engine/Editor/EditorSystem.h
#	include/Engine/Rendering/EPicking.h
#	include/Engine/Rendering/Renderer.h
#	include/Game/Game.h
#	resources/Schema/Components.xsd
#	resources/Schema/Entities/Test.xml
#	src/Engine/Editor/EditorSystem.cpp
#	src/Engine/Rendering/RawModel.cpp
#	src/Engine/Rendering/RenderQueueFactory.cpp
#	src/Engine/Rendering/Renderer.cpp
#	src/Game/Game.cpp
2016-01-12 16:13:20 +01:00
stiffly c9f11f62d2 Does not delete emitters that are paused and has not yet been played. 2016-01-12 15:37:10 +01:00
stiffly 5697e8bc85 Deleting an entity now tells openal to behave accordingly. 2016-01-12 14:51:10 +01:00
stiffly 729ebe6c8b Merge remote-tracking branch 'origin/master' into Sound
# Conflicts:
#	README.md
#	resources/Schema/Components.xsd
#	resources/Schema/Types/Entity.xsd
2016-01-12 14:50:10 +01:00
Jocke 56ac592d6d Removed debug code from Game.cpp 2016-01-12 14:16:01 +01:00
stiffly 976033c2f6 Added events: PlayBackgroundMusic, SetBGMGain, SetSFXGain. Added some editor specific code. 2016-01-12 14:03:00 +01:00
Jocke 2bf1d53f2c Merge remote-tracking branch 'origin/master' into Networking 2016-01-12 13:17:00 +01:00
Jocke 236230d12c Packets now dynamically allocates more memory when they need it.
Increased local receive buffer for Client and Server() and removed the magic number that was used
In Server.h and Client.h
(char readBuffer[INPUTSIZE] = { 0 }).
Packets start size has now been increased to 512 bytes.
Changed ComponentInfo::FieldsInOrder to store strings instead of pointers.
Removed HasEntity() and are now using ValidEntity() instead.
2016-01-12 12:00:19 +01:00
viktorljung 2450769190 some cleanup 2016-01-12 11:51:47 +01:00
viktorljung d469fe6e9a Removed picking event and added a pick function to renderer 2016-01-12 11:45:50 +01:00
Tleety 24ba3ae1f6 WIP, falloff things.
# Conflicts:
#	resources/Schema/Components/PointLight.xsd
#	resources/Shaders/ForwardPlus.frag.glsl
2016-01-11 17:57:15 +01:00
Tleety fa6dd2dc67 Basic transparancy working. 2016-01-11 17:57:15 +01:00
Tleety 3c5966d174 Now sort models according to depth. 2016-01-11 17:57:15 +01:00
Tleety 0cf8d26557 Revert "Revert "Forward+""
This reverts commit b908a9f9c6.
2016-01-11 17:56:58 +01:00
stiffly f80ad1377b Making use of Doppler effect. Added a bunch of events: Pause, stop, continue, variations of play. 2016-01-11 17:52:27 +01:00
viktorljung 3feee7fd35 Changed the structure of how RenderJobs are handled 2016-01-11 17:01:17 +01:00
William Moberg 84818f6fcb Merge pull request #28 from teamfisk/ecs
New entity loading and saving
2016-01-11 16:49:40 +01:00
Jace 349fa9d7fa Fixed crash when creating new entities 2016-01-11 16:47:30 +01:00
Jace 2a5e0420c8 Added template entity "Empty.xml" for use as root entity when creating a new map. 2016-01-11 16:40:26 +01:00
Jocke b37ffc7449 WIP Model component not working. 2016-01-11 14:58:49 +01:00
Jocke 6c13916eec Removed unnecessary code. 2016-01-11 14:58:30 +01:00
stiffly f0ad28bac4 Removed some comments. Basically did nothing 2016-01-11 14:58:15 +01:00
Jace 4a516a4d86 Added ComponentInfo::FieldsInOrder to be able to loop through component fields in a consistent order based on the component XSD definition 2016-01-11 14:56:53 +01:00
Jace 21aea6f31d Added World::ValidEntity for checking if an entity exists or not 2016-01-11 14:35:41 +01:00
Jace 297a3fb493 Support for "name" attribute on entities 2016-01-11 14:35:41 +01:00
Jace c47ef61ddc Temporary fix for widgets being annoying entities in the editor 2016-01-11 14:35:41 +01:00
Jace e8e93587e9 Fixed weird behavior when components would register multiple times (Hint: It should never happen in the first place) 2016-01-11 14:35:41 +01:00
Jace 39dd27726d MAJOR BREAKING CHANGE: EntityID 0 is now a valid entity. Use EntityID_Invalid as sentry for checks!
Also contains inseparable editor changes.
2016-01-11 14:35:41 +01:00
Jace 6adc98eea5 Now writes entities to file instead of stdout... 2016-01-11 14:35:41 +01:00
Jace ad4e723677 Added nativefiledialog to README 2016-01-11 14:35:41 +01:00
Jace 11d547cde8 Entity 0 is now a real entity in the world, created by the first entity read while importing. This makes the difference between map files and entity files automatic, since consecutive entity file loads should automatically get the world as parent, as long as the world entity has been created earlier. 2016-01-11 14:35:41 +01:00
Jace 24b9e951c2 Added stride information to ComponentInfo, refactored FieldOffsets and FieldTypes into new struct Field_t Fields while I was at it. 2016-01-11 14:35:41 +01:00
Jace 81024b4a1d First work on EntityFileWriter for saving levels 2016-01-11 14:35:41 +01:00
Jace 23e78c4947 Cleaned up code 2016-01-11 14:35:15 +01:00
Jace 3e7f27e1fe Added error handler for DOM parsers 2016-01-11 14:35:15 +01:00
Jace ee83394678 Unified some previously duplicated code 2016-01-11 14:35:15 +01:00
Jace 03456ad731 EntityFileParser 2016-01-11 14:35:15 +01:00
Jace 0bcbcda8b8 EntityFilePreprocessor
WIP

WIP

EntityFilePreprocessor
2016-01-11 14:35:15 +01:00
Jace c6655ce0d3 Merge pull request #26 from teamfisk/revert-25-Forward+
Revert "Forward+"
2016-01-11 13:49:02 +01:00
Jace b908a9f9c6 Revert "Forward+" 2016-01-11 13:48:55 +01:00
Jace dc7ed2e0ba Merge pull request #25 from teamfisk/Forward+
Forward+
2016-01-11 12:43:43 +01:00
viktorljung b8db80bc40 Added camera to PickingPass and fixed memory leak 2016-01-11 10:47:39 +01:00
Tleety f71bfca142 Fixed cullLights into CullLights 2016-01-11 10:23:22 +01:00
Tleety dbb44fb4e4 Changing cullLights to Culllights, need to do this in 2 commits since Git extensions is fucked. 2016-01-11 10:22:56 +01:00
viktorljung a7b43b06a2 Camera component and RenderQueue changes 2016-01-08 16:21:59 +01:00
Tleety 6e6460a000 Commented out the bugged models 2016-01-08 16:15:18 +01:00
stiffly 3cce9f8075 Using absolute transform 2016-01-08 15:29:20 +01:00
Tleety 9f871bbe7c Lights now use the absolute position instead of it's local position. 2016-01-08 14:31:44 +01:00
Tleety 2bd60be741 Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	resources/Schema/Types/Entity.xsd
2016-01-08 14:14:43 +01:00
Tleety dab4ba2164 Pointlights are now using the pointlight component and the Light renderqueue to draw. 2016-01-08 14:12:09 +01:00
Tleety 25a99a04c5 Added Visable bool and a better description to Pointlight component. 2016-01-08 14:11:35 +01:00
William Moberg 13ade6d7f2 Merge pull request #24 from teamfisk/HealthSystem
Fixed so the PlayerDeath event doesn't get spammed while the player i…
2016-01-08 11:54:11 +01:00
verysecrethero 592776e783 Fixed so the PlayerDeath event doesn't get spammed while the player is dead. Also made sure that any remaining healthDeltas are cleared when dead. 2016-01-08 11:37:51 +01:00
verysecrethero ff44dccb33 Merge pull request #23 from teamfisk/OrderedSystemPipeline
Ordered system pipeline approved
2016-01-08 10:32:58 +01:00
William Moberg ef9ce7932a New small fix. 2016-01-07 17:40:47 +01:00
stiffly da6e50dc7e Correct orientation. Need to clean this up. 2016-01-07 17:04:43 +01:00
William Moberg beb0967c3b Merge branch 'master' into OrderedSystemPipeline
# Conflicts:
#	src/Game/Game.cpp
2016-01-07 16:49:20 +01:00
verysecrethero 0e0a361a38 HotFix: Updated the CMakeList.txt in src/Game so it has the HealthSystem.cpp. This is needed otherwise the solution cant find that file 2016-01-07 16:36:18 +01:00
William Moberg 6ebc4fc784 Merge pull request #22 from teamfisk/HealthSystem
Health system
2016-01-07 16:17:17 +01:00
William Moberg 7fb71f17b2 Destruct all systems properly in the pipeline. 2016-01-07 16:13:52 +01:00
stiffly 2838446072 In lack of camera entity I created a Listener cube to test 3D sound. Works fine. Updates listener pos each tick. 2016-01-07 16:03:33 +01:00
verysecrethero e52c0c9633 Now using the easier/cleaner way of getting/setting the HealthProperties 2016-01-07 15:27:39 +01:00
stiffly d8c4c6e5ff Created a primitive SoundSystem. Can play a sound with 'P' button. Using resourcemanager. Not using the created components yet. 2016-01-07 15:22:46 +01:00
verysecrethero 578ca13f79 Merge remote-tracking branch 'origin/master' into HealthSystem 2016-01-07 15:19:32 +01:00
William Moberg 4048ce6bd4 Small fix. 2016-01-07 15:18:35 +01:00
William Moberg c4642cc530 Merge branch 'master' into OrderedSystemPipeline
# Conflicts:
#	include/Engine/Core/SystemPipeline.h
2016-01-07 15:07:16 +01:00
William Moberg 32ebc061b4 Merge pull request #21 from teamfisk/AndersTest
Pull request approved.
2016-01-07 14:57:12 +01:00
verysecrethero a1ed79dfbf HealthSystemTest has been created. This runs a single test simple test with HealthEvents and HealthSystem. Also some minor changes 2016-01-07 14:53:31 +01:00
verysecrethero 638c236ceb HealthSystem tested and working. Also the 3 new PlayerEvents seems to work. TODO: a proper test in the testclass 2016-01-07 14:53:31 +01:00
verysecrethero f67f22c82d Added Healthrelated events and start of HealthSystem, also reverted the crash "fix" 2016-01-07 14:53:31 +01:00
verysecrethero f3ff433bf7 Merge remote-tracking branch 'origin/master' into AndersTest 2016-01-07 14:51:08 +01:00
verysecrethero 85ff86a2fe Revert "Exit Crash has been dealt with. There is no need to unsubscribe game since m_ContextRelays has already been destroyed at that point"
This reverts commit 0ae6c42df8.
2016-01-07 14:50:13 +01:00
William Moberg fa8775a72e Renamed vars and added some comments. 2016-01-07 10:28:18 +01:00
Jace 49884d7e60 Fix for crash when unsubscription during event processing (untested) 2016-01-06 13:47:02 +01:00
Tleety e7bb8954bf Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	include/Engine/Rendering/Renderer.h
#	resources/Schema/Components.xsd
#	resources/Schema/Entities/Test.xml
#	src/Engine/Rendering/Renderer.cpp
2016-01-06 11:35:55 +01:00
Tleety e510f2b88c Forward plus render pass now removed from Renderer.cpp to it's own class. 2016-01-06 11:32:42 +01:00
Jace 34cbbb3eb1 Fixed exit crash(es) 2016-01-06 11:20:16 +01:00
verysecrethero 0ae6c42df8 Exit Crash has been dealt with. There is no need to unsubscribe game since m_ContextRelays has already been destroyed at that point 2016-01-05 15:22:16 +01:00
verysecrethero 3678cceb1c Merge remote-tracking branch 'origin/master' into AndersTest 2016-01-05 14:48:16 +01:00
William Moberg de8461e257 SystemPipeline should update systems in order depending on input update priority in AddSystem. 2015-12-18 15:33:25 +01:00
viktorljung bd82f75dd0 Some merge fixes, needs more work 2015-12-18 15:28:44 +01:00
Tleety eb69e03e82 Merge branch 'Forward+' of github.com:teamfisk/TacticalZ into Forward+ 2015-12-18 15:28:25 +01:00
Tleety d38f58165f Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	include/Engine/Rendering/Renderer.h
#	src/Engine/Rendering/RenderState.cpp
#	src/Engine/Rendering/Renderer.cpp
2015-12-18 15:27:47 +01:00
Viktor Ljung c133223bac Merge pull request #19 from teamfisk/Networking
Networking
2015-12-18 14:54:11 +01:00
verysecrethero 2f6d4fcd0b Adjusted some of the corefiles back to the original in preparation for the Pull Request 2015-12-18 14:49:35 +01:00
Tleety 069a6756b9 LightcullingPass for forward+ is now separate from Renderer.cpp. 2015-12-18 14:31:16 +01:00
stiffly a550b6077e Re-enabled InputCommand debugging info in console 2015-12-18 14:25:55 +01:00
verysecrethero e0cc25dbac Fixed the OctTreeTestGameClass.cpp so it draws the OctTree nicely again 2015-12-18 14:22:57 +01:00
stiffly 00bc55370d Added error check in Collision.cpp 2015-12-18 14:19:28 +01:00
stiffly 330f08b926 Merge remote-tracking branch 'origin/master' into Networking
# Conflicts:
#	include/Game/PlayerSystem.h
#	src/Game/Game.cpp
#	src/Game/PlayerSystem.cpp
2015-12-18 14:18:53 +01:00
stiffly a0255f1b31 Now uses config file to determine if client or server should be started. 2015-12-18 13:34:21 +01:00
viktorljung ef4cbfece8 Added PointLight Component in XML files 2015-12-18 13:20:55 +01:00
Tleety ab6af30a28 Base classes for decoupled forward+ renderer and a fix where if you had to many lights in a tile(200-300+) the list would fill up before the end of frustums. 2015-12-18 12:02:02 +01:00
stiffly a858dab8b6 Network not longer threaded 2015-12-18 12:00:14 +01:00
verysecrethero b1ae96f737 Merge remote-tracking branch 'origin/master' into AndersTest
# Conflicts:
#	include/Game/Game.h
#	src/Engine/Core/OctTree.cpp
#	src/Game/Game.cpp
#	src/Tests/CMakeLists.txt
#	src/Tests/OctTreeTest.cpp
#	src/Tests/WorldTest.cpp
2015-12-18 11:57:21 +01:00
Jace 7dcd75fccc Merge pull request #18 from teamfisk/OctTree
CollisionSystem, TriggerSystem and Octree
2015-12-18 11:42:44 +01:00
verysecrethero 1e5e24a036 The tests seems to work under boost 1.59 but test explorer window is broken in 1.60. also changed ResourceManagerTest.cpp 2015-12-18 11:37:02 +01:00
viktorljung 3636ad45af Changed to correct branch 2015-12-18 11:29:11 +01:00
stiffly 6d649e4d35 Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	src/Engine/Network/Client.cpp
2015-12-18 11:26:48 +01:00
stiffly 5c1a93021b Client now reads address and port from config file. Default address is set to local host. 2015-12-18 11:22:13 +01:00
viktorljung 6cf7c12d34 Forward+ working 2015-12-18 11:09:54 +01:00
Jocke ad43cc44c3 Merge remote-tracking branch 'origin/Networking' into Networking 2015-12-18 11:03:21 +01:00
Jocke 002e1d8c5a Removed magic number from Packet constructor in Packet.cpp. 2015-12-18 10:52:46 +01:00
Jocke 30db0b10fd Removed NetworkDefinitions.h and moved #define MAXCONNECTIONS 8
#define INPUTSIZE 128 to Network.h.
2015-12-18 10:36:14 +01:00
Jocke 97f8be1915 Made Network.h's Start() and Update pure virtual and removed cpp.
Removed unnecessary code from NetworkDefinitions.h.
Renamed sizeOfPackage to sizeOfPacket in Packet.cpp.
2015-12-18 10:21:56 +01:00
Jocke 0eb51a0fea Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	include/Engine/Network/Packet.h
#	src/Engine/Network/Packet.cpp
2015-12-18 10:16:31 +01:00
verysecrethero 13f7fb2561 Stashed test fixes for boost 1.6 2015-12-18 10:01:05 +01:00
stiffly 0b714e593f Removed WinLeakCheck. Minor variable name changes. removed IsWASDKeyDown struct 2015-12-17 17:56:15 +01:00
viktorljung 4a817613e3 Forward+ semi working 2015-12-17 17:55:44 +01:00
verysecrethero 8beddca89a Merge remote-tracking branch 'origin/master' into AndersTest 2015-12-17 17:48:28 +01:00
William Moberg 5e0fe975f3 Small error handling check. 2015-12-17 17:48:00 +01:00
Jocke db5b6ad519 Added more error code to Packet class 2015-12-17 17:32:49 +01:00
William Moberg a26c8f2a24 Merge branch 'master' into OctTree 2015-12-17 17:30:44 +01:00
stiffly 076030a252 Fixes, mostly name changes 2015-12-17 17:28:43 +01:00
William Moberg 0f59b863ee Renamed IF_DEBUG_IS to DEBUG_IF, slightly different behavior and added some safety checking for auto creating AABBs from models. 2015-12-17 17:08:47 +01:00
Adam Byléhn d0927373a3 Merge pull request #20 from teamfisk/Editor
More usable editor
2015-12-17 16:51:59 +01:00
William Moberg 46ae2d39af Merge branch 'master' into OctTree
# Conflicts:
#	src/Game/Game.cpp
2015-12-17 16:44:01 +01:00
Jace e9128efd13 Translation widget planes 2015-12-17 15:30:43 +01:00
Jace 00f6056f7c Uniform scaling when dragging scaling widget origin 2015-12-17 15:30:43 +01:00
Jace a655f0bae5 Drag-and-drop asset picking and base work for showing component field tooltips in the editor 2015-12-17 15:30:43 +01:00
Jace cf6dde6c09 Boost dependency updated to version 1.60! 2015-12-17 15:30:43 +01:00
Jace c1b9404e52 Created a FileDropped event for when a file is dropped onto the client by the OS 2015-12-17 15:30:43 +01:00
Jace 8000654005 Model loading now fetches material opacity value properly 2015-12-17 15:28:05 +01:00
stiffly 000adb198f Reset RenderQueueFactory.cpp to original state 2015-12-17 14:36:36 +01:00
stiffly 51a2da9cc0 Removed old Event that is not used 2015-12-17 14:28:17 +01:00
stiffly 0f0a1ceca7 No more fake packet loss 2015-12-17 14:22:31 +01:00
stiffly 50822d09fc Merge remote-tracking branch 'origin/master' into Networking
# Conflicts:
#	src/Game/Game.cpp
2015-12-17 14:10:02 +01:00
William Moberg 3e2ffdb85b Fixed comment on Trigger events. 2015-12-17 13:48:35 +01:00
William Moberg 5160a45b44 Made Ray into a class with checks so the direction will always be normalized. 2015-12-17 13:41:34 +01:00
William Moberg 03d5f0dd67 Added an macro IF_DEBUG_IS(x) that executes if run in debug mode, AABB has a check so max and min corners are set properly in debug mode. 2015-12-17 13:31:54 +01:00
stiffly 4bb4e29515 More cleaning code 2015-12-17 13:23:15 +01:00
stiffly a6a08f48bb Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	include/Engine/Network/Client.h
#	src/Engine/Network/Client.cpp
2015-12-17 11:24:34 +01:00
viktorljung aeca1dec18 Merge remote-tracking branch 'origin/master' into Rendering
# Conflicts:
#	src/Engine/Editor/EditorSystem.cpp
#	src/Engine/Rendering/PickingPass.cpp
#	src/Game/Game.cpp
2015-12-17 11:17:58 +01:00
viktorljung 0f1b06f74e Fixed camera rotation bug 2015-12-17 11:13:34 +01:00
stiffly ba831f8a3c WIP Cleaning 2015-12-17 10:59:55 +01:00
Tobias Dahl 1a9b765d47 Merge pull request #17 from teamfisk/Editor
Kinda usable editor
2015-12-17 10:59:08 +01:00
Jace c8460e0a6c It's no use 2015-12-17 10:55:54 +01:00
stiffly 4c29e071af Cleaned code 2015-12-17 10:47:08 +01:00
Jace b87f559291 Updated default configs with editor stuff 2015-12-17 10:46:49 +01:00
Jace d4f5856304 Component attributes no longer get set on the wrong entity when switching selection while editing a field 2015-12-17 10:44:34 +01:00
viktorljung 6a3c14540d fixes 2015-12-17 10:38:13 +01:00
Jocke 2cb5441b1c Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	src/Engine/Network/Client.cpp
2015-12-17 09:47:15 +01:00
stiffly 97a0d97b0b Can now send transform components. 2015-12-16 17:56:44 +01:00
Jace a914a7f924 Switched to deps/master branch 2015-12-16 17:22:35 +01:00
Jace dbbbb7b4e7 Working rotations and translations relative to global and local space for children 2015-12-16 17:20:56 +01:00
William Moberg a23d69af9a Removed old relics from OctTree testing in OctTree. 2015-12-16 17:08:55 +01:00
Jocke 425f3ca3dd Fixed "trying to read more than package size" warnings. 2015-12-16 16:49:18 +01:00
William Moberg 6d1cbd928e Improved collision logic, still not perfect since it updates before PlayerSystem. 2015-12-16 16:34:27 +01:00
Jocke 6da5fd1263 Restructured code and added bool to stop client from spamming Snapshots to a server when
it wasn't connected to one.
2015-12-16 15:47:51 +01:00
Jocke 6eebce05af Merge remote-tracking branch 'origin/Networking' into Networking 2015-12-16 14:58:36 +01:00
Jocke 58a9d38e26 Added a class that client and server inherits from.
Class and server now share the same pointer i game.
You are now able to start a client and a server on the same computer.
2015-12-16 14:56:53 +01:00
stiffly 50ccf96268 Movement code not buggy anymore. Also changed package to not allocate more data than needed. 2015-12-16 13:52:16 +01:00
viktorljung 5602b32507 Forward+ Fixes 2015-12-16 13:36:38 +01:00
William Moberg cf0ff9bfe5 Simple quickly made CollisionSystem. 2015-12-16 12:23:08 +01:00
William Moberg d10df6ae09 TriggerSystem implemented and working. 2015-12-16 12:22:15 +01:00
William Moberg 99b76d7ae1 Fixed returning address to temporary in functions. AABB also constructible from glm::vec4s. 2015-12-16 12:19:43 +01:00
Jace 661532e355 Slightly more usable entity tree 2015-12-16 12:05:55 +01:00
Jace bd6adcc157 Added SetParent to World 2015-12-16 12:05:37 +01:00
stiffly a2d55feed1 Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	src/Engine/Network/Client.cpp
#	src/Engine/Network/Server.cpp
2015-12-16 11:12:15 +01:00
Jocke e74b2b6874 Made it easier for non network members to create packages and extract information from them by addin PopFrontString() and PopFrontPrimitive<type>(). 2015-12-16 10:40:40 +01:00
Jace 322aedaf72 Basic transformation widgets 2015-12-16 09:47:38 +01:00
stiffly 3f602c9d63 Test code 2015-12-15 17:55:08 +01:00
stiffly 082b3fd3df Removed old input events from client 2015-12-15 17:22:46 +01:00
William Moberg 04a01104b5 Merge branch 'master' into OctTree
# Conflicts:
#	src/Engine/CMakeLists.txt
#	src/Game/Game.cpp
2015-12-15 17:11:11 +01:00
stiffly 9b348a7d97 Updated movement code once again. 2015-12-15 16:50:59 +01:00
stiffly 889e0bb3d3 Cleaned up PlayerSystem. Sets velocity to 0 every frame. 2015-12-15 16:35:09 +01:00
stiffly 1669649186 Fixed bug with entityID. Also trying to fix movement WIP. 2015-12-15 16:24:09 +01:00
Tleety 1431bd1a11 DebugChanges 2015-12-15 15:39:23 +01:00
William Moberg ed82a0939a Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree 2015-12-15 15:37:14 +01:00
William Moberg e2417be8c7 Very simple CollisionSystem made, 'Z','Y' to toggle on/off. 2015-12-15 15:36:28 +01:00
stiffly 472a8db81a Various bug fixes. 2015-12-15 15:32:31 +01:00
viktorljung fa66e9ff47 Camera Switch event now working, Camera models Rotation still bugged 2015-12-15 15:29:19 +01:00
Tleety 1e370bac13 ForwardPlus base debug commit. 2015-12-15 15:28:37 +01:00
Jocke e940c1d604 WIP 2015-12-15 14:55:56 +01:00
stiffly 478c692315 Refactoring. Client and server has Update Loop that runs before any game logic each frame. 2015-12-15 14:53:56 +01:00
William Moberg 170610bcb1 Added a TriggerSystem, seems to work as intended. 2015-12-15 14:49:52 +01:00
verysecrethero 454ed0032b Refactored some RayVsModel tests 2015-12-15 14:01:49 +01:00
verysecrethero 1910ab705b AndersTest misc small mergefixes 2015-12-15 13:48:14 +01:00
stiffly 0a8a9e5099 Merge remote-tracking branch 'origin/master' into Networking
# Conflicts:
#	src/Engine/Rendering/RenderState.cpp
#	src/Game/Game.cpp
2015-12-15 11:50:01 +01:00
verysecrethero f9508657f5 Merge remote-tracking branch 'origin/master' into AndersTest
# Conflicts:
#	include/Engine/Core/InputController.h
#	include/Game/Game.h
2015-12-15 11:32:47 +01:00
stiffly b698a0d36f WIP
Adding models now crashes. Threading
Added a create player event that currently is not used.
2015-12-15 11:21:46 +01:00
verysecrethero 1229a99af4 Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree 2015-12-15 11:07:51 +01:00
verysecrethero 8e431c8edd RayVsModel && RayVsAABB tests added and working. Also adjusted RayVsModel,RayVsAABB with deltas when values are very close to each other (floatingprecision problems) 2015-12-15 11:07:09 +01:00
Jace 51dd627ae3 Added Fonts to deploy.bat 2015-12-15 09:49:43 +01:00
Jace c296c4eb3b Fixed picking pass... again... 2015-12-15 09:49:38 +01:00
Jace 422e6f5264 Created a RenderState for ImGuiRenderPass 2015-12-14 20:26:04 +01:00
Viktor Ljung 9cee8b5478 Merge pull request #16 from teamfisk/Editor
Added BlendEquation and BlendFunc to RenderState ...
2015-12-14 20:25:10 +01:00
Jace 522679b14c Added BlendEquation and BlendFunc to RenderState, and cleaned it up A LOT 2015-12-14 20:23:29 +01:00
viktorljung d9ea0192d1 Added RenderSystem and removed RenderQueueFactory 2015-12-14 20:07:02 +01:00
viktorljung ef07a9d536 Merge remote-tracking branch 'origin/master' into Rendering
# Conflicts:
#	include/Engine/Rendering/RenderQueueFactory.h
2015-12-14 19:11:00 +01:00
viktorljung 05b78265be Fixed some transparency bugs and started on component based camera 2015-12-14 19:10:00 +01:00
Viktor Ljung 25683e8a8a Merge pull request #15 from teamfisk/Editor
Editor
2015-12-14 19:05:27 +01:00
verysecrethero 948f6d5de7 RayVsModel & RayVsAABB comparison continued 2015-12-14 17:53:11 +01:00
William Moberg ae7d4b9097 Put Collision folder in CMakeLists.txt and altered paths. 2015-12-14 17:35:39 +01:00
Tleety 7c714d1f98 Changed some error handling in the RenderState class. 2015-12-14 17:35:01 +01:00
William Moberg e6fa9df3a5 Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree 2015-12-14 17:08:51 +01:00
William Moberg 59095c2ce5 Started on CollisionSystem and TriggerSystem. Moved collision code to Collision folder. 2015-12-14 17:08:00 +01:00
stiffly 3f77da4a07 Merge remote-tracking branch 'origin/master' into Networking
# Conflicts:
#	include/Game/Game.h
#	resources/DefaultConfig.ini
#	src/Game/Game.cpp
2015-12-14 17:07:12 +01:00
verysecrethero 7f8e78c8cd RayVsModel tests in progress 2015-12-14 17:04:35 +01:00
stiffly bac0a1de26 Removed annoying cube 2015-12-14 16:55:23 +01:00
stiffly bf82bbb5d5 Merge remote-tracking branch 'origin/Networking' into Networking 2015-12-14 16:50:51 +01:00
Jocke e52052b431 IdentifyPacketLoss() crashed when multiple users connected which
also crashed the server. The function is not needed for now as the server logic is not
implemented.
2015-12-14 16:50:16 +01:00
stiffly 8d9ff2b6dc Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	src/Engine/Network/Client.cpp
2015-12-14 16:41:59 +01:00
Jocke 63db236dfa Fixed bug which made the player not able to move diagonally.
Fixed a bug were m_PlayerID was not set for the client when connecting.
2015-12-14 16:35:43 +01:00
Jace cddd9026fb Toggle editor with "ToggleEditor" command. Enable editor with "Debug.EnableEditor" config variable. 2015-12-14 16:12:52 +01:00
Jace ea239b19bd Fixed component type resolution order to prioritize custom types before native ones, since namespace information doesn't exist at that stage. 2015-12-14 16:12:20 +01:00
Jace f8d927cd91 Don't render invisible model components 2015-12-14 16:11:37 +01:00
Jace 798c73132e Fixed ScreenCoords::ToPixelData stack corruption 2015-12-14 16:11:08 +01:00
Jace fb2cd0c6ae Fixed float angle wrapping 2015-12-14 15:20:55 +01:00
Jace bc6a211276 Removed RenderState log spam 2015-12-14 14:54:19 +01:00
Jace 7719274a37 Correct asset reference for fonts 2015-12-14 14:54:03 +01:00
Jace 797036c204 Fixed picking event 2015-12-14 14:24:11 +01:00
Jace 3a9577c9fb fixup! Enabled rendering "transparency" 2015-12-14 14:08:37 +01:00
Jace 545869e342 Added scene graph UI to Editor 2015-12-14 13:58:28 +01:00
Jace 07c4744436 Added World DeleteEntity, HasComponent and GetEntityChildren 2015-12-14 13:58:27 +01:00
Jace b8620eac26 Made debug camera detect UI focus properly 2015-12-14 13:58:27 +01:00
Jace 7bc492134d Enabled rendering "transparency" 2015-12-14 13:58:24 +01:00
Jace 7c1182c28f Fixed absolute positions once and for all (maybe?) 2015-12-14 13:57:56 +01:00
Jace 2f3843e595 Editor version 1 2015-12-14 13:57:55 +01:00
Jace 5f3c234819 Added DeleteComponent function to world 2015-12-14 13:57:54 +01:00
Jace 9a119f38bb Added events processing to SystemPipeline 2015-12-14 13:57:54 +01:00
Jace 524af211e0 Made resource loading fail gracefully when a resource can't be loaded. Resources should now throw exceptions in their constuctor if the resource can't be loaded. This will result in ResourceManager::Load returning null. 2015-12-14 13:57:53 +01:00
Jace 91ace0d2a0 Fixed bug in ComponentPool::Delete. Wasn't taking EntityID into account when freeing memory. 2015-12-14 13:57:53 +01:00
Jace 2018ba27ae Added KnowsEntity function to ComponentPool to query whether an entity has a component attached 2015-12-14 13:57:52 +01:00
Jace b66cf47ff0 Revert "Clearing raw input events from event broker to encourage use of input commands instead"
This reverts commit 2e7e8d3546.
2015-12-14 13:57:52 +01:00
Jace e5084e13ec Added EditorSystem 2015-12-14 13:57:51 +01:00
Jace 8a6030bf57 Added support for "Impure" systems, which only update once per frame and contain their own logic for manipulating the world, instead of relying on a single list of components. 2015-12-14 13:57:51 +01:00
Jace 2e321e15a5 Cleaned up ImGuiRenderPass 2015-12-14 13:57:50 +01:00
Jace c81a054601 Subscribed ImGui to MouseScroll event 2015-12-14 13:57:50 +01:00
Jace af14d60493 Added MouseScroll event to input manager 2015-12-14 13:57:49 +01:00
Jace 0465fdb16d Added ImGui for compilation 2015-12-14 13:57:49 +01:00
Jace 0c6ac1e060 Added ImGui to README 2015-12-14 13:57:48 +01:00
Jace 7db1feac17 Added basic ImGui implementation 2015-12-14 13:57:45 +01:00
Jace 653b4689b5 Added KeyboardChar event for keyboard text input 2015-12-14 13:56:24 +01:00
Adam Byléhn 6723e71fee Merge pull request #14 from teamfisk/Input
Input
2015-12-14 13:55:11 +01:00
Jace d16cbe84f0 Merge remote-tracking branch 'origin/master' into Input
# Conflicts:
#	src/Engine/Rendering/Renderer.cpp
2015-12-14 13:40:22 +01:00
Jace 95ce024bb6 Merge pull request #13 from teamfisk/RendererDecoupling
Renderer decoupling
2015-12-14 13:39:20 +01:00
Jace a7ed455766 Merge branch 'master' into Input 2015-12-14 13:19:38 +01:00
Tleety d182e6c453 Merge remote-tracking branch 'origin/master' into RendererDecoupling
# Conflicts:
#	src/Game/Game.cpp
2015-12-14 13:16:56 +01:00
verysecrethero 5fce7490a9 MergeFix OctTree williambranch and andersbranch 2015-12-14 11:57:18 +01:00
Jace e76a6b74a3 Merge branch 'master' of github.com:teamfisk/TacticalZ
# Conflicts:
#	src/Game/Game.cpp
2015-12-14 11:41:59 +01:00
Jace e82911cb8b Renderer FOV setting in Config.ini 2015-12-14 11:39:13 +01:00
verysecrethero 8abef7024d Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree
# Conflicts:
#	src/Tests/OctTreeTest.cpp
2015-12-14 11:14:09 +01:00
verysecrethero bf08ffe392 Added InputManagerTest 2015-12-14 11:02:23 +01:00
verysecrethero 5f5cab1171 Added Tests for ResourceManager 2015-12-14 10:55:49 +01:00
William Moberg 8d87841691 Merge branch 'master' into OctTree 2015-12-14 10:51:23 +01:00
William Moberg 11e37ca898 Added functions to test ray vs triangle- and model-intersections. 2015-12-14 10:42:45 +01:00
Jace 30474b70df MouseInputHandler 2015-12-12 13:42:46 +01:00
Jace 03e226ffea Refactored InputProxy to gracefully handle cases where multiple origins send the same command 2015-12-12 13:42:35 +01:00
Jace 2e7e8d3546 Clearing raw input events from event broker to encourage use of input commands instead 2015-12-12 13:42:35 +01:00
Jace 013f911ae2 Added MouseInputHandler and firstPersonInputController to aid in creation of first person movement. 2015-12-12 13:42:34 +01:00
Jace 35624008e7 InputProxy with a KeyboardInputHandler to translate keyboard keys to input commands. Input origins are bound to commands through the BindOrigin event, or through loading them from a config file. 2015-12-12 13:42:34 +01:00
Jace 5d46a10a4e Added GetAll function to config file that returns a list of all top level keys in a config file 2015-12-12 13:42:33 +01:00
Jace 784a04b8ad Fixed bug in config file overriding. Previously it was silently overwriting the whole default config and relied on hardcoded values for defaults. 2015-12-12 13:42:33 +01:00
Jace bffc97f310 Groundwork for input command proxy 2015-12-12 13:42:33 +01:00
Jace 7464facab9 Next generation raptor copter 2015-12-12 03:38:17 +01:00
Tobias Dahl f14c62f3d3 Merge pull request #12 from teamfisk/PlayerSystem
Player system
2015-12-11 17:15:00 +01:00
Tleety d406059c79 Small bugfix. 2015-12-11 17:00:06 +01:00
Tleety 59b261534a Cleaned some comments and random annoyances in Renderer 2015-12-11 16:57:02 +01:00
Tleety 45b87ed6b1 ShaderProgram is now a Resource.
All shaderprograms are now pointers and loaded with Resourcemanager.
2015-12-11 16:53:46 +01:00
William Moberg 55aad493ff Fixed warnings in OctTree. Cleaned unit tests. 2015-12-11 16:45:38 +01:00
William Moberg 9a7d77f29d Removed notes in OldOctTree. 2015-12-11 16:44:49 +01:00
stiffly 36ae451ea6 Indentation 2015-12-11 16:22:14 +01:00
verysecrethero b3bb0e543f Added EventBroker Test from the other project 2015-12-11 16:17:23 +01:00
Tleety 53d5736420 Fixed a bugg with RenderState.
Renderstate now also handles the Frambuffer binding.
2015-12-11 16:07:12 +01:00
William Moberg 81034420a9 Put back old version of OctTree for testing, made unit tests.
Tests shows the old version checks for collisions etc. faster, new version adds objects into tree faster, and doesn't give duplicated results.
2015-12-11 16:04:30 +01:00
stiffly 15442c8c75 Merge branch 'PlayerSystem' into Networking
# Conflicts:
#	src/Game/Game.cpp
2015-12-11 15:45:27 +01:00
stiffly 3da69c8a1b Fixed indentation 2015-12-11 15:29:57 +01:00
stiffly 16d636a87c Removed Initialize function for systems. 2015-12-11 15:23:56 +01:00
stiffly 4da33ff4ec Fixed movement on a "player" cube. Very simple system atm 2015-12-11 15:00:57 +01:00
stiffly c2435fda2d Added Component to Components.xsd and Entity.xsd 2015-12-11 14:27:54 +01:00
Tleety 433331e752 DrawPass now moved to it's own class to make renderer cleaner. 2015-12-11 14:22:54 +01:00
stiffly 094c7fbb44 Added system to CMakeLists.txt. 2015-12-11 14:20:36 +01:00
stiffly 0b60979c7b Added a Initialize function for systems. 2015-12-11 14:03:00 +01:00
Tleety 2366cd3520 Merge remote-tracking branch 'origin/master' into RendererDecoupling 2015-12-11 13:52:41 +01:00
Tleety 725a8896ce PickingPass now publishes an event that others can listen to to get pickingdata. 2015-12-11 13:51:08 +01:00
verysecrethero 350038057d Misc OctTreeTest changes 2015-12-11 13:51:07 +01:00
stiffly 80f028edf2 Added a very basic PlayerSystem, and a PlayerComponent. 2015-12-11 13:45:19 +01:00
Jocke 23c3f0709b Merge branch 'Networking' of github.com:teamfisk/TacticalZ into Networking 2015-12-11 11:59:22 +01:00
Jocke 01d7388f91 Reactored the package loss logic.
Server cannot handle multiple clients yet.
Fixed WorldTest code by adding astrix.
2015-12-11 11:55:23 +01:00
Tleety 8c563a2d76 Merge remote-tracking branch 'origin/Picking' into RendererDecoupling
# Conflicts:
#	include/Engine/Rendering/Renderer.h
#	src/Engine/Rendering/Renderer.cpp
2015-12-11 11:21:58 +01:00
Tleety 91edab34bc PickingPass now sets state and clear it when done.
PickingState now it's own class so renderer is a bit cleaner.
2015-12-11 11:18:30 +01:00
verysecrethero 1ceea91f4a Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree
# Conflicts:
#	include/Engine/Core/OctTree.h
#	src/Engine/Core/OctTree.cpp
2015-12-10 18:02:03 +01:00
William Moberg 4195baa5dc ContainedObject in OctTree made private. 2015-12-10 17:57:09 +01:00
William Moberg 37f9ab2322 Quick fix for unit test compilation. 2015-12-10 17:53:33 +01:00
verysecrethero d8b1f4e514 ConfigFileTest attempt to explore the memleaks further 2015-12-10 17:46:17 +01:00
stiffly 6a3335315a Merge branch 'master' into Networking 2015-12-10 17:26:01 +01:00
verysecrethero c651face4c ConfigFile now has tests covering the whole class 2015-12-10 17:20:47 +01:00
stiffly 641a43b2ec Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	src/Engine/Network/Client.cpp
2015-12-10 17:16:22 +01:00
stiffly 58952725e9 Added class Package to help refactor the code. The code got easier to read. 2015-12-10 17:07:18 +01:00
verysecrethero de044dabd3 Added ConfigFileTests! 2015-12-10 16:55:28 +01:00
William Moberg ce7b26ccac Merge branch 'master' into OctTree
# Conflicts:
#	include/Game/Game.h
#	include/Game/HardcodedTestWorld.h
#	src/Game/Game.cpp
2015-12-10 16:37:55 +01:00
Tleety cefc4e5257 PickingPassState done. 2015-12-10 16:06:25 +01:00
William Moberg 0d8f7acb7e OctTree doesn't check the same object multiple times if it exists in multiple places in the tree. 2015-12-10 16:04:55 +01:00
Tleety 37cf42527b RenderState class structure made. 2015-12-10 16:03:48 +01:00
Jocke 99543a300d Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	include/Engine/Network/NetworkDefinitions.h
#	include/Game/Game.h
#	src/Engine/Network/Client.cpp
#	src/Game/Game.cpp
2015-12-10 14:40:06 +01:00
Jocke f377d9ba70 Fixed client movement. 2015-12-10 14:14:36 +01:00
stiffly d22e59f28f Merge remote-tracking branch 'origin/master' into Networking
NOTE (in config file):
[Debug]
LoadMap=Schema/Entities/Test.xml

# Conflicts:
#	include/Game/Game.h
#	src/Game/Game.cpp
2015-12-10 13:53:18 +01:00
verysecrethero 7804d42fea OctTree debug temporarily disabled because of the new master layout 2015-12-10 13:42:39 +01:00
stiffly 9a8f5293af Can now Identify Packet Loss. Enumerated messages that loops around 0-1000. 2015-12-10 12:55:28 +01:00
verysecrethero e535f629bc Merge branch 'master' into PlayerTakeCapturePoint
# Conflicts:
#	include/Game/Game.h
#	include/Game/HardcodedTestWorld.h
#	src/Game/Game.cpp
2015-12-10 11:50:29 +01:00
verysecrethero c60e968836 Removed a boxclear in the end of the test2 method 2015-12-10 11:03:40 +01:00
Tleety 9d3313e3ed Calculate frustrum removed from code untill Nvidia isn't shit. 2015-12-10 10:46:27 +01:00
verysecrethero bc8a922b77 Merging octTreeTests a bit 2015-12-09 17:57:32 +01:00
Jocke 663aca2641 Moved client and server from header.
Fixed so user are able to start a server and client on the same computer.
Starting 2 servers on the same computer will probably still crash the newest server (Don't do it).
2015-12-09 17:50:30 +01:00
stiffly 4de613814b WIP Packet loss identification. Put packetID in message 2015-12-09 17:43:36 +01:00
Tleety de6e74c0b1 Forward+ Debugging commit, dont try it. 2015-12-09 17:36:03 +01:00
William Moberg e580540143 Made some optimizations in OctTree and added a unit test for BoxesInSameRegion. 2015-12-09 17:16:11 +01:00
Tleety 393a774140 Framework for Forward+ renderer, Buggy. 2015-12-09 14:50:39 +01:00
Jocke 0807a7d0ae Fixed the bug where starting a server made the program crash on closing.
Fixed some memory leaks in Client.cpp.
2015-12-09 14:43:43 +01:00
Jocke ba150a264c Fixed bug that cause the program to crash when closing if a server had been started.
Removed memory leaks in Client.cpp.
2015-12-09 14:41:26 +01:00
verysecrethero b650eb95df Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree 2015-12-09 13:57:22 +01:00
verysecrethero 8949db5456 Little more work with OctTreeTest 2015-12-09 13:56:59 +01:00
William Moberg 14bcb7ea0d Added Update call in Game to test OctTree by using collision. 2015-12-09 13:52:17 +01:00
verysecrethero 519178dfba Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree
# Conflicts:
#	src/Engine/Core/OctTree.cpp
2015-12-09 13:37:27 +01:00
Jocke 0e6353dd79 Fixed bug where closing glwindow as client crashed.
Server bug is still present.
2015-12-09 13:37:02 +01:00
verysecrethero ed5cd392ab Further work in testing OctTree 2015-12-09 13:29:15 +01:00
William Moberg bad42fae1c OctTree differentiates between static/dynamic objects now. Added a general BoxesInSameRegion method. 2015-12-09 13:27:00 +01:00
stiffly 247ff09743 Smoother movement over network. Some refactoring on client side. Now uses EKeyUp to determine if a key is pressed. 2015-12-09 13:02:39 +01:00
stiffly 2a35c3055e Renamed NetworkDefines.h --> NetworkDefinitions.h 2015-12-09 11:08:57 +01:00
stiffly ce41421dbb Added a "StartNetwork" bool to DefaultConfig. 2015-12-09 10:37:40 +01:00
verysecrethero 1d0810db10 OctTree is now drawn perfectly 2015-12-09 10:24:06 +01:00
verysecrethero c85bb2eef7 Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree 2015-12-09 10:08:26 +01:00
verysecrethero 75402b0f93 Working on OctTree tests 2015-12-09 10:08:08 +01:00
stiffly f83e217638 Bugfix. if-statement was incorrect 2015-12-08 18:35:30 +01:00
stiffly 58db7b755a Random bugfixes and cleanup. 2015-12-08 18:24:08 +01:00
stiffly a8c0a1f294 Merge branch 'Networking' of github.com:teamfisk/TacticalZ into Networking
# Conflicts:
#	include/Engine/Network/Client.h
#	src/Engine/Network/Client.cpp
2015-12-08 18:07:18 +01:00
stiffly 9f54a08536 Implemented new version of snapshot for 3D world. Also some cleanup. 2015-12-08 17:57:01 +01:00
Jocke 24dada149f Cleaned up code in Client.h and Client.cpp.
Moved ping code into Ping() function.
2015-12-08 17:18:03 +01:00
William Moberg a7fb77d998 OctTree can check if a box collides with a box in the OctTree. 2015-12-08 17:12:58 +01:00
William Moberg 32d2aa6a93 AABB can also be created with center position and its size. 2015-12-08 17:01:50 +01:00
Jocke d1880754f5 Merge branch 'Networking' of github.com:teamfisk/TacticalZ into Networking 2015-12-08 16:42:32 +01:00
stiffly 27b44d2511 Input events for Client done. Instead of windows getAsyncKeyState(); 2015-12-08 16:41:48 +01:00
Jocke 94adaf8ae3 Added support for multiplayer.
Reactored code, clumped together variables in PlayerDefinition.h.
Integrated server with entity system.
2015-12-08 16:41:22 +01:00
stiffly 6dc5112c26 Merge branch 'Networking' of github.com:teamfisk/TacticalZ into Networking
# Conflicts:
#	include/Engine/Network/Client.h
#	src/Game/Game.cpp
2015-12-08 16:15:50 +01:00
stiffly e92119c99e WIP trying to get Eventsystem to work in client. 2015-12-08 16:13:53 +01:00
Jocke c48c9e1f86 Added leak check when using windows (WinLeakCheck.h).
Added server to project.
A server can now be started in the project.
2015-12-08 13:54:18 +01:00
verysecrethero 7ac2aaef15 Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree
# Conflicts:
#	src/Engine/Core/OctTree.cpp
2015-12-08 11:16:34 +01:00
verysecrethero 06f56d13d1 added some octTreeTest tests and a few comments in OctTree 2015-12-08 11:14:01 +01:00
Jocke 8f55e90d2d Merge branch 'Networking' of github.com:teamfisk/TacticalZ into Networking
# Conflicts:
#	include/Game/Game.h
2015-12-08 11:11:12 +01:00
Jocke b5a010a517 Network now runs on it's own thread.
Network now sends Disconnect message when game is terminated.
2015-12-08 11:02:40 +01:00
William Moberg b87e543420 Merge branch 'master' into OctTree 2015-12-08 10:47:27 +01:00
William Moberg fa3816e55d Fixed flawed unit test. 2015-12-08 10:44:12 +01:00
stiffly ee41721a75 Merge remote-tracking branch 'origin/master' into Networking 2015-12-08 10:41:04 +01:00
William Moberg 648ba502bb Added small test for OctTree. 2015-12-07 17:27:57 +01:00
stiffly 2c993e82d6 Added the old prototype logic to Client.h. Can now communicate with a external server(on prototype). 2015-12-07 16:55:12 +01:00
stiffly cbbb7deaea Copy pasta error. Corrected #ifndef 2015-12-07 16:53:33 +01:00
stiffly de5bdef58c Rectangle definition conflicted with a definition included by <boost/asio.hpp>. 2015-12-07 16:52:42 +01:00
William Moberg 000ad6358f Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree 2015-12-07 16:26:49 +01:00
William Moberg 04a8eeebe8 Added test get methods and some comments. 2015-12-07 16:25:01 +01:00
stiffly d8d63f804a Added utility headers for network interface. 2015-12-07 16:11:27 +01:00
William Moberg 955c9ce534 Removed superfluous function declaration. 2015-12-07 16:00:34 +01:00
William Moberg e8d23f3b3f Added AABBVsAABB function. 2015-12-07 15:59:41 +01:00
verysecrethero 89aa8c44b0 Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree 2015-12-07 10:03:55 +01:00
verysecrethero f0e407bec2 Started on OctTreeTest (Merging with OctTree) 2015-12-07 10:03:36 +01:00
William Moberg 8e21b1fe35 Added ray collision detection in leaf nodes. Fixed possible bug in OctTree::AddBox 2015-12-03 19:25:40 +01:00
verysecrethero 17133b316a Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree 2015-12-03 17:31:07 +01:00
verysecrethero 28a290600b BOOST MEM LEAK VS VISUAL STUDIO MEM LEAKS COMMENTED TESTS 2015-12-03 17:30:12 +01:00
William Moberg af5b3a9302 Fixed wrong paths and added an outDistance to RayVsAABB. 2015-12-03 17:24:53 +01:00
William Moberg abb61d2cd6 Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree
# Conflicts:
#	include/Engine/Core/Collision.h
#	src/Engine/Core/Collision.cpp
2015-12-03 17:11:35 +01:00
William Moberg 2f13f5da7a Relocated AABB and Ray in Collision.h to their own files. Started implementation on OctTree. 2015-12-03 17:03:27 +01:00
verysecrethero 464650c370 more tests added 2015-12-02 16:31:39 +01:00
verysecrethero af294f78b7 czdxvxdfvxvxvc 2015-12-02 16:26:30 +01:00
verysecrethero c840183467 Merge remote-tracking branch 'origin/master' into OctTree 2015-12-02 15:43:51 +01:00
verysecrethero 1f99d46a8d Merge branch 'master' into OctTree 2015-12-02 15:15:05 +01:00
verysecrethero fd99562c7a yrryr567yry567 2015-12-02 15:03:55 +01:00
William Moberg c698149bdd Added Ray, AABB structs, and basic rayVsAABB test function. 2015-12-02 14:24:21 +01:00
William Moberg fa0ace8c68 Added empty OctTree files. 2015-12-02 11:32:56 +01:00
William Moberg 1d19c6901e Added collision files. 2015-12-02 11:18:52 +01:00
250 changed files with 13225 additions and 2495 deletions
+13 -10
View File
@@ -1,19 +1,22 @@
#### Bundled libraries
Libraries bundled along with binaries for Windows (MSVC14), available as a submodule in the *deps* directory of the source tree.
| Project | Version | License |
| ------------------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **[GLFW](http://www.glfw.org)** | 3.1.2 | [zlib/libpng License](http://www.glfw.org/license.html) |
| **[GLM](http://glm.g-truc.net/0.9.5/index.html)** | 0.9.7.1 | [MIT License](http://glm.g-truc.net/copying.txt) |
| **[GLEW](http://glew.sourceforge.net)** | 1.13.0 | [Modified BSD License](http://glew.sourceforge.net/glew.txt), [Mesa 3-D License](http://glew.sourceforge.net/mesa.txt), [Khronos License](http://glew.sourceforge.net/khronos.txt) |
| **[Assimp](http://assimp.sourceforge.net)** | 3.1.1 | [BSD 3-Clause License](http://assimp.sourceforge.net/main_license.html) |
| **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) |
| **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) |
| **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| Project | Version | License |
| ---------------------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **[GLFW](http://www.glfw.org)** | 3.1.2 | [zlib/libpng License](http://www.glfw.org/license.html) |
| **[GLM](http://glm.g-truc.net/0.9.5/index.html)** | 0.9.7.1 | [MIT License](http://glm.g-truc.net/copying.txt) |
| **[GLEW](http://glew.sourceforge.net)** | 1.13.0 | [Modified BSD License](http://glew.sourceforge.net/glew.txt), [Mesa 3-D License](http://glew.sourceforge.net/mesa.txt), [Khronos License](http://glew.sourceforge.net/khronos.txt) |
| **[Assimp](http://assimp.sourceforge.net)** | 3.1.1 | [BSD 3-Clause License](http://assimp.sourceforge.net/main_license.html) |
| **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) |
| **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) |
| **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| **[ImGui](https://github.com/ocornut/imgui)** | 2015-12-12 | [MIT License](https://github.com/ocornut/imgui/blob/de3a154f3801de22c8e0bd2aeabf663a70c05972/LICENSE) |
| **[nativefiledialog](https://github.com/mlabbe/nativefiledialog)** | 2016-01-08 | [nativefiledialog Licence](https://github.com/mlabbe/nativefiledialog/blob/master/LICENSE) |
| **[OpenAL](https://www.openal.org/)** | 1.1 | [OpenAL License](resources/Licenses/OpenAL.txt)
#### External libraries
Libraries that are too big to be bundled with the project.
| Project | Version | License | Root folder environment variable (Windows) |
| ---------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | ------------------------------------------ |
| **[Boost](http://www.boost.org)** | 1.59.0+ | [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt) | BOOST_ROOT |
| **[Boost](http://www.boost.org)** | 1.60.0+ | [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt) | BOOST_ROOT |
+1 -1
Submodule assets updated: b37468222e...a3c92ac876
+1 -1
Submodule deps updated: 9861acd762...bf83f099ba
@@ -0,0 +1,24 @@
#ifndef CollidableOctreeSystem_h__
#define CollidableOctreeSystem_h__
#include "../Core/System.h"
#include "../Core/Octree.h"
#include "Collision.h"
class CollidableOctreeSystem : public ImpureSystem, public PureSystem
{
public:
CollidableOctreeSystem(EventBroker* eventBroker, Octree<AABB>* octree)
: System(eventBroker)
, PureSystem("Collidable")
, m_Octree(octree)
{ }
virtual void Update(World* world, double dt) override;
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) override;
private:
Octree<AABB>* m_Octree;
};
#endif
+67
View File
@@ -0,0 +1,67 @@
#ifndef Collision_h__
#define Collision_h__
//NOTE: Collision.h needs to be #included before <GLFW/glfw3.h>,
//because Collision #includes "RawModel.h", which has "Texture.h", which has "OpenGL.h" which must be #included first
//or you will get "fatal error C1189: #error: gl.h included before glew.h"
#include <vector>
#include <boost/optional.hpp>
#include "../Core/Ray.h"
#include "../Core/AABB.h"
#include "../Rendering/RawModel.h"
#include "../Core/Transform.h"
#include "../Core/Entity.h"
#include "../Core/EntityWrapper.h"
class World;
struct ComponentWrapper;
namespace Collision
{
//Return true if the ray hits the box.
bool RayAABBIntr(const Ray& ray, const AABB& box);
bool RayVsAABB(const Ray& ray, const AABB& box);
//Return true if the ray hits the box, also outputs distance from ray origin to intersection point in [outDistance].
bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance);
//Return true if the ray hits any of the triangles in the model. Stops checking when a hit is detected.
bool RayVsModel(const Ray& ray,
const std::vector<RawModel::Vertex>& modelVertices,
const std::vector<unsigned int>& modelIndices);
//Return true if the ray hits any of the triangles in the model.
//Also returns the position of the intersection point. Will loop through all the whole model indices.
bool RayVsModel(const Ray& ray,
const std::vector<RawModel::Vertex>& modelVertices,
const std::vector<unsigned int>& modelIndices,
glm::vec3& outHitPosition);
//Return true if the ray hits any of the triangles in the model.
//Also returns the distance from the ray origin to the closest
//intersection point, and the barycentric u,v-coordinates. Will loop through all the whole model indices.
bool RayVsModel(const Ray& ray,
const std::vector<RawModel::Vertex>& modelVertices,
const std::vector<unsigned int>& modelIndices,
float& outDistance,
float& outUCoord,
float& outVCoord);
bool AABBvsTriangles(const AABB& box,
const std::vector<RawModel::Vertex>& modelVertices,
const std::vector<unsigned int>& modelIndices,
const glm::mat4& modelMatrix,
glm::vec3& outResolutionVector);
//Return true if the boxes are intersecting.
bool AABBVsAABB(const AABB& a, const AABB& b);
//Return true if the boxes are intersecting.
//Also outputs the minimum translation that box [a] would need in order to resolve collision.
bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation);
bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon = 0.0001f);
// Calculates an absolute AABB from an entity AABB component
boost::optional<AABB> EntityAbsoluteAABB(EntityWrapper& entity);
}
#endif
@@ -0,0 +1,36 @@
#ifndef CollisionSystem_h__
#define CollisionSystem_h__
#include <GLFW/glfw3.h>
#include <glm/common.hpp>
#include "../Common.h"
#include "../Core/System.h"
#include "../Core/EventBroker.h"
#include "../Core/EKeyUp.h"
#include "../Core/Octree.h"
class CollisionSystem : public PureSystem
{
public:
CollisionSystem(EventBroker* eventBroker, Octree<AABB>* octree)
: System(eventBroker)
, PureSystem("Collidable")
, m_Octree(octree)
, zPress(false)
{
//TODO: Debug stuff, remove later.
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &CollisionSystem::OnKeyUp);
}
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) override;
private:
Octree<AABB>* m_Octree;
bool zPress;
EventRelay<CollisionSystem, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp &event);
};
#endif
+39
View File
@@ -0,0 +1,39 @@
#ifndef Events_TriggerEnter_h__
#define Events_TriggerEnter_h__
#include "../Core/EventBroker.h"
#include "../Core/Entity.h"
namespace Events
{
/** Thrown once, when an entity is only touching a trigger. */
struct TriggerTouch : Event
{
/** The id of the entity that touches the trigger. */
EntityID Entity;
/** The id of the trigger entity. */
EntityID Trigger;
};
/** Thrown once, when an entity has completely left a trigger. */
struct TriggerLeave : Event
{
/** The id of the entity that left the trigger. */
EntityID Entity;
/** The id of the trigger entity. */
EntityID Trigger;
};
/** Thrown once, when an entity is completely contained inside a trigger. */
struct TriggerEnter : Event
{
/** The id of the entity that entered the trigger. */
EntityID Entity;
/** The id of the trigger entity. */
EntityID Trigger;
};
}
#endif
+54
View File
@@ -0,0 +1,54 @@
#ifndef TriggerSystem_h__
#define TriggerSystem_h__
#include <glm/common.hpp>
#include <unordered_set>
#include "../Core/System.h"
#include "../Core/EventBroker.h"
#include "../Core/Octree.h"
#include "ETrigger.h"
class AABB;
class TriggerSystem : public PureSystem
{
public:
TriggerSystem(EventBroker* eventBroker, Octree<AABB>* octree)
: System(eventBroker)
, PureSystem("Trigger")
, m_Octree(octree)
{
EVENT_SUBSCRIBE_MEMBER(m_ETouch, &TriggerSystem::OnTouch);
EVENT_SUBSCRIBE_MEMBER(m_EEnter, &TriggerSystem::OnEnter);
EVENT_SUBSCRIBE_MEMBER(m_ELeave, &TriggerSystem::OnLeave);
}
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) override;
private:
Octree<AABB>* m_Octree;
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesTouchingTrigger;
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesCompletelyInTrigger;
//TODO: Only exists for debug purposes, remove later.
EventRelay<TriggerSystem, Events::TriggerEnter> m_EEnter;
bool OnEnter(const Events::TriggerEnter &event);
EventRelay<TriggerSystem, Events::TriggerTouch> m_ETouch;
bool OnTouch(const Events::TriggerTouch &event);
EventRelay<TriggerSystem, Events::TriggerLeave> m_ELeave;
bool OnLeave(const Events::TriggerLeave &event);
//True if leave event was thrown.
bool throwLeaveIfWasInTrigger(std::unordered_set<EntityID>& triggerSet, EntityID pId, EntityID tId);
template<typename Event>
void publish(EntityID pId, EntityID tId)
{
Event e;
e.Trigger = tId;
e.Entity = pId;
m_EventBroker->Publish(e);
}
};
#endif
+3 -1
View File
@@ -1,7 +1,9 @@
#include <memory>
#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <unordered_map>
#include "Core/Util/Logging.h"
#include "Core/Util/Logging.h"
#include "Core/Util/IfDebug.h"
+29
View File
@@ -0,0 +1,29 @@
#ifndef AABB_h__
#define AABB_h__
#include "../GLM.h"
class AABB
{
public:
AABB() = default;
//No checks are made. Values in minPos must be less than values in maxPos, i.e. min.x < max.x, etc.
AABB(const glm::vec3& minPos, const glm::vec3& maxPos);
AABB(const glm::vec4& minPos, const glm::vec4& maxPos);
//No checks are made. Size must consist of non-negative numbers.
static AABB FromOriginSize(const glm::vec3& origin, const glm::vec3& size);
virtual ~AABB();
const glm::vec3& MinCorner() const { return m_MinCorner; }
const glm::vec3& MaxCorner() const { return m_MaxCorner; }
const glm::vec3& Origin() const { return m_Origin; }
const glm::vec3 Size() const { return 2.0f * m_HalfSize; }
const glm::vec3& HalfSize() const { return m_HalfSize; }
private:
glm::vec3 m_MinCorner;
glm::vec3 m_MaxCorner;
glm::vec3 m_Origin;
glm::vec3 m_HalfSize;
};
#endif
+14 -4
View File
@@ -9,14 +9,24 @@ struct ComponentInfo
{
std::string Annotation;
unsigned int Allocation = 0;
unsigned int Stride = 0;
std::map<std::string, std::string> FieldAnnotations;
std::map<std::string, std::map<std::string, int>> FieldEnumDefinitions;
};
struct Field_t
{
std::string Name;
std::string Type;
unsigned int Offset;
unsigned int Stride;
};
std::string Name;
std::unordered_map<std::string, std::string> FieldTypes;
std::unordered_map<std::string, unsigned int> FieldOffsets;
Meta_t Meta;
std::unordered_map<std::string, Field_t> Fields;
std::vector<std::string> FieldsInOrder;
unsigned int Stride = 0;
std::shared_ptr<char> Defaults = nullptr;
std::shared_ptr<Meta_t> Meta = nullptr;
};
template<>
+4 -2
View File
@@ -20,7 +20,7 @@ public:
~ComponentPoolForwardIterator() = default;
ComponentPoolForwardIterator& operator=(const ComponentPoolForwardIterator& other) = default;
ComponentPoolForwardIterator& operator++();
ComponentPoolForwardIterator& operator++(int);
ComponentPoolForwardIterator operator++(int);
bool operator!=(const ComponentPoolForwardIterator& other) const;
bool operator==(const ComponentPoolForwardIterator& other) const;
ComponentWrapper operator*() const;
@@ -43,7 +43,7 @@ public:
ComponentPool(const ::ComponentInfo& ci)
: m_ComponentInfo(ci)
, m_Pool(ci.Meta.Allocation, sizeof(EntityID) + ci.Meta.Stride)
, m_Pool(ci.Meta->Allocation, sizeof(EntityID) + ci.Stride)
{ }
ComponentPool(const ComponentPool& other) = delete;
ComponentPool(const ComponentPool&& other) = delete;
@@ -54,6 +54,8 @@ public:
ComponentWrapper Allocate(EntityID entity);
// Get the component belonging to a specific entity
ComponentWrapper GetByEntity(EntityID ent);
// Returns true if the pool contains a component for the specified entity
bool KnowsEntity(EntityID ent);
// Delete a component and free its memory
void Delete(ComponentWrapper& wrapper);
+33 -19
View File
@@ -18,22 +18,32 @@ struct ComponentWrapper
const ::EntityID EntityID;
char* Data;
template <typename T>
T& Property(std::string name)
int Enum(const char* fieldName, const char* enumKey)
{
unsigned int offset = Info.FieldOffsets.at(name);
return *reinterpret_cast<T*>(&Data[offset]);
return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey);
}
template <typename T>
void SetProperty(std::string name, const T value) { Property<T>(name) = value; }
T& Field(std::string name)
{
const ComponentInfo::Field_t& field = Info.Fields.at(name);
if (sizeof(T) > field.Stride) {
std::stringstream message;
message << "Type size of \"" << typeid(T).name() << "\" doesn't match size of component field \"" << Info.Name << "." << name << "\"!";
throw new std::runtime_error(message.str().c_str());
}
return *reinterpret_cast<T*>(&Data[field.Offset]);
}
template <typename T>
void SetField(std::string name, const T value) { Field<T>(name) = value; }
//template <typename T>
//void SetProperty(std::string name, T& value) { Property<T>(name) = value; }
//void SetField(std::string name, T& value) { Field<T>(name) = value; }
// Specialization for string literals
template <std::size_t N>
void SetProperty(std::string name, const char(&value)[N]) { Property<std::string>(name) = std::string(value); }
void SetField(std::string name, const char(&value)[N]) { Field<std::string>(name) = std::string(value); }
struct SubscriptProxy
{
friend struct ComponentWrapper;
@@ -47,18 +57,21 @@ struct ComponentWrapper
std::string m_PropertyName;
public:
template <typename T>
operator T&() { return m_Component->Property<T>(m_PropertyName); }
// Return the integer value of an enum type key for this field
int Enum(const char* enumKey) { return m_Component->Enum(m_PropertyName.c_str(), enumKey); }
template <typename T>
void operator=(const T val) { m_Component->SetProperty<T>(m_PropertyName, val); }
operator T&() { return m_Component->Field<T>(m_PropertyName); }
template <typename T>
void operator=(const T val) { m_Component->SetField<T>(m_PropertyName, val); }
// TODO: Pass by reference and rvalue (universal reference?)
//template <typename T>
//void operator=(T& val) { m_Component->SetProperty<T>(m_PropertyName, val); }
//void operator=(T& val) { m_Component->SetField<T>(m_PropertyName, val); }
// Specialization for string literals
template<std::size_t N>
void operator=(const char(&val)[N]) { m_Component->SetProperty<N>(m_PropertyName, val); }
template <std::size_t N>
void operator=(const char(&val)[N]) { m_Component->SetField<N>(m_PropertyName, val); }
};
SubscriptProxy operator[](std::string propertyName) { return SubscriptProxy(this, propertyName); }
};
@@ -71,21 +84,22 @@ public:
ComponentWrapperFactory(std::string componentTypeName, std::size_t allocation = 0)
{
m_ComponentInfo.Name = componentTypeName;
m_ComponentInfo.Meta.Allocation = allocation;
m_ComponentInfo.Meta->Allocation = allocation;
}
template <typename T>
void AddProperty(std::string fieldName, T defaultValue)
{
m_DefaultValues.push_back(defaultValue);
m_ComponentInfo.FieldTypes[fieldName] = typeid(T).name();
m_ComponentInfo.FieldOffsets[fieldName] = m_ComponentInfo.Meta.Stride;
m_ComponentInfo.Meta.Stride += sizeof(T);
m_ComponentInfo.Fields[fieldName].Name = typeid(T).name();
m_ComponentInfo.Fields[fieldName].Offset = m_ComponentInfo.Stride;
m_ComponentInfo.Fields[fieldName].Stride = sizeof(T);
m_ComponentInfo.Stride += sizeof(T);
}
ComponentInfo& Finalize()
{
m_ComponentInfo.Defaults = std::shared_ptr<char>(new char[m_ComponentInfo.Meta.Stride]);
m_ComponentInfo.Defaults = std::shared_ptr<char>(new char[m_ComponentInfo.Stride]);
std::size_t offset = 0;
for (auto& val : m_DefaultValues) {
memcpy(m_ComponentInfo.Defaults.get() + offset, val.Data.get(), val.Size);
+19 -1
View File
@@ -5,6 +5,7 @@
#include <boost/filesystem.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/lexical_cast.hpp>
#include "../Common.h"
#include "ResourceManager.h"
@@ -19,12 +20,14 @@ private:
public:
template <typename T>
T Get(std::string key, T defaultValue);
template <typename T>
std::vector<std::pair<std::string, T>> GetAll(std::string key);
template <typename T>
void Set(std::string key, T value);
void SaveToDisk();
private:
private:
boost::filesystem::path m_Path;
boost::property_tree::ptree m_PTreeDefaults;
boost::property_tree::ptree m_PTreeOverrides;
@@ -37,6 +40,21 @@ T ConfigFile::Get(std::string key, T defaultValue)
return m_PTreeMerged.get<T>(key, defaultValue);
}
template <typename T>
std::vector<std::pair<std::string, T>> ConfigFile::GetAll(std::string key)
{
std::vector<std::pair<std::string, T>> out;
auto parent = m_PTreeMerged.find(key);
if (parent == m_PTreeMerged.not_found()) {
return out;
}
for (auto& child : parent->second) {
T value = boost::lexical_cast<T>(child.second.data());
out.push_back(std::make_pair(child.first, value));
}
return out;
}
template <typename T>
void ConfigFile::Set(std::string key, T value)
{
+20
View File
@@ -0,0 +1,20 @@
#ifndef EComponentAttached_h__
#define EComponentAttached_h__
#include "EventBroker.h"
#include "World.h"
#include "Entity.h"
#include "ComponentWrapper.h"
namespace Events
{
struct ComponentAttached : Event
{
EntityWrapper Entity;
ComponentWrapper Component;
};
}
#endif
+16
View File
@@ -0,0 +1,16 @@
#ifndef EFileDropped_h__
#define EFileDropped_h__
#include "EventBroker.h"
namespace Events
{
struct FileDropped : Event
{
std::string Path;
};
}
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef Events_KeyboardChar_h__
#define Events_KeyboardChar_h__
#include "EventBroker.h"
namespace Events
{
struct KeyboardChar : Event
{
double Timestamp = 0.f;
unsigned int Char = 0;
};
}
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef Events_MouseScroll_h__
#define Events_MouseScroll_h__
#include "EventBroker.h"
namespace Events
{
struct MouseScroll : Event
{
double DeltaX;
double DeltaY;
};
}
#endif
+20
View File
@@ -0,0 +1,20 @@
#ifndef EPlayerDamage_h__
#define EPlayerDamage_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
namespace Events
{
struct PlayerDamage : Event
{
double DamageAmount;
EntityID PlayerDamagedID;
//optional TypeOfDamage
std::string TypeOfDamage;
};
}
#endif
+20
View File
@@ -0,0 +1,20 @@
#ifndef EPlayerDeath_h__
#define EPlayerDeath_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
namespace Events
{
struct PlayerDeath : Event
{
//KilledBy,KilledByWhat is optional for now. It might be used later in the playerlog-system
EntityID KilledBy;
EntityID PlayerID;
std::string KilledByWhat;
};
}
#endif
+18
View File
@@ -0,0 +1,18 @@
#ifndef EPlayerHealthPickup_h__
#define EPlayerHealthPickup_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
namespace Events
{
struct PlayerHealthPickup : Event
{
double HealthAmount;
EntityID PlayerHealedID;
};
}
#endif
+2
View File
@@ -2,5 +2,7 @@
#define Entity_h__
typedef unsigned int EntityID;
const static unsigned int EntityID_Invalid = -1;
#endif
+8 -8
View File
@@ -285,7 +285,7 @@ private:
XSValue::Status status;
XSValue* val = XSValue::getActualValue(child->getNodeValue(), XSValue::dt_integer, status);
compInfo.Meta.Allocation += val->fData.fValue.f_int;
compInfo.Meta->Allocation += val->fData.fValue.f_int;
}
// Save documentation string
@@ -293,11 +293,11 @@ private:
if (documentationTags->getLength() != 0) {
auto child = documentationTags->item(0)->getFirstChild();
if (child != nullptr) {
compInfo.Meta.Annotation = XSTR(child->getNodeValue());
compInfo.Meta->Annotation = XSTR(child->getNodeValue());
}
}
// TODO: Parse annotation string XML
// compInfo.Meta.Allocation = ...
// compInfo.Meta->Allocation = ...
} else {
std::cout << "Warning: Component is missing an annotation!" << std::endl;
}
@@ -344,7 +344,7 @@ private:
fieldOffset += getTypeStride(type);
}
compInfo.Meta.Stride = fieldOffset;
compInfo.Stride = fieldOffset;
m_ComponentInfo[compInfo.Name] = compInfo;
}
}
@@ -367,14 +367,14 @@ private:
std::string componentName = XSTR(component->getLocalName());
auto& compInfo = m_ComponentInfo.at(componentName);
compInfo.Meta.Allocation += 1;
compInfo.Meta->Allocation += 1;
}
std::cout << "COMPONENT INFO" << std::endl;
for (auto& pair : m_ComponentInfo) {
ComponentInfo& ci = pair.second;
std::cout << "Component: " << ci.Name << " (" << ci.Meta.Annotation << ")" << std::endl;
std::cout << " Allocation: " << ci.Meta.Allocation << std::endl;
std::cout << "Component: " << ci.Name << " (" << ci.Meta->Annotation << ")" << std::endl;
std::cout << " Allocation: " << ci.Meta->Allocation << std::endl;
std::cout << " Fields:" << std::endl;
// Calculate component size
@@ -393,7 +393,7 @@ private:
cs.ComponentName = ci.Name;
cs.Stride = stride;
cs.Info = ci;
cs.Data = new char[stride*ci.Meta.Allocation];
cs.Data = new char[stride*ci.Meta->Allocation];
m_ComponentStore[cs.ComponentName] = cs;
}
}
+164
View File
@@ -0,0 +1,164 @@
#ifndef EntityFile_h__
#define EntityFile_h__
#include <stack>
#include <boost/lexical_cast.hpp>
#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLChar.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/framework/XMLDocumentHandler.hpp>
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/framework/psvi/XSModelGroup.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSValue.hpp>
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMLSInput.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include "../GLM.h"
#include "Util/XercesString.h"
#include "ResourceManager.h"
#include "Entity.h"
#include "ComponentInfo.h"
class EntityFileHandler
{
friend class EntityFileSAXHandler;
public:
// @param EntityID The entity found
// @param EntityID The parent of the entity
typedef std::function<void(EntityID, EntityID, const std::string&)> OnStartEntityCallback;
void SetStartEntityCallback(OnStartEntityCallback c) { m_OnStartEntityCallback = c; }
// @param EntityID The entity the component corresponds to
// @param std::string Type name of the component
typedef std::function<void(EntityID, const std::string&)> OnStartComponentCallback;
void SetStartComponentCallback(OnStartComponentCallback c) { m_OnStartComponentCallback = c; }
// @param EntityID Entity
// @param std::string Component name
// @param std::string Field name
// @param std::map<std::string, std::string> Field attribute names and values
typedef std::function<void(EntityID, const std::string&, const std::string&, const std::map<std::string, std::string>&)> OnStartFieldCallback;
void SetStartFieldCallback(OnStartFieldCallback c) { m_OnStartFieldCallback = c; }
// @param EntityID Entity
// @param std::string Component name
// @param std::string Field name
// @param char* Field data
typedef std::function<void(EntityID, const std::string&, const std::string&, const char*)> OnStartFieldDataCallback;
void SetStartFieldDataCallback(OnStartFieldDataCallback c) { m_OnStartFieldDataCallback = c; }
private:
OnStartEntityCallback m_OnStartEntityCallback = nullptr;
OnStartComponentCallback m_OnStartComponentCallback = nullptr;
OnStartFieldCallback m_OnStartFieldCallback = nullptr;
OnStartFieldDataCallback m_OnStartFieldDataCallback = nullptr;
};
class EntityFileSAXHandler : public xercesc::DefaultHandler
{
public:
enum class State
{
Unknown,
Entity,
Component,
ComponentField
};
EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader);
void startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) override;
void characters(const XMLCh* const chars, const XMLSize_t length) override;
void endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) override;
void warning(const xercesc::SAXParseException& e);
void error(const xercesc::SAXParseException& e);
void fatalError(const xercesc::SAXParseException& e);
private:
const EntityFileHandler* m_Handler;
xercesc::XMLGrammarPool* m_GrammarPool;
xercesc::SAX2XMLReader* m_Reader;
//State m_CurrentScope = State::Unknown;
std::stack<State> m_StateStack;
unsigned int m_NextEntityID = 0;
std::stack<EntityID> m_EntityStack;
std::string m_CurrentComponent;
std::string m_CurrentField;
std::map<std::string, std::string> m_CurrentAttributes;
void onStartEntity(const xercesc::Attributes& attrs);
void onEndEntity();
void onStartEntityRef(const xercesc::Attributes& attrs);
void onStartComponent(const std::string& name);
void onEndComponent(const std::string& name);
void onStartComponentField(const std::string& field, const xercesc::Attributes& attrs);
void onEndComponentField(const std::string& field);
void onFieldData(char* data);
};
class EntityFileXMLErrorHandler : public xercesc::ErrorHandler
{
public:
void warning(const xercesc::SAXParseException& e) override
{
reportParseException("Warning", e);
}
void error(const xercesc::SAXParseException& e) override
{
reportParseException("Error", e);
}
void fatalError(const xercesc::SAXParseException& e) override
{
reportParseException("FATAL ERROR", e);
}
void resetErrors() override { }
private:
void reportParseException(std::string type, const xercesc::SAXParseException& e)
{
char* message = xercesc::XMLString::transcode(e.getMessage());
char* systemID = xercesc::XMLString::transcode(e.getSystemId());
std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl;
std::cerr << type << ": " << message << std::endl;
xercesc::XMLString::release(&systemID);
xercesc::XMLString::release(&message);
}
};
class EntityFile : public Resource
{
friend class ResourceManager;
friend class EntityFileSAXHandler;
private:
EntityFile(boost::filesystem::path path);
~EntityFile();
public:
static std::size_t GetTypeStride(std::string typeName);
static void WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map<std::string, std::string>& attributes);
static void WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData);
xercesc::XMLGrammarPool* GrammarPool() const { return m_GrammarPool; }
void Parse(const EntityFileHandler* handler) const;
private:
boost::filesystem::path m_FilePath;
xercesc::XMLGrammarPool* m_GrammarPool;
xercesc::SAX2XMLReader* m_SAX2XMLReader;
//std::map<std::string, ::ComponentInfo> m_ComponentInfo;
//std::vector<std::string> m_EntityReferences;
static void setReaderFeatures(xercesc::SAX2XMLReader* reader);
};
#endif
+29
View File
@@ -0,0 +1,29 @@
#ifndef EntityFileParser_h__
#define EntityFileParser_h__
#include "EntityFile.h"
#include "World.h"
class EntityFileParser
{
public:
EntityFileParser(const EntityFile* entityFile);
EntityID MergeEntities(World* world, EntityID baseParent = EntityID_Invalid);
private:
const EntityFile* m_EntityFile;
EntityFileHandler m_Handler;
World* m_World = nullptr;
EntityID m_FirstEntity = EntityID_Invalid;
// Maps EntityIDs local to the file to real IDs in the world after they've been
// created in order to resolve parent-child relationships.
std::map<EntityID, EntityID> m_EntityIDMapper;
void onStartEntity(EntityID entity, EntityID parent, const std::string& name);
void onStartComponent(EntityID entity, const std::string& component);
void onStartComponentField(EntityID entity, const std::string& componentType, const std::string& fieldName, const std::map<std::string, std::string>& attributes);
void onFieldData(EntityID entity, const std::string& componentType, const std::string& fieldName, const char* fieldData);
};
#endif
@@ -0,0 +1,38 @@
#ifndef EntityFilePreprocessor_h__
#define EntityFilePreprocessor_h__
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/framework/psvi/XSModelGroup.hpp>
#include <xercesc/framework/psvi/XSModelGroupDefinition.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSValue.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include "Util/XercesString.h"
#include "ResourceManager.h"
#include "World.h"
#include "EntityFile.h"
class EntityFilePreprocessor
{
public:
EntityFilePreprocessor(const EntityFile* entityFile);
void RegisterComponents(World* world);
private:
const EntityFile* m_EntityFile;
std::map<std::string, unsigned int> m_ComponentCounts;
std::map<std::string, ComponentInfo> m_ComponentInfo;
void onStartComponent(EntityID entity, std::string type);
void parseComponentInfo();
void parseDefaults();
std::string parseAnnotationXML(const XMLCh* xml);
};
#endif
+39
View File
@@ -0,0 +1,39 @@
#ifndef EntityFileWriter_h__
#define EntityFileWriter_h__
#include <boost/filesystem.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include "Util/XercesString.h"
#include "EntityFile.h"
#include "World.h"
class EntityFileWriter
{
public:
EntityFileWriter(boost::filesystem::path file)
: m_FilePath(file)
{
using namespace xercesc;
m_DOMImplementation = DOMImplementationRegistry::getDOMImplementation(XS::ToXMLCh("LS"));
m_DOMLSSerializer = static_cast<DOMImplementationLS*>(m_DOMImplementation)->createLSSerializer();
m_DOMLSSerializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, true);
m_DOMLSSerializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
}
void WriteWorld(World* world);
void WriteEntity(World* world, EntityID entity);
private:
boost::filesystem::path m_FilePath;
xercesc::DOMImplementation* m_DOMImplementation;
xercesc::DOMLSSerializer* m_DOMLSSerializer;
void appendEntityChildren(xercesc::DOMElement* parentElement, const World* world, EntityID entity);
void appentEntityComponents(xercesc::DOMElement* parentElemetn, const World* world, EntityID entity);
};
#endif
+32
View File
@@ -0,0 +1,32 @@
#ifndef EntityWrapper_h__
#define EntityWrapper_h__
#include <boost/optional.hpp>
#include "ComponentWrapper.h"
class World;
struct EntityWrapper
{
EntityWrapper()
: World(nullptr)
, ID(EntityID_Invalid)
{ }
EntityWrapper(::World* world, EntityID id)
: World(world)
, ID(id)
{ }
::World* World;
EntityID ID;
static const EntityWrapper Invalid;
bool HasComponent(const std::string& componentName);
ComponentWrapper operator[](const std::string& componentName);
bool operator==(const EntityWrapper& e);
explicit operator EntityID();
};
#endif
-141
View File
@@ -1,141 +0,0 @@
#ifndef EntityXMLFile_h__
#define EntityXMLFile_h__
#include <sstream>
#include "../Common.h"
#include "../GLM.h"
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMLSInput.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/framework/Wrapper4InputSource.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLFloat.hpp>
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/framework/psvi/XSModelGroup.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSValue.hpp>
#include <xercesc/framework/XMLValidator.hpp>
#include "ResourceManager.h"
#include "Entity.h"
#include "ComponentInfo.h"
class World;
class EntityPreprocessorXMLErrorHandler : public xercesc::DOMErrorHandler
{
public:
bool handleError(const xercesc::DOMError &e) override
{
char* message = xercesc::XMLString::transcode(e.getMessage());
std::cerr << "Preprocessor DOMError: " << message << std::endl;
xercesc::XMLString::release(&message);
return false;
}
};
class EntityParserXMLErrorHandler : public xercesc::ErrorHandler
{
public:
void warning(const xercesc::SAXParseException& e) override
{
reportParseException("Warning", e);
}
void error(const xercesc::SAXParseException& e) override
{
reportParseException("Error", e);
}
void fatalError(const xercesc::SAXParseException& e) override
{
reportParseException("FATAL ERROR", e);
}
void resetErrors() override { }
private:
void reportParseException(std::string type, const xercesc::SAXParseException& e)
{
char* message = xercesc::XMLString::transcode(e.getMessage());
char* systemID = xercesc::XMLString::transcode(e.getSystemId());
std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl;
std::cerr << type << ": " << message << std::endl;
xercesc::XMLString::release(&systemID);
xercesc::XMLString::release(&message);
}
};
class XSTR
{
public:
XSTR(const XMLCh* const xmlString)
{
m_AsChar = xercesc::XMLString::transcode(xmlString);
}
XSTR(const char* normalString)
{
m_AsXMLCh = xercesc::XMLString::transcode(normalString);
}
~XSTR()
{
if (m_AsChar != nullptr) {
xercesc::XMLString::release(&m_AsChar);
}
if (m_AsXMLCh != nullptr) {
xercesc::XMLString::release(&m_AsXMLCh);
}
}
operator const char*() const { return m_AsChar; }
operator const XMLCh*() const { return m_AsXMLCh; }
private:
char* m_AsChar = nullptr;
XMLCh* m_AsXMLCh = nullptr;
};
class EntityXMLFile : public Resource
{
friend class ResourceManager;
private:
EntityXMLFile(std::string path);
public:
~EntityXMLFile();
void PopulateWorld(World* world);
private:
static unsigned int InstanceCount;
std::string m_EntityFile;
xercesc::XMLGrammarPool* m_GrammarPool = nullptr;
EntityParserXMLErrorHandler* m_ErrorHandler = nullptr;
xercesc::XercesDOMParser* m_DOMParser = nullptr;
xercesc::DOMDocument* m_DOMDocument = nullptr;
std::map<std::string, ComponentInfo> m_ComponentInfo;
// Preprocesses the entity file to insert include-by-copy child entities
// TODO: Make this work in memory instead of saving to file
void preprocess(std::string inPath, std::string outPath);
void parseComponentInfo();
void parseDefaults();
void predictComponentAllocation();
void parseEntityGraph(World* world, xercesc::DOMElement* parent, EntityID parentEntity);
std::size_t getTypeStride(std::string typeName);
float getFloatAttribute(const xercesc::DOMElement* element, const char* attribute) const;
void writeData(const xercesc::DOMElement* element, std::string typeName, char* outData);
};
#endif
+71 -67
View File
@@ -13,123 +13,127 @@
relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \
m_EventBroker->Subscribe(relay);
typedef unsigned int EventID;
class EventBroker;
class BaseEventRelay
{
friend class EventBroker;
friend class EventBroker;
protected:
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName)
, m_Broker(nullptr)
{ }
~BaseEventRelay();
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName)
, m_Broker(nullptr)
{ }
~BaseEventRelay();
public:
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
protected:
std::string m_ContextTypeName;
std::string m_EventTypeName;
EventBroker* m_Broker;
EventID m_EventID;
std::string m_ContextTypeName;
std::string m_EventTypeName;
EventBroker* m_Broker;
};
template <typename ContextType, typename EventType>
class EventRelay : public BaseEventRelay
{
public:
typedef std::function<bool(const EventType&)> CallbackType;
typedef std::function<bool(EventType&)> CallbackType;
EventRelay()
: m_Callback(nullptr)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay(CallbackType callback)
: m_Callback(callback)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay()
: m_Callback(nullptr)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay(CallbackType callback)
: m_Callback(callback)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
protected:
bool Receive(const std::shared_ptr<Event> event) override;
bool Receive(const std::shared_ptr<Event> event) override;
private:
CallbackType m_Callback;
CallbackType m_Callback;
};
template <typename ContextType, typename EventType>
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
{
if (m_Callback != nullptr) {
return m_Callback(*static_cast<const EventType*>(event.get()));
} else {
return false;
}
if (m_Callback != nullptr) {
return m_Callback(*static_cast<EventType*>(event.get()));
} else {
return false;
}
}
class EventBroker
{
template <typename ContextType, typename EventType> friend class EventRelay;
template <typename ContextType, typename EventType> friend class EventRelay;
public:
EventBroker()
{
m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>();
}
EventBroker()
{
m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>();
}
void Subscribe(BaseEventRelay &relay);
template <typename EventType>
void Publish(const EventType &event);
/*
Process all events in a given context.
Returns: Number of events processed
*/
template <typename ContextType>
int Process();
int Process(std::string contextTypeName);
void Swap();
void Clear();
void Unsubscribe(BaseEventRelay &relay);
void Subscribe(BaseEventRelay &relay);
template <typename EventType>
void Publish(const EventType &event);
/*
Process all events in a given context.
Returns: Number of events processed
*/
template <typename ContextType>
int Process();
int Process(std::string contextTypeName);
void Swap();
void Clear();
void Unsubscribe(BaseEventRelay &relay);
private:
bool m_IsProcessing = false;
bool m_IsProcessing = false;
EventID m_NextEventID = 0;
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
typedef std::string EventTypeName_t; // typeid(EventType).name()
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
typedef std::string EventTypeName_t; // typeid(EventType).name()
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
ContextRelays_t m_ContextRelays;
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
ContextRelays_t m_ContextRelays;
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
std::vector<std::tuple<EventID, ContextTypeName_t, EventTypeName_t>> m_RelaysToUnsubscribe;
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
std::shared_ptr<EventQueue_t> m_EventQueueRead;
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
std::shared_ptr<EventQueue_t> m_EventQueueRead;
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
void subscribeImmediate(BaseEventRelay& relay);
void unsubscribeImmediate(BaseEventRelay& relay);
void subscribeImmediate(BaseEventRelay& relay);
void unsubscribeImmediate(std::tuple<EventID, ContextTypeName_t, EventTypeName_t> identifier);
};
template <typename EventType>
void EventBroker::Publish(const EventType &event)
{
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
for (auto it = itpair.first; it != itpair.second; ++it)
{
it->second->Receive(event);
}*/
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
for (auto it = itpair.first; it != itpair.second; ++it)
{
it->second->Receive(event);
}*/
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
}
template <typename ContextType>
int EventBroker::Process()
{
const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName);
const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName);
}
#endif
+4 -7
View File
@@ -11,25 +11,22 @@ template <typename EventContext>
class InputController
{
public:
InputController(std::shared_ptr<dd::EventBroker> eventBroker)
: EventBroker(eventBroker)
InputController(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ Initialize(); }
virtual void Initialize()
{
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &InputController::OnCommand);
EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &InputController::OnMouseMove);
}
virtual bool OnCommand(const Events::InputCommand &event) { return false; }
virtual bool OnMouseMove(const Events::MouseMove &event) { return false; }
virtual bool OnCommand(const Events::InputCommand& e) { return false; }
protected:
std::shared_ptr<dd::EventBroker> EventBroker;
EventBroker* m_EventBroker;
private:
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
};
#endif
+10
View File
@@ -8,12 +8,15 @@
#include "EventBroker.h"
#include "EKeyDown.h"
#include "EKeyUp.h"
#include "EKeyboardChar.h"
#include "EMousePress.h"
#include "EMouseRelease.h"
#include "EMouseMove.h"
#include "EMouseScroll.h"
#include "ELockMouse.h"
#include "EGamepadAxis.h"
#include "EGamepadButton.h"
#include "EFileDropped.h"
class InputManager
{
@@ -64,6 +67,13 @@ private:
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
static std::vector<unsigned int> GLFWCharCallbackQueue;
static void GLFWCharCallback(GLFWwindow* window, unsigned int c);
static std::vector<std::pair<double, double>> GLFWScrollCallbackQueue;
static void GLFWScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
static std::vector<std::string> GLFWDropCallbackQueue;
static void GLFWDropCallback(GLFWwindow* window, int count, const char* paths[]);
};
#endif
+15 -5
View File
@@ -5,6 +5,14 @@
template <typename T>
class MemoryPoolForwardIterator;
namespace DisableMemoryPool
{
//if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
//if false -> Use pool allocation.
//Should default to false, unless the DisableMemoryPool is true in the Config.ini files.
extern bool Value;
}
//This is the class to use if you want to allocate blocks (slots) of raw memory, with a fixed maximum size (stride).
//Additionally, if you know that every memory-block will contain one object of a specific type, (i.e. the stride for the slot
//will the size of the object type) you should use ObjectPool<T> instead, your life will become easier.
@@ -80,8 +88,8 @@ public:
//If element cannot be allocated in the pool, because the memory ran out, memory is allocated dynamically with malloc() "outside the pool".
char* Allocate()
{
for (; m_CurrentAllocSlot < m_NumSlots && m_SlotIsAllocated[m_CurrentAllocSlot]; ++m_CurrentAllocSlot);
if (m_CurrentAllocSlot < m_NumSlots) {
for (; m_CurrentAllocSlot < m_NumSlots && m_SlotIsAllocated[m_CurrentAllocSlot] && !DisableMemoryPool::Value; ++m_CurrentAllocSlot);
if (m_CurrentAllocSlot < m_NumSlots && !DisableMemoryPool::Value) {
if (m_LowestAllocatedSlot > m_CurrentAllocSlot)
m_LowestAllocatedSlot = m_CurrentAllocSlot;
//Mark the slot as allocated.
@@ -93,7 +101,9 @@ public:
else {
m_ExtraMemory.push_back((char*)malloc(m_Stride));
//We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead.
LOG_WARNING("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size());
if (!DisableMemoryPool::Value) {
LOG_WARNING("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size());
}
return m_ExtraMemory.back();
}
}
@@ -108,7 +118,7 @@ public:
//(i.e. IsAllocatedInPool may give false positives)
//if it was malloc():ed
//so, we may enter here even if we shouldn't.
if (IsAllocatedInPool(obj)) {
if (!DisableMemoryPool::Value && IsAllocatedInPool(obj)) {
--m_NumAllocatedSlots;
const size_t freeSlot = (obj - m_StartAddress) / m_Stride;
m_SlotIsAllocated[freeSlot] = false;
@@ -253,7 +263,7 @@ public:
}
//Postfix increment i.e. iter++. Prefer pre-increment (++iter) for efficiency.
MemoryPoolForwardIterator& operator++(int)
MemoryPoolForwardIterator operator++(int)
{
MemoryPoolForwardIterator<T> copyIter(*this);
operator++();
+233
View File
@@ -0,0 +1,233 @@
#ifndef Octree_h__
#define Octree_h__
#include <type_traits>
#include "../Common.h"
#include "AABB.h"
//Fwd declarations.
class Ray;
namespace OctSpace
{
struct Output;
struct ContainedObject;
struct Child;
}
//T needs to be AABB, or inherit from AABB.
//T also needs to have a default constructor.
template<typename T>
class Octree
{
public:
Octree() = delete;
~Octree();
//For the root Octree, [octreeBounds] should be a box containing the entire level.
Octree(const AABB& octreeBounds, int subDivisions);
//We cannot copy the Octree as of now, because of the recursive dynamic allocation.
//Define these if the Octree suddenly needs to be copied, think of the children Child* ptrs.
Octree(const Octree& other) = delete;
Octree(const Octree&& other) = delete;
Octree& operator= (const Octree& other) = delete;
//Add a dynamic object (one that moves around) into the tree.
void AddDynamicObject(const T& object);
//Add a static object (that does not move) into the tree.
void AddStaticObject(const T& object);
//Get the objects that are in the same area as the input [box], the objects are put in [outObjects].
//The type Box must be AABB, or inherit from AABB.
template<typename Box>
void ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects);
//Empty the tree of all objects, static and dynamic.
void ClearObjects();
//Empty the tree of all dynamic objects. Static objects remain in the tree.
void ClearDynamicObjects();
//Returns true if the ray collides with something in the tree. Result is written to [data].
bool RayCollides(const Ray& ray, OctSpace::Output& data);
//Returns true if the box collides with something in the tree.
//On collision with a box, that box is written to [outBoxIntersected].
//Note: More efficient than calling ObjectsInSameRegion from outside and testing there.
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected);
private:
OctSpace::Child* m_Root;
std::vector<OctSpace::ContainedObject> m_StaticObjects;
std::vector<OctSpace::ContainedObject> m_DynamicObjects;
void falsifyObjectChecks();
};
namespace OctSpace
{
struct Output
{
float CollideDistance;
};
struct ContainedObject
{
ContainedObject()
: Box(nullptr)
, Checked(false)
{}
template<typename BoxlikeObject>
ContainedObject(const BoxlikeObject& box)
: Box(new BoxlikeObject(box))
, Checked(false)
{}
std::unique_ptr<AABB> Box;
bool Checked;
};
struct Child
{
~Child();
Child(const AABB& octTreeBounds,
int subDivisions,
std::vector<ContainedObject>& staticObjects,
std::vector<ContainedObject>& dynamicObjects);
Child(const Child& other) = delete;
Child(const Child&& other) = delete;
Child& operator= (const Child& other) = delete;
void AddDynamicObject(const AABB& box);
void AddStaticObject(const AABB& box);
template<typename T, typename Box>
void ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects) const;
void ClearObjects();
void ClearDynamicObjects();
bool RayCollides(const Ray& ray, Output& data) const;
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const;
Child* m_Children[8];
//Indices into the lists in Octree.
std::vector<int> m_StaticObjIndices;
std::vector<int> m_DynamicObjIndices;
AABB m_Box;
//Reference to the lists in Octree.
std::vector<ContainedObject>& m_StaticObjectsRef;
std::vector<ContainedObject>& m_DynamicObjectsRef;
inline bool hasChildren() const;
int childIndexContainingPoint(const glm::vec3& point) const;
std::vector<int> childIndicesContainingBox(const AABB& box) const;
};
}
template<typename T>
Octree<T>::Octree(const AABB& octTreeBounds, int subDivisions)
: m_Root(new OctSpace::Child(octTreeBounds, subDivisions, m_StaticObjects, m_DynamicObjects))
{
static_assert(std::is_base_of<AABB, T>::value, "template argument type T in Octree must be a subclass of AABB.");
}
template<typename T>
Octree<T>::~Octree()
{
delete m_Root;
}
template<typename T>
void Octree<T>::AddDynamicObject(const T& object)
{
m_Root->AddDynamicObject(object);
m_DynamicObjects.emplace_back(object);
}
template<typename T>
void Octree<T>::AddStaticObject(const T& object)
{
m_Root->AddStaticObject(object);
m_StaticObjects.emplace_back(object);
}
template<typename T>
template<typename Box>
void Octree<T>::ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects)
{
static_assert(std::is_base_of<AABB, Box>::value, "template argument type Box in Octree<T>::ObjectsInSameRegion must be a subclass of AABB.");
falsifyObjectChecks();
m_Root->ObjectsInSameRegion(box, outObjects);
}
template<typename T>
void Octree<T>::ClearObjects()
{
m_StaticObjects.clear();
m_DynamicObjects.clear();
m_Root->ClearObjects();
}
template<typename T>
void Octree<T>::ClearDynamicObjects()
{
m_DynamicObjects.clear();
m_Root->ClearDynamicObjects();
}
template<typename T>
bool Octree<T>::RayCollides(const Ray& ray, OctSpace::Output& data)
{
falsifyObjectChecks();
data.CollideDistance = -1;
return m_Root->RayCollides(ray, data);
}
template<typename T>
bool Octree<T>::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected)
{
falsifyObjectChecks();
return m_Root->BoxCollides(boxToTest, outBoxIntersected);
}
template<typename T>
void Octree<T>::falsifyObjectChecks()
{
for (auto& obj : m_StaticObjects) {
obj.Checked = false;
}
for (auto& obj : m_DynamicObjects) {
obj.Checked = false;
}
}
template<typename T, typename Box>
void OctSpace::Child::ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects) const
{
if (hasChildren()) {
for (auto i : childIndicesContainingBox(box)) {
m_Children[i]->ObjectsInSameRegion(box, outObjects);
}
} else {
size_t startIndex = outObjects.size();
int numDuplicates = 0;
outObjects.resize(outObjects.size() + m_StaticObjIndices.size() + m_DynamicObjIndices.size());
for (size_t i = 0; i < m_StaticObjIndices.size(); ++i) {
ContainedObject& obj = m_StaticObjectsRef[m_StaticObjIndices[i]];
if (obj.Checked) {
++numDuplicates;
} else {
obj.Checked = true;
outObjects[startIndex + i - numDuplicates] = *static_cast<T*>(obj.Box.get());
}
}
for (size_t i = 0; i < m_DynamicObjIndices.size(); ++i) {
ContainedObject& obj = m_DynamicObjectsRef[m_DynamicObjIndices[i]];
if (obj.Checked) {
++numDuplicates;
} else {
obj.Checked = true;
outObjects[startIndex + i - numDuplicates] = *static_cast<T*>(obj.Box.get());
}
}
for (size_t i = 0; i < numDuplicates; ++i) {
outObjects.pop_back();
}
}
}
#endif
+31
View File
@@ -0,0 +1,31 @@
#ifndef Ray_h__
#define Ray_h__
#include "../GLM.h"
#include "../Common.h"
class Ray
{
public:
Ray(const glm::vec3& origin, const glm::vec3& dir)
: m_Origin(origin)
, m_Direction(glm::normalize(dir))
{
DEBUG_IF(true) {
if (glm::any(glm::isnan(m_Direction))) {
LOG_WARNING("Ray Direction was set to the zero-vector, expect unknown side effects and/or crashes.");
}
}
}
const glm::vec3& Origin() const { return m_Origin; }
const glm::vec3& Direction() const { return m_Direction; }
//Sets the ray origin at parameter.
void SetOrigin(const glm::vec3& origin) { m_Origin = origin; }
//Normalizes the parameter and sets direction to it.
void SetDirection(const glm::vec3& direction) { m_Direction = glm::normalize(direction); }
private:
glm::vec3 m_Origin;
glm::vec3 m_Direction;
};
#endif // Ray_h__
+132 -39
View File
@@ -12,7 +12,6 @@
/** Base Resource class.
Implement this class for every resource to be handled by the resource manager.
Implement Create() to return a new object of that type.
*/
class Resource
{
@@ -22,6 +21,23 @@ protected:
Resource() { }
public:
//Should be thrown in a Resource's constructor if it cannot complete because another resource is still loading.
//Not actually an error, just a message to the ResourceManager.
struct StillLoadingException : public std::exception
{
virtual const char* what() const throw()
{
return "Resource is still loading.";
}
};
struct FailedLoadingException : public std::exception
{
virtual const char* what() const throw()
{
return "Resource is failed to load.";
}
};
// Pretend that this is a pure virtual function that you have to implement
// FIXME: Why did we do this again instead of just using the constructor?
// static Resource* Create(std::string resourceName);
@@ -33,6 +49,15 @@ public:
unsigned int ResourceID;
};
//Any class inheriting from this class will always be loaded on the master thread, not on a parallel worker thread.
//This is important in case some instructions must be executed on the main thread, e.g. OpenGL commands, like glBindBuffer.
//This resource can still be loaded asyncronously, but it will not be loaded in a thread, instead it's constructor will
//be called once on every ResourceManager::Load, just throw StillLoadingException in the constructor if it is not done yet.
class ThreadUnsafeResource : public Resource
{
friend class ResourceManager;
};
/** Singleton resource manager to keep track of and cache any external engine assets */
class ResourceManager
{
@@ -40,6 +65,7 @@ private:
ResourceManager();
public:
static bool UseThreading;
/*static ResourceManager& Instance()
{
static ResourceManager s;
@@ -49,15 +75,6 @@ public:
template <typename T>
static void RegisterType(std::string typeName);
/** Preloads a resource and caches it for future use
@tparam T Resource type.
@param resourceName Fully qualified name of the resource to preload.
*/
template <typename T>
static void Preload(std::string resourceName);
static void Preload(std::string resourceType, std::string resourceName);
/** Checks if a resource is in cache
@param resourceType Resource type as string.
@@ -65,15 +82,20 @@ public:
*/
// TODO: Templateify
static bool IsResourceLoaded(std::string resourceType, std::string resourceName);
/** Return value should always be a valid pointer, will throw an exception on error.
If the resource has been loaded already, returns a pointer to it.
/** Hot-loads a resource and caches it for future use
If Async is false: Hot-loads a resource, caches it for future use, and returns a pointer to it.
If Async is true: If the resource is not loaded yet, starts loading the resource
in the background and throws Resource::StillLoadingException immediately.
@tparam T Resource type.
@tparam async Set this to true if the resource should be loaded asyncronously.
@param resourceName Fully qualified name of the resource to load.
*/
template <typename T>
static T* Load(std::string resourceName, Resource* parent = nullptr);
static Resource* Load(std::string resourceType, std::string resourceName, Resource* parent = nullptr);
template <typename T, bool async = false>
static T* Load(const std::string& resourceName, Resource* parent = nullptr);
/** Reloads an already loaded resource, keeping its resource ID intact.
@@ -87,19 +109,31 @@ public:
static void Update();
private:
//This is a haxy way to make sure that IsMainThread is run when the program starts, so the master thread id is set.
struct MasterThreadChecker
{
MasterThreadChecker()
{
ResourceManager::IsMainThread();
}
};
const static MasterThreadChecker m_Checker;
static std::unordered_map<std::string, std::string> m_CompilerTypenameToResourceType;
static std::unordered_map<std::string, std::function<Resource*(std::string)>> m_FactoryFunctions; // type -> factory function
static std::unordered_map<std::pair<std::string, std::string>, Resource*> m_ResourceCache; // (type, name) -> resource
static std::unordered_map<std::string, Resource*> m_ResourceFromName; // name -> resource
static std::unordered_map<Resource*, Resource*> m_ResourceParents; // resource -> parent resource
static std::unordered_map<std::pair<std::string, std::string>, boost::thread> m_LoadingThreads; // (type, name) -> loading thread
static std::unordered_map<std::pair<std::string, std::string>, std::exception_ptr> m_LoadingThreadExceptions; // (type, name) -> exceptions
static boost::recursive_mutex m_Mutex;
// TODO: Getters for IDs
static unsigned int m_CurrentResourceTypeID;
static std::unordered_map<std::string, unsigned int> m_ResourceTypeIDs;
// Number of resources of a type. Doubles as local ID.
static std::unordered_map<unsigned int, unsigned int> m_ResourceCount;
// Flag to suppress hot-load warnings when a preloading resource chain loads another resource
static bool m_Preloading;
static FileWatcher m_FileWatcher;
static void fileWatcherCallback(std::string path, FileWatcher::FileEventFlags flags);
@@ -108,22 +142,13 @@ private:
static unsigned int GetNewResourceID(unsigned int typeID);
// Internal: Create a resource and cache it
static Resource* CreateResource(std::string resourceType, std::string resourceName, Resource* parent);
static Resource* createResourceThrowing(const std::string& resourceType, const std::string& resourceName, Resource* parent);
static Resource* createResource(const std::string& resourceType, const std::string& resourceName, Resource* parent, std::exception_ptr& exception);
static Resource* cacheResource(Resource* resource, const std::string& resourceType, const std::string& resourceName, Resource* parent);
static bool IsMainThread();
};
template <typename T>
T* ResourceManager::Load(std::string resourceName, Resource* parent /* = nullptr */)
{
auto resourceTypename = typeid(T).name();
auto it = m_CompilerTypenameToResourceType.find(resourceTypename);
if (it == m_CompilerTypenameToResourceType.end()) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename);
return nullptr;
}
return static_cast<T*>(Load(it->second, resourceName, parent));
}
template <typename T>
void ResourceManager::RegisterType(std::string typeName)
{
@@ -131,17 +156,85 @@ void ResourceManager::RegisterType(std::string typeName)
m_FactoryFunctions[typeName] = [](std::string resourceName) { return new T(resourceName); };
}
template <typename T>
void ResourceManager::Preload(std::string resourceName)
template <typename T, bool async>
static T* ResourceManager::Load(const std::string& resourceName, Resource* parent /* = nullptr */)
{
auto resourceTypename = typeid(T).name();
auto it = m_CompilerTypenameToResourceType.find(resourceTypename);
if (it == m_CompilerTypenameToResourceType.end()) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename);
return;
}
auto resourceTypename = typeid(T).name();
auto iter = m_CompilerTypenameToResourceType.find(resourceTypename);
if (iter == m_CompilerTypenameToResourceType.end()) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename);
throw Resource::FailedLoadingException();
}
Preload(it->second, resourceName);
std::string resourceType = iter->second;
constexpr bool mustNotLoadInThread = std::is_base_of<ThreadUnsafeResource, T>::value;
if (mustNotLoadInThread && !IsMainThread()) {
LOG_ERROR("Failed to Load \"%s\": ThreadUnsafeResource type \"%s\" load in the constructor of another resource that is loaded asyncronously.", resourceName.c_str(), iter->second.c_str());
throw Resource::FailedLoadingException();
}
auto cacheKey = std::make_pair(resourceType, resourceName);
decltype(m_ResourceCache)::iterator it;
//If a thread has already been launched to load this resource.
auto tIt = m_LoadingThreads.find(cacheKey);
if (UseThreading && tIt != m_LoadingThreads.end()) {
if (async) {
//Throw StillLoadingException if the thread is still working.
if (!tIt->second.try_join_for(boost::chrono::nanoseconds(1))) {
throw Resource::StillLoadingException();
}
//Else we know the thread has completed.
} else {
//Wait for the thread to finish loading.
tIt->second.join();
}
//When the thread is done, delete the thread.
m_LoadingThreads.erase(tIt);
//Rethrow the thread exception if it threw any.
auto excIt = m_LoadingThreadExceptions.find(cacheKey);
std::exception_ptr exception = excIt->second;
m_LoadingThreadExceptions.erase(excIt);
if (exception) {
std::rethrow_exception(exception);
}
}
//If resource has already been cached and completely loaded.
it = m_ResourceCache.find(cacheKey);
if (it != m_ResourceCache.end()) {
if (it->second != nullptr) {
return static_cast<T*>(it->second);
} else {
//Don't return null on failure, exception instead.
throw Resource::FailedLoadingException();
}
}
//If resource is not cached..
if (UseThreading && async) {
if (mustNotLoadInThread) {
try {
return static_cast<T*>(createResourceThrowing(resourceType, resourceName, parent));
} catch (const Resource::StillLoadingException&) {
throw;
}
} else {
//Create a thread that loads the resource into cache.
m_LoadingThreads[cacheKey] = boost::thread(createResource, resourceType, resourceName, parent, m_LoadingThreadExceptions[cacheKey]);
throw Resource::StillLoadingException();
}
} else {
//load and return the resource.
while (true) {
try {
return static_cast<T*>(createResourceThrowing(resourceType, resourceName, parent));
} catch (const Resource::StillLoadingException&) {
continue;
} catch (const std::exception&) {
throw;
}
}
}
}
#endif
+34 -8
View File
@@ -3,23 +3,49 @@
#include "EventBroker.h"
#include "World.h"
#include "EntityWrapper.h"
#include "ComponentWrapper.h"
class System
{
friend class SystemPipeline;
public:
System(const EventBroker* eventBroker, std::string componentType)
: m_EventBroker(eventBroker)
, m_ComponentType(componentType)
protected:
System()
: m_EventBroker(nullptr)
{ }
System(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
virtual ~System() = default;
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
EventBroker* m_EventBroker;
};
private:
const EventBroker* m_EventBroker;
std::string m_ComponentType;
class PureSystem : public virtual System
{
friend class SystemPipeline;
protected:
PureSystem(std::string componentType)
: m_ComponentType(componentType)
{ }
virtual ~PureSystem() = default;
const std::string m_ComponentType;
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) = 0;
};
class ImpureSystem : public virtual System
{
friend class SystemPipeline;
protected:
ImpureSystem() = default;
virtual ~ImpureSystem() = default;
virtual void Update(World* world, double dt) = 0;
};
#endif
+52 -21
View File
@@ -9,50 +9,81 @@
class SystemPipeline
{
public:
SystemPipeline(const EventBroker* eventBroker)
SystemPipeline(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
~SystemPipeline()
{
for (auto& pair : m_Systems) {
for (auto& system : pair.second) {
delete system;
for (UnorderedSystems& group : m_OrderedSystemGroups) {
for (auto& pair : group.Systems) {
delete pair.second;
}
}
}
template <typename T, typename... Arguments>
void AddSystem(Arguments... args)
//All systems with orderlevel 0 will be updated first, then 1, 2, etc.
void AddSystem(int updateOrderLevel, Arguments... args)
{
if (updateOrderLevel + 1 > m_OrderedSystemGroups.size()) {
m_OrderedSystemGroups.resize(updateOrderLevel + 1);
}
UnorderedSystems& group = m_OrderedSystemGroups[updateOrderLevel];
System* system = new T(m_EventBroker, args...);
if (!system->m_ComponentType.empty()) {
m_Systems[system->m_ComponentType].push_back(system);
} else {
LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name());
delete system;
group.Systems[typeid(T).name()] = system;
PureSystem* pureSystem = dynamic_cast<PureSystem*>(system);
if (pureSystem != nullptr) {
if (!pureSystem->m_ComponentType.empty()) {
group.PureSystems[pureSystem->m_ComponentType].push_back(pureSystem);
} else {
LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name());
}
}
ImpureSystem* impureSystem = dynamic_cast<ImpureSystem*>(system);
if (impureSystem != nullptr) {
group.ImpureSystems.push_back(impureSystem);
}
}
void Update(World* world, double dt)
{
for (auto& pair : m_Systems) {
const std::string& componentName = pair.first;
auto& systems = pair.second;
const ComponentPool* pool = world->GetComponents(componentName);
if (pool == nullptr) {
continue;
for (UnorderedSystems& group : m_OrderedSystemGroups) {
// Process events
for (auto& pair : group.Systems) {
m_EventBroker->Process(pair.first);
}
for (auto& component : *pool) {
for (auto& system : systems) {
system->Update(world, component, dt);
// Update
for (auto& system : group.ImpureSystems) {
system->Update(world, dt);
}
for (auto& pair : group.PureSystems) {
const std::string& componentName = pair.first;
auto& systems = pair.second;
const ComponentPool* pool = world->GetComponents(componentName);
if (pool == nullptr) {
continue;
}
for (auto& component : *pool) {
for (auto& system : systems) {
system->UpdateComponent(world, EntityWrapper(world, component.EntityID), component, dt);
}
}
}
}
}
private:
const EventBroker* m_EventBroker;
std::unordered_map<std::string, std::vector<System*>> m_Systems;
EventBroker* m_EventBroker;
struct UnorderedSystems
{
std::map<std::string, System*> Systems;
std::map<std::string, std::vector<PureSystem*>> PureSystems;
std::vector<ImpureSystem*> ImpureSystems;
};
std::vector<UnorderedSystems> m_OrderedSystemGroups;
};
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef Transform_h__
#define Transform_h__
#include "../GLM.h"
#include "World.h"
namespace Transform
{
glm::vec3 AbsolutePosition(World* world, EntityID entity);
glm::quat AbsoluteOrientation(World* world, EntityID entity);
glm::vec3 AbsoluteScale(World* world, EntityID entity);
glm::mat4 ModelMatrix(EntityID entity, World* world);
}
#endif
+12
View File
@@ -0,0 +1,12 @@
// Example:
// DEBUG_IF(condition) {
// // This code is executed only in debug mode and if condition is true.
// }
// NOTE: condition statement is not executed at all in release mode.
#ifndef DEBUG_IF
#ifndef DEBUG
#define DEBUG_IF(c) if(c)
#else
#define DEBUG_IF(c) if(false)
#endif
#endif
+46
View File
@@ -0,0 +1,46 @@
#ifndef Util_XercesString_h__
#define Util_XercesString_h__
#include <string>
#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/XMLString.hpp>
namespace XS
{
class ToString
{
public:
ToString(const XMLCh* const str) { m_AsChar = xercesc::XMLString::transcode(str); }
~ToString()
{
if (m_AsChar != nullptr) {
xercesc::XMLString::release(&m_AsChar);
}
}
operator std::string() const { return std::string(m_AsChar); }
private:
char* m_AsChar = nullptr;
};
class ToXMLCh
{
public:
ToXMLCh(const std::string str) { m_Transcoded = xercesc::XMLString::transcode(str.c_str()); }
ToXMLCh(const char* str) { m_Transcoded = xercesc::XMLString::transcode(str); }
~ToXMLCh()
{
if (m_Transcoded != nullptr) {
xercesc::XMLString::release(&m_Transcoded);
}
}
operator const XMLCh*() const { return m_Transcoded; }
private:
XMLCh* m_Transcoded = nullptr;
};
}
#endif
+26 -5
View File
@@ -14,24 +14,45 @@ public:
// Create empty entity
EntityID CreateEntity(EntityID parent = 0);
// Delete entity and all components within
void DeleteEntity(EntityID entity);
// Check if an entity exists
bool ValidEntity(EntityID entity) const;
// Register a component type and allocate space for it
void RegisterComponent(ComponentInfo& ci);
// Attach a component to an entity and fill it with default values
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
ComponentWrapper AttachComponent(EntityID entity, const std::string& componentType);
// Check if an entity has a component
bool HasComponent(EntityID entity, const std::string& componentType) const;
// Get a component of an entity
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
ComponentWrapper GetComponent(EntityID entity, const std::string& componentType);
// Delete a component off an entity
void DeleteComponent(EntityID entity, const std::string& componentType);
// Get all components of the specified type
const ComponentPool* GetComponents(std::string componentType);
const ComponentPool* GetComponents(const std::string& componentType);
// Get entity parent
EntityID GetParent(EntityID entity);
// Change the parent of an entity
void SetParent(EntityID entity, EntityID parent);
// Get children of an entity
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> GetChildren(EntityID entity);
// Get all component pools
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
// Get the entity children map
const std::unordered_multimap<EntityID, EntityID>& GetEntityChildren() const { return m_EntityChildren; }
// Set the textual name of an entity
void SetName(EntityID entity, const std::string& name);
// Get the textual name of an entity
std::string GetName(EntityID entity) const;
private:
EntityID m_CurrentEntityID = 1;
EntityID m_CurrentEntityID = 0;
std::unordered_map<EntityID, EntityID> m_EntityParents;
// TODO: This should be a more effective structure
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
std::unordered_map<EntityID, std::string> m_EntityNames;
EntityID generateEntityID();
};
+94
View File
@@ -0,0 +1,94 @@
#include <imgui/imgui.h>
#include <glm/gtx/common.hpp>
#include <boost/filesystem/path.hpp>
#include <nativefiledialog/nfd.h>
#include "../Core/System.h"
#include "../Core/EMousePress.h"
#include "../Core/EMouseRelease.h"
#include "../Core/EMouseMove.h"
#include "../Core/ConfigFile.h"
#include "../Input/EInputCommand.h"
#include "../Rendering/IRenderer.h"
#include "../Core/Transform.h"
#include "../Core/EFileDropped.h"
#include "../Core/EntityFilePreprocessor.h"
#include "../Core/EntityFileParser.h"
#include "../Core/EntityFileWriter.h"
class EditorSystem : public ImpureSystem
{
public:
EditorSystem(EventBroker* eventBroker, IRenderer* renderer);
virtual void Update(World* world, double dt) override;
private:
IRenderer* m_Renderer;
World* m_World = nullptr;
Camera* m_Camera = nullptr;
bool m_Enabled;
bool m_Visible;
boost::filesystem::path m_DefaultEntityDir;
boost::filesystem::path m_CurrentFile;
std::vector<glm::vec2> m_PickingQueue;
enum class WidgetMode
{
None,
Translate,
Rotate,
Scale
} m_WidgetMode = WidgetMode::None;
enum class WidgetSpace
{
Local,
Global
} m_WidgetSpace = WidgetSpace::Global;
EntityID m_Widget = EntityID_Invalid;
EntityID m_WidgetX = EntityID_Invalid;
EntityID m_WidgetPlaneX = EntityID_Invalid;
EntityID m_WidgetY = EntityID_Invalid;
EntityID m_WidgetPlaneY = EntityID_Invalid;
EntityID m_WidgetZ = EntityID_Invalid;
EntityID m_WidgetPlaneZ = EntityID_Invalid;
EntityID m_WidgetOrigin = EntityID_Invalid;
glm::vec3 m_WidgetCurrentAxis;
float m_WidgetPickingDepth = 0.f;
glm::vec3 m_WidgetPickingPosition = glm::vec3(0);
EntityID m_Selection = EntityID_Invalid;
EntityID m_LastSelection = EntityID_Invalid;
EntityID m_UIDraggingEntity = EntityID_Invalid;
glm::vec3 m_Position;
std::string m_LastDroppedFile;
static boost::filesystem::path openDialog(boost::filesystem::path defaultPath);
static boost::filesystem::path saveDialog(boost::filesystem::path defaultPath);
EventRelay<EditorSystem, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
EventRelay<EditorSystem, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e);
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e);
EventRelay<EditorSystem, Events::MouseMove> m_EMouseMove;
bool OnMouseMove(const Events::MouseMove& e);
EventRelay<EditorSystem, Events::FileDropped> m_EFileDropped;
bool OnFileDropped(const Events::FileDropped& e);
void Picking();
void createWidget();
void updateWidget();
void setWidgetMode(WidgetMode newMode);
void setWidgetSpace(WidgetSpace space);
void drawUI(World* world, double dt);
bool createDeleteButton(std::string componentType);
bool createEntityNode(World* world, EntityID entity);
void changeParent(EntityID entity, EntityID newParent);
void fileImport(World* world);
void fileSave(World* world);
void fileSaveAs(World* world);
};
+1 -1
View File
@@ -40,7 +40,7 @@ public:
m_TexturePressed = resourceName;
}
void Draw(RenderQueueCollection& rq) override
void Draw(RenderScene& rq) override
{
if (m_Texture == nullptr && !m_TextureReleased.empty()) {
SetTexture(m_TextureReleased);
+2 -2
View File
@@ -212,7 +212,7 @@ public:
virtual void Update(double dt) { }
void DrawLayered(RenderQueueCollection& rq)
void DrawLayered(RenderScene& rq)
{
if (this->Hidden())
return;
@@ -232,7 +232,7 @@ public:
}
}
virtual void Draw(RenderQueueCollection& rq) { }
virtual void Draw(RenderScene& rq) { }
protected:
::EventBroker* m_EventBroker;
+1 -1
View File
@@ -16,7 +16,7 @@ public:
void EnableScissor() { m_ScissorEnabled = true; }
void DisableScissor() { m_ScissorEnabled = false; }
void Draw(RenderQueueCollection& rq) override
void Draw(RenderScene& rq) override
{
if (m_Texture == nullptr)
return;
-24
View File
@@ -1,24 +0,0 @@
#ifndef Events_BindGamepadAxis_h__
#define Events_BindGamepadAxis_h__
#include "Core/EventBroker.h"
#include "Core/EGamepadAxis.h"
namespace Events
{
/** Called to bind a gamepad axis to an input command. */
struct BindGamepadAxis : Event
{
/** The axis to bind. */
Gamepad::Axis Axis;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation.
Multiplied by the 0-1 clamped value of the axis.
*/
float Value;
};
}
-26
View File
@@ -1,26 +0,0 @@
#ifndef Events_BindGamepadButton_h__
#define Events_BindGamepadButton_h__
#include "Core/EventBroker.h"
#include "Core/EGamepadButton.h"
namespace Events
{
/** Called to bind a gamepad button to an input command. */
struct BindGamepadButton : Event
{
/** The gamepad button to bind. */
Gamepad::Button Button;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation.
Multiplied by the 0-1 clamped value of the button.
*/
float Value;
};
}
#endif
-25
View File
@@ -1,25 +0,0 @@
#ifndef Events_BindKey_h__
#define Events_BindKey_h__
#include "Core/EventBroker.h"
namespace Events
{
/** Called to bind a keyboard key to an input command. */
struct BindKey : Event
{
/** The GLFW key code to bind. */
int KeyCode;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation.
Multiplied by the 0-1 clamped value of the key.
*/
float Value;
};
}
#endif
-25
View File
@@ -1,25 +0,0 @@
#ifndef Events_BindMouseButton_h__
#define Events_BindMouseButton_h__
#include "Core/EventBroker.h"
namespace Events
{
/** Called to bind a mouse button to an input command. */
struct BindMouseButton : Event
{
/** The GLFW mouse button code to bind. */
int Button;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation.
Multiplied by the 0-1 clamped value of the button.
*/
float Value;
};
}
#endif
@@ -0,0 +1,70 @@
#ifndef FirstPersonInputController_h__
#define FirstPersonInputController_h__
#include "../GLM.h"
#include "../Core/InputController.h"
#include "../Core/ELockMouse.h"
template <typename EventContext>
class FirstPersonInputController : public InputController<EventContext>
{
public:
FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID)
: InputController(eventBroker)
, m_PlayerID(playerID)
{
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
}
const glm::quat Orientation() const { return m_Orientation; }
void LockMouse()
{
Events::LockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = true;
}
void UnlockMouse()
{
Events::UnlockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = false;
}
virtual bool OnCommand(const Events::InputCommand& e) override
{
if (m_PlayerID != e.PlayerID) {
return false;
}
if (m_MouseLocked) {
if (e.Command == "Pitch") {
float val = glm::radians(e.Value);
m_Orientation = m_Orientation * glm::angleAxis<float>(-val, glm::vec3(1, 0, 0));
return true;
}
if (e.Command == "Yaw") {
float val = glm::radians(e.Value);
m_Orientation = glm::angleAxis<float>(-val, glm::vec3(0, 1, 0)) * m_Orientation;
return true;
}
}
return false;
}
protected:
const unsigned int m_PlayerID;
glm::quat m_Orientation;
bool m_MouseLocked = false;
EventRelay<EventContext, Events::LockMouse> m_ELockMouse;
bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; }
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; }
};
#endif
+25
View File
@@ -0,0 +1,25 @@
#ifndef InputHandler_h__
#define InputHandler_h__
#include "../Common.h"
#include "../Core/EventBroker.h"
#include "InputProxy.h"
class InputHandler
{
public:
InputHandler(EventBroker* eventBroker, InputProxy* inputProxy)
: m_EventBroker(eventBroker)
, m_InputProxy(inputProxy)
{ }
virtual bool BindOrigin(std::string origin, std::string command, float value) = 0;
virtual void Update(double dt) { }
virtual float GetCommandValue(std::string command) = 0;
protected:
EventBroker* m_EventBroker;
InputProxy* m_InputProxy;
};
#endif
+28 -127
View File
@@ -1,146 +1,47 @@
#ifndef InputSystem_h__
#define InputSystem_h__
#ifndef InputProxy_h__
#define InputProxy_h__
#include <array>
#include <unordered_map>
#include <steam/steam_api.h>
#include "Core/EKeyUp.h"
#include "Core/EKeyDown.h"
#include "Core/EMousePress.h"
#include "Core/EMouseRelease.h"
#include "Core/EGamepadAxis.h"
#include "Core/EGamepadButton.h"
#include "Core/Util/EnumClassHash.h"
#include "EBindKey.h"
#include "EBindMouseButton.h"
#include "EBindGamepadAxis.h"
#include "EBindGamepadButton.h"
#include <boost/tokenizer.hpp>
#include "../Common.h"
#include "../Core/ResourceManager.h"
#include "../Core/ConfigFile.h"
#include "EInputCommand.h"
#include "EBindOrigin.h"
class InputProxy;
class InputHandler
{
public:
InputHandler(EventBroker* eventBroker, InputProxy* inputProxy)
: m_EventBroker(eventBroker)
, m_InputProxy(inputProxy)
{ }
virtual void Update(double dt) { }
virtual bool BindOrigin(std::string origin, std::string command, float value) = 0;
protected:
EventBroker* m_EventBroker;
InputProxy* m_InputProxy;
};
class InputHandler;
class InputProxy
{
public:
InputProxy(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{
EVENT_SUBSCRIBE_MEMBER(m_EBindOrigin, &InputProxy::OnBindOrigin);
}
void Update(double dt)
{
m_EventBroker->Process<InputProxy>();
m_EventBroker->Process<InputHandler>();
for (auto& handler : m_Handlers) {
handler->Update(dt);
}
}
void Process()
{
// Accumulate the input values of all unique commands published by input handlers
for (auto& pair : m_CommandQueue) {
Events::InputCommand e;
e.PlayerID = pair.first.first;
e.Command = pair.first.second;
e.Value = 0;
for (auto& value : pair.second) {
e.Value += value;
}
e.Value = std::max(-1.f, std::min(e.Value, 1.f));
m_EventBroker->Publish(e);
LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID);
}
m_CommandQueue.clear();
}
InputProxy(EventBroker* eventBroker);
~InputProxy();
void LoadBindings(std::string file);
void Update(double dt);
void Process();
template <typename T>
void AddHandler()
{
m_Handlers.push_back(new T(m_EventBroker, this));
}
void Publish(const Events::InputCommand& e)
{
auto key = std::make_pair(e.PlayerID, e.Command);
m_CommandQueue[key].push_back(e.Value);
}
void AddHandler();
void Publish(const Events::InputCommand& e);
protected:
EventBroker* m_EventBroker;
std::vector<InputHandler*> m_Handlers;
// Represents every unique command (has of PlayerID & Command) and all values reported for that command
std::map<std::string, std::set<InputHandler*>> m_CommandHandlers;
// Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame
std::map<std::pair<unsigned int, std::string>, std::vector<float>> m_CommandQueue;
std::map<std::string, float> m_CurrentCommandValues;
std::map<std::string, float> m_LastCommandValues;
EventRelay<InputProxy, Events::BindOrigin> m_EBindOrigin;
bool OnBindOrigin(const Events::BindOrigin& e)
{
bool originBound = false;
for (auto& handler : m_Handlers) {
bool result = handler->BindOrigin(e.Origin, e.Command, e.Value);
if (result) {
if (originBound) {
LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str());
}
originBound = true;
}
}
if (!originBound) {
LOG_ERROR("No input handler responded to binding input origin \"%s\"!", e.Origin.c_str());
}
return originBound;
}
//std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandMouseButtonValues; // command string -> mouse button value for command
//std::unordered_map<std::string, std::unordered_map<Gamepad::Axis, float, EnumClassHash>> m_CommandGamepadAxisValues; // command string -> gamepad axis value for command
//std::unordered_map<std::string, std::unordered_map<Gamepad::Button, float, EnumClassHash>> m_CommandGamepadButtonValues; // command string -> gamepad button value for command
//// Input binding tables
//std::unordered_multimap<int, std::tuple<std::string, float>> m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string
//std::unordered_multimap<Gamepad::Axis, std::tuple<std::string, float>, EnumClassHash> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value
//std::unordered_multimap<Gamepad::Button, std::tuple<std::string, float>, EnumClassHash> m_GamepadButtonBindings; // Gamepad::Button -> command string
//// Input events
//EventRelay<InputProxy, Events::MousePress> m_EMousePress;
//bool OnMousePress(const Events::MousePress &event);
//EventRelay<InputProxy, Events::MouseRelease> m_EMouseRelease;
//bool OnMouseRelease(const Events::MouseRelease &event);
//EventRelay<InputProxy, Events::GamepadAxis> m_EGamepadAxis;
//bool OnGamepadAxis(const Events::GamepadAxis &event);
//EventRelay<InputProxy, Events::GamepadButtonDown> m_EGamepadButtonDown;
//bool OnGamepadButtonDown(const Events::GamepadButtonDown &event);
//EventRelay<InputProxy, Events::GamepadButtonUp> m_EGamepadButtonUp;
//bool OnGamepadButtonUp(const Events::GamepadButtonUp &event);
//// Input binding events
//EventRelay<InputProxy, Events::BindMouseButton> m_EBindMouseButton;
//bool OnBindMouseButton(const Events::BindMouseButton &event);
//EventRelay<InputProxy, Events::BindGamepadAxis> m_EBindGamepadAxis;
//bool OnBindGamepadAxis(const Events::BindGamepadAxis &event);
//EventRelay<InputProxy, Events::BindGamepadButton> m_EBindGamepadButton;
//bool OnBindGamepadButton(const Events::BindGamepadButton &event);
//float GetCommandTotalValue(std::string command);
//void PublishCommand(int playerID, std::string command, float value);
bool OnBindOrigin(const Events::BindOrigin& e);
};
template <typename T>
void InputProxy::AddHandler()
{
m_Handlers.push_back(new T(m_EventBroker, this));
}
#endif
+12 -51
View File
@@ -1,67 +1,28 @@
#ifndef KeyboardInputHandler_h__
#define KeyboardInputHandler_h__
#include <GLFW/glfw3.h>
#include "InputProxy.h"
#include "InputHandler.h"
#include "Core/EKeyDown.h"
#include "Core/EKeyUp.h"
class KeyboardInputHandler : public InputHandler
{
public:
KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy)
: InputHandler(eventBroker, inputProxy)
{
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &KeyboardInputHandler::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &KeyboardInputHandler::OnKeyUp);
KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
m_OriginKeyCodes["R"] = GLFW_KEY_R;
}
bool BindOrigin(std::string origin, std::string command, float value) override
{
auto originIt = m_OriginKeyCodes.find(origin);
if (originIt == m_OriginKeyCodes.end()) {
return false;
}
int keyCode = originIt->second;
m_KeyBindings[keyCode] = std::make_tuple(command, value);
return true;
}
bool BindOrigin(std::string origin, std::string command, float value) override;
virtual float GetCommandValue(std::string command) override;
private:
std::unordered_map<std::string, int> m_OriginKeyCodes;
std::unordered_map<int, std::tuple<std::string, float>> m_KeyBindings; // GLFW_KEY... -> command string & value
std::unordered_map<std::string, float> m_CommandValues;
EventRelay<InputHandler, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown& e)
{
auto it = m_KeyBindings.find(e.KeyCode);
if (it == m_KeyBindings.end()) {
return false;
}
Events::InputCommand ic;
ic.PlayerID = 0;
std::tie(ic.Command, ic.Value) = it->second;
m_InputProxy->Publish(ic);
return true;
}
bool OnKeyDown(const Events::KeyDown& e);
EventRelay<InputHandler, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp& e)
{
auto it = m_KeyBindings.find(e.KeyCode);
if (it == m_KeyBindings.end()) {
return false;
}
bool OnKeyUp(const Events::KeyUp& e);
};
Events::InputCommand ic;
ic.PlayerID = 0;
std::tie(ic.Command, std::ignore) = it->second;
ic.Value = 0;
m_InputProxy->Publish(ic);
return true;
}
};
#endif
+38
View File
@@ -0,0 +1,38 @@
#ifndef MouseInputHandler_h__
#define MouseInputHandler_h__
#include <GLFW/glfw3.h>
#include "InputHandler.h"
#include "Core/EMousePress.h"
#include "Core/EMouseRelease.h"
#include "Core/EMouseMove.h"
class MouseInputHandler : public InputHandler
{
public:
MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
bool BindOrigin(std::string origin, std::string command, float value) override;
virtual float GetCommandValue(std::string command) override;
private:
std::unordered_map<std::string, int> m_OriginCodes;
std::unordered_map<std::string, char> m_OriginAxes;
std::unordered_map<int, std::tuple<std::string, float>> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value
std::unordered_map<char, std::tuple<std::string, float>> m_Axes; // Axis -> command string & value
std::unordered_map<std::string, float> m_CommandValues;
std::unordered_map<std::string, float> m_ContinuousCommandValues;
EventRelay<InputHandler, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e);
EventRelay<InputHandler, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e);
EventRelay<InputHandler, Events::MouseMove> m_EMouseMove;
bool OnMouseMove(const Events::MouseMove& e);
bool hasOrigin(std::string origin);
};
#endif
@@ -1,98 +0,0 @@
#include <steam/steam_api.h>
#include "InputProxy.h"
class SteamControllerInputHandler : public InputHandler
{
public:
SteamControllerInputHandler(EventBroker* eventBroker, InputProxy* inputProxy)
: InputHandler(eventBroker, inputProxy)
{
SteamController()->Init();
}
~SteamControllerInputHandler()
{
SteamController()->Shutdown();
}
void Update(double dt) override
{
std::array<ControllerHandle_t, STEAM_CONTROLLER_MAX_COUNT> controllers;
int numControllers = SteamController()->GetConnectedControllers(controllers.data());
for (int i = 0; i < numControllers; i++) {
auto controllerHandle = controllers.at(i);
auto actionSetHandle = SteamController()->GetActionSetHandle("InGameControls");
//SteamController()->ShowBindingPanel(controllerHandle);
SteamController()->ActivateActionSet(controllerHandle, actionSetHandle);
for (auto& command : m_Commands) {
Events::InputCommand ic;
ic.PlayerID = i + 1;
ic.Command = command.first;
auto digitalActionHandle = m_DigitalActionHandles.at(ic.Command);
auto handle = SteamController()->GetDigitalActionHandle("DebugReload");
auto data = SteamController()->GetDigitalActionData(controllerHandle, handle);
LOG_DEBUG("Controller %i, active %i, value %i", i, data.bActive, data.bState);
if (data.bState) {
ic.Value = command.second;
} else {
ic.Value = 0.f;
}
//m_InputProxy->Publish(ic);
}
}
}
bool BindOrigin(std::string origin, std::string command, float value) override
{
if (origin != "SteamController") {
return false;
}
m_Commands[command] = value;
m_DigitalActionHandles[command] = SteamController()->GetDigitalActionHandle(command.c_str());
return true;
}
private:
std::map<std::string, float> m_Commands;
std::map<std::string, ControllerDigitalActionHandle_t> m_DigitalActionHandles;
//std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandKeyboardValues; // command string -> keyboard key value for command
std::unordered_map<int, std::tuple<std::string, float>> m_KeyBindings; // GLFW_KEY... -> command string & value
EventRelay<InputHandler, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown& e)
{
auto it = m_KeyBindings.find(e.KeyCode);
if (it == m_KeyBindings.end()) {
return false;
}
Events::InputCommand ic;
ic.PlayerID = 0;
std::tie(ic.Command, ic.Value) = it->second;
m_InputProxy->Publish(ic);
return true;
}
EventRelay<InputHandler, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp& e)
{
auto it = m_KeyBindings.find(e.KeyCode);
if (it == m_KeyBindings.end()) {
return false;
}
Events::InputCommand ic;
ic.PlayerID = 0;
std::tie(ic.Command, std::ignore) = it->second;
ic.Value = 0;
m_InputProxy->Publish(ic);
return true;
}
};
+73 -4
View File
@@ -1,14 +1,83 @@
#ifndef Client_h__
#define Client_h__
#include <boost\asio.hpp>
#include <string>
#include <ctime>
class Client
#include <glm/common.hpp>
#include <boost/asio.hpp>
#include "Network/Network.h"
#include "Network/MessageType.h"
#include "Network/PlayerDefinition.h"
#include "Network/SnapshotDefinitions.h"
#include "Core/World.h"
#include "Core/EventBroker.h"
#include "Core/ConfigFile.h"
#include "Input/EInputCommand.h"
class Client : public Network
{
Client();
~Client();
public:
Client(ConfigFile* config);
~Client();
void Start(World* world, EventBroker* eventBroker) override;
void Update() override;
private:
// Assio UDP logic
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
boost::asio::io_service m_IOService;
boost::asio::ip::udp::socket m_Socket;
// Sending message to server logic
int bytesRead = -1;
char readBuf[INPUTSIZE] = { 0 };
int snapshotInterval = 33;
std::clock_t previousSnapshotMessage = std::clock();
// Packet loss logic
unsigned int m_PacketID = 0;
unsigned int m_PreviousPacketID = 0;
unsigned int m_SendPacketID = 0;
// Game logic
World* m_World;
std::string m_PlayerName;
int m_PlayerID = -1;
// Network logic
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
SnapshotDefinitions m_NextSnapshot;
double m_DurationOfPingTime;
std::clock_t m_StartPingTime;
// Use to check if we should send disconnect message
// if game is turned of by closing window.
bool m_WasStarted = false;
// Private member functions
void readFromServer();
void sendSnapshotToServer();
int receive(char* data, size_t length);
void send(Packet& packet);
void connect();
void disconnect();
void ping();
void moveMessageHead(char*& data, size_t& length, size_t stepSize);
void parseMessageType(Packet& packet);
void parseEventMessage(Packet& packet);
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType);
void parseConnect(Packet& packet);
void parsePing();
void parseServerPing();
void parseSnapshot(Packet& packet);
void identifyPacketLoss();
bool isConnected();
EntityID createPlayer();
// Events
EventBroker* m_EventBroker;
EventRelay<Client, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand &e);
};
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef MessageType_h__
#define MessageType_h__
// Message types used by both server and client.
// Used to determine what type of message was sent.
enum class MessageType
{
Connect,
Disconnect,
ClientPing,
ServerPing,
Message,
Snapshot,
Event,
};
#endif
+19
View File
@@ -0,0 +1,19 @@
#ifndef Network_h__
#define Network_h__
#include "Core/World.h"
#include "Core/EventBroker.h"
#include "Network/Packet.h"
#define MAXCONNECTIONS 8
#define INPUTSIZE 4097
class Network
{
public:
virtual ~Network() { };
virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
virtual void Update() = 0;
};
#endif
+66
View File
@@ -0,0 +1,66 @@
#ifndef Packet_h__
#define Packet_h__
#include <string>
#include "Network/MessageType.h"
#include "Core/Util/Logging.h"
// Defines the
class Packet
{
public:
// arg1: Type of message (Connect, Disconnect...)
// arg2: PacketID for identifying packet loss.
Packet(MessageType type, unsigned int& packetID);
// Used to create packet from already existing data buffer.
Packet(char* data, const int sizeOfPacket);
~Packet();
void Init(MessageType type, unsigned int& packetID);
// Add primitive types like int, float, char...
template<typename T>
void WritePrimitive(T val)
{
// Check if we are trying to add more than the package can fit.
if (m_MaxPacketSize < m_Offset + sizeof(T)) {
LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for! New size is %i bytes\n", m_MaxPacketSize*2);
resizeData();
}
memcpy(m_Data + m_Offset, &val, sizeof(T));
m_Offset += sizeof(T);
}
// Pops the first element as if it was a primitive.
template<typename T>
T ReadPrimitive()
{
if (m_Offset < m_ReturnDataOffset + sizeof(T)) {
LOG_WARNING("Packet PopFrontPrimitive(): You are trying to remove more than what exists in this packet!");
return -1;
}
T returnValue;
memcpy(&returnValue, m_Data + m_ReturnDataOffset, sizeof(T));
m_ReturnDataOffset += sizeof(T);
return returnValue;
}
// Add a string to the message
void WriteString(const std::string& str);
// Add data to the message
void WriteData(char* data, int sizeOfData);
// Pops the first element as if it was a string.
std::string ReadString();
char* ReadData(int SizeOfData);
int Size() { return m_Offset; };
char* Data() { return m_Data; };
unsigned int DataReadSize() { return m_ReturnDataOffset; }
unsigned int MaxSize() { return m_MaxPacketSize; }
private:
char* m_Data;
unsigned int m_ReturnDataOffset = 0;
int m_Offset = 0;
unsigned int m_MaxPacketSize = 512;
void resizeData();
};
#endif
+11
View File
@@ -0,0 +1,11 @@
#ifndef PlayerDefinition_h__
#define PlayerDefinition_h__
#include <string>
struct PlayerDefinition {
int EntityID = -1;
std::string Name = "";
boost::asio::ip::udp::endpoint Endpoint;
};
#endif
+72 -4
View File
@@ -1,12 +1,80 @@
#ifndef Server_h__
#define Server_h__
#include <boost\asio.hpp>
#include <string>
#include <ctime>
class Server
#include <glm/common.hpp>
#include <boost/asio/ip/udp.hpp>
#include "Network/MessageType.h"
#include "Network/PlayerDefinition.h"
#include "Core/World.h"
#include "Core/EventBroker.h"
#include "Network/Network.h"
class Server : public Network
{
Server();
~Server();
public:
Server();
~Server();
void Start(World* m_world, EventBroker *eventBroker) override;
void Update() override;
private:
// UDP logic
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
boost::asio::io_service m_IOService;
boost::asio::ip::udp::socket m_Socket;
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
// Sending messages to client logic
char readBuffer[INPUTSIZE] = { 0 };
int bytesRead = 0;
// time for previouse message
std::clock_t previousePingMessage = std::clock();
std::clock_t previousSnapshotMessage = std::clock();
std::clock_t timOutTimer = std::clock();
// How often we send messages (milliseconds)
int intervalMs = 1000;
int snapshotInterval = 50;
int checkTimeOutInterval = 100;
//Timers
std::clock_t m_StartPingTime;
std::clock_t m_StopTimes[8];
// Game logic
World* m_World;
EventBroker* m_EventBroker;
// vec.size() = ammount of players to create, stores playerID's
std::vector<unsigned int> m_PlayersToCreate;
// Packet loss logic
unsigned int m_PacketID;
unsigned int m_PreviousPacketID;
unsigned int m_SendPacketID;
// Private member functions
int receive(char* data, size_t length);
void readFromClients();
void send(Packet& packet, int playerID);
void send(Packet& packet);
void moveMessageHead(char*& data, size_t& length, size_t stepSize);
void broadcast(std::string message);
void broadcast(Packet& packet);
void sendSnapshot();
void sendPing();
void checkForTimeOuts();
void disconnect(int i);
void parseMessageType(Packet& packet);
void parseEvent(Packet& packet);
void parseConnect(Packet& packet);
void parseDisconnect();
void parseClientPing();
void parseServerPing();
void parseSnapshot(Packet& packet);
void identifyPacketLoss();
EntityID createPlayer();
};
#endif
@@ -0,0 +1,12 @@
#ifndef SnapshotDefinitions_h__
#define SnapshotDefinitions_h__
struct SnapshotDefinitions
{
// "+Forward" is 8 characters * sizeof(char) = 8
std::string InputForward;
// "+Right" is 6 characters * sizeof(char) = 6
std::string InputRight;
};
#endif
+1 -1
View File
@@ -3,7 +3,7 @@
#include "../Core/ResourceManager.h"
class BaseTexture : public Resource
class BaseTexture : public ThreadUnsafeResource
{
friend class ResourceManager;
+6 -8
View File
@@ -26,13 +26,12 @@ public:
glm::quat Orientation() const { return m_Orientation; }
void SetOrientation(glm::quat val);
/*float Pitch() const { return m_Pitch; }
void Pitch(float val);
float Yaw() const { return m_Yaw; }
void Yaw(float val);*/
glm::mat4 ProjectionMatrix() const { return m_ProjectionMatrix; }
void SetProjectionMatrix(glm::mat4 val);
glm::mat4 ViewMatrix() const { return m_ViewMatrix; }
void SetViewMatrix(glm::mat4 val);
float AspectRatio() const { return m_AspectRatio; }
void SetAspectRatio(float val);
@@ -46,11 +45,10 @@ public:
float FarClip() const { return m_FarClip; }
void SetFarClip(float val);
void UpdateViewMatrix();
void UpdateProjectionMatrix();
private:
void UpdateViewMatrix();
void UpdateProjectionMatrix();
glm::vec3 m_Position;
glm::quat m_Orientation;
@@ -0,0 +1,66 @@
#include <imgui/imgui.h>
#include "../Input/FirstPersonInputController.h"
template <typename EventContext>
class DebugCameraInputController : public FirstPersonInputController<EventContext>
{
public:
DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID)
: FirstPersonInputController(eventBroker, playerID)
{ }
void SetPosition(const glm::vec3 position) { m_Position = position; }
void SetOrientation(const glm::quat orientation) { m_Orientation = orientation; }
const glm::vec3 Position() const { return m_Position; }
void SetBaseSpeed(float speed) { m_BaseSpeed = speed; }
virtual bool OnCommand(const Events::InputCommand& e) override
{
ImGuiIO& io = ImGui::GetIO();
if (e.Command == "PrimaryFire") {
if (e.Value > 0) {
if (!io.WantCaptureMouse) {
LockMouse();
}
} else {
UnlockMouse();
}
return false;
}
if (!io.WantCaptureKeyboard) {
if (e.Command == "Right") {
float value = std::max(-1.f, std::min(e.Value, 1.f));
m_Velocity.x = value;
}
if (e.Command == "Forward") {
float value = std::max(-1.f, std::min(e.Value, 1.f));
m_Velocity.z = -value;
}
if (e.Command == "Sprint") {
if (e.Value > 0.f) {
m_Speed = m_BaseSpeed * 2.f * (e.Value);
} else {
m_Speed = m_BaseSpeed;
}
}
}
return FirstPersonInputController::OnCommand(e);
}
void Update(double dt)
{
if (glm::length2(m_Velocity) > 0) {
m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt);
}
}
protected:
glm::vec3 m_Position = glm::vec3(0, 0, 0);
glm::vec3 m_Velocity = glm::vec3(0, 0, 0);
float m_BaseSpeed = 2.0f;
float m_Speed = m_BaseSpeed;
};
+38
View File
@@ -0,0 +1,38 @@
#ifndef DrawFinalPass_h__
#define DrawFinalPass_h__
#include "IRenderer.h"
#include "DrawFinalPassState.h"
#include "LightCullingPass.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class DrawFinalPass
{
public:
DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass);
~DrawFinalPass() { }
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(RenderScene& scene);
//Getters
private:
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
Texture* m_WhiteTexture;
const IRenderer* m_Renderer;
const LightCullingPass* m_LightCullingPass;
ShaderProgram* m_ForwardPlusProgram;
};
#endif
@@ -0,0 +1,15 @@
#ifndef DrawFinalPassState_h__
#define DrawFinalPassState_h__
#include "Rendering/RenderState.h"
class DrawFinalPassState : public RenderState
{
public:
DrawFinalPassState();
~DrawFinalPassState();
private:
};
#endif
+42
View File
@@ -0,0 +1,42 @@
#ifndef DrawScenePass_h__
#define DrawScenePass_h__
#include "IRenderer.h"
#include "DrawScenePassState.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class DrawScenePass
{
public:
DrawScenePass(IRenderer* renderer);
~DrawScenePass() { }
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(RenderScene& scene);
//Getters
private:
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
static bool DepthSort(const std::shared_ptr<RenderJob> &i, const std::shared_ptr<RenderJob> &j)
{
return (i->Depth < j->Depth);
};
Texture* m_WhiteTexture;
const IRenderer* m_Renderer;
ShaderProgram* m_BasicForwardProgram;
};
#endif
@@ -0,0 +1,15 @@
#ifndef DrawScenePassState_h__
#define DrawScenePassState_h__
#include "Rendering/RenderState.h"
class DrawScenePassState : public RenderState
{
public:
DrawScenePassState();
~DrawScenePassState();
private:
};
#endif
+1 -1
View File
@@ -9,7 +9,7 @@ class DummyRenderer : public IRenderer
{
public:
virtual void Initialize() override;
virtual void Draw(RenderQueueCollection& rq) override;
virtual void Draw(RenderFrame& rq) override;
};
#endif
-69
View File
@@ -1,69 +0,0 @@
#ifndef Events_Picking_h__
#define Events_Picking_h__
#include "../OpenGL.h"
#include "../GLM.h"
#include "../Core/EventBroker.h"
#include "Util/ScreenCoords.h"
#include "FrameBuffer.h"
#include "../Core/Entity.h"
#include "Util/UnorderedMapVec2.h"
namespace Events
{
/** Thrown Every frame, use functions to pick*/
struct Picking : Event
{
public:
Picking(FrameBuffer* pickingBuffer, GLuint* depthBuffer, glm::mat4 projectionMatrix, glm::mat4 viewMatrix, Rectangle resolution, const std::unordered_map<glm::vec2, EntityID>* pickingColorsToEntity)
: PickingBuffer(pickingBuffer)
, DepthBuffer(depthBuffer)
, ProjectionMatrix(projectionMatrix)
, ViewMatrix(viewMatrix)
, Resolution(resolution)
, PickingColorsToEntity(pickingColorsToEntity)
{ }
struct PickData
{
//Picked Entity
EntityID Entity;
//World position of the "pick"
glm::vec3 Position;
};
PickData Pick(glm::vec2 screenCoord) const
{
PickData pickData;
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer);
auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1]));
if (it != PickingColorsToEntity->end()) {
pickData.Entity = it->second;
} else {
pickData.Entity = -1;
}
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, Resolution.Width - screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);
return pickData;
}
private:
FrameBuffer* PickingBuffer;
GLuint* DepthBuffer;
const glm::mat4 ProjectionMatrix;
const glm::mat4 ViewMatrix;
const Rectangle Resolution;
const std::unordered_map<glm::vec2, EntityID>* PickingColorsToEntity;
};
}
#endif
+23
View File
@@ -0,0 +1,23 @@
#ifndef Events_SetCamera_h__
#define Events_SetCamera_h__
#include "../Core/EventBroker.h"
#include "../Core/Entity.h"
#include <string.h>
namespace Events
{
struct SetCamera : Event
{
public:
SetCamera() { };
std::string Name;
private:
};
}
#endif
+27 -14
View File
@@ -9,6 +9,17 @@
#include "Camera.h"
#include "RenderQueue.h"
#include "Model.h"
#include "../Core/World.h" //So temp
struct PickData
{
EntityID Entity;
glm::vec3 Position; //World position
float Depth;
::Camera* Camera;
const ::World* World;
};
class IRenderer
{
@@ -20,29 +31,31 @@ public:
void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; }
bool VSYNC() const { return m_VSYNC; }
void SetVSYNC(bool vsync) { m_VSYNC = vsync; }
::Camera* Camera() const { return m_Camera; }
void SetCamera(::Camera* camera)
{
if (camera == nullptr) {
m_Camera = m_DefaultCamera;
} else {
m_Camera = camera;
}
}
::Camera* Camera() const { return m_Camera; }
void SetCamera(::Camera* camera)
{
if (camera == nullptr) {
m_Camera = m_DefaultCamera;
} else {
m_Camera = camera;
}
}
virtual void Initialize() = 0;
virtual void Update(double dt) = 0;
virtual void Draw(RenderQueueCollection& rq) = 0;
virtual void Draw(RenderFrame& rq) = 0;
virtual PickData Pick(glm::vec2 screenCord) = 0;
World* m_World; //Temp world, untill viktor merge.
protected:
Rectangle m_Resolution = Rectangle(1280, 720);
Rectangle m_Resolution = Rectangle::Rectangle(1280, 720);
bool m_Fullscreen = false;
bool m_VSYNC = false;
int m_GLVersion[2];
std::string m_GLVendor;
::Camera* m_DefaultCamera;
::Camera* m_Camera = nullptr;
GLFWwindow* m_Window = nullptr;
::Camera* m_DefaultCamera;
::Camera* m_Camera = nullptr;
};
#endif // Renderer_h__
@@ -0,0 +1,77 @@
#include <imgui/imgui.h>
#include "../OpenGL.h"
#include "IRenderer.h"
#include "RenderState.h"
#include "../Core/EventBroker.h"
#include "../Core/EMousePress.h"
#include "../Core/EMouseRelease.h"
#include "../Core/EMouseMove.h"
#include "../Core/EMouseScroll.h"
#include "../Core/EKeyDown.h"
#include "../Core/EKeyUp.h"
#include "../Core/EKeyboardChar.h"
class ImGuiRenderState : public RenderState
{
public:
ImGuiRenderState()
: RenderState()
{
BindFramebuffer(0);
Enable(GL_BLEND);
BlendEquation(GL_FUNC_ADD);
BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Disable(GL_CULL_FACE);
Disable(GL_DEPTH_TEST);
Enable(GL_SCISSOR_TEST);
}
};
class ImGuiRenderPass
{
public:
ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker);
void Update(double dt);
void Draw();
private:
IRenderer* m_Renderer;
EventBroker* m_EventBroker;
GLFWwindow* g_Window;
double g_DeltaTime = 0.0;
float g_MouseWheel = 0.f;
GLuint g_FontTexture;
int g_ShaderHandle;
int g_VertHandle;
int g_FragHandle;
int g_AttribLocationTex;
int g_AttribLocationProjMtx;
int g_AttribLocationPosition;
int g_AttribLocationUV;
int g_AttribLocationColor;
GLuint g_VboHandle;
GLuint g_VaoHandle;
GLuint g_ElementsHandle;
EventRelay<ImGuiRenderPass, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e);
EventRelay<ImGuiRenderPass, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e);
EventRelay<ImGuiRenderPass, Events::MouseMove> m_EMouseMove;
bool OnMouseMove(const Events::MouseMove& e);
EventRelay<ImGuiRenderPass, Events::MouseScroll> m_EMouseScroll;
bool OnMouseScroll(const Events::MouseScroll& e);
EventRelay<ImGuiRenderPass, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown& e);
EventRelay<ImGuiRenderPass, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp& e);
EventRelay<ImGuiRenderPass, Events::KeyboardChar> m_EKeyboardChar;
bool OnKeyboardChar(const Events::KeyboardChar& e);
bool createDeviceObjects();
bool createFontsTexture();
void newFrame();
};
@@ -0,0 +1,83 @@
#ifndef LightCullingPass_h__
#define LightCullingPass_h__
#define TILE_SIZE 16
#define MAX_LIGHTS_PER_TILE 200
#include "IRenderer.h"
#include "LightCullingPassState.h"
#include "ShaderProgram.h"
#include "RenderQueue.h"
class LightCullingPass
{
public:
LightCullingPass(IRenderer* renderer);
~LightCullingPass();
void GenerateNewFrustum(RenderScene& scene);
void OnResolutionChange();
void SetSSBOSizes();
void CullLights(RenderScene& scene);
void FillLightList(RenderScene& scene);
GLuint FrustumSSBO() const { return m_FrustumSSBO; }
GLuint LightSSBO() const { return m_LightSSBO; }
GLuint LightGridSSBO() const { return m_LightGridSSBO; }
GLuint LightOffsetSSBO() const { return m_LightOffsetSSBO; }
GLuint LightIndexSSBO() const { return m_LightIndexSSBO; }
private:
void InitializeSSBOs();
void InitializeShaderPrograms();
const IRenderer* m_Renderer;
GLuint m_FrustumSSBO = 0;
GLuint m_LightSSBO = 0;
GLuint m_LightGridSSBO = 0;
GLuint m_LightOffsetSSBO = 0;
GLuint m_LightIndexSSBO = 0;
ShaderProgram* m_CalculateFrustumProgram;
ShaderProgram* m_LightCullProgram;
int m_NumberOfTiles = 0;
struct Plane {
glm::vec3 Normal;
float d;
};
struct Frustum {
Plane Planes[4];
};
Frustum* m_Frustums;
//This should be a component
struct PointLight {
glm::vec4 Position = glm::vec4(0.f);
glm::vec4 Color = glm::vec4(1.f);
float Radius = 5.f;
float Intensity = 0.8f;
float Falloff = 0.3f;
float Padding = 1337;
};
std::vector<PointLight> m_PointLights;
struct LightGrid {
float Start;
float Amount;
glm::vec2 Padding;
};
LightGrid* m_LightGrid;
int m_LightOffset = 0;
float* m_LightIndex;
};
#endif
+5 -1
View File
@@ -4,7 +4,7 @@
#include "RawModel.h"
#include "../OpenGL.h"
class Model : public RawModel
class Model : public ThreadUnsafeResource
{
friend class ResourceManager;
@@ -13,11 +13,15 @@ private:
public:
~Model();
const std::vector<RawModel::MaterialGroup>& MaterialGroups() const { return m_RawModel->MaterialGroups; }
const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; }
const std::vector<RawModel::Vertex>& Vertices() const { return m_RawModel->m_Vertices; }
GLuint VAO;
GLuint ElementBuffer;
private:
RawModel* m_RawModel;
GLuint VertexBuffer;
GLuint DiffuseVertexColorBuffer;
GLuint SpecularVertexColorBuffer;
+55
View File
@@ -0,0 +1,55 @@
#ifndef ModelJob_h__
#define ModelJob_h__
#include <cstdint>
#include "../Common.h"
#include "../GLM.h"
#include "../Core/ComponentWrapper.h"
#include "Texture.h"
#include "Model.h"
#include "RenderJob.h"
#include "../Core/ResourceManager.h"
#include "Camera.h"
#include "../Core/World.h"
struct ModelJob : RenderJob
{
ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, World* world)
: RenderJob()
{
Model = model;
TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0;
DiffuseTexture = matGroup.Texture.get();
NormalTexture = matGroup.NormalMap.get();
SpecularTexture = matGroup.SpecularMap.get();
StartIndex = matGroup.StartIndex;
EndIndex = matGroup.EndIndex;
Matrix = matrix;
Color = modelComponent["Color"];
Entity = modelComponent.EntityID;
World = world;
};
unsigned int TextureID;
unsigned int ShaderID;
EntityID Entity;
glm::mat4 Matrix;
const Texture* DiffuseTexture;
const Texture* NormalTexture;
const Texture* SpecularTexture;
float Shininess = 0.f;
glm::vec4 Color;
const ::Model* Model = nullptr;
unsigned int StartIndex = 0;
unsigned int EndIndex = 0;
World* World;
void CalculateHash() override
{
Hash = TextureID;
}
};
#endif
+66
View File
@@ -0,0 +1,66 @@
#ifndef PickingPass_h__
#define PickingPass_h__
#include "IRenderer.h"
#include "PickingPassState.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Util/UnorderedMapiVec2.h"
#include "../Core/EventBroker.h"
#include "../Core/World.h"
class PickingPass
{
public:
PickingPass(IRenderer* renderer, EventBroker* eb);
~PickingPass();
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(RenderScene& scene);
void ClearPicking();
//Getters
const ShaderProgram& PickingProgram() const { return *m_PickingProgram; }
//const std::unordered_map<glm::ivec2, EntityID>& PickingColorsToEntity() const { return m_PickingColorsToEntity; }
GLuint PickingTexture() const { return m_PickingTexture; }
GLuint DepthBuffer() const { return m_DepthBuffer; }
const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; }
PickData Pick(glm::vec2 screenCoord);
private:
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
EventBroker* m_EventBroker;
const IRenderer* m_Renderer;
ShaderProgram* m_PickingProgram;
Camera* m_Camera;
struct PickingInfo
{
EntityID Entity;
const ::World* World;
::Camera* Camera;
};
std::unordered_map<glm::ivec2, PickingInfo> m_PickingColorsToEntity;
GLuint m_PickingTexture;
GLuint m_DepthBuffer;
FrameBuffer m_PickingBuffer;
int m_ColorCounter[2];
std::map<std::tuple<EntityID, const World*, Camera*>, glm::ivec2> m_EntityColors;
};
#endif
@@ -0,0 +1,15 @@
#ifndef PickingPassState_h__
#define PickingPassState_h__
#include "Rendering/RenderState.h"
class PickingPassState : public RenderState
{
public:
PickingPassState(GLuint frameBuffer);
~PickingPassState();
private:
};
#endif
+39
View File
@@ -0,0 +1,39 @@
#ifndef PointLightJob_h__
#define PointLightJob_h__
#include <cstdint>
#include "../Common.h"
#include "../GLM.h"
#include "../Core/ComponentWrapper.h"
#include "RenderJob.h"
#include "../Core/Transform.h"
#include "../Core/World.h"
struct PointLightJob : RenderJob
{
PointLightJob(ComponentWrapper transformComponent, ComponentWrapper pointLightComponent, World* m_World)
: RenderJob()
{
Position = glm::vec4((glm::vec3)transformComponent["Position"], 1.0f);
Position = glm::vec4(Transform::AbsolutePosition(m_World, transformComponent.EntityID), 1.f);
Color = (glm::vec4)pointLightComponent["Color"];
Radius = (double)pointLightComponent["Radius"];
Intensity = (double)pointLightComponent["Intensity"];
Falloff = (double)pointLightComponent["Falloff"];
};
glm::vec4 Position;
glm::vec4 Color;
float Radius;
float Intensity;
float Falloff;
float padding = 123;
void CalculateHash() override
{
Hash = 0;
}
};
#endif
+5 -1
View File
@@ -46,14 +46,18 @@ public:
struct MaterialGroup
{
float Shininess;
float Transparency;
std::string TexturePath;
std::shared_ptr<::Texture> Texture;
std::string NormalMapPath;
std::shared_ptr<::Texture> NormalMap;
std::string SpecularMapPath;
std::shared_ptr<::Texture> SpecularMap;
unsigned int StartIndex;
unsigned int EndIndex;
};
std::vector<MaterialGroup> TextureGroups;
std::vector<MaterialGroup> MaterialGroups;
std::vector<Vertex> m_Vertices;
std::vector<unsigned int> m_Indices;
+32
View File
@@ -0,0 +1,32 @@
#ifndef RenderJob_h__
#define RenderJob_h__
#include <cstdint>
#include "../Common.h"
#include "../GLM.h"
#include "../Core/ComponentWrapper.h"
#include "RenderQueue.h"
struct RenderJob
{
friend class RenderQueue;
public:
float Depth;
protected:
uint64_t Hash;
virtual void CalculateHash() = 0;
bool operator<(const RenderJob& rhs)
{
return this->Hash < rhs.Hash;
}
};
#endif
+47 -103
View File
@@ -8,61 +8,13 @@
#include "../GLM.h"
#include "../Core/Util/Rectangle.h"
#include "../Core/Entity.h"
#include "Camera.h"
#include "RenderJob.h"
#include "ModelJob.h"
#include "PointLightJob.h"
class Model;
class Skeleton;
class Texture;
class RenderQueue;
//TODO: Render: Remove obsolete RenderJobs and fix standard values on variables.
struct RenderJob
{
friend class RenderQueue;
float Depth;
protected:
uint64_t Hash;
virtual void CalculateHash() = 0;
bool operator<(const RenderJob& rhs)
{
return this->Hash < rhs.Hash;
}
};
struct ModelJob : RenderJob
{
unsigned int ShaderID = 0;
unsigned int TextureID = 0;
//TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this
EntityID Entity;
glm::mat4 ModelMatrix;
const Texture* DiffuseTexture;
const Texture* NormalTexture;
const Texture* SpecularTexture;
float Shininess = 0.f;
glm::vec4 Color;
const Model* Model = nullptr;
unsigned int StartIndex = 0;
unsigned int EndIndex = 0;
// Animation
Skeleton* Skeleton = nullptr;
bool NoRootMotion = true;
std::string AnimationName;
double AnimationTime = 0;
void CalculateHash() override
{
Hash = TextureID;
}
};
/*
struct SpriteJob : RenderJob
{
unsigned int ShaderID = 0;
@@ -82,73 +34,65 @@ struct SpriteJob : RenderJob
struct PointLightJob : RenderJob
{
glm::vec3 Position;
glm::vec3 SpecularColor = glm::vec3(1, 1, 1);
glm::vec3 DiffuseColor = glm::vec3(1, 1, 1);
float Radius = 1.f;
float Intensity = 0.8f;
glm::vec4 Position;
glm::vec4 Color;
float Radius;
float Intensity;
float Falloff;
float padding = 123;
void CalculateHash() override
{
Hash = 0;
}
};
*/
class RenderQueue
struct RenderScene
{
public:
template <typename T>
void Add(T &job)
{
job.CalculateHash();
Jobs.push_back(std::shared_ptr<T>(new T(job)));
m_Size++;
}
void Sort()
{
Jobs.sort();
}
::Camera* Camera;
std::list<std::shared_ptr<RenderJob>> ForwardJobs;
std::list<std::shared_ptr<RenderJob>> PointLightJobs;
Rectangle Viewport;
void Clear()
{
Jobs.clear();
m_Size = 0;
ForwardJobs.clear();
PointLightJobs.clear();
}
int Size() const { return m_Size; }
std::list<std::shared_ptr<RenderJob>>::const_iterator begin()
{
return Jobs.begin();
}
std::list<std::shared_ptr<RenderJob>>::const_iterator end()
{
return Jobs.end();
}
std::list<std::shared_ptr<RenderJob>> Jobs;
private:
int m_Size = 0;
};
struct RenderQueueCollection
struct RenderFrame
{
RenderQueue Forward;
RenderQueue Lights;
public:
void Clear()
{
Forward.Clear();
Lights.Clear();
}
void Add(RenderScene &scene)
{
RenderScenes.push_back(std::shared_ptr<RenderScene>(new RenderScene(scene)));
m_Size++;
}
void Sort()
{
Forward.Sort();
Lights.Sort();
}
void Clear()
{
RenderScenes.clear();
m_Size = 0;
}
int Size() const { return m_Size; }
std::list<std::shared_ptr<RenderScene>>::const_iterator begin()
{
return RenderScenes.begin();
}
std::list<std::shared_ptr<RenderScene>>::const_iterator end()
{
return RenderScenes.end();
}
std::list<std::shared_ptr<RenderScene>> RenderScenes;
private:
int m_Size = 0;
};
#endif
@@ -1,31 +0,0 @@
#ifndef RenderQueueFactory_h__
#define RenderQueueFactory_h__
#include "../Core/World.h"
#include "RenderQueue.h"
#include "../Core/ResourceManager.h"
#include "Model.h"
#include "../GLM.h"
class RenderQueueFactory
{
public:
RenderQueueFactory();
void Update(World* world);
RenderQueueCollection RenderQueues() const { return m_RenderQueues; }
private:
RenderQueueCollection m_RenderQueues;
void FillModels(World* world, RenderQueue* renderQueue);
void FillLights(World* world, RenderQueue* renderQueue);
glm::mat4 ModelMatrix(World* world, EntityID entity);
glm::vec3 AbsolutePosition(World* world, EntityID entity);
glm::quat AbsoluteOrientation(World* world, EntityID entity);
glm::vec3 AbsoluteScale(World* world, EntityID entity);
};
#endif
+27
View File
@@ -0,0 +1,27 @@
#ifndef RenderState_h__
#define RenderState_h__
#include <functional>
#include "../Common.h"
#include "../OpenGL.h"
#include "../GLM.h"
class RenderState
{
public:
RenderState() = default;
~RenderState();
bool Enable(GLenum cap);
bool Disable(GLenum cap);
bool CullFace(GLenum mode);
bool ClearColor(glm::vec4 color);
bool Clear(GLbitfield mask);
bool BindFramebuffer(GLint framebuffer);
bool BlendEquation(GLenum mode);
bool BlendFunc(GLenum sfactor, GLenum dfactor);
private:
std::vector<std::function<void(void)>> m_ResetFunctions;
};
#endif
+55
View File
@@ -0,0 +1,55 @@
#ifndef RenderSystem_h__
#define RenderSystem_h__
#include "../Core/System.h"
#include "RenderQueue.h"
#include "../GLM.h"
#include "../OpenGL.h"
#include "../Core/ResourceManager.h"
#include "ESetCamera.h"
#include "Model.h"
#include "../Core/EKeyDown.h"
#include "../Input/EInputCommand.h"
#include "Camera.h"
#include "ModelJob.h"
#include "Renderer.h"
#include "PointLightJob.h"
#include "../Core/Transform.h"
#include "DebugCameraInputController.h"
class RenderSystem : public ImpureSystem
{
public:
RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame);
~RenderSystem();
virtual void Update(World* world, double dt) override;
private:
World* m_World = nullptr;
const IRenderer* m_Renderer;
RenderFrame* m_RenderFrame;
bool m_SwitchCamera = false;
Camera* m_Camera;
DebugCameraInputController<RenderSystem>* m_DebugCameraInputController;
std::list<ComponentWrapper> m_CameraComponents;
EventRelay<RenderSystem, Events::SetCamera> m_ESetCamera;
bool OnSetCamera(const Events::SetCamera &event);
EntityID m_CurrentCamera = EntityID_Invalid;
void switchCamera(EntityID entity);
void updateCamera(World* world, double dt);
void updateProjectionMatrix(ComponentWrapper& cameraComponent);
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
};
#endif
+33 -25
View File
@@ -10,55 +10,63 @@
#include "Util/UnorderedMapVec2.h"
#include "FrameBuffer.h"
#include "../Core/World.h"
#include "PickingPass.h"
#include "DrawScenePass.h"
#include "LightCullingPass.h"
#include "DrawFinalPass.h"
#include "../Core/EventBroker.h"
#include "EPicking.h"
#include "ImGuiRenderPass.h"
#include "Camera.h"
#include "../Core/Transform.h"
class Renderer : public IRenderer
{
public:
Renderer(EventBroker* eventBroker)
Renderer(EventBroker* eventBroker, World* world)
: m_EventBroker(eventBroker)
, m_World(world)
{ }
virtual void Initialize() override;
virtual void Update(double dt) override;
virtual void Draw(RenderQueueCollection& rq) override;
virtual void Initialize() override;
virtual void Update(double dt) override;
virtual void Draw(RenderFrame& frame) override;
virtual PickData Pick(glm::vec2 screenCoord) override;
private:
//----------------------Variables----------------------//
//----------------------Variables----------------------//
EventBroker* m_EventBroker;
World* m_World;
Texture* m_ErrorTexture;
Texture* m_WhiteTexture;
float m_CameraMoveSpeed;
FrameBuffer m_PickingBuffer;
GLuint m_PickingTexture;
GLuint m_DepthBuffer;
Texture* m_ErrorTexture;
Texture* m_WhiteTexture;
Model* m_ScreenQuad;
Model* m_UnitQuad;
Model* m_UnitSphere;
std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity;
DrawScenePass* m_DrawScenePass;
PickingPass* m_PickingPass;
LightCullingPass* m_LightCullingPass;
ImGuiRenderPass* m_ImGuiRenderPass;
DrawFinalPass* m_DrawFinalPass;
//----------------------Functions----------------------//
void InitializeWindow();
void InitializeShaders();
//----------------------Functions----------------------//
void InitializeWindow();
void InitializeShaders();
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeRenderPasses();
//TODO: Renderer: Get InputUpdate out of renderer
void InputUpdate(double dt);
void PickingPass(RenderQueueCollection& rq);
void InputUpdate(double dt);
//void PickingPass(RenderQueueCollection& rq);
void DrawScreenQuad(GLuint textureToDraw);
void DrawScene(RenderQueueCollection& rq);
static bool DepthSort(const std::shared_ptr<RenderJob> &i, const std::shared_ptr<RenderJob> &j) { return (i->Depth < j->Depth); }
void FillDepth(RenderScene& scene);
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
//--------------------ShaderPrograms-------------------//
ShaderProgram m_BasicForwardProgram;
ShaderProgram m_PickingProgram;
ShaderProgram m_DrawScreenQuadProgram;
ShaderProgram* m_BasicForwardProgram;
ShaderProgram* m_DrawScreenQuadProgram;
};
#endif
+10 -3
View File
@@ -1,6 +1,9 @@
#ifndef ShaderProgram_h__
#define ShaderProgram_h__
#include "../Common.h"
#include "../OpenGL.h"
#include "../Core/ResourceManager.h"
#include <fstream>
class Shader
@@ -60,11 +63,13 @@ public:
: ShaderType(fileName) { }
};
class ShaderProgram
class ShaderProgram : public Resource
{
public:
ShaderProgram()
friend class ResourceManager;
private:
ShaderProgram(std::string)
: m_ShaderProgramHandle(0) { }
public:
~ShaderProgram();
void AddShader(std::shared_ptr<Shader> shader);
@@ -79,3 +84,5 @@ private:
GLuint m_ShaderProgramHandle;
std::vector<std::shared_ptr<Shader>> m_Shaders;
};
#endif
+1 -1
View File
@@ -9,7 +9,7 @@ inline bool _GLERROR(const char* info, const char* file, const char* func, unsig
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
_LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s %i %s", info, error, gluErrorString(error));
_LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s, %i, %s", info, error, gluErrorString(error));
return true;
}
@@ -0,0 +1,24 @@
#pragma once
#ifndef UnorderedMapiVec2_h__
#define UnorderedMapiVec2_h__
#include <functional>
#include <boost/functional/hash.hpp>
#include <glm/vec2.hpp>
template<>
struct std::hash<glm::ivec2>
{
inline std::size_t operator()(const glm::ivec2 &v) const
{
return boost::hash<float>()(v.x) ^ boost::hash<float>()(v.y);
}
inline bool operator()(const glm::ivec2& a, const glm::ivec2& b)const
{
return a.x == b.x && a.y == b.y;
}
};
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef Events_ContinueSound_h__
#define Events_ContinueSound_h__
#include "Core/EventBroker.h"
#include "Core/Entity.h"
namespace Events
{
// Continues to play a sound from where it was paused.
struct ContinueSound : Event
{
EntityID EmitterID;
};
}
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef Events_PauseSound_h__
#define Events_PauseSound_h__
#include "Core/EventBroker.h"
#include "Core/Entity.h"
namespace Events
{
// Pauses a playing sound
struct PauseSound : Event
{
EntityID EmitterID;
};
}
#endif
@@ -0,0 +1,18 @@
#ifndef Events_PlayBackgroundMusic_h__
#define Events_PlayBackgroundMusic_h__
#include <string>
#include "Core/Entity.h"
#include "Core/Event.h"
namespace Events
{
// Play a sound that will be heared the same anywhere
struct PlayBackgroundMusic : public Event
{
std::string FilePath = "";
};
}
#endif
+21
View File
@@ -0,0 +1,21 @@
#ifndef Events_PlaySoundOnEntity_h__
#define Events_PlaySoundOnEntity_h__
#include <string>
#include "Core/Entity.h"
#include "Core/Event.h"
namespace Events
{
// Plays a sound on an entity with a SoundEmitter component attached.
// Sound behavior is thereby specified in the SoundEmitter component.
struct PlaySoundOnEntity : public Event
{
EntityID EmitterID = 0;
std::string FilePath = "";
};
}
#endif
@@ -0,0 +1,26 @@
#ifndef Events_PlaySoundOnPosition_h__
#define Events_PlaySoundOnPosition_h__
#include <string>
#include <glm/common.hpp>
#include "Core/Event.h"
namespace Events
{
// Plays a sound on a given position. Idk if this would be useful.
struct PlaySoundOnPosition : public Event
{
glm::vec3 Position = glm::vec3(0);
std::string FilePath = "";
float Gain = 1;
float Pitch = 1;
bool Loop = false;
float MaxDistance = 20;
float RollOffFactor = 1;
float ReferenceDistance = 1;
};
}
#endif
+16
View File
@@ -0,0 +1,16 @@
#ifndef Events_SetBGMGain_h__
#define Events_SetBGMGain_h__
#include "Core/Event.h"
namespace Events
{
// Set the "volume" for all background sounds
struct SetBGMGain : public Event
{
float Gain;
};
}
#endif
+16
View File
@@ -0,0 +1,16 @@
#ifndef Events_SetSFXGain_h__
#define Events_SetSFXGain_h__
#include "Core/Event.h"
namespace Events
{
// Set the "volume" for all effect sounds
struct SetSFXGain : public Event
{
float Gain;
};
}
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef Events_StopSound_h__
#define Events_StopSound_h__
#include "Core/EventBroker.h"
#include "Core/Entity.h"
namespace Events
{
// Stops a sound emitter, and will also delete it.
struct StopSound : Event
{
EntityID EmitterID;
};
}
#endif

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