Compare commits
364 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f6528e0c7 | |||
| 0a3d3f5392 | |||
| c0b31dc92c | |||
| c5b4ea84a0 | |||
| b5605c839d | |||
| 84818f6fcb | |||
| 349fa9d7fa | |||
| 2a5e0420c8 | |||
| 4a516a4d86 | |||
| 21aea6f31d | |||
| 297a3fb493 | |||
| c47ef61ddc | |||
| e8e93587e9 | |||
| 39dd27726d | |||
| 6adc98eea5 | |||
| ad4e723677 | |||
| 11d547cde8 | |||
| 24b9e951c2 | |||
| 81024b4a1d | |||
| 23e78c4947 | |||
| 3e7f27e1fe | |||
| ee83394678 | |||
| 03456ad731 | |||
| 0bcbcda8b8 | |||
| c6655ce0d3 | |||
| b908a9f9c6 | |||
| dc7ed2e0ba | |||
| f71bfca142 | |||
| dbb44fb4e4 | |||
| 6e6460a000 | |||
| 9f871bbe7c | |||
| 2bd60be741 | |||
| dab4ba2164 | |||
| 25a99a04c5 | |||
| 13ade6d7f2 | |||
| 592776e783 | |||
| ff44dccb33 | |||
| ef9ce7932a | |||
| beb0967c3b | |||
| 0e0a361a38 | |||
| 6ebc4fc784 | |||
| 7fb71f17b2 | |||
| e52c0c9633 | |||
| 578ca13f79 | |||
| 4048ce6bd4 | |||
| c4642cc530 | |||
| 32ebc061b4 | |||
| a1ed79dfbf | |||
| 638c236ceb | |||
| f67f22c82d | |||
| f3ff433bf7 | |||
| 85ff86a2fe | |||
| fa8775a72e | |||
| 49884d7e60 | |||
| e7bb8954bf | |||
| e510f2b88c | |||
| 34cbbb3eb1 | |||
| 0ae6c42df8 | |||
| 3678cceb1c | |||
| de8461e257 | |||
| eb69e03e82 | |||
| d38f58165f | |||
| c133223bac | |||
| 2f6d4fcd0b | |||
| 069a6756b9 | |||
| a550b6077e | |||
| e0cc25dbac | |||
| 00bc55370d | |||
| 330f08b926 | |||
| a0255f1b31 | |||
| ef4cbfece8 | |||
| ab6af30a28 | |||
| a858dab8b6 | |||
| b1ae96f737 | |||
| 7dcd75fccc | |||
| 1e5e24a036 | |||
| 3636ad45af | |||
| 6d649e4d35 | |||
| 5c1a93021b | |||
| 6cf7c12d34 | |||
| ad43cc44c3 | |||
| 002e1d8c5a | |||
| 30db0b10fd | |||
| 97f8be1915 | |||
| 0eb51a0fea | |||
| 13f7fb2561 | |||
| 0b714e593f | |||
| 4a817613e3 | |||
| 8beddca89a | |||
| 5e0fe975f3 | |||
| db5b6ad519 | |||
| a26c8f2a24 | |||
| 076030a252 | |||
| 0f59b863ee | |||
| d0927373a3 | |||
| 46ae2d39af | |||
| e9128efd13 | |||
| 00f6056f7c | |||
| a655f0bae5 | |||
| cf6dde6c09 | |||
| c1b9404e52 | |||
| 8000654005 | |||
| 000adb198f | |||
| 51a2da9cc0 | |||
| 0f0a1ceca7 | |||
| 50822d09fc | |||
| 3e2ffdb85b | |||
| 5160a45b44 | |||
| 03d5f0dd67 | |||
| 4bb4e29515 | |||
| a6a08f48bb | |||
| ba831f8a3c | |||
| 1a9b765d47 | |||
| c8460e0a6c | |||
| 4c29e071af | |||
| b87f559291 | |||
| d4f5856304 | |||
| 6a3c14540d | |||
| 2cb5441b1c | |||
| 97a0d97b0b | |||
| a914a7f924 | |||
| dbbbb7b4e7 | |||
| a23d69af9a | |||
| 425f3ca3dd | |||
| 6d1cbd928e | |||
| 6da5fd1263 | |||
| 6eebce05af | |||
| 58a9d38e26 | |||
| 50ccf96268 | |||
| 5602b32507 | |||
| cf0ff9bfe5 | |||
| d10df6ae09 | |||
| 99b76d7ae1 | |||
| 661532e355 | |||
| bd6adcc157 | |||
| a2d55feed1 | |||
| e74b2b6874 | |||
| 322aedaf72 | |||
| 3f602c9d63 | |||
| 082b3fd3df | |||
| 04a01104b5 | |||
| 9b348a7d97 | |||
| 889e0bb3d3 | |||
| 1669649186 | |||
| 1431bd1a11 | |||
| ed82a0939a | |||
| e2417be8c7 | |||
| 472a8db81a | |||
| 1e370bac13 | |||
| e940c1d604 | |||
| 478c692315 | |||
| 170610bcb1 | |||
| 454ed0032b | |||
| 1910ab705b | |||
| 0a8a9e5099 | |||
| f9508657f5 | |||
| b698a0d36f | |||
| 1229a99af4 | |||
| 8e431c8edd | |||
| 51dd627ae3 | |||
| c296c4eb3b | |||
| 422e6f5264 | |||
| 9cee8b5478 | |||
| 522679b14c | |||
| 25683e8a8a | |||
| 948f6d5de7 | |||
| ae7d4b9097 | |||
| 7c714d1f98 | |||
| e6fa9df3a5 | |||
| 59095c2ce5 | |||
| 3f77da4a07 | |||
| 7f8e78c8cd | |||
| bac0a1de26 | |||
| bf82bbb5d5 | |||
| e52052b431 | |||
| 8d9ff2b6dc | |||
| 63db236dfa | |||
| cddd9026fb | |||
| ea239b19bd | |||
| f8d927cd91 | |||
| 798c73132e | |||
| fb2cd0c6ae | |||
| bc6a211276 | |||
| 7719274a37 | |||
| 797036c204 | |||
| 3a9577c9fb | |||
| 545869e342 | |||
| 07c4744436 | |||
| b8620eac26 | |||
| 7bc492134d | |||
| 7c1182c28f | |||
| 2f3843e595 | |||
| 5f3c234819 | |||
| 9a119f38bb | |||
| 524af211e0 | |||
| 91ace0d2a0 | |||
| 2018ba27ae | |||
| b66cf47ff0 | |||
| e5084e13ec | |||
| 8a6030bf57 | |||
| 2e321e15a5 | |||
| c81a054601 | |||
| af14d60493 | |||
| 0465fdb16d | |||
| 0c6ac1e060 | |||
| 7db1feac17 | |||
| 653b4689b5 | |||
| 6723e71fee | |||
| d16cbe84f0 | |||
| 95ce024bb6 | |||
| a7ed455766 | |||
| d182e6c453 | |||
| 5fce7490a9 | |||
| e76a6b74a3 | |||
| e82911cb8b | |||
| 8abef7024d | |||
| bf08ffe392 | |||
| 5f5cab1171 | |||
| 8d87841691 | |||
| 11e37ca898 | |||
| 30474b70df | |||
| 03e226ffea | |||
| 2e7e8d3546 | |||
| 013f911ae2 | |||
| 35624008e7 | |||
| 5d46a10a4e | |||
| 784a04b8ad | |||
| bffc97f310 | |||
| 7464facab9 | |||
| f14c62f3d3 | |||
| d406059c79 | |||
| 59b261534a | |||
| 45b87ed6b1 | |||
| 55aad493ff | |||
| 9a7d77f29d | |||
| 36ae451ea6 | |||
| b3bb0e543f | |||
| 53d5736420 | |||
| 81034420a9 | |||
| 15442c8c75 | |||
| 3da69c8a1b | |||
| 16d636a87c | |||
| 4da33ff4ec | |||
| c2435fda2d | |||
| 433331e752 | |||
| 094c7fbb44 | |||
| 0b60979c7b | |||
| 2366cd3520 | |||
| 725a8896ce | |||
| 350038057d | |||
| 80f028edf2 | |||
| 23c3f0709b | |||
| 01d7388f91 | |||
| 8c563a2d76 | |||
| 91edab34bc | |||
| 1ceea91f4a | |||
| 4195baa5dc | |||
| 37f9ab2322 | |||
| d8b1f4e514 | |||
| 6a3335315a | |||
| 6326a60a79 | |||
| c651face4c | |||
| 641a43b2ec | |||
| 58952725e9 | |||
| de044dabd3 | |||
| ce7b26ccac | |||
| bb900c5110 | |||
| cefc4e5257 | |||
| 0d8f7acb7e | |||
| 37cf42527b | |||
| 99543a300d | |||
| f377d9ba70 | |||
| d22e59f28f | |||
| 7804d42fea | |||
| 9a8f5293af | |||
| e535f629bc | |||
| aa805f9a41 | |||
| c60e968836 | |||
| 9d3313e3ed | |||
| dc4f5ad26e | |||
| eaca1c4dd1 | |||
| 0367826f16 | |||
| 352074da04 | |||
| 53ef749736 | |||
| bc8a922b77 | |||
| 663aca2641 | |||
| 4de613814b | |||
| de6e74c0b1 | |||
| e580540143 | |||
| 90a79c702f | |||
| 393a774140 | |||
| 0807a7d0ae | |||
| ba150a264c | |||
| 578018607a | |||
| 58d827f7d0 | |||
| 3085ccdfbf | |||
| b650eb95df | |||
| 8949db5456 | |||
| 14bcb7ea0d | |||
| 519178dfba | |||
| 0e6353dd79 | |||
| ed5cd392ab | |||
| bad42fae1c | |||
| 247ff09743 | |||
| c9b140bd6b | |||
| 2a35c3055e | |||
| c9d1ba6cae | |||
| eb9c217eb4 | |||
| ce41421dbb | |||
| 1d0810db10 | |||
| c85bb2eef7 | |||
| 75402b0f93 | |||
| d597c7e60e | |||
| 0dbe0fe48e | |||
| f83e217638 | |||
| 58db7b755a | |||
| 1e1ce4e127 | |||
| 9fbea18330 | |||
| f337305dee | |||
| d7de4fc694 | |||
| a8c0a1f294 | |||
| 9f54a08536 | |||
| 03bbe25a1e | |||
| 24dada149f | |||
| a7fb77d998 | |||
| 32d2aa6a93 | |||
| d1880754f5 | |||
| 27b44d2511 | |||
| 94adaf8ae3 | |||
| 6dc5112c26 | |||
| e92119c99e | |||
| c48c9e1f86 | |||
| 7ac2aaef15 | |||
| 06f56d13d1 | |||
| 8f55e90d2d | |||
| b5a010a517 | |||
| b87e543420 | |||
| fa3816e55d | |||
| ee41721a75 | |||
| 648ba502bb | |||
| 2c993e82d6 | |||
| cbbb7deaea | |||
| de5bdef58c | |||
| 000ad6358f | |||
| 04a8eeebe8 | |||
| d8d63f804a | |||
| 955c9ce534 | |||
| e8d23f3b3f | |||
| 89aa8c44b0 | |||
| f0e407bec2 | |||
| 8e21b1fe35 | |||
| 17133b316a | |||
| 28a290600b | |||
| af5b3a9302 | |||
| abb61d2cd6 | |||
| 2f13f5da7a | |||
| 464650c370 | |||
| af294f78b7 | |||
| c840183467 | |||
| 1f99d46a8d | |||
| fd99562c7a | |||
| c698149bdd | |||
| fa0ace8c68 | |||
| 1d19c6901e |
@@ -4,7 +4,3 @@ bin/
|
|||||||
lib/
|
lib/
|
||||||
# Because apparently nobody has any self control
|
# Because apparently nobody has any self control
|
||||||
*.orig
|
*.orig
|
||||||
|
|
||||||
tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/x64/Debug/
|
|
||||||
tools/LiveTexturing/mayaPluginRTT/x64/Debug/
|
|
||||||
*.suo
|
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
#### Bundled libraries
|
#### Bundled libraries
|
||||||
Libraries bundled along with binaries for Windows (MSVC14), available as a submodule in the *deps* directory of the source tree.
|
Libraries bundled along with binaries for Windows (MSVC14), available as a submodule in the *deps* directory of the source tree.
|
||||||
|
|
||||||
| Project | Version | License |
|
| Project | Version | License |
|
||||||
| ------------------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| **[GLFW](http://www.glfw.org)** | 3.1.2 | [zlib/libpng License](http://www.glfw.org/license.html) |
|
| **[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) |
|
| **[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) |
|
| **[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) |
|
| **[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) |
|
| **[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) |
|
| **[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) |
|
| **[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 | https://github.com/mlabbe/nativefiledialog/blob/master/LICENSE |
|
||||||
|
|
||||||
#### External libraries
|
#### External libraries
|
||||||
Libraries that are too big to be bundled with the project.
|
Libraries that are too big to be bundled with the project.
|
||||||
|
|
||||||
| Project | Version | License | Root folder environment variable (Windows) |
|
| 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: e4dc9529f2...c8e631f449
@@ -1,13 +1,13 @@
|
|||||||
# XERCES_FOUND
|
# Xerces_FOUND
|
||||||
# XERCES_INCLUDE_DIRS
|
# Xerces_INCLUDE_DIRS
|
||||||
# XERCES_LIBRARIES
|
# Xerces_LIBRARIES
|
||||||
|
|
||||||
find_path(XERCES_INCLUDE_DIR xercesc/dom/dom.hpp
|
find_path(Xerces_INCLUDE_DIR xercesc/dom/dom.hpp
|
||||||
/usr/local/include
|
/usr/local/include
|
||||||
/usr/include
|
/usr/include
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(XERCES_LIBRARY
|
find_library(Xerces_LIBRARY
|
||||||
NAMES
|
NAMES
|
||||||
xerces-c_3
|
xerces-c_3
|
||||||
xerces-c_3D
|
xerces-c_3D
|
||||||
@@ -16,8 +16,8 @@ find_library(XERCES_LIBRARY
|
|||||||
/usr/lib
|
/usr/lib
|
||||||
)
|
)
|
||||||
|
|
||||||
set(XERCES_INCLUDE_DIRS ${XERCES_INCLUDE_DIR})
|
set(Xerces_INCLUDE_DIRS ${Xerces_INCLUDE_DIR})
|
||||||
set(XERCES_LIBRARIES ${XERCES_LIBRARY})
|
set(Xerces_LIBRARIES ${Xerces_LIBRARY})
|
||||||
|
|
||||||
find_package_handle_standard_args(Xerces DEFAULT_MSG XERCES_LIBRARY XERCES_INCLUDE_DIR)
|
find_package_handle_standard_args(Xerces DEFAULT_MSG Xerces_LIBRARY Xerces_INCLUDE_DIR)
|
||||||
mark_as_advanced(Xerces_FOUND XERCES_INCLUDE_DIR XERCES_LIBRARY)
|
mark_as_advanced(Xerces_FOUND Xerces_INCLUDE_DIR Xerces_LIBRARY)
|
||||||
|
|||||||
+1
-1
Submodule deps updated: 1b478d3159...bf83f099ba
@@ -0,0 +1,59 @@
|
|||||||
|
#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 "Core/Ray.h"
|
||||||
|
#include "Core/AABB.h"
|
||||||
|
#include "Engine/Rendering/RawModel.h"
|
||||||
|
#include "Core/Entity.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);
|
||||||
|
|
||||||
|
//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);
|
||||||
|
|
||||||
|
//Returns true if the entity has a boundingbox. Outputs the aabb in [outBox].
|
||||||
|
bool GetEntityBox(World* world, EntityID entity, AABB& outBox, bool forceBoxFromModel = false);
|
||||||
|
bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#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"
|
||||||
|
|
||||||
|
class CollisionSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CollisionSystem(EventBroker* eventBroker)
|
||||||
|
: PureSystem(eventBroker, "AABB")
|
||||||
|
, zPress(false)
|
||||||
|
{
|
||||||
|
//TODO: Debug stuff, remove later.
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &CollisionSystem::OnKeyUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& cAABB, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool zPress;
|
||||||
|
EventRelay<CollisionSystem, Events::KeyUp> m_EKeyUp;
|
||||||
|
bool OnKeyUp(const Events::KeyUp &event);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef TriggerSystem_h__
|
||||||
|
#define TriggerSystem_h__
|
||||||
|
|
||||||
|
#include <glm/common.hpp>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "ETrigger.h"
|
||||||
|
|
||||||
|
class AABB;
|
||||||
|
|
||||||
|
class TriggerSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TriggerSystem(EventBroker* eventBroker)
|
||||||
|
: PureSystem(eventBroker, "Trigger")
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& collision, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesTouchingTrigger;
|
||||||
|
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesCompletelyInTrigger;
|
||||||
|
|
||||||
|
//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
|
||||||
@@ -5,3 +5,4 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "Core/Util/Logging.h"
|
#include "Core/Util/Logging.h"
|
||||||
|
#include "Core/Util/IfDebug.h"
|
||||||
@@ -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.
|
||||||
|
virtual void CreateFromCenter(const glm::vec3& center, 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& Center() const { return m_Center; }
|
||||||
|
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_Center;
|
||||||
|
glm::vec3 m_HalfSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -12,9 +12,16 @@ struct ComponentInfo
|
|||||||
unsigned int Stride = 0;
|
unsigned int Stride = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Field_t
|
||||||
|
{
|
||||||
|
std::string Type;
|
||||||
|
unsigned int Offset;
|
||||||
|
unsigned int Stride;
|
||||||
|
};
|
||||||
|
|
||||||
std::string Name;
|
std::string Name;
|
||||||
std::unordered_map<std::string, std::string> FieldTypes;
|
std::unordered_map<std::string, Field_t> Fields;
|
||||||
std::unordered_map<std::string, unsigned int> FieldOffsets;
|
std::vector<const Field_t*> FieldsInOrder;
|
||||||
Meta_t Meta;
|
Meta_t Meta;
|
||||||
std::shared_ptr<char> Defaults = nullptr;
|
std::shared_ptr<char> Defaults = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
~ComponentPoolForwardIterator() = default;
|
~ComponentPoolForwardIterator() = default;
|
||||||
ComponentPoolForwardIterator& operator=(const ComponentPoolForwardIterator& other) = default;
|
ComponentPoolForwardIterator& operator=(const ComponentPoolForwardIterator& other) = default;
|
||||||
ComponentPoolForwardIterator& operator++();
|
ComponentPoolForwardIterator& operator++();
|
||||||
ComponentPoolForwardIterator& operator++(int);
|
ComponentPoolForwardIterator operator++(int);
|
||||||
bool operator!=(const ComponentPoolForwardIterator& other) const;
|
bool operator!=(const ComponentPoolForwardIterator& other) const;
|
||||||
bool operator==(const ComponentPoolForwardIterator& other) const;
|
bool operator==(const ComponentPoolForwardIterator& other) const;
|
||||||
ComponentWrapper operator*() const;
|
ComponentWrapper operator*() const;
|
||||||
@@ -54,6 +54,8 @@ public:
|
|||||||
ComponentWrapper Allocate(EntityID entity);
|
ComponentWrapper Allocate(EntityID entity);
|
||||||
// Get the component belonging to a specific entity
|
// Get the component belonging to a specific entity
|
||||||
ComponentWrapper GetByEntity(EntityID ent);
|
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
|
// Delete a component and free its memory
|
||||||
void Delete(ComponentWrapper& wrapper);
|
void Delete(ComponentWrapper& wrapper);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define ComponentWrapper_h__
|
#define ComponentWrapper_h__
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "EntityWrapper.h"
|
#include "Entity.h"
|
||||||
#include "ComponentInfo.h"
|
#include "ComponentInfo.h"
|
||||||
#include "Util/Any.h"
|
#include "Util/Any.h"
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ struct ComponentWrapper
|
|||||||
ComponentWrapper(const ComponentInfo& componentInfo, char* data)
|
ComponentWrapper(const ComponentInfo& componentInfo, char* data)
|
||||||
: Info(componentInfo)
|
: Info(componentInfo)
|
||||||
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
||||||
, Data(data + sizeof(EntityID))
|
, Data(data + sizeof(::EntityID))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
const ComponentInfo& Info;
|
const ComponentInfo& Info;
|
||||||
@@ -21,7 +21,7 @@ struct ComponentWrapper
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T& Property(std::string name)
|
T& Property(std::string name)
|
||||||
{
|
{
|
||||||
unsigned int offset = Info.FieldOffsets.at(name);
|
unsigned int offset = Info.Fields.at(name).Offset;
|
||||||
return *reinterpret_cast<T*>(&Data[offset]);
|
return *reinterpret_cast<T*>(&Data[offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +78,9 @@ public:
|
|||||||
void AddProperty(std::string fieldName, T defaultValue)
|
void AddProperty(std::string fieldName, T defaultValue)
|
||||||
{
|
{
|
||||||
m_DefaultValues.push_back(defaultValue);
|
m_DefaultValues.push_back(defaultValue);
|
||||||
m_ComponentInfo.FieldTypes[fieldName] = typeid(T).name();
|
m_ComponentInfo.Fields[fieldName].Name = typeid(T).name();
|
||||||
m_ComponentInfo.FieldOffsets[fieldName] = m_ComponentInfo.Meta.Stride;
|
m_ComponentInfo.Fields[fieldName].Offset = m_ComponentInfo.Meta.Stride;
|
||||||
|
m_ComponentInfo.Fields[fieldName].Stride = sizeof(T);
|
||||||
m_ComponentInfo.Meta.Stride += sizeof(T);
|
m_ComponentInfo.Meta.Stride += sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,10 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/range/adaptors.hpp>
|
||||||
|
#include <ini_file/ini_file.hpp>
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
|
|
||||||
@@ -22,26 +23,49 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void Set(std::string key, T value);
|
void Set(std::string key, T value);
|
||||||
|
|
||||||
|
const ini_file::section* GetSection(std::string section);
|
||||||
|
const ini_file::section_map& GetSections() { return m_Merged; }
|
||||||
|
const ini_file::param* GetParam(std::string key);
|
||||||
|
|
||||||
void SaveToDisk();
|
void SaveToDisk();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::filesystem::path m_Path;
|
boost::filesystem::path m_Path;
|
||||||
boost::property_tree::ptree m_PTreeDefaults;
|
ini_file::section_map m_Defaults;
|
||||||
boost::property_tree::ptree m_PTreeOverrides;
|
ini_file::section_map m_Overrides;
|
||||||
boost::property_tree::ptree m_PTreeMerged;
|
ini_file::section_map m_Merged;
|
||||||
|
|
||||||
|
// Merge ini file section map b into a
|
||||||
|
void mergeINI(ini_file::section_map& a, const ini_file::section_map& b);
|
||||||
|
// Convert an ini key delimited by periods to a section and a param
|
||||||
|
boost::optional<std::pair<std::string, std::string>> tokenizeKey(std::string key);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T ConfigFile::Get(std::string key, T defaultValue)
|
T ConfigFile::Get(std::string key, T defaultValue)
|
||||||
{
|
{
|
||||||
return m_PTreeMerged.get<T>(key, defaultValue);
|
auto param = GetParam(key);
|
||||||
|
if (param == nullptr) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::lexical_cast<T>(param->get_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ConfigFile::Set(std::string key, T value)
|
void ConfigFile::Set(std::string key, T value)
|
||||||
{
|
{
|
||||||
m_PTreeOverrides.put<T>(key, value);
|
std::string section;
|
||||||
m_PTreeMerged.put<T>(key, value);
|
std::string param;
|
||||||
|
if (auto tokens = tokenizeKey(key)) {
|
||||||
|
std::tie(section, param) = *tokens;
|
||||||
|
} else {
|
||||||
|
LOG_WARNING("%s: Malformed config key \"%s\"", m_Path.string().c_str(), key.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Overrides[section][param] = boost::lexical_cast<std::string>(value);
|
||||||
|
m_Merged[section][param] = boost::lexical_cast<std::string>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
#ifndef DeveloperConsole_h__
|
||||||
|
#define DeveloperConsole_h__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/tokenizer.hpp>
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "ConfigFile.h"
|
||||||
|
|
||||||
|
class DeveloperConsole
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DeveloperConsole() = delete;
|
||||||
|
|
||||||
|
static void MergeConfig(std::string configFile)
|
||||||
|
{
|
||||||
|
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
|
LOG_DEBUG("Debug.LogLevel %i", config->Get<int>("Debug.LogLevel", -1));
|
||||||
|
config->Set("Debug.LogLevel", 8);
|
||||||
|
LOG_DEBUG("Debug.LogLevel %i", config->Get<int>("Debug.LogLevel", -1));
|
||||||
|
config->Set("Test.TesTest.Testies", "Hello");
|
||||||
|
config->SaveToDisk();
|
||||||
|
for (auto& section : config->GetSections()) {
|
||||||
|
for (auto& param : *section.second) {
|
||||||
|
std::cout << "// " << param.second->get_comment() << std::endl;
|
||||||
|
std::cout << section.first << "." << param.first << " " << param.second->get_value() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& section : config->GetSections()) {
|
||||||
|
for (auto& param : *section.second) {
|
||||||
|
std::string key = section.first + "." + param.first;
|
||||||
|
m_VariableBindingSetters[key] = [config, key](std::string value) {
|
||||||
|
config->Set<std::string>(key, value);
|
||||||
|
};
|
||||||
|
m_VariableBindingGetters[key] = [config, key]() {
|
||||||
|
return config->Get<std::string>(key, "");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static typename std::enable_if<std::is_enum<T>::value, void>::type
|
||||||
|
BindVariable(std::string path, T& variable)
|
||||||
|
{
|
||||||
|
BindVariable<T, std::underlying_type<T>::type>(path, variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename R = T>
|
||||||
|
static typename std::enable_if<!std::is_enum<R>::value, void>::type
|
||||||
|
BindVariable(std::string path, T& variable)
|
||||||
|
{
|
||||||
|
m_VariableBindingSetters[path] = [&variable](std::string value) {
|
||||||
|
variable = static_cast<T>(boost::lexical_cast<R>(value));
|
||||||
|
};
|
||||||
|
|
||||||
|
m_VariableBindingGetters[path] = [&variable]() {
|
||||||
|
return boost::lexical_cast<std::string>(static_cast<R>(variable));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Consume(const std::string& command)
|
||||||
|
{
|
||||||
|
if (command.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::char_separator<char> argumentSeparator(" ");
|
||||||
|
tokenizer tokens(command, argumentSeparator);
|
||||||
|
|
||||||
|
for (tokenizer::const_iterator it = tokens.begin(); it != tokens.end(); it++) {
|
||||||
|
consumeToken(it, tokens.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Consume(std::istream& stream)
|
||||||
|
{
|
||||||
|
std::string input;
|
||||||
|
std::getline(stream, input);
|
||||||
|
Consume(input);
|
||||||
|
|
||||||
|
/*if (stream.peek() == '\n') {
|
||||||
|
printValue(key);
|
||||||
|
} else {
|
||||||
|
std::string newValue;
|
||||||
|
stream >> newValue;
|
||||||
|
|
||||||
|
if (m_VariableBindingSetters.find(key) != m_VariableBindingSetters.end()) {
|
||||||
|
m_VariableBindingSetters.at(key)(newValue);
|
||||||
|
} else {
|
||||||
|
std::cout << "Unknown path: " << key << std::endl;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto& config : m_ConfigFiles) {
|
||||||
|
config->Set(key, newValue);
|
||||||
|
config->SaveToDisk();
|
||||||
|
LOG_DEBUG("Key %s set to new value %s and saved to disk.", key.c_str(), newValue.c_str());
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
|
||||||
|
|
||||||
|
static std::map<std::string, std::function<std::string()>> m_VariableBindingGetters;
|
||||||
|
static std::map<std::string, std::function<void(std::string)>> m_VariableBindingSetters;
|
||||||
|
static std::map<std::string, std::function<std::string(std::string)>> m_VariableBindingMappers;
|
||||||
|
static std::map<std::string, std::string> m_VariableDocumentation;
|
||||||
|
|
||||||
|
static void consumeToken(tokenizer::iterator& token, const tokenizer::iterator end)
|
||||||
|
{
|
||||||
|
tokenizer::iterator next = token;
|
||||||
|
next++;
|
||||||
|
|
||||||
|
if (next == end) {
|
||||||
|
printValue(token);
|
||||||
|
} else {
|
||||||
|
setValue(token, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printValue(tokenizer::iterator token)
|
||||||
|
{
|
||||||
|
std::string key = *token;
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
if (m_VariableBindingGetters.find(key) != m_VariableBindingGetters.end()) {
|
||||||
|
std::cout << key << " = " << m_VariableBindingGetters.at(key)() << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Unknown path: " << key << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!value.empty()) {
|
||||||
|
std::cout << key << " = " << value << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Unknown path: " << key << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setValue(tokenizer::iterator& token, const tokenizer::iterator end)
|
||||||
|
{
|
||||||
|
std::string key = *token;
|
||||||
|
std::string value = *(++token);
|
||||||
|
|
||||||
|
if (m_VariableBindingSetters.find(key) != m_VariableBindingSetters.end()) {
|
||||||
|
m_VariableBindingSetters.at(key)(value);
|
||||||
|
} else {
|
||||||
|
std::cout << "Unknown path: " << key << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef EFileDropped_h__
|
||||||
|
#define EFileDropped_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct FileDropped : Event
|
||||||
|
{
|
||||||
|
std::string Path;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef Entity_h__
|
||||||
|
#define Entity_h__
|
||||||
|
|
||||||
|
typedef unsigned int EntityID;
|
||||||
|
const static unsigned int EntityID_Invalid = -1;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,12 +1,293 @@
|
|||||||
|
#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 "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)
|
||||||
|
: m_Handler(handler)
|
||||||
|
, m_Reader(reader)
|
||||||
|
{
|
||||||
|
// 0 is imaginary world entity
|
||||||
|
m_EntityStack.push(0);
|
||||||
|
m_StateStack.push(State::Unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
void startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) override
|
||||||
|
{
|
||||||
|
std::string name = XS::ToString(_localName);
|
||||||
|
|
||||||
|
if (m_StateStack.top() == State::Unknown || m_StateStack.top() == State::Entity) {
|
||||||
|
if (name == "Entity") {
|
||||||
|
m_StateStack.push(State::Entity);
|
||||||
|
onStartEntity(attrs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (name == "EntityRef") {
|
||||||
|
onStartEntityRef(attrs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string uri = XS::ToString(_uri);
|
||||||
|
if (m_StateStack.top() == State::Entity) {
|
||||||
|
if (uri == "components") {
|
||||||
|
m_StateStack.push(State::Component);
|
||||||
|
onStartComponent(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_StateStack.top() == State::Component) {
|
||||||
|
m_StateStack.push(State::ComponentField);
|
||||||
|
onStartComponentField(name, attrs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void characters(const XMLCh* const chars, const XMLSize_t length) override
|
||||||
|
{
|
||||||
|
if (m_StateStack.top() == State::ComponentField) {
|
||||||
|
char* transcoded = xercesc::XMLString::transcode(chars);
|
||||||
|
onFieldData(transcoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) override
|
||||||
|
{
|
||||||
|
std::string name = XS::ToString(_localName);
|
||||||
|
if (m_StateStack.top() == State::Entity) {
|
||||||
|
if (name == "Entity") {
|
||||||
|
m_StateStack.pop();
|
||||||
|
onEndEntity();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string uri = XS::ToString(_uri);
|
||||||
|
if (m_StateStack.top() == State::Component) {
|
||||||
|
//if (uri == "components") {
|
||||||
|
m_StateStack.pop();
|
||||||
|
onEndComponent(name);
|
||||||
|
return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_StateStack.top() == State::ComponentField) {
|
||||||
|
m_StateStack.pop();
|
||||||
|
onEndComponentField(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fatalError(const xercesc::SAXParseException& e)
|
||||||
|
{
|
||||||
|
XS::ToString s(e.getMessage());
|
||||||
|
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
|
||||||
|
//throw 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)
|
||||||
|
{
|
||||||
|
EntityID parent = m_EntityStack.top();
|
||||||
|
|
||||||
|
if (m_Handler->m_OnStartEntityCallback) {
|
||||||
|
std::string name;
|
||||||
|
auto xName = attrs.getValue(XS::ToXMLCh("name"));
|
||||||
|
if (xName != nullptr) {
|
||||||
|
name = XS::ToString(xName);
|
||||||
|
}
|
||||||
|
m_Handler->m_OnStartEntityCallback(m_NextEntityID, parent, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_EntityStack.push(m_NextEntityID);
|
||||||
|
m_NextEntityID++;
|
||||||
|
}
|
||||||
|
void onEndEntity()
|
||||||
|
{
|
||||||
|
m_EntityStack.pop();
|
||||||
|
}
|
||||||
|
void onStartEntityRef(const xercesc::Attributes& attrs)
|
||||||
|
{
|
||||||
|
std::string path = XS::ToString(attrs.getValue(XS::ToXMLCh("file")));
|
||||||
|
|
||||||
|
xercesc::SAX2XMLReader* parser = xercesc::XMLReaderFactory::createXMLReader();
|
||||||
|
parser->setContentHandler(this);
|
||||||
|
parser->setErrorHandler(this);
|
||||||
|
parser->parse(path.c_str());
|
||||||
|
delete parser;
|
||||||
|
}
|
||||||
|
void onStartComponent(const std::string& name)
|
||||||
|
{
|
||||||
|
//LOG_DEBUG(" Component: %s", name.c_str());
|
||||||
|
m_CurrentComponent = name;
|
||||||
|
if (m_Handler->m_OnStartComponentCallback) {
|
||||||
|
m_Handler->m_OnStartComponentCallback(m_EntityStack.top(), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onEndComponent(const std::string& name) { }
|
||||||
|
void onStartComponentField(const std::string& field, const xercesc::Attributes& attrs)
|
||||||
|
{
|
||||||
|
//LOG_DEBUG(" Field: %s", field.c_str());
|
||||||
|
m_CurrentField = field;
|
||||||
|
m_CurrentAttributes.clear();
|
||||||
|
for (int i = 0; i < attrs.getLength(); i++) {
|
||||||
|
auto name = attrs.getQName(i);
|
||||||
|
auto value = attrs.getValue(name);
|
||||||
|
//LOG_DEBUG(" %s = %s", (char*)XS::ToString(name), (char*)XS::ToString(value));
|
||||||
|
m_CurrentAttributes[XS::ToString(name).operator std::string()] = XS::ToString(value).operator std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Handler->m_OnStartFieldCallback) {
|
||||||
|
m_Handler->m_OnStartFieldCallback(m_EntityStack.top(), m_CurrentComponent, field, m_CurrentAttributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onEndComponentField(const std::string& field) { }
|
||||||
|
|
||||||
|
void onFieldData(char* data)
|
||||||
|
{
|
||||||
|
//LOG_DEBUG(" Data: %s", data);
|
||||||
|
|
||||||
|
if (m_Handler->m_OnStartFieldDataCallback) {
|
||||||
|
m_Handler->m_OnStartFieldDataCallback(m_EntityStack.top(), m_CurrentComponent, m_CurrentField, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
xercesc::XMLString::release(&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
|
class EntityFile : public Resource
|
||||||
{
|
{
|
||||||
friend class ResourceManager;
|
friend class ResourceManager;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EntityFile(std::string path);
|
EntityFile(boost::filesystem::path path);
|
||||||
|
~EntityFile();
|
||||||
|
|
||||||
public:
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef EntityFileParser_h__
|
||||||
|
#define EntityFileParser_h__
|
||||||
|
|
||||||
|
#include "EntityFile.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
class EntityFileParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EntityFileParser(const EntityFile* entityFile);
|
||||||
|
|
||||||
|
void MergeEntities(World* world);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const EntityFile* m_EntityFile;
|
||||||
|
EntityFileHandler m_Handler;
|
||||||
|
World* m_World = nullptr;
|
||||||
|
// 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,36 @@
|
|||||||
|
#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/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();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef Entity_h__
|
|
||||||
#define Entity_h__
|
|
||||||
|
|
||||||
typedef unsigned int EntityID;
|
|
||||||
|
|
||||||
struct EntityWrapper
|
|
||||||
{
|
|
||||||
EntityWrapper(EntityID entityID)
|
|
||||||
: ID(entityID)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
EntityID ID;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -13,123 +13,127 @@
|
|||||||
relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \
|
relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \
|
||||||
m_EventBroker->Subscribe(relay);
|
m_EventBroker->Subscribe(relay);
|
||||||
|
|
||||||
|
typedef unsigned int EventID;
|
||||||
|
|
||||||
class EventBroker;
|
class EventBroker;
|
||||||
|
|
||||||
class BaseEventRelay
|
class BaseEventRelay
|
||||||
{
|
{
|
||||||
friend class EventBroker;
|
friend class EventBroker;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
|
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
|
||||||
: m_ContextTypeName(contextTypeName)
|
: m_ContextTypeName(contextTypeName)
|
||||||
, m_EventTypeName(eventTypeName)
|
, m_EventTypeName(eventTypeName)
|
||||||
, m_Broker(nullptr)
|
, m_Broker(nullptr)
|
||||||
{ }
|
{ }
|
||||||
~BaseEventRelay();
|
~BaseEventRelay();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
|
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string m_ContextTypeName;
|
EventID m_EventID;
|
||||||
std::string m_EventTypeName;
|
std::string m_ContextTypeName;
|
||||||
EventBroker* m_Broker;
|
std::string m_EventTypeName;
|
||||||
|
EventBroker* m_Broker;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ContextType, typename EventType>
|
template <typename ContextType, typename EventType>
|
||||||
class EventRelay : public BaseEventRelay
|
class EventRelay : public BaseEventRelay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<bool(const EventType&)> CallbackType;
|
typedef std::function<bool(const EventType&)> CallbackType;
|
||||||
|
|
||||||
EventRelay()
|
EventRelay()
|
||||||
: m_Callback(nullptr)
|
: m_Callback(nullptr)
|
||||||
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
|
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
|
||||||
{ }
|
{ }
|
||||||
EventRelay(CallbackType callback)
|
EventRelay(CallbackType callback)
|
||||||
: m_Callback(callback)
|
: m_Callback(callback)
|
||||||
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
|
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Receive(const std::shared_ptr<Event> event) override;
|
bool Receive(const std::shared_ptr<Event> event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CallbackType m_Callback;
|
CallbackType m_Callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ContextType, typename EventType>
|
template <typename ContextType, typename EventType>
|
||||||
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
|
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
|
||||||
{
|
{
|
||||||
if (m_Callback != nullptr) {
|
if (m_Callback != nullptr) {
|
||||||
return m_Callback(*static_cast<const EventType*>(event.get()));
|
return m_Callback(*static_cast<const EventType*>(event.get()));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventBroker
|
class EventBroker
|
||||||
{
|
{
|
||||||
template <typename ContextType, typename EventType> friend class EventRelay;
|
template <typename ContextType, typename EventType> friend class EventRelay;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EventBroker()
|
EventBroker()
|
||||||
{
|
{
|
||||||
m_EventQueueRead = std::make_shared<EventQueue_t>();
|
m_EventQueueRead = std::make_shared<EventQueue_t>();
|
||||||
m_EventQueueWrite = std::make_shared<EventQueue_t>();
|
m_EventQueueWrite = std::make_shared<EventQueue_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Subscribe(BaseEventRelay &relay);
|
void Subscribe(BaseEventRelay &relay);
|
||||||
template <typename EventType>
|
template <typename EventType>
|
||||||
void Publish(const EventType &event);
|
void Publish(const EventType &event);
|
||||||
/*
|
/*
|
||||||
Process all events in a given context.
|
Process all events in a given context.
|
||||||
Returns: Number of events processed
|
Returns: Number of events processed
|
||||||
*/
|
*/
|
||||||
template <typename ContextType>
|
template <typename ContextType>
|
||||||
int Process();
|
int Process();
|
||||||
int Process(std::string contextTypeName);
|
int Process(std::string contextTypeName);
|
||||||
void Swap();
|
void Swap();
|
||||||
void Clear();
|
void Clear();
|
||||||
void Unsubscribe(BaseEventRelay &relay);
|
void Unsubscribe(BaseEventRelay &relay);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_IsProcessing = false;
|
bool m_IsProcessing = false;
|
||||||
|
EventID m_NextEventID = 0;
|
||||||
|
|
||||||
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
|
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
|
||||||
typedef std::string EventTypeName_t; // typeid(EventType).name()
|
typedef std::string EventTypeName_t; // typeid(EventType).name()
|
||||||
|
|
||||||
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
|
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
|
||||||
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
|
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
|
||||||
ContextRelays_t m_ContextRelays;
|
ContextRelays_t m_ContextRelays;
|
||||||
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
|
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
|
||||||
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
|
std::vector<std::tuple<EventID, ContextTypeName_t, EventTypeName_t>> m_RelaysToUnsubscribe;
|
||||||
|
|
||||||
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
|
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_EventQueueRead;
|
||||||
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
|
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
|
||||||
|
|
||||||
void subscribeImmediate(BaseEventRelay& relay);
|
void subscribeImmediate(BaseEventRelay& relay);
|
||||||
void unsubscribeImmediate(BaseEventRelay& relay);
|
void unsubscribeImmediate(std::tuple<EventID, ContextTypeName_t, EventTypeName_t> identifier);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename EventType>
|
template <typename EventType>
|
||||||
void EventBroker::Publish(const EventType &event)
|
void EventBroker::Publish(const EventType &event)
|
||||||
{
|
{
|
||||||
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
|
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
|
||||||
for (auto it = itpair.first; it != itpair.second; ++it)
|
for (auto it = itpair.first; it != itpair.second; ++it)
|
||||||
{
|
{
|
||||||
it->second->Receive(event);
|
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>
|
template <typename ContextType>
|
||||||
int EventBroker::Process()
|
int EventBroker::Process()
|
||||||
{
|
{
|
||||||
const std::string contextTypeName = typeid(ContextType).name();
|
const std::string contextTypeName = typeid(ContextType).name();
|
||||||
return Process(contextTypeName);
|
return Process(contextTypeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11,25 +11,22 @@ template <typename EventContext>
|
|||||||
class InputController
|
class InputController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InputController(std::shared_ptr<dd::EventBroker> eventBroker)
|
InputController(EventBroker* eventBroker)
|
||||||
: EventBroker(eventBroker)
|
: m_EventBroker(eventBroker)
|
||||||
{ Initialize(); }
|
{ Initialize(); }
|
||||||
|
|
||||||
virtual void Initialize()
|
virtual void Initialize()
|
||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &InputController::OnCommand);
|
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 OnCommand(const Events::InputCommand& e) { return false; }
|
||||||
virtual bool OnMouseMove(const Events::MouseMove &event) { return false; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<dd::EventBroker> EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
|
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
|
||||||
EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,12 +8,15 @@
|
|||||||
#include "EventBroker.h"
|
#include "EventBroker.h"
|
||||||
#include "EKeyDown.h"
|
#include "EKeyDown.h"
|
||||||
#include "EKeyUp.h"
|
#include "EKeyUp.h"
|
||||||
|
#include "EKeyboardChar.h"
|
||||||
#include "EMousePress.h"
|
#include "EMousePress.h"
|
||||||
#include "EMouseRelease.h"
|
#include "EMouseRelease.h"
|
||||||
#include "EMouseMove.h"
|
#include "EMouseMove.h"
|
||||||
|
#include "EMouseScroll.h"
|
||||||
#include "ELockMouse.h"
|
#include "ELockMouse.h"
|
||||||
#include "EGamepadAxis.h"
|
#include "EGamepadAxis.h"
|
||||||
#include "EGamepadButton.h"
|
#include "EGamepadButton.h"
|
||||||
|
#include "EFileDropped.h"
|
||||||
|
|
||||||
class InputManager
|
class InputManager
|
||||||
{
|
{
|
||||||
@@ -64,6 +67,13 @@ private:
|
|||||||
|
|
||||||
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
|
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
|
||||||
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
|
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
|
#endif
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Postfix increment i.e. iter++. Prefer pre-increment (++iter) for efficiency.
|
//Postfix increment i.e. iter++. Prefer pre-increment (++iter) for efficiency.
|
||||||
MemoryPoolForwardIterator& operator++(int)
|
MemoryPoolForwardIterator operator++(int)
|
||||||
{
|
{
|
||||||
MemoryPoolForwardIterator<T> copyIter(*this);
|
MemoryPoolForwardIterator<T> copyIter(*this);
|
||||||
operator++();
|
operator++();
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#ifndef OctTree_h__
|
||||||
|
#define OctTree_h__
|
||||||
|
|
||||||
|
#include "Core/AABB.h"
|
||||||
|
|
||||||
|
class Ray;
|
||||||
|
|
||||||
|
class OctTree
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Output
|
||||||
|
{
|
||||||
|
float CollideDistance;
|
||||||
|
};
|
||||||
|
|
||||||
|
OctTree();
|
||||||
|
~OctTree();
|
||||||
|
//For the root OctTree, [octTreeBounds] should be a box containing the entire level.
|
||||||
|
OctTree(const AABB& octTreeBounds, int subDivisions);
|
||||||
|
|
||||||
|
//We cannot copy the OctTree as of now, because of the recursive dynamic allocation.
|
||||||
|
//Define these if the OctTree suddenly needs to be copied, think of the children OctChild* ptrs.
|
||||||
|
OctTree(const OctTree& other) = delete;
|
||||||
|
OctTree(const OctTree&& other) = delete;
|
||||||
|
OctTree& operator= (const OctTree& other) = delete;
|
||||||
|
//Add a dynamic object (one that moves around) into the tree.
|
||||||
|
void AddDynamicObject(const AABB& box);
|
||||||
|
//Add a static object (that does not move) into the tree.
|
||||||
|
void AddStaticObject(const AABB& box);
|
||||||
|
//Get the boxes that are in the same area as the input [box], the boxes are put in [outBoxes].
|
||||||
|
void BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes);
|
||||||
|
//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, 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 BoxesInSameRegion from outside and testing there.
|
||||||
|
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct OctChild; //Fwd declaration;
|
||||||
|
struct ContainedObject
|
||||||
|
{
|
||||||
|
ContainedObject()
|
||||||
|
: Box(AABB())
|
||||||
|
, Checked(false)
|
||||||
|
{}
|
||||||
|
ContainedObject(AABB box)
|
||||||
|
: Box(box)
|
||||||
|
, Checked(false)
|
||||||
|
{}
|
||||||
|
AABB Box;
|
||||||
|
bool Checked;
|
||||||
|
};
|
||||||
|
OctChild* m_Root;
|
||||||
|
std::vector<ContainedObject> m_StaticObjects;
|
||||||
|
std::vector<ContainedObject> m_DynamicObjects;
|
||||||
|
|
||||||
|
bool m_UpdatedOnce;
|
||||||
|
unsigned int m_BoxID;
|
||||||
|
glm::vec3 m_PrevPos;
|
||||||
|
glm::quat m_PrevOri;
|
||||||
|
|
||||||
|
void falsifyObjectChecks();
|
||||||
|
|
||||||
|
struct OctChild
|
||||||
|
{
|
||||||
|
~OctChild();
|
||||||
|
OctChild(const AABB& octTreeBounds,
|
||||||
|
int subDivisions,
|
||||||
|
std::vector<OctTree::ContainedObject>& staticObjects,
|
||||||
|
std::vector<OctTree::ContainedObject>& dynamicObjects);
|
||||||
|
OctChild(const OctChild& other) = delete;
|
||||||
|
OctChild(const OctChild&& other) = delete;
|
||||||
|
OctChild& operator= (const OctChild& other) = delete;
|
||||||
|
void AddDynamicObject(const AABB& box);
|
||||||
|
void AddStaticObject(const AABB& box);
|
||||||
|
void BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes) const;
|
||||||
|
void ClearObjects();
|
||||||
|
void ClearDynamicObjects();
|
||||||
|
bool RayCollides(const Ray& ray, Output& data) const;
|
||||||
|
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const;
|
||||||
|
|
||||||
|
OctChild* m_Children[8];
|
||||||
|
//Indices into the lists in OctTree.
|
||||||
|
std::vector<int> m_StaticObjIndices;
|
||||||
|
std::vector<int> m_DynamicObjIndices;
|
||||||
|
AABB m_Box;
|
||||||
|
//Reference to the lists in OctTree.
|
||||||
|
std::vector<OctTree::ContainedObject>& m_StaticObjectsRef;
|
||||||
|
std::vector<OctTree::ContainedObject>& m_DynamicObjectsRef;
|
||||||
|
|
||||||
|
inline bool hasChildren() const;
|
||||||
|
int childIndexContainingPoint(const glm::vec3& point) const;
|
||||||
|
std::vector<int> childIndicesContainingBox(const AABB& box) const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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__
|
||||||
@@ -82,6 +82,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void Reload(std::string resourceName);
|
static void Reload(std::string resourceName);
|
||||||
|
|
||||||
|
static void Release(std::string resourceType, std::string resourceName);
|
||||||
|
|
||||||
static void Update();
|
static void Update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef System_h__
|
||||||
|
#define System_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "ComponentWrapper.h"
|
||||||
|
|
||||||
|
class System
|
||||||
|
{
|
||||||
|
friend class SystemPipeline;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
System(EventBroker* eventBroker)
|
||||||
|
: m_EventBroker(eventBroker)
|
||||||
|
{ }
|
||||||
|
virtual ~System() = default;
|
||||||
|
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PureSystem : public System
|
||||||
|
{
|
||||||
|
friend class SystemPipeline;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PureSystem(EventBroker* eventBroker, std::string componentType)
|
||||||
|
: System(eventBroker)
|
||||||
|
, m_ComponentType(componentType)
|
||||||
|
{ }
|
||||||
|
virtual ~PureSystem() = default;
|
||||||
|
|
||||||
|
const std::string m_ComponentType;
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& component, double dt) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImpureSystem : public System
|
||||||
|
{
|
||||||
|
friend class SystemPipeline;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ImpureSystem(EventBroker* eventBroker)
|
||||||
|
: System(eventBroker)
|
||||||
|
{ }
|
||||||
|
virtual ~ImpureSystem() = default;
|
||||||
|
|
||||||
|
virtual void Update(World* world, double dt) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#ifndef SystemPipeline_h__
|
||||||
|
#define SystemPipeline_h__
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "EventBroker.h"
|
||||||
|
#include "System.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
class SystemPipeline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SystemPipeline(EventBroker* eventBroker)
|
||||||
|
: m_EventBroker(eventBroker)
|
||||||
|
{ }
|
||||||
|
~SystemPipeline()
|
||||||
|
{
|
||||||
|
for (UnorderedSystems& group : m_OrderedSystemGroups) {
|
||||||
|
for (auto& pair : group.Systems) {
|
||||||
|
delete pair.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Arguments>
|
||||||
|
//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...);
|
||||||
|
group.Systems[typeid(T).name()] = system;
|
||||||
|
|
||||||
|
if (std::is_base_of<PureSystem, T>::value) {
|
||||||
|
PureSystem* pureSystem = static_cast<PureSystem*>(system);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::is_base_of<ImpureSystem, T>::value) {
|
||||||
|
ImpureSystem* impureSystem = static_cast<ImpureSystem*>(system);
|
||||||
|
group.ImpureSystems.push_back(impureSystem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(World* world, double dt)
|
||||||
|
{
|
||||||
|
for (UnorderedSystems& group : m_OrderedSystemGroups) {
|
||||||
|
// Process events
|
||||||
|
for (auto& pair : group.Systems) {
|
||||||
|
m_EventBroker->Process(pair.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
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, component, dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto& system : group.ImpureSystems) {
|
||||||
|
system->Update(world, dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
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
|
||||||
@@ -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
|
||||||
@@ -80,4 +80,27 @@ static void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsign
|
|||||||
#define LOG_DEBUG(format, ...) \
|
#define LOG_DEBUG(format, ...) \
|
||||||
LOG(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
|
LOG(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
// Set the log level temporarily for the current scope
|
||||||
|
#define LOG_LEVEL_SCOPE(logLevel) \
|
||||||
|
_LOG_LEVEL_SCOPED_HELPER<logLevel> _logLevelScopedHelper;
|
||||||
|
|
||||||
|
template <_LOG_LEVEL LEVEL>
|
||||||
|
class _LOG_LEVEL_SCOPED_HELPER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
_LOG_LEVEL_SCOPED_HELPER()
|
||||||
|
{
|
||||||
|
m_OriginalLogLevel = LOG_LEVEL;
|
||||||
|
LOG_LEVEL = LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
~_LOG_LEVEL_SCOPED_HELPER()
|
||||||
|
{
|
||||||
|
LOG_LEVEL = m_OriginalLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
_LOG_LEVEL m_OriginalLogLevel;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // Logging_h__
|
#endif // Logging_h__
|
||||||
@@ -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
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#define World_h__
|
#define World_h__
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "EntityWrapper.h"
|
#include "Entity.h"
|
||||||
#include "ObjectPool.h"
|
#include "ObjectPool.h"
|
||||||
#include "ComponentPool.h"
|
#include "ComponentPool.h"
|
||||||
|
|
||||||
@@ -12,23 +12,45 @@ public:
|
|||||||
World() = default;
|
World() = default;
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
|
// Create empty entity
|
||||||
EntityID CreateEntity(EntityID parent = 0);
|
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
|
// Register a component type and allocate space for it
|
||||||
void RegisterComponent(ComponentInfo& ci);
|
void RegisterComponent(ComponentInfo& ci);
|
||||||
// Attach a component to an entity and fill it with default values
|
// Attach a component to an entity and fill it with default values
|
||||||
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
|
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
|
||||||
|
// Check if an entity has a component
|
||||||
|
bool HasComponent(EntityID entity, std::string componentType) const;
|
||||||
// Get a component of an entity
|
// Get a component of an entity
|
||||||
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
||||||
|
// Delete a component off an entity
|
||||||
|
void DeleteComponent(EntityID entity, std::string componentType);
|
||||||
// Get all components of the specified type
|
// Get all components of the specified type
|
||||||
const ComponentPool& GetComponents(std::string componentType);
|
const ComponentPool* GetComponents(std::string componentType);
|
||||||
|
// Get entity parent
|
||||||
|
EntityID GetParent(EntityID entity);
|
||||||
|
// Change the parent of an entity
|
||||||
|
void SetParent(EntityID entity, EntityID parent);
|
||||||
|
// 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:
|
private:
|
||||||
EntityID m_CurrentEntityID = 0;
|
EntityID m_CurrentEntityID = 0;
|
||||||
|
|
||||||
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
||||||
|
// TODO: This should be a more effective structure
|
||||||
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
|
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
|
||||||
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
|
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
|
||||||
|
std::unordered_map<EntityID, std::string> m_EntityNames;
|
||||||
|
|
||||||
EntityID generateEntityID();
|
EntityID generateEntityID();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 "../Rendering/EPicking.h"
|
||||||
|
#include "../Core/EFileDropped.h"
|
||||||
|
#include "../Rendering/RenderQueueFactory.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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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::Picking> m_EPicking;
|
||||||
|
bool OnPicking(const Events::Picking& e);
|
||||||
|
EventRelay<EditorSystem, Events::FileDropped> m_EFileDropped;
|
||||||
|
bool OnFileDropped(const Events::FileDropped& e);
|
||||||
|
|
||||||
|
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,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;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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,22 @@
|
|||||||
|
#ifndef Events_BindOrigin_h__
|
||||||
|
#define Events_BindOrigin_h__
|
||||||
|
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Called to bind an input origin to an input command. */
|
||||||
|
struct BindOrigin : Event
|
||||||
|
{
|
||||||
|
/** The input origin to bind. */
|
||||||
|
std::string Origin;
|
||||||
|
/** The command to send. */
|
||||||
|
std::string Command;
|
||||||
|
/** The value to send for positive stimulation. */
|
||||||
|
float Value = 1.f;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -13,7 +13,7 @@ struct InputCommand : Event
|
|||||||
/** The command that was sent. */
|
/** The command that was sent. */
|
||||||
std::string Command;
|
std::string Command;
|
||||||
/** The value of the command. */
|
/** The value of the command. */
|
||||||
float Value;
|
float Value = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef InputProxy_h__
|
||||||
|
#define InputProxy_h__
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
|
#include "../Core/ConfigFile.h"
|
||||||
|
#include "EInputCommand.h"
|
||||||
|
#include "EBindOrigin.h"
|
||||||
|
|
||||||
|
class InputHandler;
|
||||||
|
|
||||||
|
class InputProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InputProxy(EventBroker* eventBroker);
|
||||||
|
~InputProxy();
|
||||||
|
|
||||||
|
void LoadBindings(std::string file);
|
||||||
|
void Update(double dt);
|
||||||
|
void Process();
|
||||||
|
template <typename T>
|
||||||
|
void AddHandler();
|
||||||
|
void Publish(const Events::InputCommand& e);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
std::vector<InputHandler*> m_Handlers;
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void InputProxy::AddHandler()
|
||||||
|
{
|
||||||
|
m_Handlers.push_back(new T(m_EventBroker, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
#ifndef InputSystem_h__
|
|
||||||
#define InputSystem_h__
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include "Core/System.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 "EInputCommand.h"
|
|
||||||
|
|
||||||
namespace Systems
|
|
||||||
{
|
|
||||||
|
|
||||||
class InputSystem : public System
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InputSystem(World* world, std::shared_ptr<dd::EventBroker> eventBroker)
|
|
||||||
: System(world, eventBroker)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void RegisterComponents(ComponentFactory* cf) override;
|
|
||||||
void Initialize() override;
|
|
||||||
|
|
||||||
void Update(double dt) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandKeyboardValues; // command string -> keyboard key value for command
|
|
||||||
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_KeyBindings; // GLFW_KEY... -> command string & value
|
|
||||||
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<InputSystem, Events::KeyDown> m_EKeyDown;
|
|
||||||
bool OnKeyDown(const Events::KeyDown &event);
|
|
||||||
EventRelay<InputSystem, Events::KeyUp> m_EKeyUp;
|
|
||||||
bool OnKeyUp(const Events::KeyUp &event);
|
|
||||||
EventRelay<InputSystem, Events::MousePress> m_EMousePress;
|
|
||||||
bool OnMousePress(const Events::MousePress &event);
|
|
||||||
EventRelay<InputSystem, Events::MouseRelease> m_EMouseRelease;
|
|
||||||
bool OnMouseRelease(const Events::MouseRelease &event);
|
|
||||||
EventRelay<InputSystem, Events::GamepadAxis> m_EGamepadAxis;
|
|
||||||
bool OnGamepadAxis(const Events::GamepadAxis &event);
|
|
||||||
EventRelay<InputSystem, Events::GamepadButtonDown> m_EGamepadButtonDown;
|
|
||||||
bool OnGamepadButtonDown(const Events::GamepadButtonDown &event);
|
|
||||||
EventRelay<InputSystem, Events::GamepadButtonUp> m_EGamepadButtonUp;
|
|
||||||
bool OnGamepadButtonUp(const Events::GamepadButtonUp &event);
|
|
||||||
// Input binding events
|
|
||||||
EventRelay<InputSystem, Events::BindKey> m_EBindKey;
|
|
||||||
bool OnBindKey(const Events::BindKey &event);
|
|
||||||
EventRelay<InputSystem, Events::BindMouseButton> m_EBindMouseButton;
|
|
||||||
bool OnBindMouseButton(const Events::BindMouseButton &event);
|
|
||||||
EventRelay<InputSystem, Events::BindGamepadAxis> m_EBindGamepadAxis;
|
|
||||||
bool OnBindGamepadAxis(const Events::BindGamepadAxis &event);
|
|
||||||
EventRelay<InputSystem, Events::BindGamepadButton> m_EBindGamepadButton;
|
|
||||||
bool OnBindGamepadButton(const Events::BindGamepadButton &event);
|
|
||||||
|
|
||||||
float GetCommandTotalValue(std::string command);
|
|
||||||
void PublishCommand(int playerID, std::string command, float value);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef KeyboardInputHandler_h__
|
||||||
|
#define KeyboardInputHandler_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "InputHandler.h"
|
||||||
|
#include "Core/EKeyDown.h"
|
||||||
|
#include "Core/EKeyUp.h"
|
||||||
|
|
||||||
|
class KeyboardInputHandler : public InputHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KeyboardInputHandler(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_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);
|
||||||
|
EventRelay<InputHandler, Events::KeyUp> m_EKeyUp;
|
||||||
|
bool OnKeyUp(const Events::KeyUp& e);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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,14 +1,84 @@
|
|||||||
#ifndef Client_h__
|
#ifndef Client_h__
|
||||||
#define 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();
|
public:
|
||||||
~Client();
|
Client(ConfigFile* config);
|
||||||
|
~Client();
|
||||||
|
void Start(World* world, EventBroker* eventBroker) override;
|
||||||
|
void Update() override;
|
||||||
|
void Close();
|
||||||
|
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[1024] = { 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;
|
||||||
|
bool m_ThreadIsRunning = true;
|
||||||
|
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 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
|
#endif
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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 128
|
||||||
|
|
||||||
|
class Network
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Network() { };
|
||||||
|
virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
|
||||||
|
virtual void Update() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#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();
|
||||||
|
// 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!");
|
||||||
|
}
|
||||||
|
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(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; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* m_Data;
|
||||||
|
unsigned int m_ReturnDataOffset = 0;
|
||||||
|
int m_Offset = 0;
|
||||||
|
unsigned int m_MaxPacketSize = 128;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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
|
||||||
@@ -1,12 +1,85 @@
|
|||||||
#ifndef Server_h__
|
#ifndef Server_h__
|
||||||
#define 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();
|
public:
|
||||||
~Server();
|
Server();
|
||||||
|
~Server();
|
||||||
|
void Start(World* m_world, EventBroker *eventBroker) override;
|
||||||
|
void Update() override;
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
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[1024] = { 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;
|
||||||
|
|
||||||
|
// Close logic
|
||||||
|
bool m_ThreadIsRunning = true;
|
||||||
|
|
||||||
|
// 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
|
#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
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#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)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#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(RenderQueueCollection& rq);
|
||||||
|
|
||||||
|
//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;
|
||||||
|
|
||||||
|
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
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#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;
|
||||||
|
// Depth
|
||||||
|
float Depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
PickData Pick(glm::vec2 screenCoord) const
|
||||||
|
{
|
||||||
|
PickData pickData;
|
||||||
|
|
||||||
|
// Invert screen y coordinate
|
||||||
|
screenCoord.y = Resolution.Height - screenCoord.y;
|
||||||
|
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer);
|
||||||
|
pickData.Depth = data.Depth;
|
||||||
|
|
||||||
|
auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1]));
|
||||||
|
if (it != PickingColorsToEntity->end()) {
|
||||||
|
pickData.Entity = it->second;
|
||||||
|
} else {
|
||||||
|
pickData.Entity = EntityID_Invalid;
|
||||||
|
}
|
||||||
|
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, 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
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
virtual void Draw(RenderQueueCollection& rq) = 0;
|
virtual void Draw(RenderQueueCollection& rq) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Rectangle m_Resolution = Rectangle(1280, 720);
|
Rectangle m_Resolution = Rectangle::Rectangle(1280, 720);
|
||||||
bool m_Fullscreen = false;
|
bool m_Fullscreen = false;
|
||||||
bool m_VSYNC = false;
|
bool m_VSYNC = false;
|
||||||
int m_GLVersion[2];
|
int m_GLVersion[2];
|
||||||
|
|||||||
@@ -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,49 @@
|
|||||||
|
#ifndef PickingPass_h__
|
||||||
|
#define PickingPass_h__
|
||||||
|
|
||||||
|
#include "IRenderer.h"
|
||||||
|
#include "PickingPassState.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
#include "Util/UnorderedMapVec2.h"
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "EPicking.h"
|
||||||
|
|
||||||
|
class PickingPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PickingPass(IRenderer* renderer, EventBroker* eb);
|
||||||
|
~PickingPass();
|
||||||
|
void InitializeTextures();
|
||||||
|
void InitializeFrameBuffers();
|
||||||
|
void InitializeShaderPrograms();
|
||||||
|
|
||||||
|
void Draw(RenderQueueCollection& rq);
|
||||||
|
|
||||||
|
|
||||||
|
//Getters
|
||||||
|
const ShaderProgram& PickingProgram() const { return *m_PickingProgram; }
|
||||||
|
const std::unordered_map<glm::vec2, 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; }
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity;
|
||||||
|
|
||||||
|
GLuint m_PickingTexture;
|
||||||
|
GLuint m_DepthBuffer;
|
||||||
|
|
||||||
|
FrameBuffer m_PickingBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#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
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "../GLM.h"
|
#include "../GLM.h"
|
||||||
#include "../Core/Util/Rectangle.h"
|
#include "../Core/Util/Rectangle.h"
|
||||||
#include "../Core/EntityWrapper.h"
|
#include "../Core/Entity.h"
|
||||||
|
|
||||||
class Model;
|
class Model;
|
||||||
class Skeleton;
|
class Skeleton;
|
||||||
|
|||||||
@@ -13,8 +13,12 @@ public:
|
|||||||
RenderQueueFactory();
|
RenderQueueFactory();
|
||||||
void Update(World* world);
|
void Update(World* world);
|
||||||
|
|
||||||
|
|
||||||
RenderQueueCollection RenderQueues() const { return m_RenderQueues; }
|
RenderQueueCollection RenderQueues() const { return m_RenderQueues; }
|
||||||
|
|
||||||
|
static glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
||||||
|
static glm::quat AbsoluteOrientation(World* world, EntityID entity);
|
||||||
|
static glm::vec3 AbsoluteScale(World* world, EntityID entity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RenderQueueCollection m_RenderQueues;
|
RenderQueueCollection m_RenderQueues;
|
||||||
|
|
||||||
@@ -22,7 +26,6 @@ private:
|
|||||||
void FillLights(World* world, RenderQueue* renderQueue);
|
void FillLights(World* world, RenderQueue* renderQueue);
|
||||||
|
|
||||||
glm::mat4 ModelMatrix(World* world, EntityID entity);
|
glm::mat4 ModelMatrix(World* world, EntityID entity);
|
||||||
glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -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
|
||||||
@@ -10,48 +10,118 @@
|
|||||||
#include "Util/UnorderedMapVec2.h"
|
#include "Util/UnorderedMapVec2.h"
|
||||||
#include "FrameBuffer.h"
|
#include "FrameBuffer.h"
|
||||||
#include "../Core/World.h"
|
#include "../Core/World.h"
|
||||||
|
#include "PickingPass.h"
|
||||||
|
#include "DrawScenePass.h"
|
||||||
|
#include "DebugCameraInputController.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TILE_SIZE 16
|
||||||
|
#define NUM_LIGHTS 3
|
||||||
|
|
||||||
|
|
||||||
|
enum lightType
|
||||||
|
{
|
||||||
|
Point,
|
||||||
|
Spot,
|
||||||
|
Directional,
|
||||||
|
Area
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "EPicking.h"
|
||||||
|
#include "ImGuiRenderPass.h"
|
||||||
|
|
||||||
class Renderer : public IRenderer
|
class Renderer : public IRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Initialize() override;
|
Renderer(EventBroker* eventBroker)
|
||||||
virtual void Update(double dt) override;
|
: m_EventBroker(eventBroker)
|
||||||
virtual void Draw(RenderQueueCollection& rq) override;
|
{ }
|
||||||
|
|
||||||
|
virtual void Initialize() override;
|
||||||
|
virtual void Update(double dt) override;
|
||||||
|
virtual void Draw(RenderQueueCollection& rq) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//----------------------Variables----------------------//
|
//----------------------Variables----------------------//
|
||||||
Texture* m_ErrorTexture;
|
EventBroker* m_EventBroker;
|
||||||
Texture* m_WhiteTexture;
|
|
||||||
float m_CameraMoveSpeed;
|
std::shared_ptr<DebugCameraInputController<Renderer>> m_DebugCameraInputController;
|
||||||
FrameBuffer m_PickingBuffer;
|
|
||||||
GLuint m_PickingTexture;
|
Texture* m_ErrorTexture;
|
||||||
GLuint m_DepthBuffer;
|
Texture* m_WhiteTexture;
|
||||||
|
float m_CameraMoveSpeed;
|
||||||
|
|
||||||
Model* m_ScreenQuad;
|
Model* m_ScreenQuad;
|
||||||
Model* m_UnitQuad;
|
Model* m_UnitQuad;
|
||||||
Model* m_UnitSphere;
|
Model* m_UnitSphere;
|
||||||
|
|
||||||
|
DrawScenePass* m_DrawScenePass;
|
||||||
|
PickingPass* m_PickingPass;
|
||||||
|
ImGuiRenderPass* m_ImGuiRenderPass;
|
||||||
|
|
||||||
|
//----------------------Functions----------------------//
|
||||||
std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity;
|
void InitializeWindow();
|
||||||
|
void InitializeShaders();
|
||||||
//----------------------Functions----------------------//
|
|
||||||
void InitializeWindow();
|
|
||||||
void InitializeShaders();
|
|
||||||
void InitializeTextures();
|
void InitializeTextures();
|
||||||
void InitializeFrameBuffers();
|
void InitializeSSBOs();
|
||||||
|
void InitializeRenderPasses();
|
||||||
//TODO: Renderer: Get InputUpdate out of renderer
|
//TODO: Renderer: Get InputUpdate out of renderer
|
||||||
void InputUpdate(double dt);
|
void InputUpdate(double dt);
|
||||||
void PickingPass(RenderQueueCollection& rq);
|
//void PickingPass(RenderQueueCollection& rq);
|
||||||
void DrawScreenQuad(GLuint textureToDraw);
|
void DrawScreenQuad(GLuint textureToDraw);
|
||||||
void DrawScene(RenderQueueCollection& rq);
|
|
||||||
|
|
||||||
|
//----------------------Forward+-----------------------//
|
||||||
|
void CalculateFrustum();
|
||||||
|
void CullLights();
|
||||||
|
//Frustum
|
||||||
|
struct Plane {
|
||||||
|
glm::vec3 Normal;
|
||||||
|
float d;
|
||||||
|
};
|
||||||
|
struct Frustum {
|
||||||
|
Plane Planes[4];
|
||||||
|
};
|
||||||
|
Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution
|
||||||
|
|
||||||
|
//Lights
|
||||||
|
void TEMPCreateLights();
|
||||||
|
//TODO: Renderer: Add Directionllights, spotlights and area lights to this as type.
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
PointLight m_PointLights[NUM_LIGHTS];
|
||||||
|
|
||||||
|
struct LightGrid {
|
||||||
|
int Amount;
|
||||||
|
int Start;
|
||||||
|
glm::vec2 Padding;
|
||||||
|
};
|
||||||
|
LightGrid m_LightGrid[80*45];
|
||||||
|
|
||||||
|
int m_LightOffset = 0;
|
||||||
|
|
||||||
|
int m_LightIndex[80*45*200];
|
||||||
|
|
||||||
|
//-------------------------SSBO------------------------//
|
||||||
|
GLuint m_FrustumSSBO = 0;
|
||||||
|
GLuint m_LightSSBO = 1;
|
||||||
|
GLuint m_LightGridSSBO = 2;
|
||||||
|
GLuint m_LightOffsetSSBO = 3;
|
||||||
|
GLuint m_LightIndexSSBO = 4;
|
||||||
|
|
||||||
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
|
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
|
||||||
//--------------------ShaderPrograms-------------------//
|
//--------------------ShaderPrograms-------------------//
|
||||||
ShaderProgram m_BasicForwardProgram;
|
ShaderProgram* m_BasicForwardProgram;
|
||||||
ShaderProgram m_PickingProgram;
|
ShaderProgram* m_DrawScreenQuadProgram;
|
||||||
ShaderProgram m_DrawScreenQuadProgram;
|
ShaderProgram* m_CalculateFrustumProgram;
|
||||||
|
ShaderProgram* m_LightCullProgram;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
|
#ifndef ShaderProgram_h__
|
||||||
|
#define ShaderProgram_h__
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "../OpenGL.h"
|
#include "../OpenGL.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
class Shader
|
class Shader
|
||||||
@@ -60,11 +63,13 @@ public:
|
|||||||
: ShaderType(fileName) { }
|
: ShaderType(fileName) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShaderProgram
|
class ShaderProgram : public Resource
|
||||||
{
|
{
|
||||||
public:
|
friend class ResourceManager;
|
||||||
ShaderProgram()
|
private:
|
||||||
|
ShaderProgram(std::string)
|
||||||
: m_ShaderProgramHandle(0) { }
|
: m_ShaderProgramHandle(0) { }
|
||||||
|
public:
|
||||||
~ShaderProgram();
|
~ShaderProgram();
|
||||||
|
|
||||||
void AddShader(std::shared_ptr<Shader> shader);
|
void AddShader(std::shared_ptr<Shader> shader);
|
||||||
@@ -79,3 +84,5 @@ private:
|
|||||||
GLuint m_ShaderProgramHandle;
|
GLuint m_ShaderProgramHandle;
|
||||||
std::vector<std::shared_ptr<Shader>> m_Shaders;
|
std::vector<std::shared_ptr<Shader>> m_Shaders;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -9,7 +9,7 @@ inline bool _GLERROR(const char* info, const char* file, const char* func, unsig
|
|||||||
GLenum error = glGetError();
|
GLenum error = glGetError();
|
||||||
if (error != GL_NO_ERROR)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ class ScreenCoords
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScreenCoords() = delete;
|
ScreenCoords() = delete;
|
||||||
|
|
||||||
|
struct PixelData
|
||||||
|
{
|
||||||
|
int Color[2];
|
||||||
|
float Depth;
|
||||||
|
};
|
||||||
|
|
||||||
//Return world position from given screenspace coordinates and depth value in viewspace.
|
//Return world position from given screenspace coordinates and depth value in viewspace.
|
||||||
static glm::vec3 ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
static glm::vec3 ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
||||||
static glm::vec3 ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
static glm::vec3 ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
||||||
@@ -18,8 +25,8 @@ public:
|
|||||||
static glm::vec3 ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
static glm::vec3 ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
||||||
//Return data from the given buffers at the coordinates given in screenspace. Buffer should probably have a texture that covers the screen.
|
//Return data from the given buffers at the coordinates given in screenspace. Buffer should probably have a texture that covers the screen.
|
||||||
//Data is given as R = x, B = y, and
|
//Data is given as R = x, B = y, and
|
||||||
static glm::vec3 ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
static PixelData ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
||||||
static glm::vec3 ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
static PixelData ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
||||||
//Return EntityID of the clicked coordinate in given screenspace coordinates.
|
//Return EntityID of the clicked coordinate in given screenspace coordinates.
|
||||||
//EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth);
|
//EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,24 @@
|
|||||||
#include "GUI/Frame.h"
|
#include "GUI/Frame.h"
|
||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
#include "Rendering/RenderQueueFactory.h"
|
#include "Rendering/RenderQueueFactory.h"
|
||||||
|
#include "Input/InputProxy.h"
|
||||||
|
#include "Input/KeyboardInputHandler.h"
|
||||||
|
#include "Input/MouseInputHandler.h"
|
||||||
|
#include "Core/EKeyDown.h"
|
||||||
|
#include "Core/EntityFilePreprocessor.h"
|
||||||
|
#include "Core/SystemPipeline.h"
|
||||||
|
#include "RaptorCopterSystem.h"
|
||||||
|
#include "PlayerSystem.h"
|
||||||
|
#include "Editor/EditorSystem.h"
|
||||||
|
#include "Core/EntityFile.h"
|
||||||
|
#include "Core/EntityFileParser.h"
|
||||||
|
|
||||||
|
// Network
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include "Network/Network.h"
|
||||||
|
#include "Network/Server.h"
|
||||||
|
#include "Network/Client.h"
|
||||||
|
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
@@ -25,9 +43,26 @@ private:
|
|||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
IRenderer* m_Renderer;
|
IRenderer* m_Renderer;
|
||||||
InputManager* m_InputManager;
|
InputManager* m_InputManager;
|
||||||
|
InputProxy* m_InputProxy;
|
||||||
GUI::Frame* m_FrameStack;
|
GUI::Frame* m_FrameStack;
|
||||||
World* m_World;
|
World* m_World;
|
||||||
|
SystemPipeline* m_SystemPipeline;
|
||||||
RenderQueueFactory* m_RenderQueueFactory;
|
RenderQueueFactory* m_RenderQueueFactory;
|
||||||
|
// Network variables
|
||||||
|
boost::thread m_NetworkThread;
|
||||||
|
|
||||||
|
// Network methods
|
||||||
|
void networkFunction();
|
||||||
|
Network* m_ClientOrServer;
|
||||||
|
bool m_IsClientOrServer = false;
|
||||||
|
|
||||||
|
EventRelay<Game, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool debugOnInputCommand(const Events::InputCommand& e);
|
||||||
|
|
||||||
|
void debugInitialize();
|
||||||
|
void debugTick(double dt);
|
||||||
|
EventRelay<Client, Events::KeyDown> m_EKeyDown;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
#include <list>
|
|
||||||
#include <tuple>
|
|
||||||
#include <boost/any.hpp>
|
|
||||||
#include "GLM.h"
|
|
||||||
#include "Core/World.h"
|
|
||||||
#include "Core/Util/Any.h"
|
|
||||||
|
|
||||||
class HardcodedTestWorld : public World
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HardcodedTestWorld()
|
|
||||||
: World()
|
|
||||||
{
|
|
||||||
registerTestComponents();
|
|
||||||
createTestEntities();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void registerTestComponents()
|
|
||||||
{
|
|
||||||
ComponentWrapperFactory f;
|
|
||||||
|
|
||||||
|
|
||||||
f = ComponentWrapperFactory("Test");
|
|
||||||
f.AddProperty("TestInteger", 1337);
|
|
||||||
f.AddProperty("TestFloat", 13.37f);
|
|
||||||
f.AddProperty("TestString", std::string("Carlito"));
|
|
||||||
RegisterComponent(f);
|
|
||||||
|
|
||||||
f = ComponentWrapperFactory("Debug");
|
|
||||||
f.AddProperty("Name", std::string("Unnamed"));
|
|
||||||
RegisterComponent(f);
|
|
||||||
|
|
||||||
f = ComponentWrapperFactory("Transform");
|
|
||||||
f.AddProperty("Position", glm::vec3(0.f, 0.f, 0.f));
|
|
||||||
f.AddProperty("Orientation", glm::quat());
|
|
||||||
f.AddProperty("Scale", glm::vec3(1.f, 1.f, 1.f));
|
|
||||||
RegisterComponent(f);
|
|
||||||
|
|
||||||
f = ComponentWrapperFactory("Model");
|
|
||||||
f.AddProperty("Resource", std::string());
|
|
||||||
f.AddProperty("Color", glm::vec4(1.f, 1.f, 1.f, 1.f));
|
|
||||||
f.AddProperty("Visible", true);
|
|
||||||
RegisterComponent(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void createTestEntities()
|
|
||||||
{
|
|
||||||
World& world = *this;
|
|
||||||
|
|
||||||
// Create an entity
|
|
||||||
EntityID e = world.CreateEntity();
|
|
||||||
|
|
||||||
// Attach a Debug component
|
|
||||||
ComponentWrapper debug = world.AttachComponent(e, "Debug");
|
|
||||||
// Set the Name field of the Debug component using subscript operator
|
|
||||||
debug["Name"] = "Carlito";
|
|
||||||
|
|
||||||
// Attach a Transform component
|
|
||||||
world.AttachComponent(e, "Transform");
|
|
||||||
// Fetch the component based on EntityID and component type
|
|
||||||
ComponentWrapper transform = world.GetComponent(e, "Transform");
|
|
||||||
// Set the fields of the Transform component
|
|
||||||
transform["Position"] = glm::vec3(0.f, 0.f, 0.f);
|
|
||||||
transform["Scale"] = glm::vec3(1.f, 1.f, 1.f);
|
|
||||||
|
|
||||||
// Move on the X axis by fetching field as reference
|
|
||||||
((glm::vec3&)transform["Position"]).x += 10.f;
|
|
||||||
// Shrink by a factor of 100
|
|
||||||
((glm::vec3&)transform["Scale"]) /= 100.f;
|
|
||||||
|
|
||||||
// Loop through all Transform components and print them
|
|
||||||
for (auto& transform : world.GetComponents("Transform")) {
|
|
||||||
glm::vec3 pos = transform["Position"];
|
|
||||||
std::cout << "Position: " << pos.x << " " << pos.y << " " << pos.z << std::endl;
|
|
||||||
glm::vec3 scale = transform["Scale"];
|
|
||||||
std::cout << "Scale: " << scale.x << " " << scale.y << " " << scale.z << std::endl;
|
|
||||||
|
|
||||||
// Fetch the Debug component also present in this entity
|
|
||||||
ComponentWrapper debug = world.GetComponent(transform.EntityID, "Debug");
|
|
||||||
std::cout << "Name: " << (std::string)debug["Name"] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create some test widgets
|
|
||||||
{
|
|
||||||
EntityID entityScaleWidget = world.CreateEntity();
|
|
||||||
ComponentWrapper transform = world.AttachComponent(entityScaleWidget, "Transform");
|
|
||||||
transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f);
|
|
||||||
ComponentWrapper model = world.AttachComponent(entityScaleWidget, "Model");
|
|
||||||
model["Resource"] = "Models/ScaleWidget.obj";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
EntityID entityRotationWidget = world.CreateEntity();
|
|
||||||
ComponentWrapper transform = world.AttachComponent(entityRotationWidget, "Transform");
|
|
||||||
transform["Position"] = glm::vec3(1.5f, 0.f, 0.f);
|
|
||||||
ComponentWrapper model = world.AttachComponent(entityRotationWidget, "Model");
|
|
||||||
model["Resource"] = "Models/RotationWidget.obj";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
EntityID entityDummyScene = world.CreateEntity();
|
|
||||||
ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform");
|
|
||||||
transform["Position"] = glm::vec3(0, 0.f, 0.f);
|
|
||||||
ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model");
|
|
||||||
model["Resource"] = "Models/DummyScene.obj";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef HealthSystem_h__
|
||||||
|
#define HealthSystem_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/common.hpp>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Core\EPlayerDamage.h";
|
||||||
|
#include "Core\EPlayerHealthPickup.h";
|
||||||
|
#include "Core\EPlayerDeath.h";
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class HealthSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HealthSystem(EventBroker* eventBroker);
|
||||||
|
|
||||||
|
//updatecomponent
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& health, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//methods which will take care of specific events
|
||||||
|
EventRelay<HealthSystem, Events::PlayerDamage> m_EPlayerDamage;
|
||||||
|
bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e);
|
||||||
|
EventRelay<HealthSystem, Events::PlayerHealthPickup> m_EPlayerHealthPickup;
|
||||||
|
bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e);
|
||||||
|
|
||||||
|
//vector which will keep track of health changes
|
||||||
|
std::vector<std::tuple<EntityID, double>> m_DeltaHealthVector;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef PlayerSystem_h__
|
||||||
|
#define PlayerSystem_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/common.hpp>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Collision/ETrigger.h"
|
||||||
|
|
||||||
|
class PlayerSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PlayerSystem(EventBroker* eventBroker)
|
||||||
|
: PureSystem(eventBroker, "Player")
|
||||||
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ETouch, &PlayerSystem::OnTouch);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EEnter, &PlayerSystem::OnEnter);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ELeave, &PlayerSystem::OnLeave);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& player, double dt) override;
|
||||||
|
private:
|
||||||
|
float m_Speed = 5;
|
||||||
|
EventRelay<PlayerSystem, Events::TriggerEnter> m_EEnter;
|
||||||
|
bool OnEnter(const Events::TriggerEnter &event);
|
||||||
|
EventRelay<PlayerSystem, Events::TriggerTouch> m_ETouch;
|
||||||
|
bool PlayerSystem::OnTouch(const Events::TriggerTouch &event);
|
||||||
|
EventRelay<PlayerSystem, Events::TriggerLeave> m_ELeave;
|
||||||
|
bool PlayerSystem::OnLeave(const Events::TriggerLeave &event);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
|
class RaptorCopterSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaptorCopterSystem(EventBroker* eventBroker)
|
||||||
|
: PureSystem(eventBroker, "RaptorCopter")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& raptorCopter, double dt) override
|
||||||
|
{
|
||||||
|
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
|
||||||
|
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"];
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,8 +1,19 @@
|
|||||||
[Debug]
|
[Debug]
|
||||||
LogLevel=1
|
LogLevel=1
|
||||||
|
LoadMap=
|
||||||
|
EditorEnabled=false
|
||||||
|
|
||||||
|
|
||||||
[Video]
|
[Video]
|
||||||
Fullscreen=false
|
Fullscreen=false
|
||||||
VSYNC=false
|
VSYNC=false
|
||||||
Width=1280
|
Width=1280
|
||||||
Height=720
|
Height=720
|
||||||
|
FOV=45
|
||||||
|
|
||||||
|
[Networking]
|
||||||
|
StartNetwork=false
|
||||||
|
IsServer=false
|
||||||
|
Name=Bob
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=13
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
[Mouse]
|
||||||
|
Sensitivity=0.5
|
||||||
|
InvertPitch=false
|
||||||
|
|
||||||
|
[Bindings]
|
||||||
|
MouseLeft=PrimaryFire
|
||||||
|
MouseX=Yaw
|
||||||
|
MouseY=Pitch
|
||||||
|
W=+Forward
|
||||||
|
S=-Forward
|
||||||
|
D=+Right
|
||||||
|
A=-Right
|
||||||
|
R=Reload
|
||||||
|
Space=Jump
|
||||||
|
LeftControl=Crouch
|
||||||
|
LeftShift=Sprint
|
||||||
|
F1=ToggleEditor
|
||||||
|
1=EditorToolMove
|
||||||
|
2=EditorToolRotate
|
||||||
|
3=EditorToolScale
|
||||||
|
X=EditorToggleTransformSpace
|
||||||
|
C=ConnectToServer
|
||||||
|
N=SwitchToServer
|
||||||
|
M=SwitchToClient
|
||||||
@@ -2,5 +2,11 @@
|
|||||||
|
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="components" elementFormDefault="qualified">
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="components" elementFormDefault="qualified">
|
||||||
<xs:include schemaLocation="Components/Transform.xsd"/>
|
<xs:include schemaLocation="Components/Transform.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Model.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Test.xsd"/>
|
<xs:include schemaLocation="Components/Test.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/RaptorCopter.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Player.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/AABB.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Trigger.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Health.xsd"/>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<c:AABB>
|
||||||
|
<BoxCenter X="0" Y="0" Z="0"/>
|
||||||
|
<BoxSize X="1" Y="1" Z="1"/>
|
||||||
|
</c:AABB>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="AABB">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="BoxCenter" type="t:Vector" minOccurs="0"/>
|
||||||
|
<xs:element name="BoxSize" type="t:Vector" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<c:Health>
|
||||||
|
<Health>100</Health>
|
||||||
|
<MaxHealth>100</MaxHealth>
|
||||||
|
</c:Health>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="Health">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Health" type="t:double" minOccurs="0"/>
|
||||||
|
<xs:element name="MaxHealth" type="t:double" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<c:Model>
|
||||||
|
<Resource></Resource>
|
||||||
|
<Color R="1" G="1" B="1" A="1"/>
|
||||||
|
<Visible>true</Visible>
|
||||||
|
</c:Model>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="Model">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A visible model loaded from disk</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Resource" type="t:string" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Model file</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="Color" type="t:Color" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Color tint</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="Visible" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Wether the model is visible or not</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<c:Player>
|
||||||
|
<Velocity X="0" Y="0" Z="0"/>
|
||||||
|
<Forward>false</Forward>
|
||||||
|
<Left>false</Left>
|
||||||
|
<Back>false</Back>
|
||||||
|
<Right>false</Right>
|
||||||
|
</c:Player>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="Player">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
|
||||||
|
<xs:element name="Forward" type="t:bool" minOccurs="0"/>
|
||||||
|
<xs:element name="Left" type="t:bool" minOccurs="0"/>
|
||||||
|
<xs:element name="Back" type="t:bool" minOccurs="0"/>
|
||||||
|
<xs:element name="Right" type="t:bool" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0</Speed>
|
||||||
|
<Axis X="0" Y="0" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="RaptorCopter">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Speed" type="t:double" minOccurs="0"/>
|
||||||
|
<xs:element name="Axis" type="t:Vector" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<c:Test>
|
|
||||||
<Integer>1</Integer>
|
|
||||||
<Float>1.333</Float>
|
|
||||||
<Vector X="1.33333" Y="2.33333" Z="3.33333"/>
|
|
||||||
<Quaternion I="1.33333" J="2.33333" K="3.33333"/>
|
|
||||||
</c:Test>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
|
||||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
|
||||||
|
|
||||||
<xs:element name="Test">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>ECS Test Component</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:all>
|
|
||||||
<xs:element name="Integer" type="t:int" minOccurs="0"/>
|
|
||||||
<xs:element name="Double" type="t:double" minOccurs="0"/>
|
|
||||||
<xs:element name="String" type="t:string" minOccurs="0"/>
|
|
||||||
<xs:element name="Vector" type="t:Vector" minOccurs="0"/>
|
|
||||||
<xs:element name="Quaternion" type="t:Quaternion" minOccurs="0"/>
|
|
||||||
</xs:all>
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:schema>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<TransformComponent>
|
<c:Transform>
|
||||||
<Position X="0" Y="0" Z="0"/>
|
<Position X="0" Y="0" Z="0"/>
|
||||||
<Orientation I="0" J="0" K="0"/>
|
<Orientation X="0" Y="0" Z="0"/>
|
||||||
<Scale X="1" Y="1" Z="1"/>
|
<Scale X="1" Y="1" Z="1"/>
|
||||||
</TransformComponent>
|
</c:Transform>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<xs:element name="Position" type="t:Vector" minOccurs="0">
|
<xs:element name="Position" type="t:Vector" minOccurs="0">
|
||||||
<xs:annotation><xs:documentation>The position vector</xs:documentation></xs:annotation>
|
<xs:annotation><xs:documentation>The position vector</xs:documentation></xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="Orientation" type="t:Quaternion" minOccurs="0"/>
|
<xs:element name="Orientation" type="t:Vector" minOccurs="0"/>
|
||||||
<xs:element name="Scale" type="t:Vector" minOccurs="0"/>
|
<xs:element name="Scale" type="t:Vector" minOccurs="0"/>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<c:Trigger>
|
||||||
|
</c:Trigger>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="Trigger">
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user