diff --git a/ChangeLog.md b/ChangeLog.md new file mode 100644 index 000000000..3e4eccbc0 --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1,279 @@ +# Upcoming version: + +Nazara Engine: +- VertexMapper:GetComponentPtr no longer throw an error if component is disabled or incompatible with template type, instead a null pointer is returned. +- Bitset swap operation is now correctly marked as noexcept` +- Mesh loaders now takes MeshParams vertexDeclaration into account +- ⚠️ Replaced RenderTarget::Get[Height|Width] by RenderTarget::GetSize +- ⚠️ Removed Window::Get[Height|Width] methods +- Fix compilation error when including Nazara/Renderer/ShaderBuilder.hpp +- Fix reflection sometimes being enabled by default for Materials +- Fix built-in unserialization of std::string which was corruption memory +- Fix Buffer::Destroy() not really destroying buffer +- Fix Bitset::TestAll() returned wrong result on full of '1' bitset +- ByteStream now returns the number of bytes written as the other streams +- Total rewriting of the color conversions +- Fix NormalizeAngle to the correct range +- Fix BoundingVolume::Lerp() with Extend_Null +- Simplification of methods Matrix4::SetRotation() and Quaternion::MakeRotationBetween() +- Fix mouve moved event generated on X11 platform when doing Mouse::SetPosition() +- EnumAsFlags specialization no longer require a `value` field to enable flags operators +- EnumAsFlags specialization `max` field can be of the same type as the enum +- Flags class now use an UInt8 or UInt16 to store the value if possible. +- Flags class is now explicitly convertible to any integer type of the same size (or greater size) than the internal size. +- Fix String movement constructor, which was leaving a null shared string (which was not reusable) +- Add Flags::Test method, in order to test one or multiple flags at once. +- ⚠️ Vector2, Vector3 and Vector4 array/pointer constructor is now explicit to prevent some mistakes as `Vector2 vec2; vec2 = 0;` + + +Nazara Development Kit: +- Added ImageWidget (#139) +- ⚠️ Removed TextAreaWidget::GetLineCount +- Fix World movement which could cause crashes when updating systems +- Fix crash occuring sometimes on keyboard event +- Add support for EchoMode to TextAreaWidget (which allows to setup password text area) +- Add signal OnTextChanged to TextAreaWidget +- ⚠️ Removed TextAreaWidget::GetGlyphUnderCursor +- Fixed minor issues relative to TextAreaWidget cursor handling +- ⚠️ Renamed BaseWidget::GrabKeyboard method to SetFocus +- Added BaseWidget::ClearFocus method and OnFocus[Lost|Received] virtual methods +- TextAreaWidget will now show a cursor as long as it has focus +- Fix BaseWidget linking error on Linux +- ⚠️ Rewrite StateMachine to fix instantaneous state changing (state change is no longer effective until the next update call) +- Fix entities destruction when coming from World::Clear() (also called by destructor), which invalidated world entities handles before destroying entities (preventing destruction callback to get valid entities handles from world) +- Add Entity::Disable method, which is a shortcut to Enable(false) +- Add BaseWidget::HasFocus +- Fix TextAreaWidget cursor sometimes showing up in readonly mode +- ⚠️ BaseWidget::OnKeyPressed now returns a boolean to indicate if it should block default action (such as tab to switch to the previous/next widget) +- Pressing tab/shift-tab will now move to the next/previous widget able to be focused on + +# 0.4: + +Build system: +- ⚠️ Update premake binaries version to premake5-alpha12 +- It is now possible to generate a tool project running which will run the premake when built on Windows (PremakeProject=true). +- Added VS2017 Windows shortcut + +Nazara Engine: +- Improved Particle Demo +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/126 File locking now works properly on Linux +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/136 Fixed std::getline with Nz::String not setting eofbit. +- Added support for CRC64 +- Added MovablePtr utility class +- ⚠️ StackAllocation class has been replaced with much-more user-friendly StackArray class. +- ⚠️ ParameterList now takes double and long long parameter instead of float and int parameters. +- Threads can now be named (for debug purposes) +- Added ParameterList::ForEach method +- Flags operators works in the global namespace as well +- **Added support for skybox reflections, realtime reflections are on the tracks!** +- ⚠️ InstancedRenderable now handle materials and skins in a generic way (which means you can use skins on every InstancedRenderable such as Billboard, Sprites, etc.). +- **Added support for coroutines (LuaCoroutine class)** +- ⚠️ Introduction of a new class, LuaState (inherited by LuaCoroutine and LuaInstance). +- **Added ENet protocol support for reliable UDP communication** +- ⚠️ SocketPoller is now able to wait on read/write status of socket +- ⚠️ SocketPoller::Wait() has now support for infinite waiting (-1) +- Added UdpSocket::ReceiveMultiple method +- **Added WIP shader build (based on AST, with support for GLSL)** +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/127 Fixed RigidBody2D::GetAABB() wrong AABB +- **Added basic support for constraints** +- Added support for collision callbacks +- Added support for raycast +- Added support for nearest body queries +- Added support for debug draw +- Added support for damping +- ⚠️ RigidBody2D created without mass are now kinematic by default instead of statics +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/128 ⚠️ **Platform-specific classes were moved to a new module: Platform** (this means Utility module no longer needs to be linked to X11/xcb or gdi32). +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/135 ⚠️ Improved vertex declarations (they now checks template type with real type) +- Mesh index buffer optimization is now disabled by default in debug mode +- It is now possible to set the vertex declaration wanted when building/loading a mesh +- It is now possible to set index/vertex buffer usage flags when building/loading a mesh +- Added VertexMapper::GetVertexBuffer() +- Added VertexMapper::GetVertexCount() +- Added VertexMapper::HasComponentOfType() +- Fixed SimpleTextDrawer bounds computation + + +Nazara Development Kit: +- ⚠️ Components no longer need to be copyable by assignation +- Added BaseComponent::GetEntity() +- ⚠️Systems are no longer copyable/clonable +- ⚠️World::[Get|Set]UpdateRate has been renamed World::[Get|Set]FixedUpdateRate. +- Added World::[Get|Set]MaximumUpdateRate. +- Added BaseWidget::CenterHorizontal() +- Added BaseWidget::CenterVertical() +- EntityHandle are now handled in such a way they will never move in memory until a world update is triggered, this means it is now safe to returns const reference to EntityHandle as long as you do not keep them from one world update to another. +- Fixed a crash when destroying a hovered widget +- Added CollisionComponent2D::GetAABB() +- Added Entity::OnEntityDestruction signal +- ⚠️EntityList were remade to take less memory and are easier to use but can only be iterated from front to back +- Entities are now automatically removed from EntityLists when destroyed. +- It is no longer required for a component to have a default constructor to be binded to Lua. +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/123 StateMachine can now handle multiple states at once +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/132 Added ProgressBarWidget +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/133 ButtonWidget color and texture can now be customized +- https://github.com/DigitalPulseSoftware/NazaraEngine/pull/130 Added CheckboxWidget +- Added OnEntityDestruction() event on components in order to let them do better cleanup. + +# 0.3 + +Build system: +- Added `Configurations` parameter for build system, with support for ReleaseWithDebug. (67dcf166b80b4de1ecb5256a271a5ac80526435d) + +Nazara Engine: +- **Added new particle demo (Space battle)**. (3c6a6cd3a9294e5ba577af9ec3bef695438c28b7) +- **Added back automatic Frustum Culling**. (a349b931e6a5b45586316763a458e1d89758542a) +- **Added Nz::Flags class to properly handle enum flags**. (d6b793f46178a05998182a4bbe595c425465eb07) +- **Refactored Buffer classes to prepare the new Renderer**. (9e0fd0a8e82567d03f063728e76f6dd5571760f2) +- **Added a way to override über-shaders used by the engine at runtime**. (d2d6bae47f326562a2c50631f169100e35ecdd09) +- ⚠️ **Reworked Nz::Cursor, it now includes default system cursors, allows to retrieve its image and is ref-counted** (6751d480b152a6203262b72e2cbe120007741621, 6751d480b152a6203262b72e2cbe120007741621, 0cab95e8aea4d2fb8a58c9dba2d609e33c748093). +- ⚠️ Nz::WindowCursor has been renamed to Nz::SystemCursor. (6751d480b152a6203262b72e2cbe120007741621) +- Added Nz::CursorController class, for indirect cursor control. (a2e5e4874469958b658c24d8a52bb9bc274e9398) +- Added Nz::UdpSocket::SendMultiple method, allowing to merge multiple buffers into the same datagram. (ea0d42f4234bcca184bb42aef16fb2a4e1346913). +- Added [Nz::TcpClient::SendMultiple](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_tcp_client.html#a495c32beb46ed9192699a3b82d358035) method, allowing to send multiple buffers at once. +- Added [Nz::PlacementDestroy](https://nazara.digitalpulsesoftware.net/doc/namespace_nz.html#a27c8667def991fc896c5beff3e62668a). (ea985fa76586762f008e4054938db3234eeaf0cb) +- Added [Nz::String::Format](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_string.html#a4b699982e7f9ea38f6d44b43ac1e2040) and [Nz::String::FormatVA](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_string.html#abe0fcbce11224b157ac756b60e8dee92) static methods. (cc6e4127dc6c61799a64404770992cef0804ad34). +- Added [Nz::ParticleGroup::GetBuffer](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_particle_mapper.html#aefe1b251efc8c9b8668842275561be0c) method. (4dc85789b59e50d964c83321dbd4b6485c04bef6) +- Added Nz::ParticleMapper::GetPointer method. (1f4e6c2d1594b7bb9dd6f4ea5480fdd16cf5f208) +- ⚠️ Structures provied by ParticleStruct header now have a float life. (472d964d587d906764ad1e05bfcc9ab1bf979483) +- Fixed scale property of Nz::TextSprite not affecting its bounding volume. (52b29bac775823294c4ad7de70f4dc3f4adfa743) +- ⚠️ Nz:MeshParams::flipUVs has been replaced by texCoordOffset and texCoordScale. (a1a7d908adc060fd7a43491c903dfe3b501d98e5) +- Fixed [Nz::Music::Stop](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_music.html#a9f0eb20328d6b35ab290b19364e95ee8) which was not resetting the playing offset. (12d7bc9aa3b672fc855478904072ed18f06e37ca, 24be97447af5c55b444a96e8d5d000e590279171) +- Reworked LuaBinding classes to try to improve compile time and generated objects memory. (5555d24afca2ec766c7625bb8e959560677b69c2). +- ⚠️ Convert OpenMode to use the new Nz::Flags class. (49dfe31fa036cdac4f531a15972e2bd52fa9ab57) +- ⚠️ Convert StreamOption to use the new Nz::Flags class. (49dfe31fa036cdac4f531a15972e2bd52fa9ab57) +- ⚠️ Convert WindowStyleFlags to use the new Nz::Flags class. (6c0422350fea520f96253df1113ee7c49233bd06) +- ⚠️ Fix typo in OpenMode_MustExist (previously written as "MustExit"). (445ab13ef8a78c07697556ae50086a9276cbf7c2) +- Added [Nz::String::GetCharacterPosition](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_string.html#acd89bc8d5afaa808c8baa480501d5f58) method. (2f4ca23cdaefc8350a95d2d6aa741602b5ee00f1) +- Exposed Nz::SoftwareBuffer class. (842786d2d482890ad3ed9ba88613f1d2a0f901ba) +- ⚠️ Removed Sphere::SquaredDistance method, use Vector3::SquaredDistance with its center instead. (5b017aecfdb86246fe8517453376801b00c23843) +- Fixed SceneAmbient shader uniform not being sent by DepthRenderTechnique. (83e345a2fc25073a9f10b0a3547a75692613f9b3) +- Fixed light selection bug (causing an object to not have any light on it although it is within its radius). (9c04d79b2906940067a32d84800edd1ffd38d9bd) +- Renderer::SetTexture and Renderer::SetTextureSampler now takes `unsigned int` instead of `UInt8` texture indexes. (09c2cbf1c5eeadac52c72459b0fb6df3064fc16a) +- When a shader fails to validate, its uniform are now dumped to the log. (0d37a3d4bf68bce9f533ad8c95225809cc312cdd) +- When a shader fails to compile, its code is now dumped to the log. (53ee8915fa0255b5c7492952919edd3a70e29b6c) +- ⚠️ Texture units used by Nazara are now static, fixes a bug with shadow. (b290a1233d725636d73c3bd8b37c394d93789524) +- Nz::Signal move constructor and assignement operators are now `noexcept`. (00144e944e6d8d894aef8b7bced9a6b364091626) +- Nz::EventHandler is now a handled object. (498b84fc690bae084a63ef379452cd45173c933a). +- Added a way to specify receive and send buffer size per socket. (c4459f5910d1f7e5833e2cbdca1dbd048a9a0416). +- Fixed ObjectHandle <= operator. (6f601101d23fe790dd83a1f69a137009116ad91b) +- Fixed Nz::UdpSocket::Receive failing when peers suddenly closes its socket. (12401e0e2f0cee0ab8fcd9124cce368e54f8037b) +- All noises classes now uses std::mt19937 as a random number generator, to ensure the same results on every machine. (1f5ea9839016964c173d919263827dee69ecb65d) + +Nazara Development Kit: +- **Added basic widgets**. (c8a12083b3133e946bf60dd060331a4b4631f8d8) +- VelocitySystem will no longer affect entities with PhysicsComponent2D. (a6853234412c744cdcb28344f02f7b0c92704d77) +- Fixed EulerAngles constructor in Lua. (d55149a0a70f6230b6f1c3fb50e37dc82a2feb9f) +- Fixed Component::OnDetached not being called on entity destruction. (5b777eb4853639d7aeb232ca46d17f0d432f47ca) + +Nazara Engine: + +# 0.2.1 + +Nazara Engine: +- Nazara binaries are now compiled with Run-Time Type-Information. (a70acdc8f44010627a65282fd3099202116d3e13) +- Nazara demos are now compiled with relative dependencies on Linux. + (d6fbb4c408d48c4a768fad7b43460c76a0df1777) +- Added [**Nz::BitCount**](https://nazara.digitalpulsesoftware.net/doc/group__core.html#ga6bfbcff78eb6cfbe3ddaedcfc8c04196) function. (82e31a3ec8449da6618f41690164c2e1d883edb4) +- Added [**Nz::Bitset::AppendBits**](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_bitset.html#a5ca8f365006c86d6d699d02471904f7e) method. (b018a400499a2356c4455a40d9f6a6c12b3cb36b) +- Added [**Nz::Bitset::Read**](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_bitset.html#aca204e1d71e36d6c8c2c544ffd9824ac) method. (f0c40ecb2f2f64f5af46f38e4b589d8c1dea824c) +- Added [**Nz::Bitset::Reverse**](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_bitset.html#af372e64f33a2114837fb25daffcc1008) method. (0abd1bbfbf6b949e350a78170aae1b45698620eb) +- Added [**Nz::Bitset::FromPointer**](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_bitset.html#a487836f91821e6d7901eb753baf47de3) static method. (f0c40ecb2f2f64f5af46f38e4b589d8c1dea824c) +- Added an operator<< for `ostream` and `Nz::Bitset`. (9d9efac2baf29842e58b3e73f255ca06cb24d1fb) +- Added `Nz::Image::HasAlpha` method. (1029b37d3654aea9fcc4fd2a43e6d32c9842268a) +- Added a [**Sprite::SetMaterial**](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_sprite.html#a3074f991b72af8146c5b5ba2fdda42fa) overload taking a material name. (d50f5ed7c88e613e01c76c3765d86b2014773ba8) +- Added a [**Sprite::SetTexture**](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_sprite.html#a6ddf41ffff1e155a99b06487e72ae47d) overload taking a texture name. (d50f5ed7c88e613e01c76c3765d86b2014773ba8) +- Added Nz::SegmentCollider2D class. (0ede1e893aab6ab159b57eea24af273e82d68d16) +- Nz::CountBits now returns a `std::size_t`. (63e9d77e77d35f9f0b14529dd8d86b2cd39b751e) +- Improved bitset unit tests by checking them with multiple blocks size (f6426a53d77ccee2297a0efa8b811e482f65a48b) +- `NDEBUG` is no longer automatically defined by Nazara headers. (fef5337279ea33f0675c55002f1df77234252168) +- The engine now asserts on CHAR_BIT equality to 8. (01be79f8524e5f68e713a6070d3b5aacfa595aa5) +- Fixed a crash occuring after a RigidBody2D got modified/removed. (874362a606f513be1888997f2f1b87cad4fbca53) +- Fixed Nz::Bitset::PerformandsAND (called by &= operator) giving wrong result. (ecfce94461d1c2b96bdab7f957e14856c7100108) +- PixelFormats with over 64 bits per components are now rejected. (119b7bcad4dd16f5499e2ec6a9da48c3985b036f) +- Fixed `PixelFormatInfo` masks bit order. (62197da39e6dccbe957794e5422454c49c4f039f) +- Fixed RigidBody2D collisions. (c99d7fd640a69f18a5f615d2ebc6d7f15d329f6e) +- Fixed RigidBody2D::AddForce application point. (7eb240e4a1fa1af16aa68197ec688f71ff3d32c4) +- Fixed Nz::Quaternion::Lerp compilation. (739291651eef4bc90ad14342415bf88d20142f0f) + +Nazara Development Kit: +- Fixed missing [group **NDK**](https://nazara.digitalpulsesoftware.net/doc/group___n_d_k.html) in documentation. (51c6b0241c074c64319f2347eaea72992951322f) +- Fixed CollisionComponent2D position when used alone. (e24d433f7563fcd4156ac3be01570752bd7c734a) +- Including the following changes in the Lua API: + - CameraComponent is now accessible from Lua (cfb40bf4dc4777012a11fea528f8203ef53c5686). + - Methods from EulerAngles and Quaternions classes are now accessible from Lua. (0886292c00ea3826c6c23e1e9d1c76bd6c0cf28d) + - Keyboard is now accessible from Lua (e50c9757e4f64aed553ebfa3859d2642c03ba58e) + +# 0.2 + +Build system: +- Added a .editorconfig file to help consistency (8126c981946591c4e5a4bc0e56268aecbe6a76f1) +- Code::Blocks is now supported by Premake5 (40276139b52e0aae7daf20d3f0a84b007e84a993) +- Global headers no longer include generation date. (fd3161c8e9bb9e262ed2359d679f1c47564dbac2) +- Upgraded Premake5 to alpha10, removing Premake4 in the process. (110064c08f429664f2ecc2a86319afee2441b28e) + +Nazara Engine: +- ⚠️**The Physics module has been renamed to Physics3D** (65bfd77623d1bf337849cc828022adf190c1d677) + - The PhysObject class has been renamed to RigidBody3D (d2c8ca0f0cfc91869e1802ee759ea2b356fc0a30) + - The PhysWorld class has been renamed to PhysWorld3D (d130719c5fd9521062f8c9e48729aba430061c77) + - The *Geom classes have been renamed to *Collider3D (fc1ea178c7e1dba7739443afcec339f6622243ae) + - The GeomType enum has been renamed to ColliderType3D and is now part of thz Nz namespace (1f75d449d61612909b1e879f2558c89dd41c2394) +- **A new Physics2D module has been added, using [chipmunk](https://chipmunk-physics.net)** (e9be18d1813197004a06d5eb13fe87232ccd6168) +- ⚠️ **`NAZARA_UTILITY_THREADED_WINDOW` got replaced by the runtime flag `WindowStyle_Threaded`**. (a7dd0e0a20c4c4401c663f4665ea9133dfbca1a5) +- LuaClass is now default-constructable and (re)initialized later with its `Reset` method (dc3e125bdac3e0c790743af78fead3a2e28c73b3) +- LuaClass is now able to bind classes with deleted destructor (3168e5ae07e29168223666dd23c29cb6cd7788ed) +- Added a `LuaInstance::Push` variadic overload able to push multiple arguments (a19edf1676181ec8765d9d61a02c8b0f2533c9df) +- The Vector classes now have a std::hash overload (74b446af2fc0898afa170c7fec8eaf6b5cf30614) +- The TextEntered event handling on Linux has been improved (7d1c5fa1af98abc2f253fd4a9c6b6d8604dbccaa) +- An interactive unit test has been added for testing the window events (34d92320b6252e1bf4e86e3544ecc06dc3126d8d) +- `AbstractLogger::IsStdReplicationEnabled()` is now const (5df095c0f178fcb5f772aaf9a9fb4bf79257b008) +- `FileLogger::IsTimeLoggingEnabled()` is now const (de0f93116aad07d5893e8d3ba3ec1313d7458bdf) +- Fixed `Apply` return type not taking references into account (1eb49d38691798d78c7e6559007d4f496b625db3) +- Fixed `LuaInstance::PushInstance` memory corruption (54b77c0f48a005e345109a85f49cbc4b28d93f07) +- Fixed `Matrix4::Get(Column|Row)` compilation (728d7b829e6604e314e9b8a6dfa5bd5d85602c7a) +- Fixed `ResourceManager::Purge` compilation (c7002830f58f092adb6c055a911397abc949fd4a) +- Fixed `Quaterniond::operator*` compilation (19dc95ae7c65b148cc5faeb897ded4880b9fba28) +- Fixed the <= operator with two ObjectRef (7597578bbf400e7610103b191e4b8e9e2af0b47f) +- ⚠️ LuaClass methods now include an `argumentCount` parameter, and the instance remains at the top of the Lua stack, shifting all parameters by one (9b7947812b4c4a4543a1447daea4472f4f674b7f) +- Fixed automatic lua binding of `T& T::Method()`, which will now return the original Lua instance instead of copying it. (d20fa0077a74dbe5e9e914f7adfd0c62faf5fa3a) +- `VideoMode` third argument (`bpp`) is now optional. (2ab311e0a68523b2113b25f24244b855cc4712bb) +- `ByteArray::ToHex` is now implemented in ByteArray.cpp, to reduce the amount of warnings generated by MSVC because of the `sprintf` call. (41e7e6af601fbd3b2ca96b188e4906c010903ef0) + +Nazara Development Kit: +- ⚠️ The Collision and Physics components now have a 3D suffix (6e289fe789d64ac9730ddc0f4cc240e02754e8a3) +- Added Collision and Physics components for 2D physics. (b5048dfb3704675b9f7438d080a9347c99884972) +- `LuaAPI::GetBinding()` will now implicitly initialize LuaAPI if required (ec161141d8d99db250f4f5a1e739123ad4f91750) +- It is now possible to change the update order of a world's systems. (51b6979bb59b6d880d0bcacef1b3d8d7420a5fa6) +- By default, the Render and Listener systems update are now performed last. (dd22e5f1054da80b5b6aff5ae96e9832b4425ed7) +- PhysicsSystem3D no longer initialize an internal PhysWorld3D if no physical entity gets created (e282442407c028c5d1cff96847b5b7f857a646bb) +- Including the following changes in the Lua API: + - `GraphicsComponent:Attach` overloads (taking local matrix and render order) are fixed. (d525669f3ae0d40266df9c34b6b1525a10a26d7e) + - Material is now accessible from Lua (aed4e1ee91d9875592adb178334220339afb72a0) + - Matrix4 is now accessible from Lua (fb518403659455ae79be848b99dd8f6083f1ab58) + - Sprite is now accessible from Lua (e034dce76dc6a2fd1f403221e1945c1a2c3e28ee) + - SpriteLibrary is now accessible from Lua (013a133f60d46114e1b02fed7eab9f9a9f506068) + - Texture is now accessible from Lua (f8b55a5063c058965668ed4277a7e50280ea100d) + - TextureLibrary is now accessible from Lua (3a64ef9e136c457a8207440e37361b5b3384e133) + - TextureManager is now accessible from Lua (3a64ef9e136c457a8207440e37361b5b3384e133) + +Issues fixed: +- #102: Some shaders used by the Graphics module may fail to compile with some drivers. +- #104: On Windows, when using threaded windows, the window position obtained by `Window::GetPosition()` never gets updated. +- #105: On Windows, when not using threaded windows, a lot of Moved events gets generated instead of just one for every movement. +- #111: On Linux, `IsKeyPressed(Keyboard::Q);` returns true if the `A` key is pressed. +- #114: Box/cubic sphere submesh generation is broken. + +# 0.1.1 + +Additions/Changes: +- Nz::Bitset now supports shifting operations (along with <<, >> operators) (37089d9a5fba52ba83f46d603381584a13036ac0). + +Issues fixed: +- #73, #81: Nazara fails to compile on Linux with x86 target. +- #75: Lua constructors may fail in some cases. +- #77: Packaging the engine under Linux fails to copy the executable binaries of the demo and unit tests. +- #78: Building with Clang fails. +- #79: `SocketPoller::Wait` does not update its `error` parameter on Linux. +- #80: When initializing the engine, some pixel format errors occurs, this currently has no side-effect. + +# 0.1 +- Initial release diff --git a/Doxyfile b/Doxyfile index 116ba2c2a..bb73485f3 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Nazara Engine" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.3 +PROJECT_NUMBER = 0.4 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/Config.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/Config.hpp index 7f620bb59..d311f8991 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/Config.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/Config.hpp @@ -27,17 +27,17 @@ #ifndef NAZARA_CONFIG_MODULENAME_HPP #define NAZARA_CONFIG_MODULENAME_HPP -/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci +/// Each modification of a parameter needs a recompilation of the module -// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) +// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower) #define NAZARA_MODULENAME_MANAGE_MEMORY 0 -// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +// Activate the security tests based on the code (Advised for development) #define NAZARA_MODULENAME_SAFE 1 -/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code +/// Each modification of a parameter following implies a modification (often minor) of the code -/// Vérification des valeurs et types de certaines constantes +/// Checking the values and types of certain constants #include #if !defined(NAZARA_STATIC) diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp index 8decf9091..723b9ac02 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp @@ -7,13 +7,13 @@ #ifndef NAZARA_CONFIG_CHECK_MODULENAME_HPP #define NAZARA_CONFIG_CHECK_MODULENAME_HPP -/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp +/// This file is used to check the constant values defined in Config.hpp #include #define CheckType(name, type, err) static_assert(std::is_ ##type ::value, #type err) #define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) -// On force la valeur de MANAGE_MEMORY en mode debug +// We force the value of MANAGE_MEMORY in debug #if defined(NAZARA_DEBUG) && !NAZARA_MODULENAME_MANAGE_MEMORY #undef NAZARA_MODULENAME_MANAGE_MEMORY #define NAZARA_MODULENAME_MANAGE_MEMORY 0 diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/DebugOff.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/DebugOff.hpp index 3e9cda8eb..29147254e 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/DebugOff.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/DebugOff.hpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Module name" // For conditions of distribution and use, see copyright notice in Config.hpp -// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp +// We suppose that Debug.hpp is already included, same goes for Config.hpp #if NAZARA_MODULENAME_MANAGE_MEMORY #undef delete #undef new diff --git a/SDK/include/NDK/Algorithm.inl b/SDK/include/NDK/Algorithm.inl index 54339ce38..39762243b 100644 --- a/SDK/include/NDK/Algorithm.inl +++ b/SDK/include/NDK/Algorithm.inl @@ -21,7 +21,7 @@ namespace Ndk static_assert(N-1 <= sizeof(ComponentId), "Name too long for this size of component id"); ComponentId componentId = 0; - for (unsigned int i = 0; i < N; ++i) + for (unsigned int i = 0; i < N - 1; ++i) componentId |= static_cast(name[i]) << i*8; return componentId; diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index 2ada48555..3b53488e4 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -8,13 +8,11 @@ #define NDK_APPLICATION_HPP #include -#include #include #include #include #include #include -#include #ifndef NDK_SERVER #include @@ -22,7 +20,7 @@ #include #include #include -#include +#include #endif namespace Ndk diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index e7f074c3e..cf5160e2f 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -2,9 +2,7 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include -#include #include namespace Ndk diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl index 0596eb589..0e27c1731 100644 --- a/SDK/include/NDK/BaseComponent.inl +++ b/SDK/include/NDK/BaseComponent.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include namespace Ndk diff --git a/SDK/include/NDK/BaseSystem.hpp b/SDK/include/NDK/BaseSystem.hpp index 99dcbf768..18cbef454 100644 --- a/SDK/include/NDK/BaseSystem.hpp +++ b/SDK/include/NDK/BaseSystem.hpp @@ -8,9 +8,7 @@ #define NDK_BASESYSTEM_HPP #include -#include #include -#include namespace Ndk { @@ -24,28 +22,28 @@ namespace Ndk public: inline BaseSystem(SystemIndex systemId); - inline BaseSystem(const BaseSystem&); + BaseSystem(const BaseSystem&) = delete; BaseSystem(BaseSystem&&) noexcept = default; virtual ~BaseSystem(); inline void Enable(bool enable = true); - virtual std::unique_ptr Clone() const = 0; - bool Filters(const Entity* entity) const; inline const EntityList& GetEntities() const; + inline float GetFixedUpdateRate() const; inline SystemIndex GetIndex() const; + inline float GetMaximumUpdateRate() const; inline int GetUpdateOrder() const; - inline float GetUpdateRate() const; inline World& GetWorld() const; inline bool IsEnabled() const; inline bool HasEntity(const Entity* entity) const; + inline void SetFixedUpdateRate(float updatePerSecond); + inline void SetMaximumUpdateRate(float updatePerSecond); void SetUpdateOrder(int updateOrder); - inline void SetUpdateRate(float updatePerSecond); inline void Update(float elapsedTime); @@ -93,8 +91,9 @@ namespace Ndk SystemIndex m_systemIndex; World* m_world; bool m_updateEnabled; + float m_fixedUpdateRate; + float m_maxUpdateRate; float m_updateCounter; - float m_updateRate; int m_updateOrder; static SystemIndex s_nextIndex; diff --git a/SDK/include/NDK/BaseSystem.inl b/SDK/include/NDK/BaseSystem.inl index 5969dd8e3..560b06584 100644 --- a/SDK/include/NDK/BaseSystem.inl +++ b/SDK/include/NDK/BaseSystem.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include #include @@ -20,24 +19,8 @@ namespace Ndk m_updateEnabled(true), m_updateOrder(0) { - SetUpdateRate(30); - } - - /*! - * \brief Constructs a BaseSystem object by copy semantic - * - * \param system System to copy - */ - - inline BaseSystem::BaseSystem(const BaseSystem& system) : - m_excludedComponents(system.m_excludedComponents), - m_requiredComponents(system.m_requiredComponents), - m_systemIndex(system.m_systemIndex), - m_updateEnabled(system.m_updateEnabled), - m_updateCounter(0.f), - m_updateRate(system.m_updateRate), - m_updateOrder(system.m_updateOrder) - { + SetFixedUpdateRate(0); + SetMaximumUpdateRate(30); } /*! @@ -61,6 +44,24 @@ namespace Ndk return m_entities; } + /*! + * \brief Gets the maximum rate of update of the system + * \return Update rate + */ + inline float BaseSystem::GetFixedUpdateRate() const + { + return (m_fixedUpdateRate > 0.f) ? 1.f / m_fixedUpdateRate : 0.f; + } + + /*! + * \brief Gets the maximum rate of update of the system + * \return Update rate + */ + inline float BaseSystem::GetMaximumUpdateRate() const + { + return (m_maxUpdateRate > 0.f) ? 1.f / m_maxUpdateRate : 0.f; + } + /*! * \brief Gets the index of the system * \return Index of the system @@ -82,16 +83,6 @@ namespace Ndk return m_updateOrder; } - /*! - * \brief Gets the rate of update of the system - * \return Update rate - */ - - inline float BaseSystem::GetUpdateRate() const - { - return (m_updateRate > 0.f) ? 1.f / m_updateRate : 0.f; - } - /*! * \brief Gets the world on which the system operate * \return World in which the system is @@ -125,15 +116,25 @@ namespace Ndk } /*! - * \brief Sets the rate of update for the system + * \brief Sets the fixed update rate for the system + * + * \param updatePerSecond Update rate, 0 means update rate is not fixed + */ + inline void BaseSystem::SetFixedUpdateRate(float updatePerSecond) + { + m_updateCounter = 0.f; + m_fixedUpdateRate = (updatePerSecond > 0.f) ? 1.f / updatePerSecond : 0.f; // 0.f means no limit + } + + /*! + * \brief Sets the maximum update rate for the system * * \param updatePerSecond Update rate, 0 means as much as possible */ - - inline void BaseSystem::SetUpdateRate(float updatePerSecond) + inline void BaseSystem::SetMaximumUpdateRate(float updatePerSecond) { m_updateCounter = 0.f; - m_updateRate = (updatePerSecond > 0.f) ? 1.f / updatePerSecond : 0.f; // 0.f means no limit + m_maxUpdateRate = (updatePerSecond > 0.f) ? 1.f / updatePerSecond : 0.f; // 0.f means no limit } /*! @@ -147,18 +148,40 @@ namespace Ndk if (!IsEnabled()) return; - if (m_updateRate > 0.f) - { - m_updateCounter += elapsedTime; + m_updateCounter += elapsedTime; - while (m_updateCounter >= m_updateRate) + if (m_maxUpdateRate > 0.f) + { + if (m_updateCounter >= m_maxUpdateRate) { - OnUpdate(m_updateRate); - m_updateCounter -= m_updateRate; + if (m_fixedUpdateRate > 0.f) + { + while (m_updateCounter >= m_fixedUpdateRate) + { + OnUpdate(m_fixedUpdateRate); + m_updateCounter -= m_fixedUpdateRate; + } + } + else + { + OnUpdate(m_maxUpdateRate); + m_updateCounter -= m_maxUpdateRate; + } } } else - OnUpdate(elapsedTime); + { + if (m_fixedUpdateRate > 0.f) + { + while (m_updateCounter >= m_fixedUpdateRate) + { + OnUpdate(m_fixedUpdateRate); + m_updateCounter -= m_fixedUpdateRate; + } + } + else + OnUpdate(elapsedTime); + } } /*! diff --git a/SDK/include/NDK/BaseWidget.hpp b/SDK/include/NDK/BaseWidget.hpp index 723e93e80..175a1d71d 100644 --- a/SDK/include/NDK/BaseWidget.hpp +++ b/SDK/include/NDK/BaseWidget.hpp @@ -12,9 +12,8 @@ #include #include #include -#include -#include -#include +#include +#include #include #include @@ -38,8 +37,12 @@ namespace Ndk inline void AddChild(std::unique_ptr&& widget); inline void Center(); + inline void CenterHorizontal(); + inline void CenterVertical(); - inline void Destroy(); + void ClearFocus(); + + void Destroy(); void EnableBackground(bool enable); @@ -53,15 +56,16 @@ namespace Ndk inline const Nz::Vector2f& GetContentSize() const; inline Nz::Vector2f GetSize() const; - inline bool IsVisible() const; + bool HasFocus() const; - void GrabKeyboard(); + inline bool IsVisible() const; virtual void ResizeToContent() = 0; void SetBackgroundColor(const Nz::Color& color); void SetCursor(Nz::SystemCursor systemCursor); inline void SetContentSize(const Nz::Vector2f& size); + void SetFocus(); inline void SetPadding(float left, float top, float right, float bottom); void SetSize(const Nz::Vector2f& size); @@ -79,12 +83,15 @@ namespace Ndk }; protected: - EntityHandle CreateEntity(); + const EntityHandle& CreateEntity(); void DestroyEntity(Entity* entity); virtual void Layout(); void InvalidateNode() override; - virtual void OnKeyPressed(const Nz::WindowEvent::KeyEvent& key); + virtual bool IsFocusable() const; + virtual void OnFocusLost(); + virtual void OnFocusReceived(); + virtual bool OnKeyPressed(const Nz::WindowEvent::KeyEvent& key); virtual void OnKeyReleased(const Nz::WindowEvent::KeyEvent& key); virtual void OnMouseEnter(); virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY); diff --git a/SDK/include/NDK/BaseWidget.inl b/SDK/include/NDK/BaseWidget.inl index e84a67a49..948769890 100644 --- a/SDK/include/NDK/BaseWidget.inl +++ b/SDK/include/NDK/BaseWidget.inl @@ -46,6 +46,24 @@ namespace Ndk SetPosition((parentSize.x - mySize.x) / 2.f, (parentSize.y - mySize.y) / 2.f); } + inline void BaseWidget::CenterHorizontal() + { + NazaraAssert(m_widgetParent, "Widget has no parent"); + + Nz::Vector2f parentSize = m_widgetParent->GetSize(); + Nz::Vector2f mySize = GetSize(); + SetPosition((parentSize.x - mySize.x) / 2.f, GetPosition(Nz::CoordSys_Local).y); + } + + inline void BaseWidget::CenterVertical() + { + NazaraAssert(m_widgetParent, "Widget has no parent"); + + Nz::Vector2f parentSize = m_widgetParent->GetSize(); + Nz::Vector2f mySize = GetSize(); + SetPosition(GetPosition(Nz::CoordSys_Local).x, (parentSize.y - mySize.y) / 2.f); + } + inline const Nz::Color& BaseWidget::GetBackgroundColor() const { return m_backgroundColor; diff --git a/SDK/include/NDK/Canvas.hpp b/SDK/include/NDK/Canvas.hpp index 33453306f..5735f1f94 100644 --- a/SDK/include/NDK/Canvas.hpp +++ b/SDK/include/NDK/Canvas.hpp @@ -9,8 +9,8 @@ #include #include -#include -#include +#include +#include namespace Ndk { @@ -34,12 +34,16 @@ namespace Ndk Canvas& operator=(Canvas&&) = delete; protected: + inline void ClearKeyboardOwner(std::size_t canvasIndex); + + inline bool IsKeyboardOwner(std::size_t canvasIndex) const; + inline void NotifyWidgetBoxUpdate(std::size_t index); inline void NotifyWidgetCursorUpdate(std::size_t index); std::size_t RegisterWidget(BaseWidget* widget); - inline void SetKeyboardOwner(BaseWidget* widget); + inline void SetKeyboardOwner(std::size_t canvasIndex); void UnregisterWidget(std::size_t index); @@ -52,7 +56,7 @@ namespace Ndk void OnEventKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event); void OnEventTextEntered(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::TextEvent& event); - struct WidgetBox + struct WidgetEntry { BaseWidget* widget; Nz::Boxf box; @@ -67,10 +71,10 @@ namespace Ndk NazaraSlot(Nz::EventHandler, OnMouseLeft, m_mouseLeftSlot); NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot); - std::vector m_widgetBoxes; + std::size_t m_keyboardOwner; + std::size_t m_hoveredWidget; + std::vector m_widgetEntries; Nz::CursorControllerHandle m_cursorController; - const WidgetBox* m_hoveredWidget; - BaseWidget* m_keyboardOwner; WorldHandle m_world; }; } diff --git a/SDK/include/NDK/Canvas.inl b/SDK/include/NDK/Canvas.inl index 9b2ba461e..f37132a51 100644 --- a/SDK/include/NDK/Canvas.inl +++ b/SDK/include/NDK/Canvas.inl @@ -3,14 +3,14 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include -#include +#include namespace Ndk { inline Canvas::Canvas(WorldHandle world, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController) : + m_keyboardOwner(InvalidCanvasIndex), + m_hoveredWidget(InvalidCanvasIndex), m_cursorController(cursorController), - m_hoveredWidget(nullptr), - m_keyboardOwner(nullptr), m_world(std::move(world)) { m_canvas = this; @@ -46,9 +46,20 @@ namespace Ndk return m_world; } + inline void Canvas::ClearKeyboardOwner(std::size_t canvasIndex) + { + if (m_keyboardOwner == canvasIndex) + SetKeyboardOwner(InvalidCanvasIndex); + } + + inline bool Canvas::IsKeyboardOwner(std::size_t canvasIndex) const + { + return m_keyboardOwner == canvasIndex; + } + inline void Canvas::NotifyWidgetBoxUpdate(std::size_t index) { - WidgetBox& entry = m_widgetBoxes[index]; + WidgetEntry& entry = m_widgetEntries[index]; Nz::Vector3f pos = entry.widget->GetPosition(); Nz::Vector2f size = entry.widget->GetContentSize(); @@ -58,15 +69,24 @@ namespace Ndk inline void Canvas::NotifyWidgetCursorUpdate(std::size_t index) { - WidgetBox& entry = m_widgetBoxes[index]; + WidgetEntry& entry = m_widgetEntries[index]; entry.cursor = entry.widget->GetCursor(); - if (m_cursorController && m_hoveredWidget == &entry) + if (m_cursorController && m_hoveredWidget == index) m_cursorController->UpdateCursor(Nz::Cursor::Get(entry.cursor)); } - inline void Ndk::Canvas::SetKeyboardOwner(BaseWidget* widget) + inline void Canvas::SetKeyboardOwner(std::size_t canvasIndex) { - m_keyboardOwner = widget; + if (m_keyboardOwner != canvasIndex) + { + if (m_keyboardOwner != InvalidCanvasIndex) + m_widgetEntries[m_keyboardOwner].widget->OnFocusLost(); + + m_keyboardOwner = canvasIndex; + + if (m_keyboardOwner != InvalidCanvasIndex) + m_widgetEntries[m_keyboardOwner].widget->OnFocusReceived(); + } } } diff --git a/SDK/include/NDK/Components/CameraComponent.hpp b/SDK/include/NDK/Components/CameraComponent.hpp index f4a29f2e4..2474a093e 100644 --- a/SDK/include/NDK/Components/CameraComponent.hpp +++ b/SDK/include/NDK/Components/CameraComponent.hpp @@ -19,7 +19,6 @@ namespace Ndk { class CameraComponent; - class Entity; using CameraComponentHandle = Nz::ObjectHandle; diff --git a/SDK/include/NDK/Components/CameraComponent.inl b/SDK/include/NDK/Components/CameraComponent.inl index 1018f9f3d..7d624f522 100644 --- a/SDK/include/NDK/Components/CameraComponent.inl +++ b/SDK/include/NDK/Components/CameraComponent.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include #include @@ -238,10 +237,9 @@ namespace Ndk NazaraAssert(m_target, "Component has no render target"); // We compute the region necessary to make this view port with the actual size of the target - float invWidth = 1.f / m_target->GetWidth(); - float invHeight = 1.f / m_target->GetHeight(); + Nz::Vector2f invSize = 1.f / Nz::Vector2f(m_target->GetSize()); - SetTargetRegion(Nz::Rectf(invWidth * viewport.x, invHeight * viewport.y, invWidth * viewport.width, invHeight * viewport.height)); + SetTargetRegion(Nz::Rectf(invSize.x * viewport.x, invSize.y * viewport.y, invSize.x * viewport.width, invSize.y * viewport.height)); } /*! diff --git a/SDK/include/NDK/Components/CollisionComponent2D.hpp b/SDK/include/NDK/Components/CollisionComponent2D.hpp index 28c3637a2..524097e32 100644 --- a/SDK/include/NDK/Components/CollisionComponent2D.hpp +++ b/SDK/include/NDK/Components/CollisionComponent2D.hpp @@ -8,18 +8,12 @@ #define NDK_COMPONENTS_COLLISIONCOMPONENT2D_HPP #include +#include #include #include -namespace Nz -{ - class RigidBody2D; -} - namespace Ndk { - class Entity; - class NDK_API CollisionComponent2D : public Component { friend class PhysicsSystem2D; @@ -29,6 +23,7 @@ namespace Ndk CollisionComponent2D(const CollisionComponent2D& collision); ~CollisionComponent2D() = default; + Nz::Rectf GetAABB() const; const Nz::Collider2DRef& GetGeom() const; void SetGeom(Nz::Collider2DRef geom); diff --git a/SDK/include/NDK/Components/CollisionComponent2D.inl b/SDK/include/NDK/Components/CollisionComponent2D.inl index 147e8ec32..f3728de84 100644 --- a/SDK/include/NDK/Components/CollisionComponent2D.inl +++ b/SDK/include/NDK/Components/CollisionComponent2D.inl @@ -2,12 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include -#include -#include -#include -#include - namespace Ndk { /*! @@ -34,6 +28,16 @@ namespace Ndk { } + /*! + * \brief Gets the collision box representing the entity + * \return The physics collision box + */ + + inline Nz::Rectf CollisionComponent2D::GetAABB() const + { + return m_staticBody->GetAABB(); + } + /*! * \brief Gets the geometry representing the entity * \return A constant reference to the physics geometry diff --git a/SDK/include/NDK/Components/CollisionComponent3D.hpp b/SDK/include/NDK/Components/CollisionComponent3D.hpp index 992e73053..ce1b719ca 100644 --- a/SDK/include/NDK/Components/CollisionComponent3D.hpp +++ b/SDK/include/NDK/Components/CollisionComponent3D.hpp @@ -8,18 +8,12 @@ #define NDK_COMPONENTS_COLLISIONCOMPONENT3D_HPP #include +#include #include #include -namespace Nz -{ - class RigidBody3D; -} - namespace Ndk { - class Entity; - class NDK_API CollisionComponent3D : public Component { friend class PhysicsSystem3D; diff --git a/SDK/include/NDK/Components/CollisionComponent3D.inl b/SDK/include/NDK/Components/CollisionComponent3D.inl index 7d82252af..69842c867 100644 --- a/SDK/include/NDK/Components/CollisionComponent3D.inl +++ b/SDK/include/NDK/Components/CollisionComponent3D.inl @@ -2,11 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include -#include -#include -#include - namespace Ndk { /*! diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 68961b99a..b59ca2921 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace Ndk { @@ -34,13 +35,15 @@ namespace Ndk inline void AddToCullingList(GraphicsComponentCullingList* cullingList) const; void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const; - void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); + inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0); inline void Clear(); inline void Detach(const Nz::InstancedRenderable* renderable); + inline bool DoesRequireRealTimeReflections() const; + inline void EnsureBoundingVolumeUpdate() const; inline void EnsureTransformMatrixUpdate() const; @@ -57,22 +60,43 @@ namespace Ndk static ComponentIndex componentIndex; private: + struct Renderable; + + void ConnectInstancedRenderableSignals(Renderable& renderable); + inline void InvalidateBoundingVolume() const; void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index); + void InvalidateRenderableMaterial(const Nz::InstancedRenderable* renderable, std::size_t skinIndex, std::size_t matIndex, const Nz::MaterialRef& newMat); inline void InvalidateRenderables(); + void InvalidateReflectionMap(); inline void InvalidateTransformMatrix(); + void RegisterMaterial(Nz::Material* material, std::size_t count = 1); + void OnAttached() override; void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; + + void OnInstancedRenderableResetMaterials(const Nz::InstancedRenderable* renderable, std::size_t newMaterialCount); + void OnInstancedRenderableSkinChange(const Nz::InstancedRenderable* renderable, std::size_t newSkinIndex); + void OnMaterialReflectionChange(const Nz::Material* material, Nz::ReflectionMode reflectionMode); void OnNodeInvalidated(const Nz::Node* node); + void UnregisterMaterial(Nz::Material* material); + void UpdateBoundingVolume() const; void UpdateTransformMatrix() const; NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot); + struct MaterialEntry + { + NazaraSlot(Nz::Material, OnMaterialReflectionModeChange, reflectionModelChangeSlot); + + std::size_t renderableCounter; + }; + struct Renderable { Renderable(const Nz::Matrix4f& transformMatrix) : @@ -81,15 +105,8 @@ namespace Ndk { } - Renderable(Renderable&& rhs) noexcept : - renderableBoundingVolumeInvalidationSlot(std::move(rhs.renderableBoundingVolumeInvalidationSlot)), - renderableDataInvalidationSlot(std::move(rhs.renderableDataInvalidationSlot)), - renderableReleaseSlot(std::move(rhs.renderableReleaseSlot)), - data(std::move(rhs.data)), - renderable(std::move(rhs.renderable)), - dataUpdated(rhs.dataUpdated) - { - } + Renderable(const Renderable&) = delete; + Renderable(Renderable&& rhs) noexcept = default; ~Renderable() { @@ -97,21 +114,15 @@ namespace Ndk renderableReleaseSlot.Disconnect(); } - Renderable& operator=(Renderable&& r) noexcept - { - data = std::move(r.data); - dataUpdated = r.dataUpdated; - renderable = std::move(r.renderable); - renderableBoundingVolumeInvalidationSlot = std::move(r.renderableBoundingVolumeInvalidationSlot); - renderableDataInvalidationSlot = std::move(r.renderableDataInvalidationSlot); - renderableReleaseSlot = std::move(r.renderableReleaseSlot); - - return *this; - } + Renderable& operator=(const Renderable&) = delete; + Renderable& operator=(Renderable&& r) noexcept = default; NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateBoundingVolume, renderableBoundingVolumeInvalidationSlot); NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableDataInvalidationSlot); + NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateMaterial, renderableMaterialInvalidationSlot); NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableRelease, renderableReleaseSlot); + NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableResetMaterials, renderableResetMaterialsSlot); + NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableSkinChange, renderableSkinChangeSlot); mutable Nz::InstancedRenderable::InstanceData data; Nz::InstancedRenderableRef renderable; @@ -127,12 +138,16 @@ namespace Ndk NazaraSlot(GraphicsComponentCullingList, OnCullingListRelease, cullingListReleaseSlot); }; + std::size_t m_reflectiveMaterialCount; mutable std::vector m_volumeCullingEntries; std::vector m_renderables; + std::unordered_map m_materialEntries; mutable Nz::BoundingVolumef m_boundingVolume; mutable Nz::Matrix4f m_transformMatrix; + Nz::TextureRef m_reflectionMap; mutable bool m_boundingVolumeUpdated; mutable bool m_transformMatrixUpdated; + unsigned int m_reflectionMapSize; }; } diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index 34bd57dd9..275fe9a9d 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -38,6 +38,17 @@ namespace Ndk InvalidateBoundingVolume(); } + /*! + * \brief Attaches a renderable to the entity + * + * \param renderable Reference to a renderable element + * \param renderOrder Render order of the element + */ + inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, int renderOrder) + { + return Attach(std::move(renderable), Nz::Matrix4f::Identity(), renderOrder); + } + /*! * \brief Clears every renderable elements */ @@ -62,12 +73,29 @@ namespace Ndk if (it->renderable == renderable) { InvalidateBoundingVolume(); + + std::size_t materialCount = renderable->GetMaterialCount(); + for (std::size_t i = 0; i < materialCount; ++i) + UnregisterMaterial(renderable->GetMaterial(i)); + m_renderables.erase(it); break; } } } + /*! + * \brief Checks if this graphics component requires real-time reflections to be generated + * + * If any of the materials attached to a GraphicsComponent (via the attached instanced renderable) needs real-time reflections, this function will return true. + * + * \return True if real-time reflections needs to be generated or false + */ + inline bool GraphicsComponent::DoesRequireRealTimeReflections() const + { + return m_reflectiveMaterialCount != 0 && m_reflectionMap; + } + /*! * \brief Ensures the bounding volume is up to date */ @@ -198,4 +226,4 @@ namespace Ndk InvalidateBoundingVolume(); InvalidateRenderables(); } -} \ No newline at end of file +} diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp index 3e2c5f8af..d89d9114f 100644 --- a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp @@ -9,7 +9,6 @@ #define NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP #include -#include #include namespace Ndk diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.inl b/SDK/include/NDK/Components/ParticleEmitterComponent.inl index 292a2ed8f..47c3602ab 100644 --- a/SDK/include/NDK/Components/ParticleEmitterComponent.inl +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.inl @@ -2,8 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include - namespace Ndk { /*! diff --git a/SDK/include/NDK/Components/ParticleGroupComponent.inl b/SDK/include/NDK/Components/ParticleGroupComponent.inl index dc3072faa..afbfc15da 100644 --- a/SDK/include/NDK/Components/ParticleGroupComponent.inl +++ b/SDK/include/NDK/Components/ParticleGroupComponent.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include #include diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.hpp b/SDK/include/NDK/Components/PhysicsComponent2D.hpp index 2bbe693a1..1d57e08b8 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent2D.hpp @@ -13,8 +13,6 @@ namespace Ndk { - class Entity; - class NDK_API PhysicsComponent2D : public Component { friend class CollisionComponent2D; @@ -24,9 +22,11 @@ namespace Ndk PhysicsComponent2D() = default; PhysicsComponent2D(const PhysicsComponent2D& physics); ~PhysicsComponent2D() = default; - + void AddForce(const Nz::Vector2f& force, Nz::CoordSys coordSys = Nz::CoordSys_Global); void AddForce(const Nz::Vector2f& force, const Nz::Vector2f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global); + void AddImpulse(const Nz::Vector2f& impulse, Nz::CoordSys coordSys = Nz::CoordSys_Global); + void AddImpulse(const Nz::Vector2f& impulse, const Nz::Vector2f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global); void AddTorque(float torque); Nz::Rectf GetAABB() const; diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.inl b/SDK/include/NDK/Components/PhysicsComponent2D.inl index 7aea6dca6..39752b645 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.inl +++ b/SDK/include/NDK/Components/PhysicsComponent2D.inl @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include -#include "PhysicsComponent2D.hpp" namespace Ndk { @@ -51,7 +50,38 @@ namespace Ndk m_object->AddForce(force, point, coordSys); } - + + /*! + * \brief Applies a impulse to the entity + * + * \param impulse Impulse to apply on the entity + * + * \remark Produces a NazaraAssert if the physics object is invalid + */ + + inline void PhysicsComponent2D::AddImpulse(const Nz::Vector2f& impulse, Nz::CoordSys coordSys) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->AddImpulse(impulse, coordSys); + } + + /*! + * \brief Applies a impulse to the entity + * + * \param impulse Impulse to apply on the entity + * \param point Point where the impulse is applied + * + * \remark Produces a NazaraAssert if the physics object is invalid + */ + + inline void PhysicsComponent2D::AddImpulse(const Nz::Vector2f& impulse, const Nz::Vector2f& point, Nz::CoordSys coordSys) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->AddImpulse(impulse, point, coordSys); + } + /*! * \brief Applies a torque to the entity * diff --git a/SDK/include/NDK/Components/PhysicsComponent3D.hpp b/SDK/include/NDK/Components/PhysicsComponent3D.hpp index 8be86537e..610b8e1df 100644 --- a/SDK/include/NDK/Components/PhysicsComponent3D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent3D.hpp @@ -13,8 +13,6 @@ namespace Ndk { - class Entity; - class NDK_API PhysicsComponent3D : public Component { friend class CollisionComponent3D; diff --git a/SDK/include/NDK/Components/VelocityComponent.inl b/SDK/include/NDK/Components/VelocityComponent.inl index 2cf4f1ec3..052985ddf 100644 --- a/SDK/include/NDK/Components/VelocityComponent.inl +++ b/SDK/include/NDK/Components/VelocityComponent.inl @@ -2,9 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include -#include - namespace Ndk { /*! diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index 9635373e0..afe4b156e 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -20,12 +19,12 @@ namespace Nz { class LuaState; + struct WindowEvent; } namespace Ndk { class Console; - class Entity; using ConsoleHandle = Nz::ObjectHandle; diff --git a/SDK/include/NDK/Console.inl b/SDK/include/NDK/Console.inl index c97adda20..fd461905f 100644 --- a/SDK/include/NDK/Console.inl +++ b/SDK/include/NDK/Console.inl @@ -2,9 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include -#include "Console.hpp" - namespace Ndk { /*! diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index 5419da0d2..93ad73bfe 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,7 @@ namespace Ndk const EntityHandle& Clone() const; + inline void Disable(); inline void Enable(bool enable = true); inline BaseComponent& GetComponent(ComponentIndex index); diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index adb2153d8..4aa497391 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -8,7 +8,6 @@ #include #include #include -#include namespace Ndk { @@ -29,12 +28,21 @@ namespace Ndk return static_cast(AddComponent(std::move(ptr))); } + /*! + * \brief Disables the entity + * + * This is just a shortcut to Enable(false) + */ + inline void Entity::Disable() + { + Enable(false); + } + /*! * \brief Enables the entity * * \param enable Should the entity be enabled */ - inline void Entity::Enable(bool enable) { if (m_enabled != enable) @@ -325,4 +333,4 @@ namespace std return hash()(id); } }; -} \ No newline at end of file +} diff --git a/SDK/include/NDK/EntityList.hpp b/SDK/include/NDK/EntityList.hpp index 8303f7fa4..4620837a0 100644 --- a/SDK/include/NDK/EntityList.hpp +++ b/SDK/include/NDK/EntityList.hpp @@ -35,6 +35,7 @@ namespace Ndk inline void Insert(Entity* entity); inline void Remove(Entity* entity); + inline void Reserve(std::size_t entityCount); // STL API inline iterator begin() const; diff --git a/SDK/include/NDK/EntityList.inl b/SDK/include/NDK/EntityList.inl index 8d871e2c6..a56eafa24 100644 --- a/SDK/include/NDK/EntityList.inl +++ b/SDK/include/NDK/EntityList.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include #include @@ -137,6 +136,16 @@ namespace Ndk } } + /*! + * \brief Reserves enough space to contains entityCount entities + * + * \param entityCount Number of entities to reserve + */ + inline void EntityList::Reserve(std::size_t entityCount) + { + m_entityBits.Reserve(entityCount); + } + // STL Interface inline EntityList::iterator EntityList::begin() const { diff --git a/SDK/include/NDK/Lua/LuaBinding.hpp b/SDK/include/NDK/Lua/LuaBinding.hpp index c1ea9206d..c93f21a42 100644 --- a/SDK/include/NDK/Lua/LuaBinding.hpp +++ b/SDK/include/NDK/Lua/LuaBinding.hpp @@ -7,7 +7,6 @@ #ifndef NDK_LUABINDING_HPP #define NDK_LUABINDING_HPP -#include #include #include #include @@ -36,6 +35,7 @@ namespace Ndk std::unique_ptr audio; std::unique_ptr graphics; std::unique_ptr renderer; + std::unique_ptr platform; #endif private: diff --git a/SDK/include/NDK/Lua/LuaBinding.inl b/SDK/include/NDK/Lua/LuaBinding.inl index d95314099..c7fb53ed4 100644 --- a/SDK/include/NDK/Lua/LuaBinding.inl +++ b/SDK/include/NDK/Lua/LuaBinding.inl @@ -2,8 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include - namespace Ndk { namespace Detail diff --git a/SDK/include/NDK/Lua/LuaBinding_Base.hpp b/SDK/include/NDK/Lua/LuaBinding_Base.hpp index 8e596e999..21d86f191 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Base.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Base.hpp @@ -23,6 +23,7 @@ namespace Ndk class LuaBinding_Renderer; class LuaBinding_SDK; class LuaBinding_Utility; + class LuaBinding_Platform; class NDK_API LuaBinding_Base { @@ -43,6 +44,7 @@ namespace Ndk static std::unique_ptr BindAudio(LuaBinding& binding); static std::unique_ptr BindGraphics(LuaBinding& binding); static std::unique_ptr BindRenderer(LuaBinding& binding); + static std::unique_ptr BindPlatform(LuaBinding& binding); #endif protected: diff --git a/SDK/include/NDK/Lua/LuaBinding_Platform.hpp b/SDK/include/NDK/Lua/LuaBinding_Platform.hpp new file mode 100644 index 000000000..502a443a5 --- /dev/null +++ b/SDK/include/NDK/Lua/LuaBinding_Platform.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_LUABINDING_SYSTEM_HPP +#define NDK_LUABINDING_SYSTEM_HPP + +#include +#include + +namespace Ndk +{ + class NDK_API LuaBinding_Platform : public LuaBinding_Base + { + public: + LuaBinding_Platform(LuaBinding& binding); + ~LuaBinding_Platform() = default; + + void Register(Nz::LuaState& state) override; + + // Platform + Nz::LuaClass keyboard; + }; +} + +#endif // NDK_LUABINDING_SYSTEM_HPP diff --git a/SDK/include/NDK/Lua/LuaBinding_SDK.hpp b/SDK/include/NDK/Lua/LuaBinding_SDK.hpp index 8a6a0915e..18cbe96c2 100644 --- a/SDK/include/NDK/Lua/LuaBinding_SDK.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_SDK.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace Ndk { diff --git a/SDK/include/NDK/Lua/LuaBinding_Utility.hpp b/SDK/include/NDK/Lua/LuaBinding_Utility.hpp index 8aefd20c6..33f19184d 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Utility.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Utility.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -26,7 +25,6 @@ namespace Ndk // Utility Nz::LuaClass abstractImage; Nz::LuaClass font; - Nz::LuaClass keyboard; Nz::LuaClass node; }; } diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 84e3fb34e..3eee85bc1 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include #include #include @@ -16,7 +15,6 @@ #include #include #include -#include #ifndef NDK_SERVER #include @@ -310,9 +308,22 @@ namespace Nz return ret; } + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Ndk::Entity** handle, TypeTag) + { + if (!state.IsOfType(index, LuaType_Nil)) + *handle = *static_cast(state.CheckUserdata(index, "Entity")); + else + *handle = nullptr; + + return 1; + } + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Ndk::EntityHandle* handle, TypeTag) { - *handle = *static_cast(state.CheckUserdata(index, "Entity")); + if (!state.IsOfType(index, LuaType_Nil)) + *handle = *static_cast(state.CheckUserdata(index, "Entity")); + else + handle->Reset(); return 1; } diff --git a/SDK/include/NDK/StateMachine.hpp b/SDK/include/NDK/StateMachine.hpp index e9e665c44..830391e55 100644 --- a/SDK/include/NDK/StateMachine.hpp +++ b/SDK/include/NDK/StateMachine.hpp @@ -24,15 +24,13 @@ namespace Ndk inline void ChangeState(std::shared_ptr state); - inline const std::shared_ptr& GetCurrentState() const; - inline bool IsTopState(const State* state) const; - inline std::shared_ptr PopState(); - inline bool PopStatesUntil(std::shared_ptr state); + inline void PopState(); + inline void PopStatesUntil(std::shared_ptr state); inline void PushState(std::shared_ptr state); - inline void SetState(std::shared_ptr state); + inline void ResetState(std::shared_ptr state); inline bool Update(float elapsedTime); @@ -40,7 +38,21 @@ namespace Ndk StateMachine& operator=(const StateMachine&) = delete; private: + enum class TransitionType + { + Pop, + PopUntil, + Push, + }; + + struct StateTransition + { + TransitionType type; + std::shared_ptr state; + }; + std::vector> m_states; + std::vector m_transitions; }; } diff --git a/SDK/include/NDK/StateMachine.inl b/SDK/include/NDK/StateMachine.inl index 1086df54d..cfc021233 100644 --- a/SDK/include/NDK/StateMachine.inl +++ b/SDK/include/NDK/StateMachine.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp +#include #include #include @@ -16,66 +17,56 @@ namespace Ndk /*! * \brief Constructs a StateMachine object with an original state * - * \param originalState State which is the entry point of the application - * - * \remark Calls "Enter" on the state - * \remark Produces a NazaraAssert if nullptr is given + * \param originalState State which is the entry point of the application, a nullptr will create an empty state machine */ - inline StateMachine::StateMachine(std::shared_ptr originalState) { - NazaraAssert(originalState, "StateMachine must have a state to begin with"); - PushState(std::move(originalState)); + if (originalState) + PushState(std::move(originalState)); } /*! * \brief Destructs the object * - * \remark Calls "Leave" on all the states + * \remark Calls "Leave" on all the states from top to bottom */ - inline StateMachine::~StateMachine() { - for (std::shared_ptr& state : m_states) - state->Leave(*this); + // Leave state from top to bottom (as if states were popped out) + for (auto it = m_states.rbegin(); it != m_states.rend(); ++it) + (*it)->Leave(*this); } /*! * \brief Replaces the current state on the top of the machine * * \param state State to replace the top one if it is nullptr, no action is performed + * + * \remark It is forbidden for a state machine to have (at any moment) the same state in its list multiple times + * \remark Like all actions popping or pushing a state, this is not immediate and will only take effect when state machine is updated */ - inline void StateMachine::ChangeState(std::shared_ptr state) { if (state) { - PopState(); - PushState(std::move(state)); + // Change state is just a pop followed by a push + StateTransition transition; + transition.type = TransitionType::Pop; + m_transitions.emplace_back(std::move(transition)); + + transition.state = std::move(state); + transition.type = TransitionType::Push; + m_transitions.emplace_back(std::move(transition)); } } - /*! - * \brief Gets the current state on the top of the machine - * \return A constant reference to the state - * - * \remark The stack is supposed to be non empty, otherwise it is undefined behaviour - * - * \see PopStatesUntil - */ - - inline const std::shared_ptr& StateMachine::GetCurrentState() const - { - return m_states.back(); - } - /*! * \brief Checks whether the state is on the top of the machine * \return true If it is the case * * \param state State to compare the top with + * \remark Because all actions popping or pushing a state don't take effect until next state machine update, this can return false on a just pushed state */ - inline bool StateMachine::IsTopState(const State* state) const { if (m_states.empty()) @@ -86,40 +77,36 @@ namespace Ndk /*! * \brief Pops the state on the top of the machine - * \return Old state on the top, nullptr if stack was empty * * \remark This method can completely empty the stack + * \remark Like all actions popping or pushing a state, this is not immediate and will only take effect when state machine is updated */ - - inline std::shared_ptr StateMachine::PopState() + inline void StateMachine::PopState() { - if (m_states.empty()) - return nullptr; + StateTransition transition; + transition.type = TransitionType::Pop; - m_states.back()->Leave(*this); - std::shared_ptr oldTopState = std::move(m_states.back()); - m_states.pop_back(); - return oldTopState; + m_transitions.emplace_back(std::move(transition)); } /*! - * \brief Pops all the states of the machine until a specific one is reached - * \return true If that specific state is on top, false if stack is empty + * \brief Pops all states of the machine until a specific one is reached * - * \param state State to find on the stack if it is nullptr, no action is performed + * \param state State to find on the stack. If nullptr is passed, no action is performed * - * \remark This method can completely empty the stack + * \remark This method will completely empty the stack if state is not present + * \remark Like all actions popping or pushing a state, this is not immediate and will only take effect when state machine is updated */ - - inline bool StateMachine::PopStatesUntil(std::shared_ptr state) + inline void StateMachine::PopStatesUntil(std::shared_ptr state) { - if (!state) - return false; + if (state) + { + StateTransition transition; + transition.state = std::move(state); + transition.type = TransitionType::PopUntil; - while (!m_states.empty() && !IsTopState(state.get())) - PopState(); - - return !m_states.empty(); + m_transitions.emplace_back(std::move(transition)); + } } /*! @@ -127,34 +114,40 @@ namespace Ndk * * \param state Next state to represent if it is nullptr, it performs no action * - * \remark Produces a NazaraAssert if the same state is pushed two times on the stack + * \remark It is forbidden for a state machine to have (at any moment) the same state in its list multiple times + * \remark Like all actions popping or pushing a state, this is not immediate and will only take effect when state machine is updated */ - inline void StateMachine::PushState(std::shared_ptr state) { if (state) { - NazaraAssert(std::find(m_states.begin(), m_states.end(), state) == m_states.end(), "The same state was pushed two times"); + StateTransition transition; + transition.state = std::move(state); + transition.type = TransitionType::Push; - m_states.push_back(std::move(state)); - m_states.back()->Enter(*this); + m_transitions.emplace_back(std::move(transition)); } } /*! * \brief Pops every states of the machine to put a new one * - * \param state State to reset the stack with if it is nullptr, no action is performed + * \param state State to reset the stack with. If state is invalid, this will clear the state machine + * + * \remark It is forbidden for a state machine to have (at any moment) the same state in its list multiple times + * \remark Like all actions popping or pushing a state, this is not immediate and will only take effect when state machine is updated */ - - inline void StateMachine::SetState(std::shared_ptr state) + inline void StateMachine::ResetState(std::shared_ptr state) { + StateTransition transition; + transition.type = TransitionType::PopUntil; //< Pop until nullptr, which basically clears the state machine + m_transitions.emplace_back(std::move(transition)); + if (state) { - while (!m_states.empty()) - PopState(); - - PushState(std::move(state)); + transition.state = std::move(state); + transition.type = TransitionType::Push; + m_transitions.emplace_back(std::move(transition)); } } @@ -164,9 +157,41 @@ namespace Ndk * * \param elapsedTime Delta time used for the update */ - inline bool StateMachine::Update(float elapsedTime) { + for (StateTransition& transition : m_transitions) + { + switch (transition.type) + { + case TransitionType::Pop: + { + std::shared_ptr& topState = m_states.back(); + topState->Leave(*this); //< Call leave before popping to ensure consistent IsTopState behavior + + m_states.pop_back(); + break; + } + + case TransitionType::PopUntil: + { + while (!m_states.empty() && m_states.back() != transition.state) + { + m_states.back()->Leave(*this); + m_states.pop_back(); + } + break; + } + + case TransitionType::Push: + { + m_states.emplace_back(std::move(transition.state)); + m_states.back()->Enter(*this); + break; + } + } + } + m_transitions.clear(); + return std::all_of(m_states.begin(), m_states.end(), [=](std::shared_ptr& state) { return state->Update(*this, elapsedTime); }); diff --git a/SDK/include/NDK/System.hpp b/SDK/include/NDK/System.hpp index 935362763..b828d1fcb 100644 --- a/SDK/include/NDK/System.hpp +++ b/SDK/include/NDK/System.hpp @@ -16,12 +16,10 @@ namespace Ndk { public: System(); - System(const System&) = default; + System(const System&) = delete; System(System&&) = default; virtual ~System(); - std::unique_ptr Clone() const override; - System& operator=(const System&) = delete; System& operator=(System&&) = default; diff --git a/SDK/include/NDK/System.inl b/SDK/include/NDK/System.inl index b3927d145..65bbe0907 100644 --- a/SDK/include/NDK/System.inl +++ b/SDK/include/NDK/System.inl @@ -28,22 +28,6 @@ namespace Ndk template System::~System() = default; - /*! - * \brief Clones the system - * \return The clone newly created - * - * \remark The system to clone should be trivially copy constructible - */ - - template - std::unique_ptr System::Clone() const - { - ///FIXME: Not fully supported in GCC (4.9.2) - //static_assert(std::is_trivially_copy_constructible::value, "SystemType should be copy-constructible"); - - return std::make_unique(static_cast(*this)); - } - /*! * \brief Registers the system by assigning it an index */ diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index a74cb9d0e..4ed015365 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -11,16 +11,16 @@ #include #include #include -#include #include -#include #include #include -#include +#include #include namespace Ndk { + class AbstractViewer; + class NDK_API RenderSystem : public System { public: @@ -52,6 +52,7 @@ namespace Ndk void OnEntityValidation(Entity* entity, bool justAdded) override; void OnUpdate(float elapsedTime) override; + void UpdateDynamicReflections(); void UpdateDirectionalShadowMaps(const Nz::AbstractViewer& viewer); void UpdatePointSpotShadowMaps(); @@ -63,6 +64,7 @@ namespace Ndk EntityList m_lights; EntityList m_pointSpotLights; EntityList m_particleGroups; + EntityList m_realtimeReflected; GraphicsComponentCullingList m_drawableCulling; Nz::BackgroundRef m_background; Nz::DepthRenderTechnique m_shadowTechnique; diff --git a/SDK/include/NDK/Systems/RenderSystem.inl b/SDK/include/NDK/Systems/RenderSystem.inl index 8a443f993..aa5c6bdae 100644 --- a/SDK/include/NDK/Systems/RenderSystem.inl +++ b/SDK/include/NDK/Systems/RenderSystem.inl @@ -4,17 +4,6 @@ namespace Ndk { - /*! - * \brief Constructs a RenderSystem object by copy semantic - * - * \param renderSystem RenderSystem to copy - */ - - inline RenderSystem::RenderSystem(const RenderSystem& renderSystem) : - System(renderSystem) - { - } - /*! * \brief Changes the render technique used for the system * \return A reference to the render technique type diff --git a/SDK/include/NDK/Widgets.hpp b/SDK/include/NDK/Widgets.hpp index a019c007b..26917a4c9 100644 --- a/SDK/include/NDK/Widgets.hpp +++ b/SDK/include/NDK/Widgets.hpp @@ -6,7 +6,11 @@ #define NDK_WIDGETS_GLOBAL_HPP #include +#include +#include +#include #include +#include #include #endif // NDK_WIDGETS_GLOBAL_HPP diff --git a/SDK/include/NDK/Widgets/ButtonWidget.hpp b/SDK/include/NDK/Widgets/ButtonWidget.hpp index 8f2231501..6214c8599 100644 --- a/SDK/include/NDK/Widgets/ButtonWidget.hpp +++ b/SDK/include/NDK/Widgets/ButtonWidget.hpp @@ -9,14 +9,17 @@ #include #include -#include +#include #include #include +namespace Nz +{ + class AbstractTextDrawer; +} + namespace Ndk { - class World; - class NDK_API ButtonWidget : public BaseWidget { public: @@ -29,17 +32,44 @@ namespace Ndk void ResizeToContent() override; + inline const Nz::Color& GetColor() const; + inline const Nz::Color& GetCornerColor() const; + inline const Nz::Color& GetHoverColor() const; + inline const Nz::Color& GetHoverCornerColor() const; + inline const Nz::Color& GetPressColor() const; + inline const Nz::Color& GetPressCornerColor() const; + + inline const Nz::TextureRef& GetTexture() const; + inline const Nz::TextureRef& GetHoverTexture() const; + inline const Nz::TextureRef& GetPressTexture() const; + + inline void SetColor(const Nz::Color& color, const Nz::Color& cornerColor); + inline void SetHoverColor(const Nz::Color& color, const Nz::Color& cornerColor); + inline void SetPressColor(const Nz::Color& color, const Nz::Color& cornerColor); + + inline void SetTexture(const Nz::TextureRef& texture); + inline void SetHoverTexture(const Nz::TextureRef& texture); + inline void SetPressTexture(const Nz::TextureRef& texture); + inline void UpdateText(const Nz::AbstractTextDrawer& drawer); ButtonWidget& operator=(const ButtonWidget&) = delete; ButtonWidget& operator=(ButtonWidget&&) = default; + static const Nz::Color& GetDefaultColor(); + static const Nz::Color& GetDefaultCornerColor(); + static const Nz::Color& GetDefaultHoverColor(); + static const Nz::Color& GetDefaultHoverCornerColor(); + static const Nz::Color& GetDefaultPressColor(); + static const Nz::Color& GetDefaultPressCornerColor(); + NazaraSignal(OnButtonTrigger, const ButtonWidget* /*button*/); private: void Layout() override; void OnMouseEnter() override; + void OnMouseButtonPress(int x, int y, Nz::Mouse::Button button) override; void OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button) override; void OnMouseExit() override; @@ -47,6 +77,24 @@ namespace Ndk EntityHandle m_gradientEntity; Nz::SpriteRef m_gradientSprite; Nz::TextSpriteRef m_textSprite; + + Nz::Color m_color; + Nz::Color m_cornerColor; + Nz::Color m_hoverColor; + Nz::Color m_hoverCornerColor; + Nz::Color m_pressColor; + Nz::Color m_pressCornerColor; + + Nz::TextureRef m_texture; + Nz::TextureRef m_hoverTexture; + Nz::TextureRef m_pressTexture; + + static Nz::Color s_color; + static Nz::Color s_cornerColor; + static Nz::Color s_hoverColor; + static Nz::Color s_hoverCornerColor; + static Nz::Color s_pressColor; + static Nz::Color s_pressCornerColor; }; } diff --git a/SDK/include/NDK/Widgets/ButtonWidget.inl b/SDK/include/NDK/Widgets/ButtonWidget.inl index 4013d290d..68df431bd 100644 --- a/SDK/include/NDK/Widgets/ButtonWidget.inl +++ b/SDK/include/NDK/Widgets/ButtonWidget.inl @@ -6,6 +6,89 @@ namespace Ndk { + inline const Nz::Color& ButtonWidget::GetColor() const + { + return m_color; + } + + inline const Nz::Color& ButtonWidget::GetCornerColor() const + { + return m_cornerColor; + } + + inline const Nz::Color& ButtonWidget::GetHoverColor() const + { + return m_hoverColor; + } + + inline const Nz::Color& ButtonWidget::GetHoverCornerColor() const + { + return m_hoverCornerColor; + } + + inline const Nz::Color& ButtonWidget::GetPressColor() const + { + return m_pressColor; + } + + inline const Nz::Color& ButtonWidget::GetPressCornerColor() const + { + return m_pressCornerColor; + } + + inline const Nz::TextureRef& ButtonWidget::GetTexture() const + { + return m_texture; + } + + inline const Nz::TextureRef& ButtonWidget::GetHoverTexture() const + { + return m_hoverTexture; + } + + inline const Nz::TextureRef& ButtonWidget::GetPressTexture() const + { + return m_pressTexture; + } + + inline void ButtonWidget::SetColor(const Nz::Color& color, const Nz::Color& cornerColor) + { + m_color = color; + m_cornerColor = cornerColor; + + m_gradientSprite->SetColor(m_color); + m_gradientSprite->SetCornerColor(Nz::RectCorner_LeftBottom, m_cornerColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_RightBottom, m_cornerColor); + } + + inline void ButtonWidget::SetHoverColor(const Nz::Color& color, const Nz::Color& cornerColor) + { + m_hoverColor = color; + m_hoverCornerColor = cornerColor; + } + + inline void ButtonWidget::SetPressColor(const Nz::Color& color, const Nz::Color& cornerColor) + { + m_pressColor = color; + m_pressCornerColor = cornerColor; + } + + inline void ButtonWidget::SetTexture(const Nz::TextureRef& texture) + { + m_texture = texture; + m_gradientSprite->SetTexture(m_texture); + } + + inline void ButtonWidget::SetHoverTexture(const Nz::TextureRef& texture) + { + m_hoverTexture = texture; + } + + inline void ButtonWidget::SetPressTexture(const Nz::TextureRef& texture) + { + m_pressTexture = texture; + } + inline void ButtonWidget::UpdateText(const Nz::AbstractTextDrawer& drawer) { m_textSprite->Update(drawer); diff --git a/SDK/include/NDK/Widgets/CheckboxWidget.hpp b/SDK/include/NDK/Widgets/CheckboxWidget.hpp new file mode 100644 index 000000000..1659199d6 --- /dev/null +++ b/SDK/include/NDK/Widgets/CheckboxWidget.hpp @@ -0,0 +1,105 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_WIDGETS_CHECKBOXWIDGET_HPP +#define NDK_WIDGETS_CHECKBOXWIDGET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class AbstractTextDrawer; +} + +namespace Ndk +{ + class NDK_API CheckboxWidget : public BaseWidget + { + friend class Sdk; + + public: + CheckboxWidget(BaseWidget* parent = nullptr); + CheckboxWidget(const CheckboxWidget&) = delete; + CheckboxWidget(CheckboxWidget&&) = default; + ~CheckboxWidget() = default; + + //virtual CheckboxWidget* Clone() const = 0; + + inline void EnableAdaptativeMargin(bool enable = true); + inline void EnableCheckbox(bool enable = true); + inline void EnableTristate(bool enable = true); + + inline bool IsCheckboxEnabled() const; + inline bool IsMarginAdaptative() const; + inline bool IsTristateEnabled() const; + + inline const Nz::Vector2f& GetCheckboxSize() const; + inline Nz::Vector2f GetCheckboxBorderSize() const; + inline CheckboxState GetState() const; + inline float GetTextMargin() const; + + inline void SetCheckboxSize(const Nz::Vector2f& size); + CheckboxState SwitchToNextState(); + void SetState(CheckboxState state); + inline void SetTextMargin(float margin); + + void ResizeToContent() override; + inline void UpdateText(const Nz::AbstractTextDrawer& drawer); + + + CheckboxWidget& operator=(const CheckboxWidget&) = delete; + CheckboxWidget& operator=(CheckboxWidget&&) = default; + + NazaraSignal(OnStateChanged, const CheckboxWidget* /*checkbox*/); + + private: + static bool Initialize(); + static void Uninitialize(); + + void Layout() override; + void UpdateCheckbox(); + + void OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button) override; + inline bool ContainsCheckbox(int x, int y) const; + + + EntityHandle m_checkboxBorderEntity; + EntityHandle m_checkboxBackgroundEntity; + EntityHandle m_checkboxContentEntity; + EntityHandle m_textEntity; + + Nz::TextureRef m_checkMark; + + Nz::SpriteRef m_checkboxContentSprite; + Nz::SpriteRef m_checkboxBorderSprite; + Nz::SpriteRef m_checkboxBackgroundSprite; + Nz::TextSpriteRef m_textSprite; + + static Nz::Color s_backgroundColor; + static Nz::Color s_disabledBackgroundColor; + static Nz::Color s_disabledBorderColor; + static Nz::Color s_borderColor; + + bool m_adaptativeMargin; + bool m_checkboxEnabled; + bool m_tristateEnabled; + + static float s_borderScale; + float m_textMargin; + CheckboxState m_state; + }; +} + +#include + +#endif // NDK_WIDGETS_CHECKBOXWIDGET_HPP diff --git a/SDK/include/NDK/Widgets/CheckboxWidget.inl b/SDK/include/NDK/Widgets/CheckboxWidget.inl new file mode 100644 index 000000000..cb20a1c0c --- /dev/null +++ b/SDK/include/NDK/Widgets/CheckboxWidget.inl @@ -0,0 +1,91 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +namespace Ndk +{ + inline void CheckboxWidget::EnableAdaptativeMargin(bool enable) + { + m_adaptativeMargin = enable; + Layout(); + } + + inline void CheckboxWidget::EnableCheckbox(bool enable) + { + m_checkboxEnabled = enable; + UpdateCheckbox(); + } + + inline void CheckboxWidget::EnableTristate(bool enable) + { + m_tristateEnabled = enable; + + if (m_tristateEnabled && GetState() == CheckboxState_Tristate) + SetState(CheckboxState_Unchecked); + } + + inline bool CheckboxWidget::IsCheckboxEnabled() const + { + return m_checkboxEnabled; + } + + inline bool CheckboxWidget::IsMarginAdaptative() const + { + return m_adaptativeMargin; + } + + inline bool CheckboxWidget::IsTristateEnabled() const + { + return m_tristateEnabled; + } + + inline const Nz::Vector2f& CheckboxWidget::GetCheckboxSize() const + { + return m_checkboxBorderSprite->GetSize(); + } + + inline Nz::Vector2f CheckboxWidget::GetCheckboxBorderSize() const + { + return GetCheckboxSize() / s_borderScale; + } + + inline CheckboxState CheckboxWidget::GetState() const + { + return m_state; + } + + inline float CheckboxWidget::GetTextMargin() const + { + return m_textMargin; + } + + inline void CheckboxWidget::SetCheckboxSize(const Nz::Vector2f& size) + { + m_checkboxBorderSprite->SetSize(size); + m_checkboxBackgroundSprite->SetSize(size - GetCheckboxBorderSize() * 2.f); + m_checkboxContentSprite->SetSize(GetCheckboxSize() - GetCheckboxBorderSize() * 2.f - Nz::Vector2f { 4.f, 4.f }); + + Layout(); + } + + inline void CheckboxWidget::SetTextMargin(float margin) + { + m_textMargin = margin; + Layout(); + } + + inline void CheckboxWidget::UpdateText(const Nz::AbstractTextDrawer& drawer) + { + m_textSprite->Update(drawer); + Layout(); + } + + inline bool CheckboxWidget::ContainsCheckbox(int x, int y) const + { + Nz::Vector2f checkboxSize = GetCheckboxSize(); + Nz::Vector3f pos = m_checkboxBorderEntity->GetComponent().GetPosition(Nz::CoordSys_Local); + + return x > pos.x && x < pos.x + checkboxSize.x && + y > pos.y && y < pos.y + checkboxSize.y; + } +} diff --git a/SDK/include/NDK/Widgets/Enums.hpp b/SDK/include/NDK/Widgets/Enums.hpp new file mode 100644 index 000000000..93e51c018 --- /dev/null +++ b/SDK/include/NDK/Widgets/Enums.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NAZARA_ENUMS_SDK_HPP +#define NAZARA_ENUMS_SDK_HPP + +namespace Ndk +{ + enum CheckboxState + { + CheckboxState_Checked, + CheckboxState_Tristate, + CheckboxState_Unchecked, + + CheckboxState_Max = CheckboxState_Unchecked + }; + + enum EchoMode + { + EchoMode_Normal, + EchoMode_Password, + EchoMode_PasswordExceptLast, + + EchoMode_Max = EchoMode_PasswordExceptLast + }; +} + +#endif // NAZARA_ENUMS_SDK_HPP diff --git a/SDK/include/NDK/Widgets/ImageWidget.hpp b/SDK/include/NDK/Widgets/ImageWidget.hpp new file mode 100644 index 000000000..7fe59c9f2 --- /dev/null +++ b/SDK/include/NDK/Widgets/ImageWidget.hpp @@ -0,0 +1,53 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_WIDGETS_IMAGEWIDGET_HPP +#define NDK_WIDGETS_IMAGEWIDGET_HPP + +#include +#include +#include +#include +#include +#include + +namespace Ndk +{ + class NDK_API ImageWidget : public BaseWidget + { + public: + ImageWidget(BaseWidget* parent = nullptr); + ImageWidget(const ImageWidget&) = delete; + ImageWidget(ImageWidget&&) = default; + ~ImageWidget() = default; + + //virtual ImageWidget* Clone() const = 0; + + void ResizeToContent() override; + + inline const Nz::Color& GetColor() const; + inline const Nz::TextureRef& GetTexture() const; + inline const Nz::Rectf& GetTextureCoords() const; + + inline void SetColor(const Nz::Color& color); + inline void SetTexture(const Nz::TextureRef& texture, bool resizeToContent = true); + inline void SetTextureCoords(const Nz::Rectf& coords); + inline void SetTextureRect(const Nz::Rectui& rect); + + ImageWidget& operator=(const ImageWidget&) = delete; + ImageWidget& operator=(ImageWidget&&) = default; + + private: + void Layout() override; + + Ndk::EntityHandle m_entity; + Nz::SpriteRef m_sprite; + }; +} + +#include + +#endif // NDK_WIDGETS_IMAGEWIDGET_HPP diff --git a/SDK/include/NDK/Widgets/ImageWidget.inl b/SDK/include/NDK/Widgets/ImageWidget.inl new file mode 100644 index 000000000..05c530f83 --- /dev/null +++ b/SDK/include/NDK/Widgets/ImageWidget.inl @@ -0,0 +1,46 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include + +namespace Ndk +{ + inline const Nz::Color& ImageWidget::GetColor() const + { + return m_sprite->GetColor(); + } + + inline const Nz::TextureRef& ImageWidget::GetTexture() const + { + return m_sprite->GetMaterial()->GetDiffuseMap(); + } + + inline const Nz::Rectf& ImageWidget::GetTextureCoords() const + { + return m_sprite->GetTextureCoords(); + } + + inline void ImageWidget::SetColor(const Nz::Color& color) + { + m_sprite->SetColor(color); + } + + inline void ImageWidget::SetTexture(const Nz::TextureRef& texture, bool resizeToContent) + { + m_sprite->SetTexture(texture, false); + + if (resizeToContent) + ResizeToContent(); + } + + inline void ImageWidget::SetTextureCoords(const Nz::Rectf& coords) + { + m_sprite->SetTextureCoords(coords); + } + + inline void ImageWidget::SetTextureRect(const Nz::Rectui& rect) + { + m_sprite->SetTextureRect(rect); + } +} diff --git a/SDK/include/NDK/Widgets/LabelWidget.hpp b/SDK/include/NDK/Widgets/LabelWidget.hpp index 06f53273c..afad46f3c 100644 --- a/SDK/include/NDK/Widgets/LabelWidget.hpp +++ b/SDK/include/NDK/Widgets/LabelWidget.hpp @@ -9,13 +9,15 @@ #include #include -#include #include +namespace Nz +{ + class AbstractTextDrawer; +} + namespace Ndk { - class World; - class NDK_API LabelWidget : public BaseWidget { public: diff --git a/SDK/include/NDK/Widgets/ProgressBarWidget.hpp b/SDK/include/NDK/Widgets/ProgressBarWidget.hpp new file mode 100644 index 000000000..f8399ca6c --- /dev/null +++ b/SDK/include/NDK/Widgets/ProgressBarWidget.hpp @@ -0,0 +1,103 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_WIDGETS_PROGRESSBARWIDGET_HPP +#define NDK_WIDGETS_PROGRESSBARWIDGET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ndk +{ + class NDK_API ProgressBarWidget : public BaseWidget + { + friend class Sdk; + + public: + ProgressBarWidget(BaseWidget* parent = nullptr); + ProgressBarWidget(const ProgressBarWidget&) = delete; + ProgressBarWidget(ProgressBarWidget&&) = default; + ~ProgressBarWidget() = default; + + //virtual ProgressBarWidget* Clone() const = 0; + + inline void EnableText(bool enable = true); + inline void EnableBorder(bool enable = true); + + inline bool IsTextEnabled() const; + inline bool IsBorderEnabled() const; + + + inline unsigned GetPercentageValue() const; + inline Nz::Vector2f GetProgressBarSize() const; + inline Nz::Vector2f GetProgressBarBorderSize() const; + inline float GetTextMargin() const; + + + inline const Nz::Color& GetBarBackgroundColor() const; + inline const Nz::Color& GetBarBackgroundCornerColor() const; + inline const Nz::Color& GetBarColor() const; + inline const Nz::Color& GetBarCornerColor() const; + + inline const Nz::TextureRef& GetBarBackgroundTexture() const; + inline const Nz::TextureRef& GetBarTexture() const; + + static const Nz::Color& GetDefaultBarColor(); + static const Nz::Color& GetDefaultBarCornerColor(); + static const Nz::Color& GetDefaultBarBackgroundColor(); + static const Nz::Color& GetDefaultBarBackgroundCornerColor(); + + + inline void SetBarBackgroundColor(const Nz::Color& globalColor, const Nz::Color& cornerColor); + inline void SetBarBackgroundTexture(Nz::TextureRef texture, bool resetColors = true); + inline void SetBarColor(const Nz::Color& globalColor, const Nz::Color& cornerColor); + inline void SetBarTexture(Nz::TextureRef texture, bool resetColors = true); + + + inline void SetPercentageValue(unsigned percentage); + inline void SetTextMargin(float margin); + inline void SetTextColor(const Nz::Color& color); + + inline void ResizeToContent() override {} + + NazaraSignal(OnValueChanged, const ProgressBarWidget* /*progressBar*/); + + private: + void Layout() override; + inline void UpdateText(); + + + EntityHandle m_borderEntity; + EntityHandle m_barEntity; + EntityHandle m_textEntity; + + static Nz::Color s_borderColor; + static Nz::Color s_barBackgroundColor; + static Nz::Color s_barBackgroundCornerColor; + static Nz::Color s_barColor; + static Nz::Color s_barCornerColor; + Nz::Color m_textColor; + + Nz::SpriteRef m_borderSprite; + Nz::SpriteRef m_barBackgroundSprite; + Nz::SpriteRef m_barSprite; + Nz::TextSpriteRef m_textSprite; + + static float s_borderScale; + float m_textMargin; + unsigned m_value; + }; +} + +#include + +#endif // NDK_WIDGETS_PROGRESSBARWIDGET_HPP diff --git a/SDK/include/NDK/Widgets/ProgressBarWidget.inl b/SDK/include/NDK/Widgets/ProgressBarWidget.inl new file mode 100644 index 000000000..325149af9 --- /dev/null +++ b/SDK/include/NDK/Widgets/ProgressBarWidget.inl @@ -0,0 +1,156 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +namespace Ndk +{ + inline void ProgressBarWidget::EnableText(bool enable) + { + m_textEntity->Enable(enable); + Layout(); + } + + inline void ProgressBarWidget::EnableBorder(bool enable) + { + m_borderEntity->Enable(enable); + } + + inline bool ProgressBarWidget::IsTextEnabled() const + { + return m_textEntity->IsEnabled(); + } + + inline bool ProgressBarWidget::IsBorderEnabled() const + { + return m_borderEntity->IsEnabled(); + } + + + inline unsigned ProgressBarWidget::GetPercentageValue() const + { + return m_value; + } + + inline Nz::Vector2f ProgressBarWidget::GetProgressBarSize() const + { + Nz::Vector3f progressBarSize = m_borderSprite->GetBoundingVolume().obb.localBox.GetLengths(); + + if (IsTextEnabled()) + { + Nz::Vector3f textSize = m_textSprite->GetBoundingVolume().obb.localBox.GetLengths(); + progressBarSize -= { textSize.x + m_textMargin, 0.f, 0.f }; + } + + return { progressBarSize.x, progressBarSize.y }; + } + + inline Nz::Vector2f ProgressBarWidget::GetProgressBarBorderSize() const + { + Nz::Vector2f barSize = GetProgressBarSize(); + return { barSize.y / s_borderScale, barSize.y / s_borderScale }; + } + + inline float ProgressBarWidget::GetTextMargin() const + { + return m_textMargin; + } + + + inline const Nz::Color& ProgressBarWidget::GetBarBackgroundColor() const + { + return m_barBackgroundSprite->GetColor(); + } + + inline const Nz::Color& ProgressBarWidget::GetBarBackgroundCornerColor() const + { + return m_barBackgroundSprite->GetCornerColor(Nz::RectCorner_LeftTop); + } + + inline const Nz::Color& ProgressBarWidget::GetBarColor() const + { + return m_barSprite->GetColor(); + } + + inline const Nz::Color& ProgressBarWidget::GetBarCornerColor() const + { + return m_barSprite->GetCornerColor(Nz::RectCorner_LeftTop); + } + + + inline const Nz::TextureRef& ProgressBarWidget::GetBarBackgroundTexture() const + { + return m_barBackgroundSprite->GetMaterial()->GetDiffuseMap(); + } + + inline const Nz::TextureRef& ProgressBarWidget::GetBarTexture() const + { + return m_barSprite->GetMaterial()->GetDiffuseMap(); + } + + + inline void ProgressBarWidget::SetBarBackgroundColor(const Nz::Color& globalColor, const Nz::Color& cornerColor) + { + m_barBackgroundSprite->SetColor(globalColor); + m_barBackgroundSprite->SetCornerColor(Nz::RectCorner_LeftTop, cornerColor); + m_barBackgroundSprite->SetCornerColor(Nz::RectCorner_RightTop, cornerColor); + m_barBackgroundSprite->SetCornerColor(Nz::RectCorner_LeftBottom, globalColor); + m_barBackgroundSprite->SetCornerColor(Nz::RectCorner_RightBottom, globalColor); + } + + inline void ProgressBarWidget::SetBarBackgroundTexture(Nz::TextureRef texture, bool resetColors) + { + m_barBackgroundSprite->SetTexture(texture, false); + + if (resetColors) + SetBarBackgroundColor(Nz::Color::White, Nz::Color::White); + } + + inline void ProgressBarWidget::SetBarColor(const Nz::Color& globalColor, const Nz::Color& cornerColor) + { + m_barSprite->SetColor(globalColor); + m_barSprite->SetCornerColor(Nz::RectCorner_LeftTop, cornerColor); + m_barSprite->SetCornerColor(Nz::RectCorner_RightTop, cornerColor); + m_barSprite->SetCornerColor(Nz::RectCorner_LeftBottom, globalColor); + m_barSprite->SetCornerColor(Nz::RectCorner_RightBottom, globalColor); + } + + inline void ProgressBarWidget::SetBarTexture(Nz::TextureRef texture, bool resetColors) + { + m_barSprite->SetTexture(texture, false); + + if (resetColors) + SetBarColor(Nz::Color::White, Nz::Color::White); + } + + + inline void ProgressBarWidget::SetPercentageValue(unsigned percentage) + { + m_value = percentage; + OnValueChanged(this); + Layout(); + } + + inline void ProgressBarWidget::SetTextMargin(float margin) + { + m_textMargin = margin; + + if (IsTextEnabled()) + Layout(); + } + + inline void ProgressBarWidget::SetTextColor(const Nz::Color& color) + { + m_textColor = color; + UpdateText(); + } + + inline void ProgressBarWidget::UpdateText() + { + if (IsTextEnabled()) + { + Nz::Vector2f size = GetContentSize(); + m_textSprite->Update(Nz::SimpleTextDrawer::Draw(Nz::String::Number(m_value).Append('%'), + static_cast(std::min(size.x, size.y) / 2.f), 0u, m_textColor)); + } + } +} diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index 7bab6f1bf..300cc2196 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -7,15 +7,13 @@ #ifndef NDK_WIDGETS_TEXTAREAWIDGET_HPP #define NDK_WIDGETS_TEXTAREAWIDGET_HPP -#include -#include -#include #include +#include +#include +#include namespace Ndk { - class World; - class NDK_API TextAreaWidget : public BaseWidget { public: @@ -32,9 +30,11 @@ namespace Ndk inline void EnableMultiline(bool enable = true); + inline unsigned int GetCharacterSize() const; inline const Nz::Vector2ui& GetCursorPosition() const; - inline std::size_t GetGlyphUnderCursor() const; - inline std::size_t GetLineCount() const; + inline const Nz::String& GetDisplayText() const; + inline EchoMode GetEchoMode() const; + inline std::size_t GetGlyphIndex(const Nz::Vector2ui& cursorPosition); inline const Nz::String& GetText() const; inline const Nz::Color& GetTextColor() const; @@ -48,8 +48,10 @@ namespace Ndk void ResizeToContent() override; + inline void SetCharacterSize(unsigned int characterSize); inline void SetCursorPosition(std::size_t glyphIndex); inline void SetCursorPosition(Nz::Vector2ui cursorPosition); + inline void SetEchoMode(EchoMode echoMode); inline void SetReadOnly(bool readOnly = true); inline void SetText(const Nz::String& text); inline void SetTextColor(const Nz::Color& text); @@ -66,27 +68,30 @@ namespace Ndk NazaraSignal(OnTextAreaKeyReturn, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); NazaraSignal(OnTextAreaKeyRight, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); NazaraSignal(OnTextAreaKeyUp, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); + NazaraSignal(OnTextChanged, const TextAreaWidget* /*textArea*/, const Nz::String& /*text*/); private: void Layout() override; - void OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) override; + bool IsFocusable() const override; + void OnFocusLost() override; + void OnFocusReceived() override; + bool OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) override; void OnKeyReleased(const Nz::WindowEvent::KeyEvent& key) override; - void OnMouseEnter() override; void OnMouseButtonPress(int /*x*/, int /*y*/, Nz::Mouse::Button button) override; - void OnMouseMoved(int x, int y, int deltaX, int deltaY) override; - void OnMouseExit() override; void OnTextEntered(char32_t character, bool repeated) override; void RefreshCursor(); + void UpdateDisplayText(); + EchoMode m_echoMode; EntityHandle m_cursorEntity; EntityHandle m_textEntity; Nz::SimpleTextDrawer m_drawer; Nz::SpriteRef m_cursorSprite; + Nz::String m_text; Nz::TextSpriteRef m_textSprite; Nz::Vector2ui m_cursorPosition; - std::size_t m_cursorGlyph; bool m_multiLineEnabled; bool m_readOnly; }; diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index ffc75c8ba..35e7c67ee 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -8,7 +8,7 @@ namespace Ndk { inline void TextAreaWidget::Clear() { - m_cursorPosition = 0; + m_cursorPosition.MakeZero(); m_drawer.Clear(); m_textSprite->Update(m_drawer); @@ -20,24 +20,40 @@ namespace Ndk m_multiLineEnabled = enable; } + inline unsigned int TextAreaWidget::GetCharacterSize() const + { + return m_drawer.GetCharacterSize(); + } + inline const Nz::Vector2ui& TextAreaWidget::GetCursorPosition() const { return m_cursorPosition; } - inline std::size_t Ndk::TextAreaWidget::GetGlyphUnderCursor() const + inline const Nz::String& TextAreaWidget::GetDisplayText() const { - return m_cursorGlyph; + return m_drawer.GetText(); } - inline std::size_t TextAreaWidget::GetLineCount() const + inline std::size_t TextAreaWidget::GetGlyphIndex(const Nz::Vector2ui& cursorPosition) { - return m_drawer.GetLineCount(); + std::size_t glyphIndex = m_drawer.GetLine(cursorPosition.y).glyphIndex + cursorPosition.x; + if (m_drawer.GetLineCount() > cursorPosition.y + 1) + glyphIndex = std::min(glyphIndex, m_drawer.GetLine(cursorPosition.y + 1).glyphIndex - 1); + else + glyphIndex = std::min(glyphIndex, m_drawer.GetGlyphCount()); + + return glyphIndex; + } + + inline EchoMode TextAreaWidget::GetEchoMode() const + { + return m_echoMode; } inline const Nz::String& TextAreaWidget::GetText() const { - return m_drawer.GetText(); + return m_text; } inline const Nz::Color& TextAreaWidget::GetTextColor() const @@ -57,27 +73,28 @@ namespace Ndk inline void TextAreaWidget::MoveCursor(int offset) { + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); if (offset >= 0) - SetCursorPosition(m_cursorGlyph + static_cast(offset)); + SetCursorPosition(cursorGlyph + static_cast(offset)); else { std::size_t nOffset = static_cast(-offset); - if (nOffset >= m_cursorGlyph) + if (nOffset >= cursorGlyph) SetCursorPosition(0); else - SetCursorPosition(m_cursorGlyph - nOffset); + SetCursorPosition(cursorGlyph - nOffset); } } inline void TextAreaWidget::MoveCursor(const Nz::Vector2i& offset) { - auto BoundOffset = [] (unsigned int cursorPosition, int offset) -> unsigned int + auto ClampOffset = [] (unsigned int cursorPosition, int cursorOffset) -> unsigned int { - if (offset >= 0) - return cursorPosition + offset; + if (cursorOffset >= 0) + return cursorPosition + cursorOffset; else { - unsigned int nOffset = static_cast(-offset); + unsigned int nOffset = static_cast(-cursorOffset); if (nOffset >= cursorPosition) return 0; else @@ -86,23 +103,28 @@ namespace Ndk }; Nz::Vector2ui cursorPosition = m_cursorPosition; - cursorPosition.x = BoundOffset(static_cast(cursorPosition.x), offset.x); - cursorPosition.y = BoundOffset(static_cast(cursorPosition.y), offset.y); + cursorPosition.x = ClampOffset(static_cast(cursorPosition.x), offset.x); + cursorPosition.y = ClampOffset(static_cast(cursorPosition.y), offset.y); SetCursorPosition(cursorPosition); } + inline void TextAreaWidget::SetCharacterSize(unsigned int characterSize) + { + m_drawer.SetCharacterSize(characterSize); + } + inline void TextAreaWidget::SetCursorPosition(std::size_t glyphIndex) { OnTextAreaCursorMove(this, &glyphIndex); - m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount()); - + glyphIndex = std::min(glyphIndex, m_drawer.GetGlyphCount()); + std::size_t lineCount = m_drawer.GetLineCount(); std::size_t line = 0U; for (std::size_t i = line + 1; i < lineCount; ++i) { - if (m_drawer.GetLine(i).glyphIndex > m_cursorGlyph) + if (m_drawer.GetLine(i).glyphIndex > glyphIndex) break; line = i; @@ -110,8 +132,8 @@ namespace Ndk const auto& lineInfo = m_drawer.GetLine(line); - m_cursorPosition.y = line; - m_cursorPosition.x = m_cursorGlyph - lineInfo.glyphIndex; + m_cursorPosition.y = static_cast(line); + m_cursorPosition.x = static_cast(glyphIndex - lineInfo.glyphIndex); RefreshCursor(); } @@ -135,25 +157,28 @@ namespace Ndk OnTextAreaCursorMove(this, &glyphIndex); - m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount()); - RefreshCursor(); } + inline void TextAreaWidget::SetEchoMode(EchoMode echoMode) + { + m_echoMode = echoMode; + + UpdateDisplayText(); + } + inline void TextAreaWidget::SetReadOnly(bool readOnly) { m_readOnly = readOnly; - - m_cursorEntity->Enable(!m_readOnly); + m_cursorEntity->Enable(!m_readOnly && HasFocus()); } inline void TextAreaWidget::SetText(const Nz::String& text) { - m_drawer.SetText(text); + m_text = text; + OnTextChanged(this, m_text); - m_textSprite->Update(m_drawer); - - SetCursorPosition(m_cursorPosition); //< Refresh cursor position (prevent it from being outside of the text) + UpdateDisplayText(); } inline void TextAreaWidget::SetTextColor(const Nz::Color& text) diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp index 29b9a4a9e..9cc6d8901 100644 --- a/SDK/include/NDK/World.hpp +++ b/SDK/include/NDK/World.hpp @@ -15,7 +15,6 @@ #include #include #include -#include namespace Ndk { diff --git a/SDK/include/NDK/World.inl b/SDK/include/NDK/World.inl index d45f0ff1d..88e33ec1d 100644 --- a/SDK/include/NDK/World.inl +++ b/SDK/include/NDK/World.inl @@ -197,7 +197,7 @@ namespace Ndk * * \param id Identifier of the entity * - * \remark Handle referenced by this function can move in memory when updating the world, do not keep a reference to a handle from a world update to another + * \remark Handle referenced by this function can move in memory when updating the world, do not keep a handle reference from a world update to another * \remark If an invalid identifier is provided, an error got triggered and an invalid handle is returned */ inline const EntityHandle& World::GetEntity(EntityId id) @@ -306,15 +306,19 @@ namespace Ndk m_killedEntities = std::move(world.m_killedEntities); m_orderedSystems = std::move(world.m_orderedSystems); m_orderedSystemsUpdated = world.m_orderedSystemsUpdated; - m_waitingEntities = std::move(world.m_waitingEntities); m_entities = std::move(world.m_entities); for (EntityBlock& block : m_entities) block.entity.SetWorld(this); + m_waitingEntities = std::move(world.m_waitingEntities); + for (auto& blockPtr : m_waitingEntities) + blockPtr->entity.SetWorld(this); + m_systems = std::move(world.m_systems); for (const auto& systemPtr : m_systems) - systemPtr->SetWorld(this); + if (systemPtr) + systemPtr->SetWorld(this); return *this; } diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index c70ec181b..e9b866d4e 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #endif @@ -147,7 +148,10 @@ namespace Ndk Nz::Vector2ui windowDimensions; if (info.window->IsValid()) - windowDimensions.Set(info.window->GetWidth(), info.window->GetHeight() / 4); + { + windowDimensions = info.window->GetSize(); + windowDimensions.y /= 4; + } else windowDimensions.MakeZero(); @@ -211,7 +215,8 @@ namespace Ndk overlay->resizedSlot.Connect(info.renderTarget->OnRenderTargetSizeChange, [&consoleRef] (const Nz::RenderTarget* renderTarget) { - consoleRef.SetSize({float(renderTarget->GetWidth()), renderTarget->GetHeight() / 4.f}); + Nz::Vector2ui size = renderTarget->GetSize(); + consoleRef.SetSize({float(size.x), size.y / 4.f}); }); info.console = std::move(overlay); diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 7368558d3..ff38e6f34 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -46,6 +46,15 @@ namespace Ndk UnregisterFromCanvas(); } + /*! + * \brief Clears keyboard focus if and only if this widget owns it. + */ + void BaseWidget::ClearFocus() + { + if (IsRegisteredToCanvas()) + m_canvas->ClearKeyboardOwner(m_canvasIndex); + } + /*! * \brief Destroy the widget, deleting it in the process. * @@ -70,7 +79,7 @@ namespace Ndk { m_backgroundSprite = Nz::Sprite::New(); m_backgroundSprite->SetColor(m_backgroundColor); - m_backgroundSprite->SetMaterial(Nz::Material::New((m_backgroundColor.IsOpaque()) ? "Basic2D" : "Translucent2D")); + m_backgroundSprite->SetMaterial(Nz::Material::New((m_backgroundColor.IsOpaque()) ? "Basic2D" : "Translucent2D")); //< TODO: Use a shared material instead of creating one everytime m_backgroundEntity = CreateEntity(); m_backgroundEntity->AddComponent().Attach(m_backgroundSprite, -1); @@ -85,9 +94,16 @@ namespace Ndk } } - void BaseWidget::GrabKeyboard() + /*! + * \brief Checks if this widget has keyboard focus + * \return true if widget has keyboard focus, false otherwhise + */ + bool BaseWidget::HasFocus() const { - m_canvas->SetKeyboardOwner(this); + if (!IsRegisteredToCanvas()) + return false; + + return m_canvas->IsKeyboardOwner(m_canvasIndex); } void BaseWidget::SetBackgroundColor(const Nz::Color& color) @@ -109,6 +125,12 @@ namespace Ndk m_canvas->NotifyWidgetCursorUpdate(m_canvasIndex); } + void BaseWidget::SetFocus() + { + if (IsRegisteredToCanvas()) + m_canvas->SetKeyboardOwner(m_canvasIndex); + } + void BaseWidget::SetSize(const Nz::Vector2f& size) { SetContentSize({std::max(size.x - m_padding.left - m_padding.right, 0.f), std::max(size.y - m_padding.top - m_padding.bottom, 0.f)}); @@ -133,9 +155,9 @@ namespace Ndk } } - EntityHandle BaseWidget::CreateEntity() + const Ndk::EntityHandle& BaseWidget::CreateEntity() { - EntityHandle newEntity = m_world->CreateEntity(); + const EntityHandle& newEntity = m_world->CreateEntity(); newEntity->Enable(m_visible); m_entities.emplace_back(newEntity); @@ -167,8 +189,22 @@ namespace Ndk m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex); } - void BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& /*key*/) + bool BaseWidget::IsFocusable() const { + return false; + } + + void BaseWidget::OnFocusLost() + { + } + + void BaseWidget::OnFocusReceived() + { + } + + bool BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) + { + return false; } void BaseWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/) diff --git a/SDK/src/NDK/Canvas.cpp b/SDK/src/NDK/Canvas.cpp index 11e9d1ce9..32f02d5c5 100644 --- a/SDK/src/NDK/Canvas.cpp +++ b/SDK/src/NDK/Canvas.cpp @@ -3,9 +3,6 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include -#include -#include -#include #include namespace Ndk @@ -16,12 +13,12 @@ namespace Ndk std::size_t Canvas::RegisterWidget(BaseWidget* widget) { - WidgetBox box; + WidgetEntry box; box.cursor = widget->GetCursor(); box.widget = widget; - std::size_t index = m_widgetBoxes.size(); - m_widgetBoxes.emplace_back(box); + std::size_t index = m_widgetEntries.size(); + m_widgetEntries.emplace_back(box); NotifyWidgetBoxUpdate(index); return index; @@ -29,91 +26,106 @@ namespace Ndk void Canvas::UnregisterWidget(std::size_t index) { - WidgetBox& entry = m_widgetBoxes[index]; + WidgetEntry& entry = m_widgetEntries[index]; - if (m_hoveredWidget == &entry) - m_hoveredWidget = nullptr; + if (m_hoveredWidget == index) + m_hoveredWidget = InvalidCanvasIndex; - if (m_keyboardOwner == entry.widget) - m_keyboardOwner = nullptr; + if (m_keyboardOwner == index) + m_keyboardOwner = InvalidCanvasIndex; - if (m_widgetBoxes.size() > 1U) + if (m_widgetEntries.size() > 1U) { - WidgetBox& lastEntry = m_widgetBoxes.back(); + WidgetEntry& lastEntry = m_widgetEntries.back(); + std::size_t lastEntryIndex = m_widgetEntries.size() - 1; entry = std::move(lastEntry); entry.widget->UpdateCanvasIndex(index); + + if (m_hoveredWidget == lastEntryIndex) + m_hoveredWidget = index; + + if (m_keyboardOwner == lastEntryIndex) + m_keyboardOwner = index; } - m_widgetBoxes.pop_back(); + m_widgetEntries.pop_back(); } void Canvas::OnEventMouseButtonPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent& event) { - if (m_hoveredWidget) + if (m_hoveredWidget != InvalidCanvasIndex) { - int x = static_cast(std::round(event.x - m_hoveredWidget->box.x)); - int y = static_cast(std::round(event.y - m_hoveredWidget->box.y)); + WidgetEntry& hoveredWidget = m_widgetEntries[m_hoveredWidget]; - m_hoveredWidget->widget->OnMouseButtonPress(x, y, event.button); + int x = static_cast(std::round(event.x - hoveredWidget.box.x)); + int y = static_cast(std::round(event.y - hoveredWidget.box.y)); + + hoveredWidget.widget->OnMouseButtonPress(x, y, event.button); } } void Canvas::OnEventMouseButtonRelease(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent & event) { - if (m_hoveredWidget) + if (m_hoveredWidget != InvalidCanvasIndex) { - int x = static_cast(std::round(event.x - m_hoveredWidget->box.x)); - int y = static_cast(std::round(event.y - m_hoveredWidget->box.y)); + WidgetEntry& hoveredWidget = m_widgetEntries[m_hoveredWidget]; - m_hoveredWidget->widget->OnMouseButtonRelease(x, y, event.button); + int x = static_cast(std::round(event.x - hoveredWidget.box.x)); + int y = static_cast(std::round(event.y - hoveredWidget.box.y)); + + hoveredWidget.widget->OnMouseButtonRelease(x, y, event.button); } } void Canvas::OnEventMouseMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event) { - const WidgetBox* bestEntry = nullptr; + std::size_t bestEntry = InvalidCanvasIndex; float bestEntryArea = std::numeric_limits::infinity(); Nz::Vector3f mousePos(float(event.x), float(event.y), 0.f); - for (const WidgetBox& entry : m_widgetBoxes) + for (std::size_t i = 0; i < m_widgetEntries.size(); ++i) { - const Nz::Boxf& box = entry.box; + const Nz::Boxf& box = m_widgetEntries[i].box; if (box.Contains(mousePos)) { float area = box.width * box.height; if (area < bestEntryArea) { - bestEntry = &entry; + bestEntry = i; bestEntryArea = area; } } } - if (bestEntry) + if (bestEntry != InvalidCanvasIndex) { if (m_hoveredWidget != bestEntry) { - if (m_hoveredWidget) - m_hoveredWidget->widget->OnMouseExit(); + if (m_hoveredWidget != InvalidCanvasIndex) + { + WidgetEntry& previouslyHovered = m_widgetEntries[m_hoveredWidget]; + previouslyHovered.widget->OnMouseExit(); + } m_hoveredWidget = bestEntry; - m_hoveredWidget->widget->OnMouseEnter(); + m_widgetEntries[m_hoveredWidget].widget->OnMouseEnter(); if (m_cursorController) - m_cursorController->UpdateCursor(Nz::Cursor::Get(m_hoveredWidget->cursor)); + m_cursorController->UpdateCursor(Nz::Cursor::Get(m_widgetEntries[m_hoveredWidget].cursor)); } - int x = static_cast(std::round(event.x - m_hoveredWidget->box.x)); - int y = static_cast(std::round(event.y - m_hoveredWidget->box.y)); + WidgetEntry& hoveredWidget = m_widgetEntries[m_hoveredWidget]; - bestEntry->widget->OnMouseMoved(x, y, event.deltaX, event.deltaY); + int x = static_cast(std::round(event.x - hoveredWidget.box.x)); + int y = static_cast(std::round(event.y - hoveredWidget.box.y)); + hoveredWidget.widget->OnMouseMoved(x, y, event.deltaX, event.deltaY); } - else if (m_hoveredWidget) + else if (m_hoveredWidget != InvalidCanvasIndex) { - m_hoveredWidget->widget->OnMouseExit(); - m_hoveredWidget = nullptr; + m_widgetEntries[m_hoveredWidget].widget->OnMouseExit(); + m_hoveredWidget = InvalidCanvasIndex; if (m_cursorController) m_cursorController->UpdateCursor(Nz::Cursor::Get(Nz::SystemCursor_Default)); @@ -122,28 +134,78 @@ namespace Ndk void Canvas::OnEventMouseLeft(const Nz::EventHandler* /*eventHandler*/) { - if (m_hoveredWidget) + if (m_hoveredWidget != InvalidCanvasIndex) { - m_hoveredWidget->widget->OnMouseExit(); - m_hoveredWidget = nullptr; + m_widgetEntries[m_hoveredWidget].widget->OnMouseExit(); + m_hoveredWidget = InvalidCanvasIndex; } } void Canvas::OnEventKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event) { - if (m_keyboardOwner) - m_keyboardOwner->OnKeyPressed(event); + if (m_keyboardOwner != InvalidCanvasIndex) + { + if (m_widgetEntries[m_keyboardOwner].widget->OnKeyPressed(event)) + return; + + if (event.code == Nz::Keyboard::Tab) + { + if (!event.shift) + { + // Forward + for (std::size_t i = m_keyboardOwner + 1; i < m_widgetEntries.size(); ++i) + { + if (m_widgetEntries[i].widget->IsFocusable()) + { + SetKeyboardOwner(i); + return; + } + } + + for (std::size_t i = 0; i < m_keyboardOwner; ++i) + { + if (m_widgetEntries[i].widget->IsFocusable()) + { + SetKeyboardOwner(i); + return; + } + } + } + else + { + // Backward + for (decltype(m_widgetEntries)::reverse_iterator rit{ m_widgetEntries.begin() + m_keyboardOwner }; rit != m_widgetEntries.rend(); ++rit) + { + if (rit->widget->IsFocusable()) + { + SetKeyboardOwner(std::distance(m_widgetEntries.begin(), rit.base()) - 1); + return; + } + } + + decltype(m_widgetEntries)::reverse_iterator rend { m_widgetEntries.begin() + m_keyboardOwner }; + for (auto rit = m_widgetEntries.rbegin(); rit != rend; ++rit) + { + if (rit->widget->IsFocusable()) + { + SetKeyboardOwner(std::distance(m_widgetEntries.begin(), rit.base()) - 1); + return; + } + } + } + } + } } void Canvas::OnEventKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event) { - if (m_keyboardOwner) - m_keyboardOwner->OnKeyReleased(event); + if (m_keyboardOwner != InvalidCanvasIndex) + m_widgetEntries[m_keyboardOwner].widget->OnKeyReleased(event); } void Canvas::OnEventTextEntered(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::TextEvent& event) { - if (m_keyboardOwner) - m_keyboardOwner->OnTextEntered(event.character, event.repeated); + if (m_keyboardOwner != InvalidCanvasIndex) + m_widgetEntries[m_keyboardOwner].widget->OnTextEntered(event.character, event.repeated); } } diff --git a/SDK/src/NDK/Components/CameraComponent.cpp b/SDK/src/NDK/Components/CameraComponent.cpp index 2441dd7a8..58523bcea 100644 --- a/SDK/src/NDK/Components/CameraComponent.cpp +++ b/SDK/src/NDK/Components/CameraComponent.cpp @@ -334,15 +334,15 @@ namespace Ndk { NazaraAssert(m_target, "CameraComponent has no target"); - unsigned int targetWidth = m_target->GetWidth(); - unsigned int targetHeight = std::max(m_target->GetHeight(), 1U); // Let's make sure we won't divide by zero + Nz::Vector2ui targetSize = m_target->GetSize(); + targetSize.y = std::max(targetSize.y, 1U); // Let's make sure we won't divide by zero // Our target region is expressed as % of the viewport dimensions, let's compute it in pixels Nz::Rectf fViewport(m_targetRegion); - fViewport.x *= targetWidth; - fViewport.y *= targetHeight; - fViewport.width *= targetWidth; - fViewport.height *= targetHeight; + fViewport.x *= targetSize.x; + fViewport.y *= targetSize.y; + fViewport.width *= targetSize.x; + fViewport.height *= targetSize.y; // Compute the new aspect ratio, if it's different we need to invalidate the projection matrix float aspectRatio = fViewport.width/fViewport.height; diff --git a/SDK/src/NDK/Components/CollisionComponent2D.cpp b/SDK/src/NDK/Components/CollisionComponent2D.cpp index ff10019f6..5a37d5e04 100644 --- a/SDK/src/NDK/Components/CollisionComponent2D.cpp +++ b/SDK/src/NDK/Components/CollisionComponent2D.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/SDK/src/NDK/Components/CollisionComponent3D.cpp b/SDK/src/NDK/Components/CollisionComponent3D.cpp index 4ec2bff81..a853cbb55 100644 --- a/SDK/src/NDK/Components/CollisionComponent3D.cpp +++ b/SDK/src/NDK/Components/CollisionComponent3D.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/SDK/src/NDK/Components/GraphicsComponent.cpp b/SDK/src/NDK/Components/GraphicsComponent.cpp index 8ec5319cd..73f6ca7f4 100644 --- a/SDK/src/NDK/Components/GraphicsComponent.cpp +++ b/SDK/src/NDK/Components/GraphicsComponent.cpp @@ -39,17 +39,6 @@ namespace Ndk } } - /*! - * \brief Attaches a renderable to the entity - * - * \param renderable Reference to a renderable element - * \param renderOrder Render order of the element - */ - void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, int renderOrder) - { - return Attach(renderable, Nz::Matrix4f::Identity(), renderOrder); - } - /*! * \brief Attaches a renderable to the entity with a specific matrix * @@ -60,26 +49,29 @@ namespace Ndk void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder) { m_renderables.emplace_back(m_transformMatrix); - Renderable& r = m_renderables.back(); - r.data.localMatrix = localMatrix; - r.data.renderOrder = renderOrder; - r.renderable = std::move(renderable); - r.renderableBoundingVolumeInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateBoundingVolume, [this] (const Nz::InstancedRenderable*) { InvalidateBoundingVolume(); }); - r.renderableDataInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size() - 1)); - r.renderableReleaseSlot.Connect(r.renderable->OnInstancedRenderableRelease, this, &GraphicsComponent::Detach); + Renderable& entry = m_renderables.back(); + entry.data.localMatrix = localMatrix; + entry.data.renderOrder = renderOrder; + entry.renderable = std::move(renderable); + + ConnectInstancedRenderableSignals(entry); + + std::size_t materialCount = entry.renderable->GetMaterialCount(); + for (std::size_t i = 0; i < materialCount; ++i) + RegisterMaterial(entry.renderable->GetMaterial(i)); InvalidateBoundingVolume(); } - /*! - * \brief Invalidates the data for renderable - * - * \param renderable Renderable to invalidate - * \param flags Flags for the instance - * \param index Index of the renderable to invalidate - * - * \remark Produces a NazaraAssert if index is out of bound - */ + void GraphicsComponent::ConnectInstancedRenderableSignals(Renderable& entry) + { + entry.renderableBoundingVolumeInvalidationSlot.Connect(entry.renderable->OnInstancedRenderableInvalidateBoundingVolume, [this](const Nz::InstancedRenderable*) { InvalidateBoundingVolume(); }); + entry.renderableDataInvalidationSlot.Connect(entry.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size() - 1)); + entry.renderableMaterialInvalidationSlot.Connect(entry.renderable->OnInstancedRenderableInvalidateMaterial, this, &GraphicsComponent::InvalidateRenderableMaterial); + entry.renderableReleaseSlot.Connect(entry.renderable->OnInstancedRenderableRelease, this, &GraphicsComponent::Detach); + entry.renderableResetMaterialsSlot.Connect(entry.renderable->OnInstancedRenderableResetMaterials, this, &GraphicsComponent::OnInstancedRenderableResetMaterials); + entry.renderableSkinChangeSlot.Connect(entry.renderable->OnInstancedRenderableSkinChange, this, &GraphicsComponent::OnInstancedRenderableSkinChange); + } void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable , Nz::UInt32 flags, std::size_t index) { @@ -94,6 +86,59 @@ namespace Ndk entry.listEntry.ForceInvalidation(); } + void GraphicsComponent::InvalidateRenderableMaterial(const Nz::InstancedRenderable* renderable, std::size_t skinIndex, std::size_t matIndex, const Nz::MaterialRef& newMat) + { + // Don't listen to dormant materials + if (renderable->GetSkin() != skinIndex) + return; + + RegisterMaterial(newMat); + + const Nz::MaterialRef& oldMat = renderable->GetMaterial(skinIndex, matIndex); + UnregisterMaterial(oldMat); + } + + void Ndk::GraphicsComponent::InvalidateReflectionMap() + { + m_entity->Invalidate(); + + if (m_reflectiveMaterialCount > 0) + { + if (!m_reflectionMap) + { + m_reflectionMap = Nz::Texture::New(); + if (!m_reflectionMap->Create(Nz::ImageType_Cubemap, Nz::PixelFormatType_RGB8, m_reflectionMapSize, m_reflectionMapSize)) + { + NazaraWarning("Failed to create reflection map, reflections will be disabled for this entity"); + return; + } + } + } + else + m_reflectionMap.Reset(); + } + + void GraphicsComponent::RegisterMaterial(Nz::Material* material, std::size_t count) + { + auto it = m_materialEntries.find(material); + if (it == m_materialEntries.end()) + { + MaterialEntry matEntry; + matEntry.reflectionModelChangeSlot.Connect(material->OnMaterialReflectionModeChange, this, &GraphicsComponent::OnMaterialReflectionChange); + matEntry.renderableCounter = count; + + if (material->GetReflectionMode() == Nz::ReflectionMode_RealTime) + { + if (m_reflectiveMaterialCount++ == 0) + InvalidateReflectionMap(); + } + + m_materialEntries.emplace(material, std::move(matEntry)); + } + else + it->second.renderableCounter += count; + } + /*! * \brief Operation to perform when component is attached to an entity */ @@ -150,11 +195,39 @@ namespace Ndk InvalidateTransformMatrix(); } - /*! - * \brief Operation to perform when the node is invalidated - * - * \param node Pointer to the node - */ + void GraphicsComponent::OnInstancedRenderableResetMaterials(const Nz::InstancedRenderable* renderable, std::size_t newMaterialCount) + { + RegisterMaterial(Nz::Material::GetDefault(), newMaterialCount); + + std::size_t materialCount = renderable->GetMaterialCount(); + for (std::size_t i = 0; i < materialCount; ++i) + UnregisterMaterial(renderable->GetMaterial(i)); + } + + void GraphicsComponent::OnInstancedRenderableSkinChange(const Nz::InstancedRenderable* renderable, std::size_t newSkinIndex) + { + std::size_t materialCount = renderable->GetMaterialCount(); + for (std::size_t i = 0; i < materialCount; ++i) + RegisterMaterial(renderable->GetMaterial(newSkinIndex, i)); + + for (std::size_t i = 0; i < materialCount; ++i) + UnregisterMaterial(renderable->GetMaterial(i)); + } + + void GraphicsComponent::OnMaterialReflectionChange(const Nz::Material* material, Nz::ReflectionMode reflectionMode) + { + // Since this signal is only called when the new reflection mode is different from the current one, no need to compare both + if (material->GetReflectionMode() == Nz::ReflectionMode_RealTime) + { + if (--m_reflectiveMaterialCount == 0) + InvalidateReflectionMap(); + } + else if (reflectionMode == Nz::ReflectionMode_RealTime) + { + if (m_reflectiveMaterialCount++ == 0) + InvalidateReflectionMap(); + } + } void GraphicsComponent::OnNodeInvalidated(const Nz::Node* node) { @@ -168,6 +241,24 @@ namespace Ndk entry.listEntry.ForceInvalidation(); //< Force invalidation on movement } + void GraphicsComponent::UnregisterMaterial(Nz::Material* material) + { + auto it = m_materialEntries.find(material); + NazaraAssert(it != m_materialEntries.end(), "Material not registered"); + + MaterialEntry& matEntry = it->second; + if (--matEntry.renderableCounter == 0) + { + if (material->GetReflectionMode() == Nz::ReflectionMode_RealTime) + { + if (--m_reflectiveMaterialCount == 0) + InvalidateReflectionMap(); + } + + m_materialEntries.erase(it); + } + } + /*! * \brief Updates the bounding volume */ diff --git a/SDK/src/NDK/Components/PhysicsComponent2D.cpp b/SDK/src/NDK/Components/PhysicsComponent2D.cpp index 58cab2982..2061029de 100644 --- a/SDK/src/NDK/Components/PhysicsComponent2D.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent2D.cpp @@ -4,11 +4,10 @@ #include #include -#include #include #include #include -#include +#include namespace Ndk { diff --git a/SDK/src/NDK/Components/PhysicsComponent3D.cpp b/SDK/src/NDK/Components/PhysicsComponent3D.cpp index 31b3fb6ac..1e6ccf0c7 100644 --- a/SDK/src/NDK/Components/PhysicsComponent3D.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent3D.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index a59bfdf81..0c8ceaa5d 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -4,7 +4,8 @@ #include #include -#include +#include +#include #include #include #include diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index fab08b237..a417a4414 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -56,7 +56,7 @@ namespace Ndk Entity::~Entity() { - if (m_world) + if (m_world && m_valid) Destroy(); } diff --git a/SDK/src/NDK/Lua/LuaBinding.cpp b/SDK/src/NDK/Lua/LuaBinding.cpp index 715351e52..4bca51e19 100644 --- a/SDK/src/NDK/Lua/LuaBinding.cpp +++ b/SDK/src/NDK/Lua/LuaBinding.cpp @@ -25,6 +25,7 @@ namespace Ndk audio = LuaBinding_Base::BindAudio(*this); renderer = LuaBinding_Base::BindRenderer(*this); graphics = LuaBinding_Base::BindGraphics(*this); + platform = LuaBinding_Base::BindPlatform(*this); #endif sdk = LuaBinding_Base::BindSDK(*this); @@ -48,6 +49,7 @@ namespace Ndk audio->Register(state); graphics->Register(state); renderer->Register(state); + platform->Register(state); #endif // ComponentType (fake enumeration to expose component indexes) diff --git a/SDK/src/NDK/Lua/LuaBinding_Core.cpp b/SDK/src/NDK/Lua/LuaBinding_Core.cpp index 1e4a02e7f..6091c88e2 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Core.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Core.cpp @@ -32,28 +32,28 @@ namespace Ndk stream.BindMethod("IsWritable", &Nz::Stream::IsWritable); stream.BindMethod("SetCursorPos", &Nz::Stream::SetCursorPos); - stream.BindMethod("Read", [] (Nz::LuaState& lua, Nz::Stream& stream, std::size_t /*argumentCount*/) -> int { + stream.BindMethod("Read", [] (Nz::LuaState& lua, Nz::Stream& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; std::size_t length = lua.Check(&argIndex); std::unique_ptr buffer(new char[length]); - std::size_t readLength = stream.Read(buffer.get(), length); + std::size_t readLength = instance.Read(buffer.get(), length); lua.PushString(Nz::String(buffer.get(), readLength)); return 1; }); - stream.BindMethod("Write", [] (Nz::LuaState& lua, Nz::Stream& stream, std::size_t /*argumentCount*/) -> int { + stream.BindMethod("Write", [] (Nz::LuaState& lua, Nz::Stream& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; std::size_t bufferSize = 0; const char* buffer = lua.CheckString(argIndex, &bufferSize); - if (stream.IsTextModeEnabled()) - lua.Push(stream.Write(Nz::String(buffer, bufferSize))); + if (instance.IsTextModeEnabled()) + lua.Push(instance.Write(Nz::String(buffer, bufferSize))); else - lua.Push(stream.Write(buffer, bufferSize)); + lua.Push(instance.Write(buffer, bufferSize)); return 1; }); } @@ -103,11 +103,11 @@ namespace Ndk clock.BindMethod("Unpause", &Nz::Clock::Unpause); // Manual - clock.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Clock& clock, std::size_t /*argumentCount*/) -> int { + clock.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Clock& instance, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("Clock(Elapsed: "); - ss << clock.GetSeconds(); + ss << instance.GetSeconds(); ss << "s, Paused: "; - ss << clock.IsPaused(); + ss << instance.IsPaused(); ss << ')'; lua.PushString(ss); @@ -159,9 +159,9 @@ namespace Ndk directory.BindStaticMethod("SetCurrent", Nz::Directory::SetCurrent); // Manual - directory.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Directory& dir, std::size_t /*argumentCount*/) -> int { + directory.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Directory& instance, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("Directory("); - ss << dir.GetPath(); + ss << instance.GetPath(); ss << ')'; lua.PushString(ss); @@ -237,7 +237,7 @@ namespace Ndk file.BindStaticMethod("Rename", &Nz::File::Rename); // Manual - file.BindMethod("Open", [] (Nz::LuaState& lua, Nz::File& file, std::size_t argumentCount) -> int + file.BindMethod("Open", [] (Nz::LuaState& lua, Nz::File& instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 2U); @@ -246,13 +246,13 @@ namespace Ndk { case 0: case 1: - return lua.Push(file.Open(lua.Check(&argIndex, Nz::OpenMode_NotOpen))); + return lua.Push(instance.Open(lua.Check(&argIndex, Nz::OpenMode_NotOpen))); case 2: { Nz::String filePath = lua.Check(&argIndex); Nz::UInt32 openMode = lua.Check(&argIndex, Nz::OpenMode_NotOpen); - return lua.Push(file.Open(filePath, openMode)); + return lua.Push(instance.Open(filePath, openMode)); } } @@ -260,7 +260,7 @@ namespace Ndk return 0; }); - file.BindMethod("SetCursorPos", [] (Nz::LuaState& lua, Nz::File& file, std::size_t argumentCount) -> int + file.BindMethod("SetCursorPos", [] (Nz::LuaState& lua, Nz::File& instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 2U); @@ -268,13 +268,13 @@ namespace Ndk switch (argCount) { case 1: - return lua.Push(file.SetCursorPos(lua.Check(&argIndex))); + return lua.Push(instance.SetCursorPos(lua.Check(&argIndex))); case 2: { Nz::CursorPosition curPos = lua.Check(&argIndex); Nz::Int64 offset = lua.Check(&argIndex); - return lua.Push(file.SetCursorPos(curPos, offset)); + return lua.Push(instance.SetCursorPos(curPos, offset)); } } @@ -282,10 +282,10 @@ namespace Ndk return 0; }); - file.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::File& file, std::size_t /*argumentCount*/) -> int { + file.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::File& instance, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("File("); - if (file.IsOpen()) - ss << "Path: " << file.GetPath(); + if (instance.IsOpen()) + ss << "Path: " << instance.GetPath(); ss << ')'; diff --git a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp index d33811f49..909a91daa 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp @@ -32,6 +32,40 @@ namespace Ndk /*********************************** Nz::InstancedRenderable ***********************************/ instancedRenderable.Reset("InstancedRenderable"); { + instancedRenderable.BindMethod("GetMaterial", [] (Nz::LuaState& lua, Nz::InstancedRenderable* instance, std::size_t argumentCount) -> int + { + std::size_t argCount = std::min(argumentCount, 2U); + switch (argCount) + { + case 0: + case 1: + { + int argIndex = 2; + std::size_t matIndex(lua.Check(&argIndex, 0)); + + return lua.Push(instance->GetMaterial(matIndex)); + } + + case 2: + { + int argIndex = 2; + std::size_t skinIndex(lua.Check(&argIndex)); + std::size_t matIndex(lua.Check(&argIndex)); + + return lua.Push(instance->GetMaterial(skinIndex, matIndex)); + } + } + + lua.Error("No matching overload for method GetMaterial"); + return 0; + }); + + instancedRenderable.BindMethod("GetMaterialCount", &Nz::InstancedRenderable::GetMaterialCount); + instancedRenderable.BindMethod("GetSkin", &Nz::InstancedRenderable::GetSkin); + instancedRenderable.BindMethod("GetSkinCount", &Nz::InstancedRenderable::GetSkinCount); + + instancedRenderable.BindMethod("SetSkin", &Nz::InstancedRenderable::SetSkin); + instancedRenderable.BindMethod("SetSkinCount", &Nz::InstancedRenderable::SetSkinCount); } /*********************************** Nz::Material ***********************************/ @@ -92,6 +126,7 @@ namespace Ndk material.BindMethod("EnableDepthSorting", &Nz::Material::EnableDepthSorting); material.BindMethod("EnableDepthWrite", &Nz::Material::EnableDepthWrite); material.BindMethod("EnableFaceCulling", &Nz::Material::EnableFaceCulling); + material.BindMethod("EnableReflectionMapping", &Nz::Material::EnableReflectionMapping); material.BindMethod("EnableScissorTest", &Nz::Material::EnableScissorTest); material.BindMethod("EnableShadowCasting", &Nz::Material::EnableShadowCasting); material.BindMethod("EnableShadowReceive", &Nz::Material::EnableShadowReceive); @@ -117,6 +152,7 @@ namespace Ndk //material.BindMethod("GetPipeline", &Nz::Material::GetPipeline); //material.BindMethod("GetPipelineInfo", &Nz::Material::GetPipelineInfo); material.BindMethod("GetPointSize", &Nz::Material::GetPointSize); + material.BindMethod("GetReflectionMode", &Nz::Material::GetReflectionMode); //material.BindMethod("GetShader", &Nz::Material::GetShader); material.BindMethod("GetShininess", &Nz::Material::GetShininess); material.BindMethod("GetSpecularColor", &Nz::Material::GetSpecularColor); @@ -139,6 +175,7 @@ namespace Ndk material.BindMethod("IsDepthSortingEnabled", &Nz::Material::IsDepthSortingEnabled); material.BindMethod("IsDepthWriteEnabled", &Nz::Material::IsDepthWriteEnabled); material.BindMethod("IsFaceCullingEnabled", &Nz::Material::IsFaceCullingEnabled); + material.BindMethod("IsReflectionMappingEnabled", &Nz::Material::IsReflectionMappingEnabled); material.BindMethod("IsScissorTestEnabled", &Nz::Material::IsScissorTestEnabled); material.BindMethod("IsStencilTestEnabled", &Nz::Material::IsStencilTestEnabled); material.BindMethod("IsShadowCastingEnabled", &Nz::Material::IsShadowCastingEnabled); @@ -160,6 +197,7 @@ namespace Ndk material.BindMethod("SetFaceFilling", &Nz::Material::SetFaceFilling); material.BindMethod("SetLineWidth", &Nz::Material::SetLineWidth); material.BindMethod("SetPointSize", &Nz::Material::SetPointSize); + material.BindMethod("SetReflectionMode", &Nz::Material::SetReflectionMode); material.BindMethod("SetShininess", &Nz::Material::SetShininess); material.BindMethod("SetSpecularColor", &Nz::Material::SetSpecularColor); material.BindMethod("SetSpecularColor", &Nz::Material::SetSpecularColor); @@ -267,22 +305,72 @@ namespace Ndk return true; }); - //model.BindMethod("GetMaterial", &Nz::Model::GetMaterial); - model.BindMethod("GetMaterialCount", &Nz::Model::GetMaterialCount); //modelClass.SetMethod("GetMesh", &Nz::Model::GetMesh); - model.BindMethod("GetSkin", &Nz::Model::GetSkin); - model.BindMethod("GetSkinCount", &Nz::Model::GetSkinCount); model.BindMethod("IsAnimated", &Nz::Model::IsAnimated); model.BindMethod("LoadFromFile", &Nz::Model::LoadFromFile, Nz::ModelParameters()); - model.BindMethod("Reset", &Nz::Model::Reset); - //model.BindMethod("SetMaterial", &Nz::Model::SetMaterial); + model.BindMethod("SetMaterial", [] (Nz::LuaState& lua, Nz::Model* instance, std::size_t argumentCount) -> int + { + std::size_t argCount = std::min(argumentCount, 3U); + switch (argCount) + { + case 2: + { + int argIndex = 2; + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + std::size_t matIndex(lua.Check(&argIndex)); + Nz::MaterialRef mat(lua.Check(&argIndex)); + + instance->SetMaterial(matIndex, std::move(mat)); + return 0; + } + else if (lua.IsOfType(argIndex, Nz::LuaType_String)) + { + Nz::String subMesh(lua.Check(&argIndex)); + Nz::MaterialRef mat(lua.Check(&argIndex)); + + instance->SetMaterial(subMesh, std::move(mat)); + return 0; + } + + break; + } + + case 3: + { + int argIndex = 2; + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + std::size_t skinIndex(lua.Check(&argIndex)); + std::size_t matIndex(lua.Check(&argIndex)); + Nz::MaterialRef mat(lua.Check(&argIndex)); + + instance->SetMaterial(skinIndex, matIndex, std::move(mat)); + return 0; + } + else if (lua.IsOfType(argIndex, Nz::LuaType_String)) + { + std::size_t skinIndex(lua.Check(&argIndex)); + Nz::String subMesh(lua.Check(&argIndex)); + Nz::MaterialRef materialRef(lua.Check(&argIndex)); + + instance->SetMaterial(skinIndex, subMesh, std::move(materialRef)); + return 0; + } + + break; + } + } + + lua.Error("No matching overload for method SetMaterial"); + return 0; + }); + //modelClass.SetMethod("SetMesh", &Nz::Model::SetMesh); //modelClass.SetMethod("SetSequence", &Nz::Model::SetSequence); - model.BindMethod("SetSkin", &Nz::Model::SetSkin); - model.BindMethod("SetSkinCount", &Nz::Model::SetSkinCount); } /*********************************** Nz::Sprite ***********************************/ @@ -301,7 +389,6 @@ namespace Ndk sprite.BindMethod("GetColor", &Nz::Sprite::GetColor); sprite.BindMethod("GetCornerColor", &Nz::Sprite::GetCornerColor); - sprite.BindMethod("GetMaterial", &Nz::Sprite::GetMaterial); sprite.BindMethod("GetOrigin", &Nz::Sprite::GetOrigin); sprite.BindMethod("GetSize", &Nz::Sprite::GetSize); sprite.BindMethod("GetTextureCoords", &Nz::Sprite::GetTextureCoords); @@ -317,12 +404,28 @@ namespace Ndk sprite.BindMethod("SetMaterial", [] (Nz::LuaState& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; - bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); - if (lua.IsOfType(argIndex, "Material")) + { + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + instance->SetMaterial(*static_cast(lua.ToUserdata(argIndex)), resizeSprite); - else - instance->SetMaterial(lua.Check(&argIndex), resizeSprite); + } + else if (lua.IsOfType(argIndex, Nz::LuaType_String)) + { + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + + instance->SetMaterial(lua.ToString(argIndex), resizeSprite); + } + else if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + std::size_t skinIndex(lua.Check(&argIndex)); + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + + if (lua.IsOfType(argIndex, "Material")) + instance->SetMaterial(skinIndex, *static_cast(lua.ToUserdata(argIndex)), resizeSprite); + else + instance->SetMaterial(skinIndex, lua.Check(&argIndex), resizeSprite); + } return 0; }); @@ -330,12 +433,28 @@ namespace Ndk sprite.BindMethod("SetTexture", [] (Nz::LuaState& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; - bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); - if (lua.IsOfType(argIndex, "Texture")) + { + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + instance->SetTexture(*static_cast(lua.ToUserdata(argIndex)), resizeSprite); - else - instance->SetTexture(lua.Check(&argIndex), resizeSprite); + } + else if (lua.IsOfType(argIndex, Nz::LuaType_String)) + { + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + + instance->SetTexture(lua.ToString(argIndex), resizeSprite); + } + else if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + std::size_t skinIndex(lua.Check(&argIndex)); + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + + if (lua.IsOfType(argIndex, "Texture")) + instance->SetTexture(skinIndex, *static_cast(lua.ToUserdata(argIndex)), resizeSprite); + else + instance->SetTexture(skinIndex, lua.Check(&argIndex), resizeSprite); + } return 0; }); @@ -366,5 +485,15 @@ namespace Ndk model.Register(state); sprite.Register(state); spriteLibrary.Register(state); + + // Nz::ReflectionMode + static_assert(Nz::ReflectionMode_Max + 1 == 3, "Nz::ReflectionMode has been updated but change was not reflected to Lua binding"); + state.PushTable(0, 3); + { + state.PushField("Probe", Nz::ReflectionMode_Probe); + state.PushField("RealTime", Nz::ReflectionMode_RealTime); + state.PushField("Skybox", Nz::ReflectionMode_Skybox); + } + state.SetGlobal("ReflectionMode"); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_Platform.cpp b/SDK/src/NDK/Lua/LuaBinding_Platform.cpp new file mode 100644 index 000000000..b910770fa --- /dev/null +++ b/SDK/src/NDK/Lua/LuaBinding_Platform.cpp @@ -0,0 +1,133 @@ +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include + +namespace Ndk +{ + std::unique_ptr LuaBinding_Base::BindPlatform(LuaBinding& binding) + { + return std::make_unique(binding); + } + + LuaBinding_Platform::LuaBinding_Platform(LuaBinding& binding) : + LuaBinding_Base(binding) + { + /*********************************** Nz::Keyboard **********************************/ + keyboard.Reset("Keyboard"); + { + keyboard.BindStaticMethod("GetKeyName", &Nz::Keyboard::GetKeyName); + keyboard.BindStaticMethod("IsKeyPressed", &Nz::Keyboard::IsKeyPressed); + } + } + + /*! + * \brief Registers the classes that will be used by the Lua instance + * + * \param instance Lua instance that will interact with the Utility classes + */ + void LuaBinding_Platform::Register(Nz::LuaState& state) + { + keyboard.Register(state); + + keyboard.PushGlobalTable(state); + { + static_assert(Nz::Keyboard::Count == 121, "Nz::Keyboard::Key has been updated but change was not reflected to Lua binding"); + + state.PushField("Undefined", Nz::Keyboard::Undefined); + + // A-Z + for (std::size_t i = 0; i < 26; ++i) + state.PushField(Nz::String('A' + char(i)), Nz::Keyboard::A + i); + + // Numerical + for (std::size_t i = 0; i < 10; ++i) + { + state.PushField("Num" + Nz::String::Number(i), Nz::Keyboard::Num0 + i); + state.PushField("Numpad" + Nz::String::Number(i), Nz::Keyboard::Numpad0 + i); + } + + // F1-F15 + for (std::size_t i = 0; i < 15; ++i) + state.PushField('F' + Nz::String::Number(i+1), Nz::Keyboard::F1 + i); + + // And all the others... + state.PushField("Down", Nz::Keyboard::Down); + state.PushField("Left", Nz::Keyboard::Left); + state.PushField("Right", Nz::Keyboard::Right); + state.PushField("Up", Nz::Keyboard::Up); + + state.PushField("Add", Nz::Keyboard::Add); + state.PushField("Decimal", Nz::Keyboard::Decimal); + state.PushField("Divide", Nz::Keyboard::Divide); + state.PushField("Multiply", Nz::Keyboard::Multiply); + state.PushField("Subtract", Nz::Keyboard::Subtract); + + state.PushField("Backslash", Nz::Keyboard::Backslash); + state.PushField("Backspace", Nz::Keyboard::Backspace); + state.PushField("Clear", Nz::Keyboard::Clear); + state.PushField("Comma", Nz::Keyboard::Comma); + state.PushField("Dash", Nz::Keyboard::Dash); + state.PushField("Delete", Nz::Keyboard::Delete); + state.PushField("End", Nz::Keyboard::End); + state.PushField("Equal", Nz::Keyboard::Equal); + state.PushField("Escape", Nz::Keyboard::Escape); + state.PushField("Home", Nz::Keyboard::Home); + state.PushField("Insert", Nz::Keyboard::Insert); + state.PushField("LAlt", Nz::Keyboard::LAlt); + state.PushField("LBracket", Nz::Keyboard::LBracket); + state.PushField("LControl", Nz::Keyboard::LControl); + state.PushField("LShift", Nz::Keyboard::LShift); + state.PushField("LSystem", Nz::Keyboard::LSystem); + state.PushField("PageDown", Nz::Keyboard::PageDown); + state.PushField("PageUp", Nz::Keyboard::PageUp); + state.PushField("Pause", Nz::Keyboard::Pause); + state.PushField("Period", Nz::Keyboard::Period); + state.PushField("Print", Nz::Keyboard::Print); + state.PushField("PrintScreen", Nz::Keyboard::PrintScreen); + state.PushField("Quote", Nz::Keyboard::Quote); + state.PushField("RAlt", Nz::Keyboard::RAlt); + state.PushField("RBracket", Nz::Keyboard::RBracket); + state.PushField("RControl", Nz::Keyboard::RControl); + state.PushField("Return", Nz::Keyboard::Return); + state.PushField("RShift", Nz::Keyboard::RShift); + state.PushField("RSystem", Nz::Keyboard::RSystem); + state.PushField("Semicolon", Nz::Keyboard::Semicolon); + state.PushField("Slash", Nz::Keyboard::Slash); + state.PushField("Space", Nz::Keyboard::Space); + state.PushField("Tab", Nz::Keyboard::Tab); + state.PushField("Tilde", Nz::Keyboard::Tilde); + state.PushField("Browser_Back", Nz::Keyboard::Browser_Back); + state.PushField("Browser_Favorites", Nz::Keyboard::Browser_Favorites); + state.PushField("Browser_Forward", Nz::Keyboard::Browser_Forward); + state.PushField("Browser_Home", Nz::Keyboard::Browser_Home); + state.PushField("Browser_Refresh", Nz::Keyboard::Browser_Refresh); + state.PushField("Browser_Search", Nz::Keyboard::Browser_Search); + state.PushField("Browser_Stop", Nz::Keyboard::Browser_Stop); + state.PushField("Media_Next", Nz::Keyboard::Media_Next); + state.PushField("Media_Play", Nz::Keyboard::Media_Play); + state.PushField("Media_Previous", Nz::Keyboard::Media_Previous); + state.PushField("Media_Stop", Nz::Keyboard::Media_Stop); + state.PushField("Volume_Down", Nz::Keyboard::Volume_Down); + state.PushField("Volume_Mute", Nz::Keyboard::Volume_Mute); + state.PushField("Volume_Up", Nz::Keyboard::Volume_Up); + state.PushField("CapsLock", Nz::Keyboard::CapsLock); + state.PushField("NumLock", Nz::Keyboard::NumLock); + state.PushField("ScrollLock", Nz::Keyboard::ScrollLock); + } + state.Pop(); + + static_assert(Nz::WindowStyle_Max + 1 == 6, "Nz::WindowStyle has been updated but change was not reflected to Lua binding"); + state.PushTable(0, Nz::WindowStyle_Max + 1); + { + state.PushField("None", Nz::WindowStyle_None); + state.PushField("Fullscreen", Nz::WindowStyle_Fullscreen); + state.PushField("Closable", Nz::WindowStyle_Closable); + state.PushField("Resizable", Nz::WindowStyle_Resizable); + state.PushField("Titlebar", Nz::WindowStyle_Titlebar); + state.PushField("Threaded", Nz::WindowStyle_Threaded); + } + state.SetGlobal("WindowStyle"); + } +} diff --git a/SDK/src/NDK/Lua/LuaBinding_SDK.cpp b/SDK/src/NDK/Lua/LuaBinding_SDK.cpp index 8952ce7d9..88190fc09 100644 --- a/SDK/src/NDK/Lua/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_SDK.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jérôme Leclercq, Arnaud Cadot +// Copyright (C) 2017 Jérôme Leclercq, Arnaud Cadot // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Lua/LuaBinding_Utility.cpp b/SDK/src/NDK/Lua/LuaBinding_Utility.cpp index 6d7baf588..14fddec73 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Utility.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Utility.cpp @@ -161,13 +161,6 @@ namespace Ndk font.BindStaticMethod("SetDefaultMinimumStepSize", &Nz::Font::SetDefaultMinimumStepSize); } - /*********************************** Nz::Keyboard **********************************/ - keyboard.Reset("Keyboard"); - { - keyboard.BindStaticMethod("GetKeyName", &Nz::Keyboard::GetKeyName); - keyboard.BindStaticMethod("IsKeyPressed", &Nz::Keyboard::IsKeyPressed); - } - /*********************************** Nz::Node **********************************/ node.Reset("Node"); { @@ -216,29 +209,29 @@ namespace Ndk node.BindMethod("SetPosition", (void(Nz::Node::*)(const Nz::Vector3f&, Nz::CoordSys)) &Nz::Node::SetPosition, Nz::CoordSys_Local); node.BindMethod("SetRotation", (void(Nz::Node::*)(const Nz::Quaternionf&, Nz::CoordSys)) &Nz::Node::SetRotation, Nz::CoordSys_Local); - node.BindMethod("Move", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t /*argumentCount*/) -> int + node.BindMethod("Move", [] (Nz::LuaState& lua, Nz::Node& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; Nz::Vector3f offset = lua.Check(&argIndex); Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); - node.Move(offset, coordSys); + instance.Move(offset, coordSys); return 0; }); - node.BindMethod("Rotate", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t /*argumentCount*/) -> int + node.BindMethod("Rotate", [] (Nz::LuaState& lua, Nz::Node& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; Nz::Quaternionf rotation = lua.Check(&argIndex); Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); - node.Rotate(rotation, coordSys); + instance.Rotate(rotation, coordSys); return 0; }); - node.BindMethod("Scale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int + node.BindMethod("Scale", [] (Nz::LuaState& lua, Nz::Node& instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 4U); @@ -248,15 +241,15 @@ namespace Ndk case 1: { if (lua.IsOfType(argIndex, Nz::LuaType_Number)) - node.Scale(lua.Check(&argIndex)); + instance.Scale(lua.Check(&argIndex)); else - node.Scale(lua.Check(&argIndex)); + instance.Scale(lua.Check(&argIndex)); return 0; } case 3: - node.Scale(lua.Check(&argIndex)); + instance.Scale(lua.Check(&argIndex)); return 0; } @@ -264,7 +257,7 @@ namespace Ndk return 0; }); - node.BindMethod("SetScale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int + node.BindMethod("SetScale", [] (Nz::LuaState& lua, Nz::Node& instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 4U); @@ -278,10 +271,10 @@ namespace Ndk { float scale = lua.Check(&argIndex); Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); - node.SetScale(scale, coordSys); + instance.SetScale(scale, coordSys); } else - node.SetScale(lua.Check(&argIndex)); + instance.SetScale(lua.Check(&argIndex)); return 0; } @@ -292,7 +285,7 @@ namespace Ndk Nz::Vector3f scale = lua.Check(&argIndex); Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); - node.SetScale(scale, coordSys); + instance.SetScale(scale, coordSys); return 0; } } @@ -301,7 +294,7 @@ namespace Ndk return 0; }); - node.BindMethod("SetInitialScale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int + node.BindMethod("SetInitialScale", [] (Nz::LuaState& lua, Nz::Node& instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 4U); @@ -311,16 +304,16 @@ namespace Ndk case 1: { if (lua.IsOfType(argIndex, Nz::LuaType_Number)) - node.SetInitialScale(lua.Check(&argIndex)); + instance.SetInitialScale(lua.Check(&argIndex)); else - node.SetInitialScale(lua.Check(&argIndex)); + instance.SetInitialScale(lua.Check(&argIndex)); return 0; } case 2: case 3: - node.SetInitialScale(lua.Check(&argIndex)); + instance.SetInitialScale(lua.Check(&argIndex)); return 0; } @@ -339,106 +332,6 @@ namespace Ndk { abstractImage.Register(state); font.Register(state); - keyboard.Register(state); node.Register(state); - - keyboard.PushGlobalTable(state); - { - static_assert(Nz::Keyboard::Count == 121, "Nz::Keyboard::Key has been updated but change was not reflected to Lua binding"); - - state.PushField("Undefined", Nz::Keyboard::Undefined); - - // A-Z - for (std::size_t i = 0; i < 26; ++i) - state.PushField(Nz::String('A' + char(i)), Nz::Keyboard::A + i); - - // Numerical - for (std::size_t i = 0; i < 10; ++i) - { - state.PushField("Num" + Nz::String::Number(i), Nz::Keyboard::Num0 + i); - state.PushField("Numpad" + Nz::String::Number(i), Nz::Keyboard::Numpad0 + i); - } - - // F1-F15 - for (std::size_t i = 0; i < 15; ++i) - state.PushField('F' + Nz::String::Number(i+1), Nz::Keyboard::F1 + i); - - // And all the others... - state.PushField("Down", Nz::Keyboard::Down); - state.PushField("Left", Nz::Keyboard::Left); - state.PushField("Right", Nz::Keyboard::Right); - state.PushField("Up", Nz::Keyboard::Up); - - state.PushField("Add", Nz::Keyboard::Add); - state.PushField("Decimal", Nz::Keyboard::Decimal); - state.PushField("Divide", Nz::Keyboard::Divide); - state.PushField("Multiply", Nz::Keyboard::Multiply); - state.PushField("Subtract", Nz::Keyboard::Subtract); - - state.PushField("Backslash", Nz::Keyboard::Backslash); - state.PushField("Backspace", Nz::Keyboard::Backspace); - state.PushField("Clear", Nz::Keyboard::Clear); - state.PushField("Comma", Nz::Keyboard::Comma); - state.PushField("Dash", Nz::Keyboard::Dash); - state.PushField("Delete", Nz::Keyboard::Delete); - state.PushField("End", Nz::Keyboard::End); - state.PushField("Equal", Nz::Keyboard::Equal); - state.PushField("Escape", Nz::Keyboard::Escape); - state.PushField("Home", Nz::Keyboard::Home); - state.PushField("Insert", Nz::Keyboard::Insert); - state.PushField("LAlt", Nz::Keyboard::LAlt); - state.PushField("LBracket", Nz::Keyboard::LBracket); - state.PushField("LControl", Nz::Keyboard::LControl); - state.PushField("LShift", Nz::Keyboard::LShift); - state.PushField("LSystem", Nz::Keyboard::LSystem); - state.PushField("PageDown", Nz::Keyboard::PageDown); - state.PushField("PageUp", Nz::Keyboard::PageUp); - state.PushField("Pause", Nz::Keyboard::Pause); - state.PushField("Period", Nz::Keyboard::Period); - state.PushField("Print", Nz::Keyboard::Print); - state.PushField("PrintScreen", Nz::Keyboard::PrintScreen); - state.PushField("Quote", Nz::Keyboard::Quote); - state.PushField("RAlt", Nz::Keyboard::RAlt); - state.PushField("RBracket", Nz::Keyboard::RBracket); - state.PushField("RControl", Nz::Keyboard::RControl); - state.PushField("Return", Nz::Keyboard::Return); - state.PushField("RShift", Nz::Keyboard::RShift); - state.PushField("RSystem", Nz::Keyboard::RSystem); - state.PushField("Semicolon", Nz::Keyboard::Semicolon); - state.PushField("Slash", Nz::Keyboard::Slash); - state.PushField("Space", Nz::Keyboard::Space); - state.PushField("Tab", Nz::Keyboard::Tab); - state.PushField("Tilde", Nz::Keyboard::Tilde); - state.PushField("Browser_Back", Nz::Keyboard::Browser_Back); - state.PushField("Browser_Favorites", Nz::Keyboard::Browser_Favorites); - state.PushField("Browser_Forward", Nz::Keyboard::Browser_Forward); - state.PushField("Browser_Home", Nz::Keyboard::Browser_Home); - state.PushField("Browser_Refresh", Nz::Keyboard::Browser_Refresh); - state.PushField("Browser_Search", Nz::Keyboard::Browser_Search); - state.PushField("Browser_Stop", Nz::Keyboard::Browser_Stop); - state.PushField("Media_Next", Nz::Keyboard::Media_Next); - state.PushField("Media_Play", Nz::Keyboard::Media_Play); - state.PushField("Media_Previous", Nz::Keyboard::Media_Previous); - state.PushField("Media_Stop", Nz::Keyboard::Media_Stop); - state.PushField("Volume_Down", Nz::Keyboard::Volume_Down); - state.PushField("Volume_Mute", Nz::Keyboard::Volume_Mute); - state.PushField("Volume_Up", Nz::Keyboard::Volume_Up); - state.PushField("CapsLock", Nz::Keyboard::CapsLock); - state.PushField("NumLock", Nz::Keyboard::NumLock); - state.PushField("ScrollLock", Nz::Keyboard::ScrollLock); - } - state.Pop(); - - static_assert(Nz::WindowStyle_Max + 1 == 6, "Nz::WindowStyle has been updated but change was not reflected to Lua binding"); - state.PushTable(0, Nz::WindowStyle_Max + 1); - { - state.PushField("None", Nz::WindowStyle_None); - state.PushField("Fullscreen", Nz::WindowStyle_Fullscreen); - state.PushField("Closable", Nz::WindowStyle_Closable); - state.PushField("Resizable", Nz::WindowStyle_Resizable); - state.PushField("Titlebar", Nz::WindowStyle_Titlebar); - state.PushField("Threaded", Nz::WindowStyle_Threaded); - } - state.SetGlobal("WindowStyle"); } } diff --git a/SDK/src/NDK/Resources/checkmark.png.h b/SDK/src/NDK/Resources/checkmark.png.h new file mode 100644 index 000000000..644161149 --- /dev/null +++ b/SDK/src/NDK/Resources/checkmark.png.h @@ -0,0 +1 @@ +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,133,0,0,0,138,8,6,0,0,0,132,140,137,233,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,225,8,14,14,24,3,208,239,186,156,0,0,0,29,105,84,88,116,67,111,109,109,101,110,116,0,0,0,0,0,67,114,101,97,116,101,100,32,119,105,116,104,32,71,73,77,80,100,46,101,7,0,0,6,196,73,68,65,84,120,218,237,157,125,172,143,101,24,199,63,199,251,33,135,136,232,197,176,70,50,105,147,90,167,49,165,161,204,50,147,151,82,44,217,26,90,141,169,182,214,106,42,42,36,189,140,106,42,170,63,196,42,127,136,229,101,52,53,83,35,33,47,203,41,9,181,157,18,149,151,195,113,250,227,121,112,58,167,56,63,231,119,95,191,235,62,190,159,237,254,211,126,183,239,245,61,207,243,220,247,125,221,215,5,66,84,32,79,18,92,16,92,4,52,7,242,203,141,218,192,49,224,32,176,23,248,75,166,168,153,180,7,186,165,163,11,208,6,184,2,104,122,142,127,87,6,236,4,222,1,102,72,198,184,105,0,244,7,222,0,246,165,193,173,238,120,77,178,198,251,68,120,9,248,35,75,70,40,63,182,74,222,184,104,11,124,8,148,6,48,195,169,241,186,100,142,231,53,49,25,56,18,208,12,101,233,135,103,59,201,29,199,171,98,99,96,51,156,26,79,75,110,255,244,3,14,24,25,98,35,80,79,146,251,166,127,250,56,183,48,196,159,64,71,73,238,155,190,192,81,35,67,148,1,67,37,185,111,186,166,127,185,86,134,152,38,201,125,211,26,248,201,208,16,159,2,181,36,187,95,242,129,175,12,13,177,29,104,34,217,253,146,7,44,50,52,196,1,160,131,100,247,205,115,134,134,56,145,46,117,133,99,134,27,26,162,12,152,40,201,125,211,157,240,91,215,229,199,60,73,238,155,203,72,146,91,172,12,177,14,168,47,217,253,210,0,88,111,104,136,189,233,114,87,56,102,190,161,33,142,164,175,41,225,152,9,198,31,150,35,36,185,111,122,167,75,66,43,67,188,40,201,125,211,14,40,70,91,216,34,165,33,176,201,208,16,219,208,22,182,123,222,71,91,216,162,28,15,27,26,162,20,184,93,146,251,166,7,112,220,208,20,79,74,114,223,180,6,246,27,26,98,49,186,241,231,154,186,192,90,67,67,236,0,10,36,187,111,102,26,26,226,16,208,73,146,251,102,48,182,59,150,131,36,185,111,58,164,127,185,86,134,152,34,201,253,111,80,109,54,52,196,50,180,99,233,158,121,134,134,40,2,154,73,114,223,140,54,52,196,97,146,187,33,194,49,93,210,64,89,153,226,30,73,238,155,70,36,135,79,86,134,152,41,201,253,99,121,208,181,26,168,35,201,125,243,128,161,33,246,0,45,37,185,111,58,27,126,71,28,3,110,144,228,190,201,39,41,22,102,245,148,24,43,201,253,243,150,161,33,62,144,220,254,25,106,104,136,173,233,234,70,56,166,61,73,201,98,171,114,67,58,249,116,78,93,108,111,116,13,147,228,254,121,193,208,16,175,74,110,255,244,38,108,133,219,138,151,128,85,182,208,57,205,177,187,25,94,76,82,117,95,56,103,177,145,33,78,162,234,50,81,48,206,240,59,98,178,228,246,207,53,216,109,99,47,71,25,84,238,169,135,93,129,244,61,64,11,73,238,159,233,70,134,40,1,10,37,119,28,203,207,147,70,166,120,68,114,251,167,25,240,179,145,33,22,73,238,56,88,104,100,136,93,168,118,68,20,220,135,93,194,204,245,146,219,63,109,8,211,181,79,223,17,145,146,7,172,194,174,84,128,136,128,137,70,134,216,141,110,116,69,65,103,108,90,50,29,215,126,68,28,212,197,110,215,242,113,201,29,7,86,253,53,150,161,146,67,81,112,35,54,85,111,247,162,115,141,40,200,39,233,157,101,81,186,176,151,228,142,131,89,70,175,141,167,36,117,28,244,194,230,176,107,21,202,143,136,130,198,192,143,6,134,248,21,53,91,137,134,55,177,201,179,236,35,169,227,160,143,209,119,196,84,73,29,7,5,216,180,137,94,135,10,138,68,195,92,3,67,28,34,185,103,42,34,160,159,209,107,227,94,73,29,7,77,72,50,165,85,63,66,156,230,109,3,67,20,161,202,249,209,208,23,155,227,240,155,36,117,60,155,84,187,13,76,161,14,60,17,49,199,192,16,159,163,109,236,104,184,149,240,103,27,7,80,185,128,104,104,148,126,248,133,126,74,220,117,33,136,89,157,93,184,75,72,186,233,21,2,151,147,20,248,248,13,88,153,46,213,142,26,254,63,166,146,116,8,14,189,162,89,168,191,191,202,52,0,238,6,86,156,227,81,253,61,112,173,209,156,10,9,95,126,104,7,42,95,88,137,124,146,139,44,153,180,84,60,0,116,12,60,175,250,132,175,162,95,2,116,147,5,206,144,7,140,2,246,157,167,160,155,73,50,167,67,97,145,128,59,73,54,56,195,213,192,151,89,16,117,66,160,249,117,37,124,119,224,229,40,27,251,52,227,201,94,121,159,95,210,199,124,54,169,13,124,77,248,106,117,202,162,34,41,237,243,110,0,129,71,102,121,158,143,25,188,54,6,203,14,137,33,150,4,124,12,103,139,171,8,95,164,108,190,236,144,16,178,245,81,41,208,42,75,243,92,73,248,203,192,58,253,76,31,239,161,31,199,15,101,97,158,247,163,75,60,102,27,82,22,165,134,215,86,115,158,151,2,191,7,158,227,116,217,33,225,78,108,210,214,78,2,87,86,99,158,11,2,207,239,219,0,171,164,40,169,133,93,178,72,30,231,223,104,117,0,48,36,224,220,74,128,17,36,53,169,4,54,23,101,202,183,64,202,148,198,132,207,183,124,84,54,248,55,211,12,77,81,70,230,213,225,94,9,60,159,53,40,105,166,18,99,141,77,49,59,131,185,117,39,236,9,232,65,160,173,44,80,153,94,198,166,56,72,213,142,161,235,0,223,4,158,203,40,133,255,191,41,192,174,29,210,169,49,166,10,243,154,20,120,14,31,41,244,103,103,139,177,41,182,156,99,62,109,129,191,3,254,254,126,146,204,49,113,22,102,27,155,162,12,184,227,44,243,89,154,195,223,22,41,67,114,96,138,245,255,51,151,225,129,127,119,142,194,93,53,90,96,215,231,162,252,168,184,153,213,145,176,93,130,119,161,92,203,140,216,144,3,83,20,3,29,210,223,47,228,252,211,254,170,186,205,222,83,97,206,140,41,57,48,197,169,190,222,155,13,126,103,150,66,156,57,61,114,100,10,139,177,19,104,168,16,103,78,109,146,203,60,53,205,16,165,192,205,10,111,213,41,191,231,95,154,46,5,107,26,51,129,47,20,234,184,150,166,33,199,54,146,36,34,81,13,10,72,114,10,106,130,33,78,144,20,103,23,89,96,105,13,49,197,243,10,101,246,24,83,3,12,177,5,165,214,101,149,150,216,159,154,102,187,30,149,218,60,6,96,117,196,166,120,70,225,11,195,248,72,13,177,137,176,183,220,47,104,90,69,248,10,41,1,174,83,232,194,178,38,50,83,168,27,143,1,227,34,50,196,6,84,69,95,175,144,10,171,141,174,10,151,29,43,34,48,197,179,10,147,45,163,157,27,226,59,109,82,217,115,49,126,207,66,74,81,209,244,156,241,137,83,83,188,172,208,228,142,129,14,13,81,132,18,112,115,74,29,146,126,155,158,76,113,155,194,146,123,102,56,50,196,92,133,195,7,29,201,205,189,144,138,99,31,208,84,225,240,195,103,14,76,49,80,97,240,197,128,28,27,98,129,66,224,143,90,192,246,28,25,162,152,36,249,71,56,100,100,142,76,49,66,210,251,94,158,22,25,27,98,137,100,247,207,48,67,67,28,162,122,181,55,133,33,107,141,76,241,160,164,142,135,78,132,175,164,175,213,70,132,132,188,31,242,30,74,192,141,150,39,178,108,134,173,192,32,201,26,63,183,0,31,3,63,144,121,79,175,195,192,58,146,179,149,158,168,95,151,11,254,1,48,107,33,165,213,10,148,99,0,0,0,0,73,69,78,68,174,66,96,130, \ No newline at end of file diff --git a/SDK/src/NDK/Sdk.cpp b/SDK/src/NDK/Sdk.cpp index 312e9a777..ee3764224 100644 --- a/SDK/src/NDK/Sdk.cpp +++ b/SDK/src/NDK/Sdk.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #endif namespace Ndk @@ -63,13 +65,6 @@ namespace Ndk // Initialize the engine first // Shared modules - #ifdef NDK_SERVER - Nz::ParameterList parameters; - parameters.SetParameter("NoWindowSystem", true); - - Nz::Utility::SetParameters(parameters); - #endif - Nz::Lua::Initialize(); Nz::Noise::Initialize(); Nz::Physics2D::Initialize(); @@ -119,6 +114,13 @@ namespace Ndk InitializeSystem(); InitializeSystem(); InitializeSystem(); + + // Widgets + if (!CheckboxWidget::Initialize()) + { + NazaraError("Failed to initialize Checkbox Widget"); + return false; + } #endif NazaraNotice("Initialized: SDK"); @@ -127,7 +129,6 @@ namespace Ndk catch (const std::exception& e) { NazaraError("Failed to initialize NDK: " + Nz::String(e.what())); - return false; } } @@ -173,6 +174,11 @@ namespace Ndk Nz::Physics3D::Uninitialize(); Nz::Utility::Uninitialize(); + #ifndef NDK_SERVER + // Widgets + CheckboxWidget::Uninitialize(); + #endif + NazaraNotice("Uninitialized: SDK"); } diff --git a/SDK/src/NDK/Systems/PhysicsSystem2D.cpp b/SDK/src/NDK/Systems/PhysicsSystem2D.cpp index 2616b185f..b05815a89 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem2D.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem2D.cpp @@ -31,18 +31,6 @@ namespace Ndk Excludes(); } - /*! - * \brief Constructs a PhysicsSystem object by copy semantic - * - * \param system PhysicsSystem to copy - */ - - PhysicsSystem2D::PhysicsSystem2D(const PhysicsSystem2D& system) : - System(system), - m_world() - { - } - void PhysicsSystem2D::CreatePhysWorld() const { NazaraAssert(!m_world, "Physics world should not be created twice"); diff --git a/SDK/src/NDK/Systems/PhysicsSystem3D.cpp b/SDK/src/NDK/Systems/PhysicsSystem3D.cpp index 3b4706cc2..9026c5a1d 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem3D.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem3D.cpp @@ -31,18 +31,6 @@ namespace Ndk Excludes(); } - /*! - * \brief Constructs a PhysicsSystem object by copy semantic - * - * \param system PhysicsSystem to copy - */ - - PhysicsSystem3D::PhysicsSystem3D(const PhysicsSystem3D& system) : - System(system), - m_world() - { - } - void PhysicsSystem3D::CreatePhysWorld() const { NazaraAssert(!m_world, "Physics world should not be created twice"); diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 022621596..3dfc81724 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -4,6 +4,9 @@ #include #include +#include +#include +#include #include #include #include @@ -36,7 +39,7 @@ namespace Ndk ChangeRenderTechnique(); SetDefaultBackground(Nz::ColorBackground::New()); SetUpdateOrder(100); //< Render last, after every movement is done - SetUpdateRate(0.f); //< We don't want any rate limit + SetMaximumUpdateRate(0.f); //< We don't want any rate limit } /*! @@ -98,15 +101,19 @@ namespace Ndk { m_drawables.Insert(entity); + GraphicsComponent& gfxComponent = entity->GetComponent(); if (justAdded) - { - GraphicsComponent& gfxComponent = entity->GetComponent(); gfxComponent.AddToCullingList(&m_drawableCulling); - } + + if (gfxComponent.DoesRequireRealTimeReflections()) + m_realtimeReflected.Insert(entity); + else + m_realtimeReflected.Remove(entity); } else { m_drawables.Remove(entity); + m_realtimeReflected.Remove(entity); if (entity->HasComponent()) { @@ -176,6 +183,7 @@ namespace Ndk m_coordinateSystemInvalidated = false; } + UpdateDynamicReflections(); UpdatePointSpotShadowMaps(); for (const Ndk::EntityHandle& camera : m_cameras) @@ -231,8 +239,12 @@ namespace Ndk Nz::SceneData sceneData; sceneData.ambientColor = Nz::Color(25, 25, 25); sceneData.background = m_background; + sceneData.globalReflectionTexture = nullptr; sceneData.viewer = &camComponent; + if (m_background && m_background->GetBackgroundType() == Nz::BackgroundType_Skybox) + sceneData.globalReflectionTexture = static_cast(m_background.Get())->GetTexture(); + m_renderTechnique->Clear(sceneData); m_renderTechnique->Draw(sceneData); } @@ -244,6 +256,19 @@ namespace Ndk * \param viewer Viewer of the scene */ + void RenderSystem::UpdateDynamicReflections() + { + Nz::SceneData dummySceneData; + dummySceneData.ambientColor = Nz::Color(0, 0, 0); + dummySceneData.background = nullptr; + dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer + + for (const Ndk::EntityHandle& handle : m_realtimeReflected) + { + //NazaraWarning("Realtime reflected: #" + handle->ToString()); + } + } + void RenderSystem::UpdateDirectionalShadowMaps(const Nz::AbstractViewer& /*viewer*/) { if (!m_shadowRT.IsValid()) @@ -322,12 +347,12 @@ namespace Ndk { static Nz::Quaternionf rotations[6] = { - Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitX()), // nzCubemapFace_PositiveX - Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitX()), // nzCubemapFace_NegativeX - Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitY()), // nzCubemapFace_PositiveY - Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitY()), // nzCubemapFace_NegativeY - Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitZ()), // nzCubemapFace_PositiveZ - Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitZ()) // nzCubemapFace_NegativeZ + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitX()), // CubemapFace_PositiveX + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitX()), // CubemapFace_NegativeX + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitY()), // CubemapFace_PositiveY + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitY()), // CubemapFace_NegativeY + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitZ()), // CubemapFace_PositiveZ + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitZ()) // CubemapFace_NegativeZ }; for (unsigned int face = 0; face < 6; ++face) diff --git a/SDK/src/NDK/Widgets/ButtonWidget.cpp b/SDK/src/NDK/Widgets/ButtonWidget.cpp index a525d7a68..35e781992 100644 --- a/SDK/src/NDK/Widgets/ButtonWidget.cpp +++ b/SDK/src/NDK/Widgets/ButtonWidget.cpp @@ -5,17 +5,29 @@ #include #include #include -#include namespace Ndk { + Nz::Color ButtonWidget::s_color { 74, 74, 74 }; + Nz::Color ButtonWidget::s_cornerColor { 180, 180, 180 }; + Nz::Color ButtonWidget::s_hoverColor { 128, 128, 128 }; + Nz::Color ButtonWidget::s_hoverCornerColor { s_cornerColor }; + Nz::Color ButtonWidget::s_pressColor { s_cornerColor }; + Nz::Color ButtonWidget::s_pressCornerColor { s_color }; + ButtonWidget::ButtonWidget(BaseWidget* parent) : - BaseWidget(parent) + BaseWidget(parent), + m_color { s_color }, + m_cornerColor { s_cornerColor }, + m_hoverColor { s_hoverColor }, + m_hoverCornerColor { s_hoverCornerColor }, + m_pressColor { s_pressColor }, + m_pressCornerColor { s_pressCornerColor } { m_gradientSprite = Nz::Sprite::New(); - m_gradientSprite->SetColor(Nz::Color(74, 74, 74)); - m_gradientSprite->SetCornerColor(Nz::RectCorner_LeftBottom, Nz::Color(180, 180, 180)); - m_gradientSprite->SetCornerColor(Nz::RectCorner_RightBottom, Nz::Color(180, 180, 180)); + m_gradientSprite->SetColor(m_color); + m_gradientSprite->SetCornerColor(Nz::RectCorner_LeftBottom, m_cornerColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_RightBottom, m_cornerColor); m_gradientSprite->SetMaterial(Nz::Material::New("Basic2D")); m_gradientEntity = CreateEntity(); @@ -31,6 +43,36 @@ namespace Ndk Layout(); } + const Nz::Color& ButtonWidget::GetDefaultColor() + { + return s_color; + } + + const Nz::Color& ButtonWidget::GetDefaultCornerColor() + { + return s_cornerColor; + } + + const Nz::Color& ButtonWidget::GetDefaultHoverColor() + { + return s_hoverColor; + } + + const Nz::Color& ButtonWidget::GetDefaultHoverCornerColor() + { + return s_hoverCornerColor; + } + + const Nz::Color& ButtonWidget::GetDefaultPressColor() + { + return s_pressColor; + } + + const Nz::Color& ButtonWidget::GetDefaultPressCornerColor() + { + return s_pressCornerColor; + } + void ButtonWidget::ResizeToContent() { SetContentSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths())); @@ -46,23 +88,47 @@ namespace Ndk m_gradientEntity->GetComponent().SetPosition(origin); m_gradientSprite->SetSize(contentSize); - Nz::Boxf textBox = m_textEntity->GetComponent().GetBoundingVolume().aabb; + Nz::Boxf textBox = m_textEntity->GetComponent().GetBoundingVolume().obb.localBox; m_textEntity->GetComponent().SetPosition(origin.x + contentSize.x / 2 - textBox.width / 2, origin.y + contentSize.y / 2 - textBox.height / 2); } + void ButtonWidget::OnMouseButtonPress(int /*x*/, int /*y*/, Nz::Mouse::Button button) + { + if (button == Nz::Mouse::Left) + { + m_gradientSprite->SetColor(m_pressColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_LeftBottom, m_pressCornerColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_RightBottom, m_pressCornerColor); + m_gradientSprite->SetTexture(m_pressTexture, false); + } + } + void ButtonWidget::OnMouseButtonRelease(int /*x*/, int /*y*/, Nz::Mouse::Button button) { if (button == Nz::Mouse::Left) + { + m_gradientSprite->SetColor(m_hoverColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_LeftBottom, m_hoverCornerColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_RightBottom, m_hoverCornerColor); + m_gradientSprite->SetTexture(m_hoverTexture, false); + OnButtonTrigger(this); + } } void ButtonWidget::OnMouseEnter() { - m_gradientSprite->SetColor(Nz::Color(128, 128, 128)); + m_gradientSprite->SetColor(m_hoverColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_LeftBottom, m_hoverCornerColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_RightBottom, m_hoverCornerColor); + m_gradientSprite->SetTexture(m_hoverTexture, false); } void ButtonWidget::OnMouseExit() { - m_gradientSprite->SetColor(Nz::Color(74, 74, 74)); + m_gradientSprite->SetColor(m_color); + m_gradientSprite->SetCornerColor(Nz::RectCorner_LeftBottom, m_cornerColor); + m_gradientSprite->SetCornerColor(Nz::RectCorner_RightBottom, m_cornerColor); + m_gradientSprite->SetTexture(m_texture, false); } } diff --git a/SDK/src/NDK/Widgets/CheckboxWidget.cpp b/SDK/src/NDK/Widgets/CheckboxWidget.cpp new file mode 100644 index 000000000..ab513c7f8 --- /dev/null +++ b/SDK/src/NDK/Widgets/CheckboxWidget.cpp @@ -0,0 +1,181 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include +#include +#include + +namespace Ndk +{ + Nz::Color CheckboxWidget::s_backgroundColor { Nz::Color::White }; + Nz::Color CheckboxWidget::s_disabledBackgroundColor { 201, 201, 201 }; + Nz::Color CheckboxWidget::s_disabledBorderColor { 62, 62, 62 }; + Nz::Color CheckboxWidget::s_borderColor { Nz::Color::Black }; + float CheckboxWidget::s_borderScale { 16.f }; + + CheckboxWidget::CheckboxWidget(BaseWidget* parent) : + BaseWidget(parent), + m_adaptativeMargin { true }, + m_checkboxEnabled { true }, + m_tristateEnabled { false }, + m_textMargin { 16.f }, + m_state { CheckboxState_Unchecked } + { + m_checkboxBorderSprite = Nz::Sprite::New(Nz::Material::New("Basic2D")); + m_checkboxBackgroundSprite = Nz::Sprite::New(Nz::Material::New("Basic2D")); + m_checkboxContentSprite = Nz::Sprite::New(Nz::Material::New("Translucent2D")); + m_textSprite = Nz::TextSprite::New(); + + m_checkboxBorderEntity = CreateEntity(); + m_checkboxBorderEntity->AddComponent().SetParent(this); + m_checkboxBorderEntity->AddComponent().Attach(m_checkboxBorderSprite); + + m_checkboxBackgroundEntity = CreateEntity(); + m_checkboxBackgroundEntity->AddComponent().SetParent(this); + m_checkboxBackgroundEntity->AddComponent().Attach(m_checkboxBackgroundSprite, 1); + + m_checkboxContentEntity = CreateEntity(); + m_checkboxContentEntity->AddComponent().SetParent(this); + m_checkboxContentEntity->AddComponent().Attach(m_checkboxContentSprite, 2); + + m_textEntity = CreateEntity(); + m_textEntity->AddComponent().SetParent(this); + m_textEntity->AddComponent().Attach(m_textSprite); + + m_checkMark = Nz::TextureLibrary::Get("Ndk::CheckboxWidget::checkmark"); + + SetCheckboxSize({ 32.f, 32.f }); + UpdateCheckbox(); + } + + bool CheckboxWidget::Initialize() + { + const Nz::UInt8 r_checkmark[] = + { + #include + }; + + Nz::TextureRef checkmarkTexture = Nz::Texture::New(); + if (!checkmarkTexture->LoadFromMemory(r_checkmark, sizeof(r_checkmark) / sizeof(r_checkmark[0]))) + { + NazaraError("Failed to load embedded checkmark"); + return false; + } + + Nz::TextureLibrary::Register("Ndk::CheckboxWidget::checkmark", checkmarkTexture); + return true; + } + + void CheckboxWidget::Uninitialize() + { + Nz::TextureLibrary::Unregister("Ndk::CheckboxWidget::checkmark"); + } + + void CheckboxWidget::SetState(CheckboxState state) + { + if (!m_checkboxEnabled) + return; + + if (state == CheckboxState_Tristate) + m_tristateEnabled = true; + + m_state = state; + UpdateCheckbox(); + } + + CheckboxState CheckboxWidget::SwitchToNextState() + { + if (!m_checkboxEnabled) + return m_state; + + switch (m_state) + { + case CheckboxState_Unchecked: + SetState(CheckboxState_Checked); + break; + + case CheckboxState_Checked: + SetState(m_tristateEnabled ? CheckboxState_Tristate : CheckboxState_Unchecked); + break; + + case CheckboxState_Tristate: + SetState(CheckboxState_Unchecked); + break; + } + + return m_state; + } + + void CheckboxWidget::ResizeToContent() + { + Nz::Vector3f textSize = m_textSprite->GetBoundingVolume().obb.localBox.GetLengths(); + Nz::Vector2f checkboxSize = GetCheckboxSize(); + + Nz::Vector2f finalSize { checkboxSize.x + (m_adaptativeMargin ? checkboxSize.x / 2.f : m_textMargin) + textSize.x, std::max(textSize.y, checkboxSize.y) }; + SetContentSize(finalSize); + } + + void CheckboxWidget::Layout() + { + BaseWidget::Layout(); + + Nz::Vector2f origin = GetContentOrigin(); + Nz::Vector2f checkboxSize = GetCheckboxSize(); + Nz::Vector2f borderSize = GetCheckboxBorderSize(); + + m_checkboxBorderEntity->GetComponent().SetPosition(origin); + m_checkboxBackgroundEntity->GetComponent().SetPosition(origin + borderSize); + + Nz::Vector3f checkboxBox = m_checkboxContentSprite->GetBoundingVolume().obb.localBox.GetLengths(); + m_checkboxContentEntity->GetComponent().SetPosition(origin.x + checkboxSize.x / 2.f - checkboxBox.x / 2.f, + origin.y + checkboxSize.y / 2.f - checkboxBox.y / 2.f); + + Nz::Vector3f textBox = m_textSprite->GetBoundingVolume().obb.localBox.GetLengths(); + m_textEntity->GetComponent().SetPosition(origin.x + checkboxSize.x + (m_adaptativeMargin ? checkboxSize.x / 2.f : m_textMargin), + origin.y + checkboxSize.y / 2.f - textBox.y / 2.f); + } + + void CheckboxWidget::OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button) + { + if (button == Nz::Mouse::Left && ContainsCheckbox(x, y) && IsCheckboxEnabled()) + { + SwitchToNextState(); + OnStateChanged(this); + } + } + + void CheckboxWidget::UpdateCheckbox() + { + if (m_checkboxEnabled) + { + m_checkboxBorderSprite->SetColor(s_borderColor); + m_checkboxBackgroundSprite->SetColor(s_backgroundColor); + } + else + { + m_checkboxBorderSprite->SetColor(s_disabledBorderColor); + m_checkboxBackgroundSprite->SetColor(s_disabledBackgroundColor); + } + + + if (m_state == CheckboxState_Unchecked) + { + m_checkboxContentEntity->Enable(false); + return; + } + else if (m_state == CheckboxState_Checked) + { + m_checkboxContentEntity->Enable(); + m_checkboxContentSprite->SetColor(Nz::Color::White); + m_checkboxContentSprite->SetTexture(m_checkMark, false); + } + else // Tristate + { + m_checkboxContentEntity->Enable(); + m_checkboxContentSprite->SetColor(Nz::Color::Black); + m_checkboxContentSprite->SetTexture(Nz::TextureRef {}); + } + } +} diff --git a/SDK/src/NDK/Widgets/ImageWidget.cpp b/SDK/src/NDK/Widgets/ImageWidget.cpp new file mode 100644 index 000000000..a845979f7 --- /dev/null +++ b/SDK/src/NDK/Widgets/ImageWidget.cpp @@ -0,0 +1,37 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include +#include + +namespace Ndk +{ + ImageWidget::ImageWidget(BaseWidget* parent) : + BaseWidget(parent) + { + m_entity = CreateEntity(); + m_entity->AddComponent(); + auto& gfx = m_entity->AddComponent(); + + m_sprite = Nz::Sprite::New(); + gfx.Attach(m_sprite); + } + + void ImageWidget::ResizeToContent() + { + Nz::Vector3ui textureSize = m_sprite->GetMaterial()->GetDiffuseMap()->GetSize(); + SetSize({ static_cast(textureSize.x), static_cast(textureSize.y) }); + } + + void ImageWidget::Layout() + { + BaseWidget::Layout(); + Nz::Vector2f origin = GetContentOrigin(); + Nz::Vector2f contentSize = GetContentSize(); + + m_entity->GetComponent().SetPosition(origin); + m_sprite->SetSize(contentSize); + } +} diff --git a/SDK/src/NDK/Widgets/LabelWidget.cpp b/SDK/src/NDK/Widgets/LabelWidget.cpp index 7e4cdf840..ae05450de 100644 --- a/SDK/src/NDK/Widgets/LabelWidget.cpp +++ b/SDK/src/NDK/Widgets/LabelWidget.cpp @@ -5,7 +5,6 @@ #include #include #include -#include namespace Ndk { diff --git a/SDK/src/NDK/Widgets/ProgressBarWidget.cpp b/SDK/src/NDK/Widgets/ProgressBarWidget.cpp new file mode 100644 index 000000000..7ad293539 --- /dev/null +++ b/SDK/src/NDK/Widgets/ProgressBarWidget.cpp @@ -0,0 +1,102 @@ +// Copyright (C) 2017 Samy Bensaid +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include +#include + +namespace Ndk +{ + float ProgressBarWidget::s_borderScale { 16.f }; + Nz::Color ProgressBarWidget::s_borderColor { Nz::Color::Black }; + Nz::Color ProgressBarWidget::s_barBackgroundColor { Nz::Color { 225, 225, 225 } }; + Nz::Color ProgressBarWidget::s_barBackgroundCornerColor { Nz::Color { 255, 255, 255 } }; + Nz::Color ProgressBarWidget::s_barColor { Nz::Color { 0, 225, 0 } }; + Nz::Color ProgressBarWidget::s_barCornerColor { Nz::Color { 220, 255, 220 } }; + + ProgressBarWidget::ProgressBarWidget(BaseWidget* parent) : + BaseWidget(parent), + m_textColor { Nz::Color::Black }, + m_textMargin { 16.f }, + m_value { 0u } + { + m_borderSprite = Nz::Sprite::New(Nz::Material::New("Basic2D")); + m_barBackgroundSprite = Nz::Sprite::New(Nz::Material::New("Basic2D")); + m_barSprite = Nz::Sprite::New(Nz::Material::New("Basic2D")); + + m_borderSprite->SetColor(s_borderColor); + SetBarBackgroundColor(s_barBackgroundColor, s_barBackgroundCornerColor); + SetBarColor(s_barColor, s_barCornerColor); + + + m_borderEntity = CreateEntity(); + m_borderEntity->AddComponent().SetParent(this); + m_borderEntity->AddComponent().Attach(m_borderSprite); + + m_barEntity = CreateEntity(); + m_barEntity->AddComponent().SetParent(this); + GraphicsComponent& graphics = m_barEntity->AddComponent(); + + graphics.Attach(m_barBackgroundSprite, 1); + graphics.Attach(m_barSprite, 2); + + + m_textSprite = Nz::TextSprite::New(); + m_textEntity = CreateEntity(); + + m_textEntity->AddComponent().SetParent(this); + m_textEntity->AddComponent().Attach(m_textSprite); + + UpdateText(); + Layout(); + } + + + const Nz::Color& ProgressBarWidget::GetDefaultBarColor() + { + return s_barColor; + } + + const Nz::Color& ProgressBarWidget::GetDefaultBarCornerColor() + { + return s_barCornerColor; + } + + const Nz::Color& ProgressBarWidget::GetDefaultBarBackgroundColor() + { + return s_barBackgroundColor; + } + + const Nz::Color& ProgressBarWidget::GetDefaultBarBackgroundCornerColor() + { + return s_barBackgroundCornerColor; + } + + + void ProgressBarWidget::Layout() + { + Nz::Vector2f origin = GetContentOrigin(); + Nz::Vector2f size = GetContentSize(); + Nz::Vector2f progressBarSize = size; + + if (IsTextEnabled()) + { + UpdateText(); + + Nz::Vector3f textSize = m_textSprite->GetBoundingVolume().obb.localBox.GetLengths(); + m_textEntity->GetComponent().SetPosition(origin.x + size.x - textSize.x, origin.y + size.y / 2.f - textSize.y); + + progressBarSize -= { textSize.x + m_textMargin, 0.f }; + } + + m_borderSprite->SetSize(progressBarSize); + Nz::Vector2f borderSize = GetProgressBarBorderSize(); + + m_barBackgroundSprite->SetSize(progressBarSize - (borderSize * 2.f)); + m_barSprite->SetSize((progressBarSize.x - (borderSize.x * 2.f)) / 100.f * static_cast(m_value), progressBarSize.y - (borderSize.y * 2.f)); + + m_borderEntity->GetComponent().SetPosition(origin.x, origin.y); + m_barEntity->GetComponent().SetPosition(origin.x + borderSize.x, origin.y + borderSize.y); + } +} diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 416975645..586de7456 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -6,15 +6,13 @@ #include #include #include -#include -#include namespace Ndk { TextAreaWidget::TextAreaWidget(BaseWidget* parent) : BaseWidget(parent), + m_echoMode(EchoMode_Normal), m_cursorPosition(0U, 0U), - m_cursorGlyph(0), m_multiLineEnabled(false), m_readOnly(false) { @@ -40,9 +38,38 @@ namespace Ndk void TextAreaWidget::AppendText(const Nz::String& text) { - m_drawer.AppendText(text); + m_text += text; + switch (m_echoMode) + { + case EchoMode_Normal: + m_drawer.AppendText(text); + break; + + case EchoMode_Password: + m_drawer.AppendText(Nz::String(text.GetLength(), '*')); + break; + + case EchoMode_PasswordExceptLast: + { + m_drawer.Clear(); + std::size_t textLength = m_text.GetLength(); + if (textLength >= 2) + { + std::size_t lastCharacterPosition = m_text.GetCharacterPosition(textLength - 2); + if (lastCharacterPosition != Nz::String::npos) + m_drawer.AppendText(Nz::String(textLength - 1, '*')); + } + + if (textLength >= 1) + m_drawer.AppendText(m_text.SubString(m_text.GetCharacterPosition(textLength - 1))); + + break; + } + } m_textSprite->Update(m_drawer); + + OnTextChanged(this, m_text); } std::size_t TextAreaWidget::GetHoveredGlyph(float x, float y) const @@ -82,18 +109,19 @@ namespace Ndk void TextAreaWidget::Write(const Nz::String& text) { - if (m_cursorGlyph >= m_drawer.GetGlyphCount()) + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); + + if (cursorGlyph >= m_drawer.GetGlyphCount()) { AppendText(text); SetCursorPosition(m_drawer.GetGlyphCount()); } else { - Nz::String currentText = m_drawer.GetText(); - currentText.Insert(currentText.GetCharacterPosition(m_cursorGlyph), text); - SetText(currentText); + m_text.Insert(m_text.GetCharacterPosition(cursorGlyph), text); + SetText(m_text); - SetCursorPosition(m_cursorGlyph + text.GetLength()); + SetCursorPosition(cursorGlyph + text.GetLength()); } } @@ -106,24 +134,43 @@ namespace Ndk RefreshCursor(); } - void TextAreaWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) + bool TextAreaWidget::IsFocusable() const + { + return !m_readOnly; + } + + void TextAreaWidget::OnFocusLost() + { + m_cursorEntity->Disable(); + } + + void TextAreaWidget::OnFocusReceived() + { + if (!m_readOnly) + m_cursorEntity->Enable(true); + } + + bool TextAreaWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) { switch (key.code) { case Nz::Keyboard::Delete: { - const Nz::String& text = m_drawer.GetText(); + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); + + std::size_t textLength = m_text.GetLength(); + if (cursorGlyph > textLength) + return true; Nz::String newText; - if (m_cursorGlyph > 0) - newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorGlyph) - 1)); + if (cursorGlyph > 0) + newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyph) - 1)); - if (m_cursorGlyph < m_drawer.GetGlyphCount()) - newText.Append(text.SubString(text.GetCharacterPosition(m_cursorGlyph + 1))); + if (cursorGlyph < textLength) + newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyph + 1))); - m_drawer.SetText(newText); - m_textSprite->Update(m_drawer); - break; + SetText(newText); + return true; } case Nz::Keyboard::Down: @@ -132,10 +179,10 @@ namespace Ndk OnTextAreaKeyDown(this, &ignoreDefaultAction); if (ignoreDefaultAction) - break; + return true; MoveCursor({0, 1}); - break; + return true; } case Nz::Keyboard::Left: @@ -144,10 +191,10 @@ namespace Ndk OnTextAreaKeyLeft(this, &ignoreDefaultAction); if (ignoreDefaultAction) - break; + return true; - MoveCursor({-1, 0}); - break; + MoveCursor(-1); + return true; } case Nz::Keyboard::Right: @@ -156,10 +203,10 @@ namespace Ndk OnTextAreaKeyRight(this, &ignoreDefaultAction); if (ignoreDefaultAction) - break; + return true; - MoveCursor({1, 0}); - break; + MoveCursor(1); + return true; } case Nz::Keyboard::Up: @@ -168,42 +215,31 @@ namespace Ndk OnTextAreaKeyUp(this, &ignoreDefaultAction); if (ignoreDefaultAction) - break; + return true; MoveCursor({0, -1}); - break; + return true; } + + default: + return false; } } - void TextAreaWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& key) + void TextAreaWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/) { } - void TextAreaWidget::OnMouseEnter() - { - m_cursorEntity->Enable(true); - } - void TextAreaWidget::OnMouseButtonPress(int x, int y, Nz::Mouse::Button button) { if (button == Nz::Mouse::Left) { - GrabKeyboard(); + SetFocus(); SetCursorPosition(GetHoveredGlyph(float(x), float(y))); } } - void TextAreaWidget::OnMouseMoved(int x, int y, int deltaX, int deltaY) - { - } - - void TextAreaWidget::OnMouseExit() - { - m_cursorEntity->Enable(false); - } - void TextAreaWidget::OnTextEntered(char32_t character, bool /*repeated*/) { if (m_readOnly) @@ -216,19 +252,19 @@ namespace Ndk bool ignoreDefaultAction = false; OnTextAreaKeyBackspace(this, &ignoreDefaultAction); - if (ignoreDefaultAction) + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); + if (ignoreDefaultAction || cursorGlyph == 0) break; - const Nz::String& text = m_drawer.GetText(); - Nz::String newText; - if (m_cursorGlyph > 1) - newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorGlyph - 1) - 1)); - if (m_cursorGlyph < m_drawer.GetGlyphCount()) - newText.Append(text.SubString(text.GetCharacterPosition(m_cursorGlyph))); + if (cursorGlyph > 1) + newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyph - 1) - 1)); - MoveCursor({-1, 0}); + if (cursorGlyph < m_text.GetLength()) + newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyph))); + + MoveCursor(-1); SetText(newText); break; } @@ -259,15 +295,19 @@ namespace Ndk void TextAreaWidget::RefreshCursor() { + if (m_readOnly) + return; + const auto& lineInfo = m_drawer.GetLine(m_cursorPosition.y); + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); std::size_t glyphCount = m_drawer.GetGlyphCount(); float position; - if (glyphCount > 0 && lineInfo.glyphIndex < m_cursorGlyph) + if (glyphCount > 0 && lineInfo.glyphIndex < cursorGlyph) { - const auto& glyph = m_drawer.GetGlyph(std::min(m_cursorGlyph, glyphCount - 1)); + const auto& glyph = m_drawer.GetGlyph(std::min(cursorGlyph, glyphCount - 1)); position = glyph.bounds.x; - if (m_cursorGlyph >= glyphCount) + if (cursorGlyph >= glyphCount) position += glyph.bounds.width; } else @@ -277,4 +317,23 @@ namespace Ndk m_cursorEntity->GetComponent().SetPosition(contentOrigin.x + position, contentOrigin.y + lineInfo.bounds.y); } + + void TextAreaWidget::UpdateDisplayText() + { + switch (m_echoMode) + { + case EchoMode_Normal: + m_drawer.SetText(m_text); + break; + + case EchoMode_Password: + case EchoMode_PasswordExceptLast: + m_drawer.SetText(Nz::String(m_text.GetLength(), '*')); + break; + } + + m_textSprite->Update(m_drawer); + + SetCursorPosition(m_cursorPosition); //< Refresh cursor position (prevent it from being outside of the text) + } } diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 702452fc4..41336c71b 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -115,10 +115,15 @@ namespace Ndk void World::Clear() noexcept { - // First, destruction of entities, then handles - // This is made to avoid that handle warn uselessly entities before their destruction - m_entities.clear(); + // Destroy every valid entity first, to ensure entities are still accessible by ID while being destroyed + for (EntityBlock* entBlock : m_entityBlocks) + { + if (entBlock->entity.IsValid()) + entBlock->entity.Destroy(); + } m_entityBlocks.clear(); + + m_entities.clear(); m_freeIdList.clear(); m_waitingEntities.clear(); diff --git a/build/Build_VS2017.bat b/build/Build_VS2017.bat new file mode 100644 index 000000000..b569c559d --- /dev/null +++ b/build/Build_VS2017.bat @@ -0,0 +1 @@ +premake5 vs2017 \ No newline at end of file diff --git a/build/config.lua b/build/config.lua index b644423b3..571bf6dc9 100644 --- a/build/config.lua +++ b/build/config.lua @@ -16,8 +16,8 @@ Configurations = "Debug,Release" -- "Debug,Release,ReleaseWithDebug" -- Setup additionnals install directories, separated by a semi-colon ; (library binaries will be copied there) --InstallDir = "/usr/local/lib64" --- Adds a project which will recall premake with its original arguments when built -PremakeProject = true +-- Adds a project which will recall premake with its original arguments when built (only works on Windows for now) +PremakeProject = false -- Excludes client-only modules/tools/examples ServerMode = false diff --git a/build/scripts/actions/encodesresources.lua b/build/scripts/actions/encodesresources.lua index 5e5376fee..f508c5c69 100644 --- a/build/scripts/actions/encodesresources.lua +++ b/build/scripts/actions/encodesresources.lua @@ -5,8 +5,14 @@ ACTION.Function = function () print("Encoding resources ...") local startClock = os.clock() local modules = os.matchdirs("../src/Nazara/*") + table.insert(modules, "../SDK/src/NDK") for k, modulePath in pairs(modules) do - local moduleName = modulePath:sub(15, -1) + local moduleName + if (modulePath:sub(4, 6) == "src") then + moduleName = modulePath:sub(15, -1) + else + moduleName = "SDK" + end local files = os.matchfiles(modulePath .. "/Resources/**") for k, filePath in pairs(files) do if (filePath:sub(-2) ~= ".h") then diff --git a/build/scripts/actions/package.lua b/build/scripts/actions/package.lua index bc86c4ba4..f1ddb5087 100644 --- a/build/scripts/actions/package.lua +++ b/build/scripts/actions/package.lua @@ -84,13 +84,13 @@ ACTION.Function = function () local libFileMasks local exeFileExt local exeFilterFunc - if (os.is("windows")) then + if (os.ishost("windows")) then binFileMasks = {"**.dll", "**.pdb"} libFileMasks = {"**.lib", "**.a"} exeFileExt = ".exe" exeFilterFunc = function (filePath) return true end else - if (os.is("macosx")) then + if (os.ishost("macosx")) then binFileMasks = {"**.dynlib"} else binFileMasks = {"**.so"} @@ -183,14 +183,7 @@ ACTION.Function = function () end end - local ok, err - if (os.is("windows")) then - ok, err = os.copyfile(v, targetPath) - else - -- Workaround: As premake is translating this to "cp %s %s", it fails if space are presents in source/destination paths. - ok, err = os.copyfile(string.format("\"%s\"", v), string.format("\"%s\"", targetPath)) - end - + local ok, err = os.copyfile(v, targetPath) if (not ok) then print("Failed to copy \"" .. v .. "\" to \"" .. targetPath .. "\": " .. err) end @@ -203,5 +196,5 @@ ACTION.Function = function () end local config = libDir .. " - " .. enabledArchs - print(string.format("Package successfully created at \"%s\" (%u MB, %s)", packageDir, size / (1024 * 1024), config)) + print(string.format("Package successfully created at \"%s\" (%u MB, %s)", packageDir, size // (1024 * 1024), config)) end diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 220d2084b..da9facd74 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -128,7 +128,7 @@ function NazaraBuild:Execute() language("C++") location(_ACTION) - if (self.Config["PremakeProject"]) then + if (self.Config["PremakeProject"] and os.ishost("windows")) then local commandLine = "premake5.exe " .. table.concat(_ARGV, ' ') project("_PremakeProject") kind("Utility") @@ -477,10 +477,8 @@ function NazaraBuild:LoadConfig() local content = f:read("*a") f:close() - local func, err = loadstring(content) + local func, err = load(content, "Config file", "t", self.Config) if (func) then - setfenv(func, self.Config) - local status, err = pcall(func) if (not status) then print("Failed to load config.lua: " .. err) @@ -607,7 +605,7 @@ function NazaraBuild:LoadConfig() end function NazaraBuild:MakeInstallCommands(infoTable) - if (os.is("windows")) then + if (os.istarget("windows")) then filter("kind:SharedLib") postbuildmessage("Copying " .. infoTable.Name .. " library and its dependencies to install/executable directories...") @@ -739,13 +737,13 @@ function NazaraBuild:Process(infoTable) for platform, defineTable in pairs(v) do platform = string.lower(platform) if (platform == "posix") then - local osname = os.get() + local osname = os.target() if (PosixOSes[osname]) then platform = osname end end - if (os.is(platform)) then + if (os.istarget(platform)) then for k,v in ipairs(defineTable) do table.insert(targetTable, v) end @@ -779,13 +777,14 @@ end function NazaraBuild:PrepareGeneric() flags({ - "C++14", "MultiProcessorCompile", "NoMinimalRebuild", "RelativeLinks", "ShadowedVariables", "UndefinedIdentifiers" }) + + cppdialect("C++14") self:FilterLibDirectory("../extlibs/lib/", libdirs) diff --git a/build/scripts/modules/graphics.lua b/build/scripts/modules/graphics.lua index 9d393d3a7..5c0bf4224 100644 --- a/build/scripts/modules/graphics.lua +++ b/build/scripts/modules/graphics.lua @@ -3,5 +3,6 @@ MODULE.Name = "Graphics" MODULE.Libraries = { "NazaraCore", "NazaraUtility", + "NazaraPlatform", "NazaraRenderer" } diff --git a/build/scripts/modules/platform.lua b/build/scripts/modules/platform.lua new file mode 100644 index 000000000..c90f6663a --- /dev/null +++ b/build/scripts/modules/platform.lua @@ -0,0 +1,31 @@ +MODULE.Name = "Platform" + +MODULE.Libraries = { + "NazaraCore", + "NazaraUtility" +} + +MODULE.OsFiles.Windows = { + "../src/Nazara/Platform/Win32/**.hpp", + "../src/Nazara/Platform/Win32/**.cpp" +} + +MODULE.OsFiles.Posix = { + "../src/Nazara/Platform/X11/**.hpp", + "../src/Nazara/Platform/X11/**.cpp" +} + +MODULE.OsLibraries.Windows = { + "gdi32" +} + +MODULE.OsLibraries.Posix = { + "X11", + "xcb", + "xcb-cursor", + "xcb-ewmh", + "xcb-icccm", + "xcb-keysyms", + "xcb-randr" +} + diff --git a/build/scripts/modules/renderer.lua b/build/scripts/modules/renderer.lua index bbc472b75..11b378d2b 100644 --- a/build/scripts/modules/renderer.lua +++ b/build/scripts/modules/renderer.lua @@ -8,7 +8,8 @@ MODULE.Defines = { MODULE.Libraries = { "NazaraCore", - "NazaraUtility" + "NazaraUtility", + "NazaraPlatform" } MODULE.OsFiles.Windows = { diff --git a/build/scripts/modules/utility.lua b/build/scripts/modules/utility.lua index c1bc186c0..fc4c989d8 100644 --- a/build/scripts/modules/utility.lua +++ b/build/scripts/modules/utility.lua @@ -5,29 +5,11 @@ MODULE.Libraries = { "stb_image" } -MODULE.OsFiles.Windows = { - "../src/Nazara/Utility/Win32/**.hpp", - "../src/Nazara/Utility/Win32/**.cpp" -} - -MODULE.OsFiles.Posix = { - "../src/Nazara/Utility/X11/**.hpp", - "../src/Nazara/Utility/X11/**.cpp" -} - MODULE.OsLibraries.Windows = { - "freetype-s", - "gdi32" + "freetype-s" } MODULE.OsLibraries.Posix = { - "freetype", - "X11", - "xcb", - "xcb-cursor", - "xcb-ewmh", - "xcb-icccm", - "xcb-keysyms", - "xcb-randr" + "freetype" } diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index c439e47b1..cea295f7e 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -37,7 +37,8 @@ TOOL.FilesExcluded = { "../SDK/**/*Widget*.*", "../SDK/**/LuaBinding_Audio.*", "../SDK/**/LuaBinding_Graphics.*", - "../SDK/**/LuaBinding_Renderer.*" + "../SDK/**/LuaBinding_Renderer.*", + "../SDK/**/LuaBinding_Platform.*" } diff --git a/build/scripts/tools/unittests_server.lua b/build/scripts/tools/unittests_server.lua index c94a54d6d..63c268347 100644 --- a/build/scripts/tools/unittests_server.lua +++ b/build/scripts/tools/unittests_server.lua @@ -25,7 +25,7 @@ TOOL.Files = { TOOL.FilesExcluded = { "../tests/Engine/Audio/**", "../tests/Engine/Graphics/**", - "../tests/Engine/Utility/**", + "../tests/Engine/Platform/**", "../tests/SDK/NDK/Application.cpp", "../tests/SDK/NDK/Systems/ListenerSystem.cpp", "../tests/SDK/NDK/Systems/RenderSystem.cpp" diff --git a/examples/DopplerEffect/build.lua b/examples/DopplerEffect/build.lua index 302011b81..837f62af4 100644 --- a/examples/DopplerEffect/build.lua +++ b/examples/DopplerEffect/build.lua @@ -9,5 +9,6 @@ EXAMPLE.Files = { EXAMPLE.Libraries = { "NazaraAudio", "NazaraCore", + "NazaraPlatform", "NazaraUtility" -} \ No newline at end of file +} diff --git a/examples/DopplerEffect/main.cpp b/examples/DopplerEffect/main.cpp index b6d2d034b..24120a2f5 100644 --- a/examples/DopplerEffect/main.cpp +++ b/examples/DopplerEffect/main.cpp @@ -12,14 +12,14 @@ #include #include // Thread::Sleep #include -#include -#include +#include +#include #include int main() { // NzKeyboard nécessite l'initialisation du module Utilitaire - Nz::Initializer audio; + Nz::Initializer audio; if (!audio) { std::cout << "Failed to initialize audio module" << std::endl; diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 4acbdf5a1..3da45342e 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -307,7 +307,8 @@ int main() // Pour éviter que le curseur ne sorte de l'écran, nous le renvoyons au centre de la fenêtre // Cette fonction est codée de sorte à ne pas provoquer d'évènement MouseMoved - Nz::Mouse::SetPosition(window.GetWidth() / 2, window.GetHeight() / 2, window); + Nz::Vector2ui size = window.GetSize(); + Nz::Mouse::SetPosition(size.x / 2, size.y / 2, window); break; } diff --git a/examples/HardwareInfo/build.lua b/examples/HardwareInfo/build.lua index afcc7b544..953cba7d9 100644 --- a/examples/HardwareInfo/build.lua +++ b/examples/HardwareInfo/build.lua @@ -12,6 +12,7 @@ EXAMPLE.Files = { EXAMPLE.Libraries = { "NazaraCore", + "NazaraPlatform", "NazaraRenderer", "NazaraUtility" } diff --git a/examples/MeshInfos/build.lua b/examples/MeshInfos/build.lua index 4e26f318b..74616762e 100644 --- a/examples/MeshInfos/build.lua +++ b/examples/MeshInfos/build.lua @@ -8,6 +8,7 @@ EXAMPLE.Files = { EXAMPLE.Libraries = { "NazaraCore", + "NazaraPlatform", "NazaraUtility" } diff --git a/examples/MeshInfos/main.cpp b/examples/MeshInfos/main.cpp index e95a2a4c2..bac5398fe 100644 --- a/examples/MeshInfos/main.cpp +++ b/examples/MeshInfos/main.cpp @@ -2,8 +2,11 @@ #include #include #include +#include #include #include +#include +#include #include #include #include diff --git a/examples/Particles/Common.cpp b/examples/Particles/Common.cpp index 5af7225f7..0ed9096ef 100644 --- a/examples/Particles/Common.cpp +++ b/examples/Particles/Common.cpp @@ -11,7 +11,7 @@ m_name(name) { } -void ParticleDemo::Enter(Ndk::StateMachine& fsm) +void ParticleDemo::Enter(Ndk::StateMachine& /*fsm*/) { m_shared.demoName->Update(Nz::SimpleTextDrawer::Draw(Nz::String::Number(m_index+1) + " - " + m_name, 48)); m_fpsCounter = 0; @@ -23,7 +23,7 @@ void ParticleDemo::Enter(Ndk::StateMachine& fsm) m_oldBackground3D = renderSystem3D.GetDefaultBackground(); } -void ParticleDemo::Leave(Ndk::StateMachine& fsm) +void ParticleDemo::Leave(Ndk::StateMachine& /*fsm*/) { m_shared.world2D->GetSystem().SetDefaultBackground(m_oldBackground2D); m_shared.world3D->GetSystem().SetDefaultBackground(m_oldBackground3D); @@ -32,7 +32,7 @@ void ParticleDemo::Leave(Ndk::StateMachine& fsm) m_particleGroups.clear(); } -bool ParticleDemo::Update(Ndk::StateMachine& fsm, float elapsedTime) +bool ParticleDemo::Update(Ndk::StateMachine& /*fsm*/, float elapsedTime) { m_fpsCounter++; if (m_updateClock.GetMilliseconds() > 1000) diff --git a/examples/Particles/LogoDemo.cpp b/examples/Particles/LogoDemo.cpp index 831fcffd5..e5e6c0925 100644 --- a/examples/Particles/LogoDemo.cpp +++ b/examples/Particles/LogoDemo.cpp @@ -21,7 +21,7 @@ struct ParticleData { Nz::Color color; Nz::Vector2f destination; - Nz::Vector2f position; + Nz::Vector3f position; Nz::Vector2f velocity; }; @@ -33,18 +33,18 @@ struct SpriteController : public Nz::ParticleController return; auto destPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Userdata0); - auto posPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); + auto posPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); auto velPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Velocity); std::uniform_real_distribution dis(-1.f, 1.f); for (unsigned int i = startId; i <= endId; ++i) { - Nz::Vector2f newVel = destPtr[i] - posPtr[i]; + Nz::Vector2f newVel = destPtr[i] - Nz::Vector2f(posPtr[i]); float length; newVel.Normalize(&length); - float distance = SquaredDistancePointSegment(oldMousePos, actualMousePos, posPtr[i]); + float distance = SquaredDistancePointSegment(oldMousePos, actualMousePos, Nz::Vector2f(posPtr[i])); if (distance < 250.f) { Nz::Vector2f mouseLine = actualMousePos - oldMousePos; @@ -162,7 +162,7 @@ ParticleDemo("Logo", sharedData) m_declaration = Nz::ParticleDeclaration::New(); m_declaration->EnableComponent(Nz::ParticleComponent_Color, Nz::ComponentType_Color, NazaraOffsetOf(ParticleData, color)); - m_declaration->EnableComponent(Nz::ParticleComponent_Position, Nz::ComponentType_Float2, NazaraOffsetOf(ParticleData, position)); + m_declaration->EnableComponent(Nz::ParticleComponent_Position, Nz::ComponentType_Float3, NazaraOffsetOf(ParticleData, position)); m_declaration->EnableComponent(Nz::ParticleComponent_Userdata0, Nz::ComponentType_Float2, NazaraOffsetOf(ParticleData, destination)); m_declaration->EnableComponent(Nz::ParticleComponent_Velocity, Nz::ComponentType_Float2, NazaraOffsetOf(ParticleData, velocity)); } @@ -231,7 +231,7 @@ bool LogoExample::Update(Ndk::StateMachine& fsm, float elapsedTime) ParticleData* sprite = static_cast(m_particles); for (std::size_t i = 0; i < m_pixels.size(); ++i) { - Nz::Vector2f particleToMouse = sprite[i].position - controller->actualMousePos; + Nz::Vector2f particleToMouse = Nz::Vector2f(sprite[i].position) - controller->actualMousePos; float sqDist = particleToMouse.GetSquaredLength(); if (sqDist < 10000.f) { @@ -251,21 +251,20 @@ bool LogoExample::Update(Ndk::StateMachine& fsm, float elapsedTime) void LogoExample::ResetParticles(float elapsed) { - unsigned int width = m_shared.target->GetWidth(); - unsigned int height = m_shared.target->GetHeight(); + Nz::Vector2ui size = m_shared.target->GetSize(); - Nz::Vector2f center = {width / 2.f, height / 2.f}; + Nz::Vector2f center = {size.x / 2.f, size.y / 2.f}; Nz::Vector2f offset = center - Nz::Vector2f(Nz::Vector2ui(m_logo.GetSize()) / 2); - std::uniform_real_distribution disX(0.f, float(width)); - std::uniform_real_distribution disY(-float(height) * 0.5f, float(height) * 1.5f); + std::uniform_real_distribution disX(0.f, float(size.x)); + std::uniform_real_distribution disY(-float(size.y) * 0.5f, float(size.y) * 1.5f); ParticleData* sprite = static_cast(m_particles); for (PixelData& data : m_pixels) { sprite->color = data.color; sprite->destination = offset + Nz::Vector2f(data.pos); - sprite->position.Set(disX(m_shared.randomGen) - float(width), disY(m_shared.randomGen)); + sprite->position.Set(disX(m_shared.randomGen) - float(size.x), disY(m_shared.randomGen), 0.f); sprite->velocity = Nz::Vector2f::Zero(); sprite++; } diff --git a/examples/Particles/SpacebattleDemo.cpp b/examples/Particles/SpacebattleDemo.cpp index 7f2cd6b4c..1dd7eb0ec 100644 --- a/examples/Particles/SpacebattleDemo.cpp +++ b/examples/Particles/SpacebattleDemo.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -317,10 +318,10 @@ ParticleDemo("Space battle", sharedData) m_spaceshipTemplate = m_shared.world3D->CreateEntity(); m_spaceshipTemplate->Enable(false); + m_spaceshipTemplate->AddComponent(); + m_spaceshipTemplate->AddComponent(); + m_spaceshipTemplate->AddComponent(); auto& gfxComponent = m_spaceshipTemplate->AddComponent(); - auto& nodeComponent = m_spaceshipTemplate->AddComponent(); - auto& velocityComponent = m_spaceshipTemplate->AddComponent(); - auto& spaceshipComponent = m_spaceshipTemplate->AddComponent(); gfxComponent.Attach(&m_spaceshipModel); m_ambientMusic.OpenFromFile("resources/ambience.ogg"); @@ -385,9 +386,7 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) m_torpedoGroup->AddController(Nz::ParticleFunctionController::New([this] (Nz::ParticleGroup& group, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) { auto positionPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); - auto rotationPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Rotation); auto sizePtr = mapper.GetComponentPtr(Nz::ParticleComponent_Size); - auto velocityPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Velocity); auto& spaceshipSystem = m_shared.world3D->GetSystem(); @@ -421,7 +420,7 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) emitter.SetEmissionCount(2); emitter.SetEmissionRate(200.f); - emitter.SetSetupFunc([this] (const Ndk::EntityHandle& entity, Nz::ParticleMapper& mapper, unsigned int count) + emitter.SetSetupFunc([this] (const Ndk::EntityHandle& emitterEntity, Nz::ParticleMapper& particleMapper, unsigned int count) { auto& gen = m_shared.randomGen; @@ -433,29 +432,29 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) std::uniform_real_distribution sizeDis(1.0f, 4.f); std::uniform_real_distribution velDis(-maxFireVel, maxFireVel); - Nz::Vector3f pos = entity->GetComponent().GetPosition(); + Nz::Vector3f pos = emitterEntity->GetComponent().GetPosition(); - Nz::ParticleStruct_Billboard* billboards = static_cast(mapper.GetPointer()); + Nz::ParticleStruct_Billboard* billboards = static_cast(particleMapper.GetPointer()); Nz::ParticleStruct_Billboard* smokeParticles = static_cast(m_smokeGroup->CreateParticles(count)); - for (unsigned int i = 0; i < count; ++i) + for (unsigned int j = 0; j < count; ++j) { - billboards[i].color = Nz::Color::White; - billboards[i].life = 1.f + lifeDis(gen); - billboards[i].position = pos + Nz::Vector3f(posDis(gen), posDis(gen), posDis(gen)); - billboards[i].rotation = rotDis(gen); - billboards[i].size = {1.28f, 1.28f}; - billboards[i].size *= sizeDis(gen); - billboards[i].velocity.Set(normalDis(gen), normalDis(gen), normalDis(gen)); - billboards[i].velocity.Normalize(); - billboards[i].velocity *= velDis(gen); + billboards[j].color = Nz::Color::White; + billboards[j].life = 1.f + lifeDis(gen); + billboards[j].position = pos + Nz::Vector3f(posDis(gen), posDis(gen), posDis(gen)); + billboards[j].rotation = rotDis(gen); + billboards[j].size = {1.28f, 1.28f}; + billboards[j].size *= sizeDis(gen); + billboards[j].velocity.Set(normalDis(gen), normalDis(gen), normalDis(gen)); + billboards[j].velocity.Normalize(); + billboards[j].velocity *= velDis(gen); - smokeParticles[i].color = Nz::Color(128, 128, 128, 0); - smokeParticles[i].life = maxSmokeLife; - smokeParticles[i].position = billboards[i].position; - smokeParticles[i].rotation = billboards[i].rotation; - smokeParticles[i].size = {2.56f, 2.56f}; - smokeParticles[i].size *= sizeDis(gen); - smokeParticles[i].velocity = billboards[i].velocity / 2.f; + smokeParticles[j].color = Nz::Color(128, 128, 128, 0); + smokeParticles[j].life = maxSmokeLife; + smokeParticles[j].position = billboards[j].position; + smokeParticles[j].rotation = billboards[j].rotation; + smokeParticles[j].size = {2.56f, 2.56f}; + smokeParticles[j].size *= sizeDis(gen); + smokeParticles[j].velocity = billboards[j].velocity / 2.f; } }); m_fireGroup->AddEmitter(entity); @@ -466,12 +465,11 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) } })); - m_torpedoGroup->SetRenderer(Nz::ParticleFunctionRenderer::New([sparkleMat1 = Nz::MaterialLibrary::Get("TorpedoFlare1")] (const Nz::ParticleGroup& group, const Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, Nz::AbstractRenderQueue* renderQueue) + m_torpedoGroup->SetRenderer(Nz::ParticleFunctionRenderer::New([sparkleMat1 = Nz::MaterialLibrary::Get("TorpedoFlare1")] (const Nz::ParticleGroup& /*group*/, const Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, Nz::AbstractRenderQueue* renderQueue) { auto positionPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); auto rotationPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Rotation); auto sizePtr = mapper.GetComponentPtr(Nz::ParticleComponent_Size); - auto velocityPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Velocity); renderQueue->AddBillboards(0, sparkleMat1, endId - startId + 1, positionPtr, sizePtr, rotationPtr); for (unsigned int i = startId; i <= endId; ++i) @@ -580,7 +578,7 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) }); m_fireGroup->AddController(movementController); - m_fireGroup->AddController(Nz::ParticleFunctionController::New([] (Nz::ParticleGroup& group, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) + m_fireGroup->AddController(Nz::ParticleFunctionController::New([] (Nz::ParticleGroup& /*group*/, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) { auto colorPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Color); auto lifePtr = mapper.GetComponentPtr(Nz::ParticleComponent_Life); @@ -591,7 +589,7 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) })); m_smokeGroup->AddController(movementController); - m_smokeGroup->AddController(Nz::ParticleFunctionController::New([] (Nz::ParticleGroup& group, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) + m_smokeGroup->AddController(Nz::ParticleFunctionController::New([] (Nz::ParticleGroup& /*group*/, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) { auto colorPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Color); auto lifePtr = mapper.GetComponentPtr(Nz::ParticleComponent_Life); @@ -617,7 +615,7 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) smokeMat->SetDiffuseColor(Nz::Color(128, 128, 128)); smokeMat->SetDiffuseMap("resources/smoke.png"); - m_fireGroup->SetRenderer(Nz::ParticleFunctionRenderer::New([fireMat] (const Nz::ParticleGroup& group, const Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, Nz::AbstractRenderQueue* renderQueue) + m_fireGroup->SetRenderer(Nz::ParticleFunctionRenderer::New([fireMat] (const Nz::ParticleGroup& /*group*/, const Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, Nz::AbstractRenderQueue* renderQueue) { auto colorPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Color); auto posPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); @@ -627,7 +625,7 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) renderQueue->AddBillboards(0, fireMat, endId - startId + 1, posPtr, sizePtr, rotPtr, colorPtr); })); - m_smokeGroup->SetRenderer(Nz::ParticleFunctionRenderer::New([smokeMat] (const Nz::ParticleGroup& group, const Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, Nz::AbstractRenderQueue* renderQueue) + m_smokeGroup->SetRenderer(Nz::ParticleFunctionRenderer::New([smokeMat] (const Nz::ParticleGroup& /*group*/, const Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, Nz::AbstractRenderQueue* renderQueue) { auto colorPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Color); auto posPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); @@ -643,13 +641,13 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) m_turretFireSound.LoadFromFile("resources/turretFire.wav"); m_turretReloadSound.LoadFromFile("resources/turretReload.wav"); - //m_onMouseMoved.Connect(m_shared.target->GetEventHandler().OnMouseMoved, this, &SpacebattleExample::OnMouseMoved); - //m_shared.target->SetCursor(Nz::SystemCursor_None); + m_onMouseMoved.Connect(m_shared.target->GetEventHandler().OnMouseMoved, this, &SpacebattleExample::OnMouseMoved); + m_shared.target->SetCursor(Nz::SystemCursor_None); ////////////////////////////////////////////////////////////////////////// Nz::TextSpriteRef introText = Nz::TextSprite::New(); - introText->Update(Nz::SimpleTextDrawer::Draw("--Tourelle de défense du secteur A407M2--\nLes contrôles ont été adaptés à vos contrôleurs:\nZQSD pour orienter la tourelle, espace pour tirer.\n", 72)); + introText->Update(Nz::SimpleTextDrawer::Draw("--Tourelle de défense du secteur A407M2--\nLes contrôles ont été adaptés à vos contrôleurs:\nLa souris contrôle l'orientation de la tourelle, cliquez pour tirer.\n", 72)); introText->SetScale(0.5f); m_introText = m_shared.world3D->CreateEntity(); @@ -682,7 +680,7 @@ bool SpacebattleExample::Update(Ndk::StateMachine& fsm, float elapsedTime) const float speed = 100.f; - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z)) + /*if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z)) m_turretCannonBaseRotation = std::max(m_turretCannonBaseRotation - speed * elapsedTime, -65.f); if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::S)) @@ -692,13 +690,13 @@ bool SpacebattleExample::Update(Ndk::StateMachine& fsm, float elapsedTime) m_turretBaseRotation += speed * elapsedTime; if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::D)) - m_turretBaseRotation -= speed * elapsedTime; + m_turretBaseRotation -= speed * elapsedTime;*/ m_turret.cannonBaseEntity->GetComponent().SetRotation(Nz::EulerAnglesf(m_turretCannonBaseRotation, 0.f, 0.f)); m_turret.rotatingBaseEntity->GetComponent().SetRotation(Nz::EulerAnglesf(0.f, m_turretBaseRotation, 0.f)); bool discharged = m_turretShootTimer < 1.f; - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space) && !discharged) + if (Nz::Mouse::IsButtonPressed(Nz::Mouse::Left) && !discharged) { m_turretFireSound.Play(); @@ -729,7 +727,7 @@ bool SpacebattleExample::Update(Ndk::StateMachine& fsm, float elapsedTime) auto& spacestationNode = m_spacestationEntity->GetComponent(); - Ndk::EntityHandle spaceship = m_spaceshipTemplate->Clone(); + const Ndk::EntityHandle& spaceship = m_spaceshipTemplate->Clone(); RegisterEntity(spaceship); auto& nodeComponent = spaceship->GetComponent(); auto& spaceshipComponent = spaceship->GetComponent(); @@ -815,12 +813,13 @@ void SpacebattleExample::CreateTurret() cannonGfx.Attach(&m_turret.cannonModel); } -void SpacebattleExample::OnMouseMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseMoveEvent& event) +void SpacebattleExample::OnMouseMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event) { const float speed = 0.1f; m_turretCannonBaseRotation = Nz::Clamp(m_turretCannonBaseRotation + speed * event.deltaY, -65.f, 40.f); m_turretBaseRotation -= event.deltaX * speed; - Nz::Mouse::SetPosition(m_shared.target->GetWidth() / 2, m_shared.target->GetHeight() / 2, *m_shared.target); + Nz::Vector2ui size = m_shared.target->GetSize(); + Nz::Mouse::SetPosition(size.x / 2, size.y / 2, *m_shared.target); } diff --git a/examples/Particles/SpacebattleDemo.hpp b/examples/Particles/SpacebattleDemo.hpp index 44852a61f..a41be7504 100644 --- a/examples/Particles/SpacebattleDemo.hpp +++ b/examples/Particles/SpacebattleDemo.hpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/examples/Particles/main.cpp b/examples/Particles/main.cpp index f4754c136..da61aad4b 100644 --- a/examples/Particles/main.cpp +++ b/examples/Particles/main.cpp @@ -59,7 +59,7 @@ int main() shared.particleCount->Update(Nz::SimpleTextDrawer::Draw("XXXXX particles", 36)); world2D.GetSystem().SetGlobalUp(Nz::Vector3f::Down()); - world3D.GetSystem().ChangeRenderTechnique(); + //world3D.GetSystem().ChangeRenderTechnique(); Ndk::EntityHandle viewEntity = world2D.CreateEntity(); @@ -100,9 +100,10 @@ int main() Nz::Boxf fpsCountBox = fpsGfx.GetBoundingVolume().aabb; Nz::Boxf particleCountBox = particleCountGfx.GetBoundingVolume().aabb; + Nz::Vector2ui windowSize = window.GetSize(); demoNameNode.SetPosition(5.f, 5.f); - particleCountNode.SetPosition(5.f, window.GetHeight() - particleCountBox.height - 5.f); - fpsNode.SetPosition(5.f, window.GetHeight() - fpsCountBox.height - particleCountBox.height - 5.f); + particleCountNode.SetPosition(5.f, windowSize.y - particleCountBox.height - 5.f); + fpsNode.SetPosition(5.f, windowSize.x - fpsCountBox.height - particleCountBox.height - 5.f); shared.demos.push_back(std::make_shared(shared)); @@ -125,7 +126,7 @@ int main() switch (event.key.code) { case Nz::Keyboard::Backspace: - stateMachine.ChangeState(stateMachine.GetCurrentState()); + stateMachine.ChangeState(shared.demos[demoIndex]); break; case Nz::Keyboard::Escape: diff --git a/examples/Tut00/build.lua b/examples/Tut00/build.lua index 678aa3394..baf738d1d 100644 --- a/examples/Tut00/build.lua +++ b/examples/Tut00/build.lua @@ -15,6 +15,7 @@ EXAMPLE.Libraries = { "NazaraNoise", "NazaraPhysics2D", "NazaraPhysics3D", + "NazaraPlatform", "NazaraRenderer", "NazaraUtility", "NazaraSDK" diff --git a/examples/Tut01/main.cpp b/examples/Tut01/main.cpp index b1d962e1e..8a3df36ff 100644 --- a/examples/Tut01/main.cpp +++ b/examples/Tut01/main.cpp @@ -40,7 +40,8 @@ int main(int argc, char* argv[]) graphicsComponent.Attach(textSprite); Nz::Boxf textBox = graphicsComponent.GetBoundingVolume().aabb; - nodeComponent.SetPosition(mainWindow.GetWidth() / 2 - textBox.width / 2, mainWindow.GetHeight() / 2 - textBox.height / 2); + Nz::Vector2ui windowSize = mainWindow.GetSize(); + nodeComponent.SetPosition(windowSize.x / 2 - textBox.width / 2, windowSize.y / 2 - textBox.height / 2); while (application.Run()) { diff --git a/examples/bin/Shaders/PhongLighting/core.frag b/examples/bin/Shaders/PhongLighting/core.frag new file mode 100644 index 000000000..f95d0eb04 --- /dev/null +++ b/examples/bin/Shaders/PhongLighting/core.frag @@ -0,0 +1,488 @@ +#if EARLY_FRAGMENT_TESTS && !ALPHA_TEST +layout(early_fragment_tests) in; +#endif + +// HACK UNTIL PROPER FIX +#if GLSL_VERSION < 400 + #undef SHADOW_MAPPING + #define SHADOW_MAPPING 0 +#endif +// HACK + +#define LIGHT_DIRECTIONAL 0 +#define LIGHT_POINT 1 +#define LIGHT_SPOT 2 + +/********************Entrant********************/ +in vec4 vColor; +in vec4 vLightSpacePos[3]; +in mat3 vLightToWorld; +in vec3 vNormal; +in vec2 vTexCoord; +in vec3 vViewDir; +in vec3 vWorldPos; + +/********************Sortant********************/ +out vec4 RenderTarget0; +out vec4 RenderTarget1; +out vec4 RenderTarget2; + +/********************Uniformes********************/ +struct Light +{ + int type; + vec4 color; + vec2 factors; + + vec4 parameters1; + vec4 parameters2; + vec2 parameters3; + bool shadowMapping; +}; + +// Lumières +uniform Light Lights[3]; +uniform samplerCube PointLightShadowMap[3]; +uniform sampler2D DirectionalSpotLightShadowMap[3]; + +// Matériau +uniform sampler2D MaterialAlphaMap; +uniform float MaterialAlphaThreshold; +uniform vec4 MaterialAmbient; +uniform vec4 MaterialDiffuse; +uniform sampler2D MaterialDiffuseMap; +uniform sampler2D MaterialEmissiveMap; +uniform sampler2D MaterialHeightMap; +uniform sampler2D MaterialNormalMap; +uniform float MaterialShininess; +uniform vec4 MaterialSpecular; +uniform sampler2D MaterialSpecularMap; + +// Autres +uniform float ParallaxBias = -0.03; +uniform float ParallaxScale = 0.02; +uniform vec2 InvTargetSize; +uniform vec3 EyePosition; +uniform samplerCube ReflectionMap; +uniform vec4 SceneAmbient; + +uniform mat4 WorldMatrix; + +uniform sampler2D TextureOverlay; + +/********************Fonctions********************/ + +#define kPI 3.1415926536 + +vec4 EncodeNormal(in vec3 normal) +{ + //return vec4(normal*0.5 + 0.5, 0.0); + return vec4(vec2(atan(normal.y, normal.x)/kPI, normal.z), 0.0, 0.0); +} + +float VectorToDepthValue(vec3 vec, float zNear, float zFar) +{ + vec3 absVec = abs(vec); + float localZ = max(absVec.x, max(absVec.y, absVec.z)); + + float normZ = ((zFar + zNear) * localZ - (2.0*zFar*zNear)) / ((zFar - zNear)*localZ); + return (normZ + 1.0) * 0.5; +} + +#if SHADOW_MAPPING +float CalculateDirectionalShadowFactor(int lightIndex) +{ + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + return (texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005)) ? 1.0 : 0.0; +} + +float CalculatePointShadowFactor(int lightIndex, vec3 lightToWorld, float zNear, float zFar) +{ + return (texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar)) ? 1.0 : 0.0; +} + +float CalculateSpotShadowFactor(int lightIndex, float lambert) +{ + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + +#if 0 + float visibility = 1.0; + float bias = 0.005 * tan(acos(NoL)); + bias = clamp(bias, MinAllowedBias, MaxAllowedBias); + + float x,y; + for (y = -1.0; y <= 1.0; y+= 1.0) + for (x = -1.0; x <= 1.0; x+= 1.0) + visibility += (textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw + vec3(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.0)).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w) ? 1.0 : 0.0; + + visibility /= 9.0; + + return visibility; +#else + float bias = 0.005 * tan(acos(lambert)); + + return (textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - bias)/lightSpacePos.w) ? 1.0 : 0.0; +#endif +} +#endif + +void main() +{ + vec4 diffuseColor = MaterialDiffuse * vColor; + +#if AUTO_TEXCOORDS + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; +#else + vec2 texCoord = vTexCoord; +#endif + +#if PARALLAX_MAPPING + float height = texture(MaterialHeightMap, texCoord).r; + float v = height*ParallaxScale + ParallaxBias; + + vec3 viewDir = normalize(vViewDir); + texCoord += v * viewDir.xy; +#endif + +#if DIFFUSE_MAPPING + diffuseColor *= texture(MaterialDiffuseMap, texCoord); +#endif + +#if FLAG_TEXTUREOVERLAY + diffuseColor *= texture(TextureOverlay, texCoord); +#endif + +#if FLAG_DEFERRED + #if ALPHA_TEST + // Inutile de faire de l'alpha-mapping sans alpha-test en Deferred (l'alpha n'est pas sauvegardé dans le G-Buffer) + #if ALPHA_MAPPING + diffuseColor.a *= texture(MaterialAlphaMap, texCoord).r; + #endif + + if (diffuseColor.a < MaterialAlphaThreshold) + discard; + #endif // ALPHA_TEST + + #if NORMAL_MAPPING + vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, texCoord)) - 1.0)); + #else + vec3 normal = normalize(vNormal); + #endif // NORMAL_MAPPING + + vec3 specularColor = MaterialSpecular.rgb; + #if SPECULAR_MAPPING + specularColor *= texture(MaterialSpecularMap, texCoord).rgb; + #endif + + /* + Texture0: Diffuse Color + Specular + Texture1: Normal + Specular + Texture2: Encoded depth + Shininess + */ + RenderTarget0 = vec4(diffuseColor.rgb, dot(specularColor, vec3(0.3, 0.59, 0.11))); + RenderTarget1 = vec4(EncodeNormal(normal)); + RenderTarget2 = vec4(0.0, 0.0, 0.0, (MaterialShininess == 0.0) ? 0.0 : max(log2(MaterialShininess), 0.1)/10.5); // http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf +#else // FLAG_DEFERRED + #if ALPHA_MAPPING + diffuseColor.a *= texture(MaterialAlphaMap, texCoord).r; + #endif + + #if ALPHA_TEST + if (diffuseColor.a < MaterialAlphaThreshold) + discard; + #endif + + vec3 lightAmbient = vec3(0.0); + vec3 lightDiffuse = vec3(0.0); + vec3 lightSpecular = vec3(0.0); + + #if NORMAL_MAPPING + vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, texCoord)) - 1.0)); + #else + vec3 normal = normalize(vNormal); + #endif + + if (MaterialShininess > 0.0) + { + vec3 eyeVec = normalize(EyePosition - vWorldPos); + + for (int i = 0; i < 3; ++i) + { + vec4 lightColor = Lights[i].color; + float lightAmbientFactor = Lights[i].factors.x; + float lightDiffuseFactor = Lights[i].factors.y; + + switch (Lights[i].type) + { + case LIGHT_DIRECTIONAL: + { + vec3 lightDir = -Lights[i].parameters1.xyz; + + // Ambient + lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float att = 1.0; + + float lambert = max(dot(normal, lightDir), 0.0); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateDirectionalShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Diffuse + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + + // Specular + vec3 reflection = reflect(-lightDir, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, MaterialShininess); + + lightSpecular += att * specularFactor * lightColor.rgb; + break; + } + + case LIGHT_POINT: + { + vec3 lightPos = Lights[i].parameters1.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDirLength = length(worldToLight); + vec3 lightDir = worldToLight / lightDirLength; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDirLength, 0.0); + + // Ambient + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + + // Specular + vec3 reflection = reflect(-lightDir, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, MaterialShininess); + + lightSpecular += att * specularFactor * lightColor.rgb; + break; + } + + case LIGHT_SPOT: + { + vec3 lightPos = Lights[i].parameters1.xyz; + vec3 lightDir = Lights[i].parameters2.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + float lightInnerAngle = Lights[i].parameters3.x; + float lightOuterAngle = Lights[i].parameters3.y; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDistance = length(worldToLight); + worldToLight /= lightDistance; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDistance, 0.0); + + // Ambient + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float lambert = max(dot(normal, worldToLight), 0.0); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateSpotShadowFactor(i, lambert); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Modification de l'atténuation pour gérer le spot + float curAngle = dot(lightDir, -worldToLight); + float innerMinusOuterAngle = lightInnerAngle - lightOuterAngle; + att *= max((curAngle - lightOuterAngle) / innerMinusOuterAngle, 0.0); + + // Diffuse + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + + // Specular + vec3 reflection = reflect(-worldToLight, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, MaterialShininess); + + lightSpecular += att * specularFactor * lightColor.rgb; + break; + } + + default: + break; + } + } + } + else + { + for (int i = 0; i < 3; ++i) + { + vec4 lightColor = Lights[i].color; + float lightAmbientFactor = Lights[i].factors.x; + float lightDiffuseFactor = Lights[i].factors.y; + + switch (Lights[i].type) + { + case LIGHT_DIRECTIONAL: + { + vec3 lightDir = -Lights[i].parameters1.xyz; + + // Ambient + lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float att = 1.0; + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateDirectionalShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + break; + } + + case LIGHT_POINT: + { + vec3 lightPos = Lights[i].parameters1.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDirLength = length(worldToLight); + vec3 lightDir = worldToLight / lightDirLength; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDirLength, 0.0); + + // Ambient + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + break; + } + + case LIGHT_SPOT: + { + vec3 lightPos = Lights[i].parameters1.xyz; + vec3 lightDir = Lights[i].parameters2.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + float lightInnerAngle = Lights[i].parameters3.x; + float lightOuterAngle = Lights[i].parameters3.y; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDistance = length(worldToLight); + worldToLight /= lightDistance; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDistance, 0.0); + + // Ambient + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float lambert = max(dot(normal, worldToLight), 0.0); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateSpotShadowFactor(i, lambert); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Modification de l'atténuation pour gérer le spot + float curAngle = dot(lightDir, -worldToLight); + float innerMinusOuterAngle = lightInnerAngle - lightOuterAngle; + att *= max((curAngle - lightOuterAngle) / innerMinusOuterAngle, 0.0); + + // Diffuse + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + } + + default: + break; + } + } + } + + lightSpecular *= MaterialSpecular.rgb; + #if SPECULAR_MAPPING + lightSpecular *= texture(MaterialSpecularMap, texCoord).rgb; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens + #endif + + vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); + + #if REFLECTION_MAPPING + vec3 eyeVec = normalize(vWorldPos - EyePosition); + + vec3 reflected = normalize(reflect(eyeVec, normal)); + //reflected = vec3(inverse(WorldMatrix) * vec4(reflected, 0.0)); + + lightColor *= texture(ReflectionMap, reflected).rgb; + #endif + + vec4 fragmentColor = vec4(lightColor, 1.0) * diffuseColor; + + #if EMISSIVE_MAPPING + float lightIntensity = dot(lightColor, vec3(0.3, 0.59, 0.11)); + + vec3 emissionColor = MaterialDiffuse.rgb * texture(MaterialEmissiveMap, texCoord).rgb; + RenderTarget0 = vec4(mix(fragmentColor.rgb, emissionColor, clamp(1.0 - 3.0*lightIntensity, 0.0, 1.0)), fragmentColor.a); + #else + RenderTarget0 = fragmentColor; + #endif // EMISSIVE_MAPPING +#endif // FLAG_DEFERRED +} + diff --git a/examples/bin/Shaders/PhongLighting/core.vert b/examples/bin/Shaders/PhongLighting/core.vert new file mode 100644 index 000000000..8943c5935 --- /dev/null +++ b/examples/bin/Shaders/PhongLighting/core.vert @@ -0,0 +1,148 @@ +/********************Entrant********************/ +#if FLAG_BILLBOARD +in vec3 InstanceData0; // center +in vec4 InstanceData1; // size | sin cos +in vec4 InstanceData2; // color +#else +in mat4 InstanceData0; +#endif + +in vec4 VertexColor; +in vec3 VertexPosition; +in vec3 VertexNormal; +in vec3 VertexTangent; +in vec2 VertexTexCoord; +in vec4 VertexUserdata0; + +/********************Sortant********************/ +out vec4 vColor; +out vec4 vLightSpacePos[3]; +out mat3 vLightToWorld; +out vec3 vNormal; +out vec2 vTexCoord; +out vec3 vViewDir; +out vec3 vWorldPos; + +/********************Uniformes********************/ +uniform vec3 EyePosition; +uniform mat4 InvViewMatrix; +uniform mat4 LightViewProjMatrix[3]; +uniform float VertexDepth; +uniform mat4 ViewMatrix; +uniform mat4 ViewProjMatrix; +uniform mat4 WorldMatrix; +uniform mat4 WorldViewProjMatrix; + +/********************Fonctions********************/ +void main() +{ +#if FLAG_VERTEXCOLOR + vec4 color = VertexColor; +#else + vec4 color = vec4(1.0); +#endif + + vec2 texCoords; + +#if FLAG_BILLBOARD + #if FLAG_INSTANCING + vec3 billboardCenter = InstanceData0; + vec2 billboardSize = InstanceData1.xy; + vec2 billboardSinCos = InstanceData1.zw; + vec4 billboardColor = InstanceData2; + + vec2 rotatedPosition; + rotatedPosition.x = VertexPosition.x*billboardSinCos.y - VertexPosition.y*billboardSinCos.x; + rotatedPosition.y = VertexPosition.y*billboardSinCos.y + VertexPosition.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = billboardCenter + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + color = billboardColor; + texCoords = VertexPosition.xy + 0.5; + #else + vec2 billboardCorner = VertexTexCoord - 0.5; + vec2 billboardSize = VertexUserdata0.xy; + vec2 billboardSinCos = VertexUserdata0.zw; + + vec2 rotatedPosition; + rotatedPosition.x = billboardCorner.x*billboardSinCos.y - billboardCorner.y*billboardSinCos.x; + rotatedPosition.y = billboardCorner.y*billboardSinCos.y + billboardCorner.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = VertexPosition + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + texCoords = VertexTexCoord; + #endif + texCoords.y = 1.0 - texCoords.y; +#else + #if FLAG_INSTANCING + #if TRANSFORM + gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); + #else + #if UNIFORM_VERTEX_DEPTH + gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); + #endif + #endif + #else + #if TRANSFORM + gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); + #else + #if UNIFORM_VERTEX_DEPTH + gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = vec4(VertexPosition, 1.0); + #endif + #endif + #endif + + texCoords = VertexTexCoord; +#endif + + vColor = color; + +#if FLAG_INSTANCING + mat3 rotationMatrix = mat3(InstanceData0); +#else + mat3 rotationMatrix = mat3(WorldMatrix); +#endif + +#if COMPUTE_TBNMATRIX + vec3 binormal = cross(VertexNormal, VertexTangent); + vLightToWorld[0] = normalize(rotationMatrix * VertexTangent); + vLightToWorld[1] = normalize(rotationMatrix * binormal); + vLightToWorld[2] = normalize(rotationMatrix * VertexNormal); +#else + vNormal = normalize(rotationMatrix * VertexNormal); +#endif + +#if SHADOW_MAPPING + for (int i = 0; i < 3; ++i) + vLightSpacePos[i] = LightViewProjMatrix[i] * WorldMatrix * vec4(VertexPosition, 1.0); +#endif + +#if TEXTURE_MAPPING + vTexCoord = VertexTexCoord; +#endif + +#if PARALLAX_MAPPING + vViewDir = EyePosition - VertexPosition; + vViewDir *= vLightToWorld; +#endif + +#if !FLAG_DEFERRED + #if FLAG_INSTANCING + vWorldPos = vec3(InstanceData0 * vec4(VertexPosition, 1.0)); + #else + vWorldPos = vec3(WorldMatrix * vec4(VertexPosition, 1.0)); + #endif +#endif +} diff --git a/include/Nazara/Audio/Audio.hpp b/include/Nazara/Audio/Audio.hpp index 1a7c7a1a4..84aee8b84 100644 --- a/include/Nazara/Audio/Audio.hpp +++ b/include/Nazara/Audio/Audio.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 86ccc6906..34b8926a4 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ namespace Nz public: Music() = default; Music(const Music&) = delete; - Music(Music&&) = delete; ///TODO + Music(Music&&) = delete; ~Music(); bool Create(SoundStream* soundStream); @@ -66,10 +67,10 @@ namespace Nz void Stop() override; Music& operator=(const Music&) = delete; - Music& operator=(Music&&) = delete; ///TODO + Music& operator=(Music&&) = delete; private: - MusicImpl* m_impl = nullptr; + MovablePtr m_impl = nullptr; bool FillAndQueueBuffer(unsigned int buffer); void MusicThread(); diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index db38f780f..ee2671070 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include namespace Nz { @@ -74,7 +74,7 @@ namespace Nz template static SoundBufferRef New(Args&&... args); SoundBuffer& operator=(const SoundBuffer&) = delete; - SoundBuffer& operator=(SoundBuffer&&) = delete; ///TODO + SoundBuffer& operator=(SoundBuffer&&) = delete; // Signals: NazaraSignal(OnSoundBufferDestroy, const SoundBuffer* /*soundBuffer*/); @@ -86,7 +86,7 @@ namespace Nz static bool Initialize(); static void Uninitialize(); - SoundBufferImpl* m_impl = nullptr; + MovablePtr m_impl = nullptr; static SoundBufferLibrary::LibraryMap s_library; static SoundBufferLoader::LoaderList s_loaders; diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index 4bcdca176..5c755d253 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -52,12 +52,12 @@ namespace Nz virtual void Stop() = 0; SoundEmitter& operator=(const SoundEmitter&) = delete; ///TODO - SoundEmitter& operator=(SoundEmitter&&) = delete; ///TODO + SoundEmitter& operator=(SoundEmitter&&) = delete; protected: SoundEmitter(); SoundEmitter(const SoundEmitter& emitter); - SoundEmitter(SoundEmitter&&) = delete; ///TODO + SoundEmitter(SoundEmitter&&) = delete; SoundStatus GetInternalStatus() const; diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 606d6969a..b4481b1a6 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Core/AbstractLogger.hpp b/include/Nazara/Core/AbstractLogger.hpp index fb2ba6c0f..2f523e2d2 100644 --- a/include/Nazara/Core/AbstractLogger.hpp +++ b/include/Nazara/Core/AbstractLogger.hpp @@ -8,7 +8,6 @@ #define NAZARA_ABSTRACTLOGGER_HPP #include -#include #include namespace Nz diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index a1d846085..095ef3710 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -130,8 +130,6 @@ namespace Nz * \brief Returns the number of elements in a C-array * \return The number of elements * - * \param name C-array - * * \see CountOf */ template @@ -308,7 +306,7 @@ namespace Nz return false; string->resize(size); - return context.stream->Read(&string[0], size) == size; + return context.stream->Read(&(*string)[0], size) == size; } /*! diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index 04fb2f3c6..b175021b4 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -76,7 +76,7 @@ namespace Nz void ShiftLeft(std::size_t pos); void ShiftRight(std::size_t pos); - void Swap(Bitset& bitset); + void Swap(Bitset& bitset) noexcept; bool Test(std::size_t bit) const; bool TestAll() const; @@ -90,8 +90,8 @@ namespace Nz void UnboundedSet(std::size_t bit, bool val = true); bool UnboundedTest(std::size_t bit) const; - Bit operator[](int index); - bool operator[](int index) const; + Bit operator[](std::size_t index); + bool operator[](std::size_t index) const; Bitset operator~() const; @@ -199,7 +199,7 @@ namespace Nz namespace std { template - void swap(Nz::Bitset& lhs, Nz::Bitset& rhs); + void swap(Nz::Bitset& lhs, Nz::Bitset& rhs) noexcept; } #include diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index 44a5e2c16..3b24586bd 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -776,7 +776,7 @@ namespace Nz * \param bitset Other bitset to swap */ template - void Bitset::Swap(Bitset& bitset) + void Bitset::Swap(Bitset& bitset) noexcept { std::swap(m_bitCount, bitset.m_bitCount); std::swap(m_blocks, bitset.m_blocks); @@ -815,7 +815,7 @@ namespace Nz for (std::size_t i = 0; i < m_blocks.size(); ++i) { Block mask = (i == m_blocks.size() - 1) ? lastBlockMask : fullBitMask; - if (m_blocks[i] == mask) // The extra bits are set to zero, thus we can't test without proceeding with a mask + if (m_blocks[i] != mask) // The extra bits are set to zero, thus we can't test without proceeding with a mask return false; } @@ -958,7 +958,7 @@ namespace Nz */ template - typename Bitset::Bit Bitset::operator[](int index) + typename Bitset::Bit Bitset::operator[](std::size_t index) { return Bit(m_blocks[GetBlockIndex(index)], Block(1U) << GetBitIndex(index)); } @@ -969,7 +969,7 @@ namespace Nz */ template - bool Bitset::operator[](int index) const + bool Bitset::operator[](std::size_t index) const { return Test(index); } @@ -1645,7 +1645,7 @@ namespace std */ template - void swap(Nz::Bitset& lhs, Nz::Bitset& rhs) + void swap(Nz::Bitset& lhs, Nz::Bitset& rhs) noexcept { lhs.Swap(rhs); } diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 81406d84f..5d6e823dc 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include namespace Nz @@ -422,7 +421,6 @@ namespace Nz /*! * \brief Resizes the string - * \return A reference to this * * \param newSize Target size */ @@ -434,7 +432,6 @@ namespace Nz /*! * \brief Resizes the string - * \return A reference to this * * \param newSize Target size * \param byte Byte to add if newSize is greather than actual size diff --git a/include/Nazara/Core/ByteStream.hpp b/include/Nazara/Core/ByteStream.hpp index eed461205..e6e941256 100644 --- a/include/Nazara/Core/ByteStream.hpp +++ b/include/Nazara/Core/ByteStream.hpp @@ -8,13 +8,14 @@ #define NAZARA_BYTESTREAM_HPP #include -#include #include -#include #include namespace Nz { + class ByteArray; + class Stream; + class NAZARA_CORE_API ByteStream { public: @@ -40,7 +41,7 @@ namespace Nz void SetStream(void* ptr, Nz::UInt64 size); void SetStream(const void* ptr, Nz::UInt64 size); - inline void Write(const void* data, std::size_t size); + inline std::size_t Write(const void* data, std::size_t size); template ByteStream& operator>>(T& value); diff --git a/include/Nazara/Core/ByteStream.inl b/include/Nazara/Core/ByteStream.inl index 1dbf9535e..49d51b7d6 100644 --- a/include/Nazara/Core/ByteStream.inl +++ b/include/Nazara/Core/ByteStream.inl @@ -101,7 +101,7 @@ namespace Nz * \brief Reads data * \return Number of data read * - * \param buffer Preallocated buffer to contain information read + * \param ptr Preallocated buffer to contain information read * \param size Size of the read and thus of the buffer */ @@ -117,7 +117,7 @@ namespace Nz /*! * \brief Sets the stream endianness * - * \param Type of the endianness + * \param endiannes Type of the endianness */ inline void ByteStream::SetDataEndianness(Endianness endiannes) @@ -154,13 +154,13 @@ namespace Nz * \remark Produces a NazaraAssert if buffer is nullptr */ - inline void ByteStream::Write(const void* data, std::size_t size) + inline std::size_t ByteStream::Write(const void* data, std::size_t size) { if (!m_context.stream) OnEmptyStream(); FlushBits(); - m_context.stream->Write(data, size); + return m_context.stream->Write(data, size); } /*! diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index 4ed06796f..0e0247f0a 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -23,6 +23,7 @@ namespace Nz inline explicit Color(UInt8 lightness); inline Color(UInt8 color[3], UInt8 alpha = 255); inline Color(const Color& color) = default; + inline Color(Color&& color) = default; inline ~Color() = default; inline bool IsOpaque() const; @@ -32,6 +33,9 @@ namespace Nz inline Color operator+(const Color& angles) const; inline Color operator*(const Color& angles) const; + inline Color& operator=(const Color& other) = default; + inline Color& operator=(Color&& other) = default; + inline Color operator+=(const Color& angles); inline Color operator*=(const Color& angles); @@ -40,13 +44,13 @@ namespace Nz static inline Color FromCMY(float cyan, float magenta, float yellow); static inline Color FromCMYK(float cyan, float magenta, float yellow, float black); - static inline Color FromHSL(UInt8 hue, UInt8 saturation, UInt8 lightness); + static inline Color FromHSL(float hue, float saturation, float lightness); static inline Color FromHSV(float hue, float saturation, float value); static inline Color FromXYZ(const Vector3f& vec); static inline Color FromXYZ(float x, float y, float z); static inline void ToCMY(const Color& color, float* cyan, float* magenta, float* yellow); static inline void ToCMYK(const Color& color, float* cyan, float* magenta, float* yellow, float* black); - static inline void ToHSL(const Color& color, UInt8* hue, UInt8* saturation, UInt8* lightness); + static inline void ToHSL(const Color& color, float* hue, float* saturation, float* lightness); static inline void ToHSV(const Color& color, float* hue, float* saturation, float* value); static inline void ToXYZ(const Color& color, Vector3f* vec); static inline void ToXYZ(const Color& color, float* x, float* y, float* z); diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 6d9fe4d35..f391f0c76 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -2,12 +2,9 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include #include -#include -#include #include namespace Nz @@ -222,35 +219,29 @@ namespace Nz * \brief Converts HSL representation to RGB * \return Color resulting * - * \param hue Hue component - * \param saturation Saturation component - * \param lightness Lightness component + * \param hue Hue component in [0, 360] + * \param saturation Saturation component [0, 1] + * \param lightness Lightness component [0, 1] */ - inline Color Color::FromHSL(UInt8 hue, UInt8 saturation, UInt8 lightness) + inline Color Color::FromHSL(float hue, float saturation, float lightness) { - if (saturation == 0) + if (NumberEquals(saturation, 0.f)) { // RGB results from 0 to 255 - return Color(lightness * 255, - lightness * 255, - lightness * 255); + return Color(static_cast(lightness * 255.f)); } else { - // Norme Windows - float l = lightness/240.f; - float h = hue/240.f; - float s = saturation/240.f; - float v2; - if (l < 0.5f) - v2 = l * (1.f + s); + if (lightness < 0.5f) + v2 = lightness * (1.f + saturation); else - v2 = (l + s) - (s*l); + v2 = (lightness + saturation) - (saturation * lightness); - float v1 = 2.f * l - v2; + float v1 = 2.f * lightness - v2; + float h = hue / 360.f; return Color(static_cast(255.f * Hue2RGB(v1, v2, h + (1.f/3.f))), static_cast(255.f * Hue2RGB(v1, v2, h)), static_cast(255.f * Hue2RGB(v1, v2, h - (1.f/3.f)))); @@ -261,9 +252,9 @@ namespace Nz * \brief Converts HSV representation to RGB * \return Color resulting * - * \param hue Hue component - * \param saturation Saturation component - * \param value Value component + * \param hue Hue component in [0, 360] + * \param saturation Saturation component in [0, 1] + * \param value Value component in [0, 1] */ inline Color Color::FromHSV(float hue, float saturation, float value) @@ -272,16 +263,15 @@ namespace Nz return Color(static_cast(value * 255.f)); else { - float h = hue/360.f * 6.f; - float s = saturation/360.f; + float h = (hue / 360.f) * 6.f; - if (NumberEquals(h, 6.f)) - h = 0; // hue must be < 1 + if (NumberEquals(h , 6.f)) + h = 0.f; // hue must be < 1 - int i = static_cast(h); - float v1 = value * (1.f - s); - float v2 = value * (1.f - s * (h - i)); - float v3 = value * (1.f - s * (1.f - (h - i))); + int i = static_cast(h); + float v1 = value * (1.f - saturation); + float v2 = value * (1.f - saturation * (h - i)); + float v3 = value * (1.f - saturation * (1.f - (h - i))); float r, g, b; switch (i) @@ -324,7 +314,7 @@ namespace Nz } // RGB results from 0 to 255 - return Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); + return Color(static_cast(r * 255.f), static_cast(g * 255.f), static_cast(b * 255.f)); } } @@ -341,7 +331,7 @@ namespace Nz } /*! - * \brief Converts XYZ representation to RGB + * \brief Converts XYZ representation (D65/2°) to RGB * \return Color resulting * * \param x X component @@ -365,12 +355,12 @@ namespace Nz r *= 12.92f; if (g > 0.0031308f) - g = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; + g = 1.055f * (std::pow(g, 1.f/2.4f)) - 0.055f; else g *= 12.92f; if (b > 0.0031308f) - b = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; + b = 1.055f * (std::pow(b, 1.f/2.4f)) - 0.055f; else b *= 12.92f; @@ -430,12 +420,12 @@ namespace Nz * \brief Converts RGB representation to HSL * * \param color Color to transform - * \param hue Hue component - * \param saturation Saturation component - * \param lightness Lightness component + * \param hue Hue component [0, 360] + * \param saturation Saturation component in [0, 1] + * \param lightness Lightness component in [0, 1] */ - inline void Color::ToHSL(const Color& color, UInt8* hue, UInt8* saturation, UInt8* lightness) + inline void Color::ToHSL(const Color& color, float* hue, float* saturation, float* lightness) { float r = color.r / 255.f; float g = color.g / 255.f; @@ -446,42 +436,41 @@ namespace Nz float deltaMax = max - min; //Delta RGB value - float l = (max + min)/2.f; + float l = (max + min) / 2.f; + *lightness = l; if (NumberEquals(deltaMax, 0.f)) { //This is a gray, no chroma... - *hue = 0; //HSL results from 0 to 1 - *saturation = 0; + *hue = 0.f; + *saturation = 0.f; } else { - //Chromatic data... - if (l < 0.5f) - *saturation = static_cast(deltaMax/(max+min)*240.f); + if (l <= 0.5f) + *saturation = deltaMax / (max + min); else - *saturation = static_cast(deltaMax/(2.f-max-min)*240.f); + *saturation = (deltaMax / (2.f - max - min)); - *lightness = static_cast(l*240.f); - - float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; - float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; - float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; + float deltaR = ((max - r) / 6.f + deltaMax / 2.f) / deltaMax; + float deltaG = ((max - g) / 6.f + deltaMax / 2.f) / deltaMax; + float deltaB = ((max - b) / 6.f + deltaMax / 2.f) / deltaMax; float h; + if (NumberEquals(r, max)) h = deltaB - deltaG; else if (NumberEquals(g, max)) - h = (1.f/3.f) + deltaR - deltaB; + h = (1.f / 3.f) + deltaR - deltaB; else - h = (2.f/3.f) + deltaG - deltaR; + h = (2.f / 3.f) + deltaG - deltaR; if (h < 0.f) h += 1.f; else if (h > 1.f) h -= 1.f; - *hue = static_cast(h*240.f); + *hue = h * 360.f; } } @@ -510,33 +499,33 @@ namespace Nz if (NumberEquals(deltaMax, 0.f)) { //This is a gray, no chroma... - *hue = 0; //HSV results from 0 to 1 - *saturation = 0; + *hue = 0.f; + *saturation = 0.f; } else { //Chromatic data... - *saturation = deltaMax/max*360.f; + *saturation = deltaMax / max; - float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; - float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; - float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; + float deltaR = ((max - r) / 6.f + deltaMax / 2.f) / deltaMax; + float deltaG = ((max - g) / 6.f + deltaMax / 2.f) / deltaMax; + float deltaB = ((max - b) / 6.f + deltaMax / 2.f) / deltaMax; float h; if (NumberEquals(r, max)) h = deltaB - deltaG; else if (NumberEquals(g, max)) - h = (1.f/3.f) + deltaR - deltaB; + h = (1.f / 3.f) + deltaR - deltaB; else - h = (2.f/3.f) + deltaG - deltaR; + h = (2.f / 3.f) + deltaG - deltaR; if (h < 0.f) h += 1.f; else if (h > 1.f) h -= 1.f; - *hue = h*360.f; + *hue = h * 360.f; } } diff --git a/include/Nazara/Core/ConditionVariable.hpp b/include/Nazara/Core/ConditionVariable.hpp index d73cb0f8f..97d4ed10f 100644 --- a/include/Nazara/Core/ConditionVariable.hpp +++ b/include/Nazara/Core/ConditionVariable.hpp @@ -8,6 +8,7 @@ #define NAZARA_CONDITIONVARIABLE_HPP #include +#include namespace Nz { @@ -19,7 +20,7 @@ namespace Nz public: ConditionVariable(); ConditionVariable(const ConditionVariable&) = delete; - inline ConditionVariable(ConditionVariable&& condition) noexcept; + ConditionVariable(ConditionVariable&& condition) noexcept = default; ~ConditionVariable(); void Signal(); @@ -29,10 +30,10 @@ namespace Nz bool Wait(Mutex* mutex, UInt32 timeout); ConditionVariable& operator=(const ConditionVariable&) = delete; - ConditionVariable& operator=(ConditionVariable&& condition) noexcept; + ConditionVariable& operator=(ConditionVariable&& condition) noexcept = default; private: - ConditionVariableImpl* m_impl; + MovablePtr m_impl; }; } diff --git a/include/Nazara/Core/ConditionVariable.inl b/include/Nazara/Core/ConditionVariable.inl index f9603e1c1..71866b880 100644 --- a/include/Nazara/Core/ConditionVariable.inl +++ b/include/Nazara/Core/ConditionVariable.inl @@ -2,8 +2,6 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include #include namespace Nz @@ -11,15 +9,6 @@ namespace Nz /*! * \class Nz::ConditionVariable */ - - /*! - * \brief Constructs a ConditionVariable object by moving another one - */ - inline ConditionVariable::ConditionVariable(ConditionVariable&& condition) noexcept : - m_impl(condition.m_impl) - { - condition.m_impl = nullptr; - } } #include diff --git a/include/Nazara/Core/Core.hpp b/include/Nazara/Core/Core.hpp index 672e4ecc9..e5b0166d5 100644 --- a/include/Nazara/Core/Core.hpp +++ b/include/Nazara/Core/Core.hpp @@ -8,7 +8,6 @@ #define NAZARA_CORE_HPP #include -#include namespace Nz { diff --git a/include/Nazara/Core/Directory.hpp b/include/Nazara/Core/Directory.hpp index 21a1da8da..ea828fe45 100644 --- a/include/Nazara/Core/Directory.hpp +++ b/include/Nazara/Core/Directory.hpp @@ -8,6 +8,7 @@ #define NAZARA_DIRECTORY_HPP #include +#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -35,7 +36,7 @@ namespace Nz Directory(); Directory(const String& dirPath); Directory(const Directory&) = delete; - Directory(Directory&&) = delete; ///TODO + Directory(Directory&&) noexcept = default; ~Directory(); void Close(); @@ -67,14 +68,14 @@ namespace Nz static bool SetCurrent(const String& dirPath); Directory& operator=(const Directory&) = delete; - Directory& operator=(Directory&&) = delete; ///TODO + Directory& operator=(Directory&&) noexcept = delete; private: NazaraMutexAttrib(m_mutex, mutable) String m_dirPath; String m_pattern; - DirectoryImpl* m_impl; + MovablePtr m_impl; }; } diff --git a/include/Nazara/Core/DynLib.hpp b/include/Nazara/Core/DynLib.hpp index 2f4ccb530..edf8ed647 100644 --- a/include/Nazara/Core/DynLib.hpp +++ b/include/Nazara/Core/DynLib.hpp @@ -8,6 +8,7 @@ #define NAZARA_DYNLIB_HPP #include +#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -28,7 +29,7 @@ namespace Nz { - using DynLibFunc = int (*)(); // "Generic" type of poiter to function + using DynLibFunc = int (*)(); // "Generic" type of pointer to function class DynLibImpl; @@ -37,7 +38,7 @@ namespace Nz public: DynLib(); DynLib(const DynLib&) = delete; - DynLib(DynLib&& lib); + DynLib(DynLib&&) noexcept = default; ~DynLib(); String GetLastError() const; @@ -49,13 +50,13 @@ namespace Nz void Unload(); DynLib& operator=(const DynLib&) = delete; - DynLib& operator=(DynLib&& lib); + DynLib& operator=(DynLib&& lib) noexcept = default; private: NazaraMutexAttrib(m_mutex, mutable) mutable String m_lastError; - DynLibImpl* m_impl; + MovablePtr m_impl; }; } diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index 937c01a44..fd171fc86 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -94,8 +94,7 @@ namespace Nz template<> struct EnumAsFlags { - static constexpr bool value = true; - static constexpr int max = OpenMode_Max; + static constexpr OpenMode max = OpenMode_Max; }; using OpenModeFlags = Flags; @@ -198,8 +197,7 @@ namespace Nz template<> struct EnumAsFlags { - static constexpr bool value = true; - static constexpr int max = StreamOption_Max; + static constexpr StreamOption max = StreamOption_Max; }; using StreamOptionFlags = Flags; diff --git a/include/Nazara/Core/ErrorFlags.hpp b/include/Nazara/Core/ErrorFlags.hpp index 76d89a858..945acc45c 100644 --- a/include/Nazara/Core/ErrorFlags.hpp +++ b/include/Nazara/Core/ErrorFlags.hpp @@ -8,7 +8,6 @@ #define NAZARA_ERRORFLAGS_HPP #include -#include namespace Nz { diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 86a224314..859b7395b 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -9,8 +9,8 @@ #include #include -#include #include +#include #include #include @@ -33,7 +33,7 @@ namespace Nz File(const String& filePath); File(const String& filePath, OpenModeFlags openMode); File(const File&) = delete; - File(File&& file) noexcept; + File(File&& file) noexcept = default; ~File(); bool Copy(const String& newFilePath); @@ -69,7 +69,7 @@ namespace Nz File& operator=(const String& filePath); File& operator=(const File&) = delete; - File& operator=(File&& file) noexcept; + File& operator=(File&& file) noexcept = default; static String AbsolutePath(const String& filePath); static inline ByteArray ComputeHash(HashType hash, const String& filePath); @@ -95,7 +95,7 @@ namespace Nz std::size_t WriteBlock(const void* buffer, std::size_t size) override; String m_filePath; - FileImpl* m_impl; + MovablePtr m_impl; }; NAZARA_CORE_API bool HashAppend(AbstractHash* hash, const File& originalFile); diff --git a/include/Nazara/Core/File.inl b/include/Nazara/Core/File.inl index 15ac3fabd..8a93fbc28 100644 --- a/include/Nazara/Core/File.inl +++ b/include/Nazara/Core/File.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include diff --git a/include/Nazara/Core/Flags.hpp b/include/Nazara/Core/Flags.hpp index b7dff544b..86844b806 100644 --- a/include/Nazara/Core/Flags.hpp +++ b/include/Nazara/Core/Flags.hpp @@ -16,24 +16,42 @@ namespace Nz template struct EnumAsFlags { - static constexpr bool value = false; - static constexpr int max = 0; + }; + + // From: https://stackoverflow.com/questions/11927032/sfinae-check-for-static-member-using-decltype + template + class IsEnumFlag + { + template::max)>::value>::type> + static std::true_type check(int); + + template static std::false_type check(...); + + public: + static constexpr bool value = decltype(check(0))::value; }; template class Flags { static_assert(std::is_enum::value, "Type must be an enumeration"); - static_assert(EnumAsFlags::value, "Enum has not been enabled as flags by an EnumAsFlags specialization"); + static_assert(IsEnumFlag::value, "Enum has not been enabled as flags by an EnumAsFlags specialization"); + + static constexpr std::size_t MaxValue = static_cast(EnumAsFlags::max); + + using BitField16 = std::conditional_t<(MaxValue > 8), UInt16, UInt8>; + using BitField32 = std::conditional_t<(MaxValue > 16), UInt32, BitField16>; public: - using BitField = typename std::conditional<(EnumAsFlags::max > 32), UInt64, UInt32>::type; + using BitField = std::conditional_t<(MaxValue > 32), UInt64, BitField32>; constexpr Flags(BitField value = 0); constexpr Flags(E enumVal); + constexpr bool Test(const Flags& flags) const; + explicit constexpr operator bool() const; - explicit constexpr operator BitField() const; + template::value && sizeof(T) >= sizeof(BitField)>> explicit constexpr operator T() const; constexpr Flags operator~() const; constexpr Flags operator&(const Flags& rhs) const; @@ -49,7 +67,7 @@ namespace Nz static constexpr BitField GetFlagValue(E enumValue); - static constexpr BitField ValueMask = ((BitField(1) << (EnumAsFlags::max + 1)) - 1); + static constexpr BitField ValueMask = ((BitField(1) << (MaxValue + 1)) - 1); private: BitField m_value; @@ -58,10 +76,10 @@ namespace Nz // Little hack to have them in both Nz and global scope namespace FlagsOperators { - template constexpr std::enable_if_t::value, Flags> operator~(E lhs); - template constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs); - template constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs); - template constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs); + template constexpr std::enable_if_t::value, Flags> operator~(E lhs); + template constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs); + template constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs); + template constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs); } using namespace FlagsOperators; diff --git a/include/Nazara/Core/Flags.inl b/include/Nazara/Core/Flags.inl index 1899e7576..36bb32ea0 100644 --- a/include/Nazara/Core/Flags.inl +++ b/include/Nazara/Core/Flags.inl @@ -29,7 +29,7 @@ namespace Nz /*! * \brief Constructs a Flags object using an Enum value * - * \param value enumVal + * \param enumVal enumVal * * Setup a Flags object with only one flag active (corresponding to the enum value passed as argument). */ @@ -40,7 +40,17 @@ namespace Nz } /*! - * \brief Tests a Flags + * \brief Tests if all flags from a Flags object are enabled + * \return True if all tested flags are enabled. + */ + template + constexpr bool Flags::Test(const Flags& flags) const + { + return (m_value & flags.m_value) == flags.m_value; + } + + /*! + * \brief Tests any flag * \return True if any flag is enabled. * * This will convert to a boolean value allowing to check if any flag is set. @@ -52,13 +62,14 @@ namespace Nz } /*! - * \brief Converts to a bitfield - * \return Enabled flags as a bitfield. + * \brief Converts to an integer + * \return Enabled flags as a integer * - * This will convert to a bitfield value. + * This will only works if the integer type is large enough to store all flags states */ template - constexpr Flags::operator BitField() const + template + constexpr Flags::operator T() const { return m_value; } @@ -222,7 +233,7 @@ namespace Nz * Returns a Flags object with all state enabled except for the enum one. */ template - constexpr std::enable_if_t::value, Flags> operator~(E lhs) + constexpr std::enable_if_t::value, Flags> operator~(E lhs) { return ~Flags(lhs); } @@ -237,7 +248,7 @@ namespace Nz * Returns a Flags object with combined states from the two enumeration values. */ template - constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs) + constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs) { return Flags(lhs) | rhs; } @@ -253,7 +264,7 @@ namespace Nz * In this case, only one flag will be enabled if both enumeration values are the same. */ template - constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs) + constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs) { return Flags(lhs) & rhs; } @@ -269,7 +280,7 @@ namespace Nz * In this case, two flags will be enabled if both the enumeration values are different. */ template - constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs) + constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs) { return Flags(lhs) ^ rhs; } diff --git a/include/Nazara/Core/GuillotineBinPack.hpp b/include/Nazara/Core/GuillotineBinPack.hpp index 61671ff50..0736447fc 100644 --- a/include/Nazara/Core/GuillotineBinPack.hpp +++ b/include/Nazara/Core/GuillotineBinPack.hpp @@ -11,7 +11,6 @@ #define NAZARA_GUILLOTINEBINPACK_HPP #include -#include #include #include diff --git a/include/Nazara/Core/Hash/Fletcher16.hpp b/include/Nazara/Core/Hash/Fletcher16.hpp index a360c3adf..85325e20c 100644 --- a/include/Nazara/Core/Hash/Fletcher16.hpp +++ b/include/Nazara/Core/Hash/Fletcher16.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace Nz { diff --git a/include/Nazara/Core/Log.hpp b/include/Nazara/Core/Log.hpp index f3826f568..1538068a2 100644 --- a/include/Nazara/Core/Log.hpp +++ b/include/Nazara/Core/Log.hpp @@ -8,11 +8,8 @@ #define NAZARA_LOG_HPP #include -#include -#include #include #include -#include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_LOG #include @@ -30,6 +27,8 @@ namespace Nz { + class AbstractLogger; + class NAZARA_CORE_API Log { friend class Core; diff --git a/include/Nazara/Core/MemoryHelper.hpp b/include/Nazara/Core/MemoryHelper.hpp index dc1bcc475..2788b4ca1 100644 --- a/include/Nazara/Core/MemoryHelper.hpp +++ b/include/Nazara/Core/MemoryHelper.hpp @@ -23,12 +23,15 @@ #endif #ifdef NAZARA_ALLOCA_SUPPORT - #define NazaraStackAllocation(size) Nz::StackAllocation(NAZARA_ALLOCA(size)) + #define NazaraStackAllocation(T, size) Nz::StackArray(static_cast(NAZARA_ALLOCA((size) * sizeof(T))), size) + #define NazaraStackAllocationNoInit(T, size) Nz::StackArray(static_cast(NAZARA_ALLOCA((size) * sizeof(T))), size, Nz::NoInitTag()) #else - #define NazaraStackAllocation(size) Nz::StackAllocation(Nz::OperatorNew(size)) + #define NazaraStackAllocation(T, size) Nz::StackArray(static_cast(Nz::OperatorNew((size) * sizeof(T))), size) + #define NazaraStackAllocationNoInit(T, size) Nz::StackArray(static_cast(Nz::OperatorNew((size) * sizeof(T))), size, Nz::NoInitTag()) #endif #include +#include namespace Nz { @@ -41,19 +44,70 @@ namespace Nz template void PlacementDestroy(T* ptr); - class StackAllocation + struct NoInitTag {}; + + template + class StackArray { public: - explicit StackAllocation(void* stackMemory); - ~StackAllocation(); + using value_type = T; + using const_iterator = const value_type*; + using const_pointer = const value_type*; + using const_reference = const value_type&; + using const_reverse_iterator = std::reverse_iterator; + using difference_type = std::ptrdiff_t; + using iterator = value_type*; + using pointer = value_type*; + using reference = value_type&; + using reverse_iterator = std::reverse_iterator; + using size_type = std::size_t; - void* GetPtr(); + StackArray(T* stackMemory, std::size_t size); + StackArray(T* stackMemory, std::size_t size, NoInitTag); + ~StackArray(); - operator void*(); + reference back(); + const_reference back() const; + + iterator begin() noexcept; + const_iterator begin() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + T* data() noexcept; + const T* data() const noexcept; + + bool empty() const noexcept; + + iterator end() noexcept; + const_iterator end() const noexcept; + + void fill(const T& value); + + reference front() noexcept; + const_reference front() const noexcept; + + size_type max_size() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + size_type size() const noexcept; + + reference operator[](size_type pos); + const_reference operator[](size_type pos) const; private: - void* m_ptr; + std::size_t m_size; + T* m_ptr; }; + } #include diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl index dcee8ca4e..c2233bac1 100644 --- a/include/Nazara/Core/MemoryHelper.inl +++ b/include/Nazara/Core/MemoryHelper.inl @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include #include @@ -77,48 +79,184 @@ namespace Nz /*! * \ingroup core - * \class Nz::StackAllocation - * \brief Core class that represents a stack allocation + * \class Nz::StackArray + * \brief Core class that represents a stack-allocated (if alloca is present) array */ + template + StackArray::StackArray(T* stackMemory, std::size_t size) : + m_size(size), + m_ptr(stackMemory) + { + for (std::size_t i = 0; i < m_size; ++i) + PlacementNew(&m_ptr[i]); + } - /*! - * \brief Constructs a StackAllocation object with a pointer to a memory allocated with NAZARA_ALLOCA or OperatorNew is alloca is not supported - * - * \param ptr Pointer to raw memory - */ - inline StackAllocation::StackAllocation(void* stackMemory) : + template + StackArray::StackArray(T* stackMemory, std::size_t size, NoInitTag) : + m_size(size), m_ptr(stackMemory) { } - /*! - * \brief Destructs the object and release memory if necessary - */ - inline StackAllocation::~StackAllocation() + template + StackArray::~StackArray() { + for (std::size_t i = 0; i < m_size; ++i) + m_ptr[i].~T(); + #ifndef NAZARA_ALLOCA_SUPPORT OperatorDelete(m_ptr); #endif } - /*! - * \brief Access the internal pointer - * \return internal memory pointer - */ - inline void* StackAllocation::GetPtr() + template + typename StackArray::reference StackArray::back() + { + assert(m_size != 0); + return m_ptr[m_size - 1]; + } + + template + typename StackArray::const_reference StackArray::back() const + { + assert(m_size != 0); + return m_ptr[m_size - 1]; + } + + template + typename StackArray::iterator StackArray::begin() noexcept + { + return iterator(&m_ptr[0]); + } + + template + typename StackArray::const_iterator StackArray::begin() const noexcept + { + return const_iterator(&m_ptr[0]); + } + + template + typename StackArray::const_iterator StackArray::cbegin() const noexcept + { + return const_iterator(&m_ptr[0]); + } + + template + typename StackArray::const_iterator StackArray::cend() const noexcept + { + return const_iterator(&m_ptr[m_size]); + } + + template + typename StackArray::const_reverse_iterator StackArray::crbegin() const noexcept + { + return const_reverse_iterator(&m_ptr[m_size]); + } + + template + typename StackArray::const_reverse_iterator StackArray::crend() const noexcept + { + return const_reverse_iterator(&m_ptr[0]); + } + + template + T* StackArray::data() noexcept { return m_ptr; } - /*! - * \brief Access the internal pointer - * \return internal memory pointer - */ - inline StackAllocation::operator void*() + template + const T* StackArray::data() const noexcept { return m_ptr; } + + template + bool StackArray::empty() const noexcept + { + return m_size == 0; + } + + template + typename StackArray::iterator StackArray::end() noexcept + { + return iterator(&m_ptr[m_size]); + } + + template + typename StackArray::const_iterator StackArray::end() const noexcept + { + return const_iterator(&m_ptr[m_size]); + } + + template + void StackArray::fill(const T& value) + { + std::fill(begin(), end(), value); + } + + template + typename StackArray::reference StackArray::front() noexcept + { + return m_ptr[0]; + } + + template + typename StackArray::const_reference StackArray::front() const noexcept + { + return m_ptr[0]; + } + + template + typename StackArray::size_type StackArray::max_size() const noexcept + { + return size(); + } + + template + typename StackArray::reverse_iterator StackArray::rbegin() noexcept + { + return reverse_iterator(&m_ptr[m_size]); + } + + template + typename StackArray::const_reverse_iterator StackArray::rbegin() const noexcept + { + return reverse_iterator(&m_ptr[m_size]); + } + + template + typename StackArray::reverse_iterator StackArray::rend() noexcept + { + return reverse_iterator(&m_ptr[0]); + } + + template + typename StackArray::const_reverse_iterator StackArray::rend() const noexcept + { + return reverse_iterator(&m_ptr[0]); + } + + template + typename StackArray::size_type StackArray::size() const noexcept + { + return m_size; + } + + template + typename StackArray::reference StackArray::operator[](size_type pos) + { + assert(pos < m_size); + return m_ptr[pos]; + } + + template + typename StackArray::const_reference StackArray::operator[](size_type pos) const + { + assert(pos < m_size); + return m_ptr[pos]; + } } #include diff --git a/include/Nazara/Core/MemoryManager.hpp b/include/Nazara/Core/MemoryManager.hpp index caed09b61..22c59de2d 100644 --- a/include/Nazara/Core/MemoryManager.hpp +++ b/include/Nazara/Core/MemoryManager.hpp @@ -8,8 +8,7 @@ #define NAZARA_MEMORYMANAGER_HPP #include -#include -#include +#include namespace Nz { diff --git a/include/Nazara/Core/MovablePtr.hpp b/include/Nazara/Core/MovablePtr.hpp new file mode 100644 index 000000000..f27e365e6 --- /dev/null +++ b/include/Nazara/Core/MovablePtr.hpp @@ -0,0 +1,38 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_MOVABLE_PTR_HPP +#define NAZARA_MOVABLE_PTR_HPP + +namespace Nz +{ + template + class MovablePtr + { + public: + MovablePtr(T* value = nullptr); + MovablePtr(const MovablePtr&) = default; + MovablePtr(MovablePtr&& ptr) noexcept; + ~MovablePtr() = default; + + T* Get() const; + + T* operator->() const; + + operator T*() const; + + MovablePtr& operator=(T* value); + MovablePtr& operator=(const MovablePtr&) = default; + MovablePtr& operator=(MovablePtr&& ptr) noexcept; + + private: + T* m_value; + }; +} + +#include + +#endif // NAZARA_MOVABLE_PTR_HPP diff --git a/include/Nazara/Core/MovablePtr.inl b/include/Nazara/Core/MovablePtr.inl new file mode 100644 index 000000000..80d342e4a --- /dev/null +++ b/include/Nazara/Core/MovablePtr.inl @@ -0,0 +1,61 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + /*! + * \ingroup core + * \class Nz::MovablePtr + * \brief Wraps a raw (non-proprietary) to allows it to be moved implicitly + */ + + template + MovablePtr::MovablePtr(T* value) : + m_value(value) + { + } + + template + MovablePtr::MovablePtr(MovablePtr&& ptr) noexcept : + m_value(ptr.m_value) + { + ptr.m_value = nullptr; + } + + template + inline T* MovablePtr::Get() const + { + return m_value; + } + + template + T* MovablePtr::operator->() const + { + return m_value; + } + + template + MovablePtr::operator T*() const + { + return m_value; + } + + template + inline MovablePtr& MovablePtr::operator=(T* value) + { + m_value = value; + + return *this; + } + + template + MovablePtr& MovablePtr::operator=(MovablePtr&& ptr) noexcept + { + std::swap(m_value, ptr.m_value); + return *this; + } +} diff --git a/include/Nazara/Core/Mutex.hpp b/include/Nazara/Core/Mutex.hpp index 303b163f1..b317cf58b 100644 --- a/include/Nazara/Core/Mutex.hpp +++ b/include/Nazara/Core/Mutex.hpp @@ -8,6 +8,7 @@ #define NAZARA_MUTEX_HPP #include +#include namespace Nz { @@ -20,7 +21,7 @@ namespace Nz public: Mutex(); Mutex(const Mutex&) = delete; - inline Mutex(Mutex&& mutex) noexcept; + Mutex(Mutex&&) noexcept = default; ~Mutex(); void Lock(); @@ -28,10 +29,10 @@ namespace Nz void Unlock(); Mutex& operator=(const Mutex&) = delete; - Mutex& operator=(Mutex&& mutex) noexcept; + Mutex& operator=(Mutex&&) noexcept = default; private: - MutexImpl* m_impl; + MovablePtr m_impl; }; } diff --git a/include/Nazara/Core/Mutex.inl b/include/Nazara/Core/Mutex.inl index 9e79fff02..ca9e5ec2f 100644 --- a/include/Nazara/Core/Mutex.inl +++ b/include/Nazara/Core/Mutex.inl @@ -12,15 +12,6 @@ namespace Nz * \ingroup core * \class Nz::Mutex */ - - /*! - * \brief Constructs a Mutex object by moving another one - */ - inline Mutex::Mutex(Mutex&& mutex) noexcept : - m_impl(mutex.m_impl) - { - mutex.m_impl = nullptr; - } } #include diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index c3e783186..b4d89531c 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -484,16 +484,17 @@ namespace Nz namespace std { - /*! - * \ingroup core - * \brief Gives a hash representation of the object, specialisation of std - * \return Hash of the ObjectRef - * - * \param object Object to hash - */ template struct hash> { + /*! + * \ingroup core + * \brief Gives a hash representation of the object, specialisation of std + * \return Hash of the ObjectRef + * + * \param object Object to hash + */ + size_t operator()(const Nz::ObjectRef& object) const { hash h; diff --git a/include/Nazara/Core/ParameterList.inl b/include/Nazara/Core/ParameterList.inl index b1983b49b..029d3d4f3 100644 --- a/include/Nazara/Core/ParameterList.inl +++ b/include/Nazara/Core/ParameterList.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include namespace Nz diff --git a/include/Nazara/Core/Primitive.inl b/include/Nazara/Core/Primitive.inl index fff7f82bb..24d14e8f7 100644 --- a/include/Nazara/Core/Primitive.inl +++ b/include/Nazara/Core/Primitive.inl @@ -385,7 +385,7 @@ namespace Nz * * \param size (Width, Depth) * \param subdivision Number of subdivision for the axis - * \param planeInfo Information for the plane + * \param plane Information for the plane * \param uvCoords Coordinates for texture */ inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Planef& plane, const Rectf& uvCoords) diff --git a/include/Nazara/Core/RefCounted.hpp b/include/Nazara/Core/RefCounted.hpp index 7a2f8c7fc..472c8a2fa 100644 --- a/include/Nazara/Core/RefCounted.hpp +++ b/include/Nazara/Core/RefCounted.hpp @@ -9,7 +9,6 @@ #include #include -#include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_REFCOUNTED #include diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index 2322b25c1..aea1e4d6c 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -17,7 +17,7 @@ namespace Nz public: Resource() = default; Resource(const Resource&) = default; - Resource(Resource&&) = default; + Resource(Resource&&) noexcept = default; virtual ~Resource(); const String& GetFilePath() const; @@ -25,7 +25,7 @@ namespace Nz void SetFilePath(const String& filePath); Resource& operator=(const Resource&) = default; - Resource& operator=(Resource&&) = default; + Resource& operator=(Resource&&) noexcept = default; private: String m_filePath; diff --git a/include/Nazara/Core/Semaphore.hpp b/include/Nazara/Core/Semaphore.hpp index 8c18cf6f4..985b49ba6 100644 --- a/include/Nazara/Core/Semaphore.hpp +++ b/include/Nazara/Core/Semaphore.hpp @@ -8,6 +8,7 @@ #define NAZARA_SEMAPHORE_HPP #include +#include namespace Nz { @@ -18,7 +19,7 @@ namespace Nz public: Semaphore(unsigned int count); Semaphore(const Semaphore&) = delete; - Semaphore(Semaphore&&) = delete; ///TODO + Semaphore(Semaphore&&) noexcept = default; ~Semaphore(); unsigned int GetCount() const; @@ -29,10 +30,10 @@ namespace Nz bool Wait(UInt32 timeout); Semaphore& operator=(const Semaphore&) = delete; - Semaphore& operator=(Semaphore&&) = delete; ///TODO + Semaphore& operator=(Semaphore&&) noexcept = default; private: - SemaphoreImpl* m_impl; + MovablePtr m_impl; }; } diff --git a/include/Nazara/Core/SerializationContext.hpp b/include/Nazara/Core/SerializationContext.hpp index cf5d83223..7839c484a 100644 --- a/include/Nazara/Core/SerializationContext.hpp +++ b/include/Nazara/Core/SerializationContext.hpp @@ -10,9 +10,6 @@ #include #include #include -#include -#include -#include namespace Nz { diff --git a/include/Nazara/Core/SerializationContext.inl b/include/Nazara/Core/SerializationContext.inl index 5edd4e618..870972655 100644 --- a/include/Nazara/Core/SerializationContext.inl +++ b/include/Nazara/Core/SerializationContext.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include namespace Nz diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 10e76c9c3..b90067bc2 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -25,6 +25,7 @@ namespace Nz SparsePtr(); SparsePtr(T* ptr); SparsePtr(VoidPtr ptr, int stride); + SparsePtr(VoidPtr ptr, std::size_t stride); template SparsePtr(const SparsePtr& ptr); SparsePtr(const SparsePtr& ptr) = default; ~SparsePtr() = default; diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index db8fb6b33..a5c9d6212 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -2,7 +2,10 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include +#include #include +#include #include namespace Nz @@ -48,6 +51,22 @@ namespace Nz Reset(ptr, stride); } + /*! + * \brief Constructs a SparsePtr object with a pointer and a step + * + * \param ptr Pointer to data + * \param stride Step between two elements + * + * \remark This constructor only exists because std::size_t is a frequent type for constructing this object, but stride may not be higher than int max + */ + + template + SparsePtr::SparsePtr(VoidPtr ptr, std::size_t stride) + { + assert(stride <= std::numeric_limits::max()); + Reset(ptr, static_cast(stride)); + } + /*! * \brief Constructs a SparsePtr object from another type of SparsePtr * diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index abd97c051..5fb3186d6 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include "Stream.hpp" namespace Nz { diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 30f88de00..918230d29 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -9,8 +9,6 @@ #include #include -#include -#include #include #include #include @@ -19,6 +17,8 @@ namespace Nz { + struct SerializationContext; + class NAZARA_CORE_API String { public: @@ -41,7 +41,7 @@ namespace Nz String(const char* string, std::size_t length); String(const std::string& string); String(const String& string) = default; - String(String&& string) noexcept = default; + inline String(String&& string) noexcept; ~String() = default; String& Append(char character); diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index 027ab4349..57c781f9e 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -7,12 +7,11 @@ namespace Nz { - /*! - * \ingroup core - * \brief Constructs a String object with a shared string by move semantic - * - * \param sharedString Shared string to move into this - */ + inline Nz::String::String(String&& string) noexcept : + m_sharedString(std::move(string.m_sharedString)) + { + string.m_sharedString = GetEmptyString(); + } inline String::String(std::shared_ptr&& sharedString) : m_sharedString(std::move(sharedString)) @@ -121,7 +120,7 @@ namespace std const char* ptr = str.GetConstBuffer(); do - h = ((h << 5) + h) + *ptr; + h = ((h << 5) + h) + static_cast(*ptr); while (*++ptr); } diff --git a/include/Nazara/Core/StringStream.hpp b/include/Nazara/Core/StringStream.hpp index 6898e5b6a..baabda3b0 100644 --- a/include/Nazara/Core/StringStream.hpp +++ b/include/Nazara/Core/StringStream.hpp @@ -17,8 +17,8 @@ namespace Nz class NAZARA_CORE_API StringStream { public: - StringStream(); - StringStream(const String& str); + StringStream() = default; + StringStream(String str); StringStream(const StringStream&) = default; StringStream(StringStream&&) noexcept = default; @@ -53,8 +53,7 @@ namespace Nz operator String() const; private: - std::vector m_strings; - std::size_t m_bufferSize; + String m_result; }; } diff --git a/include/Nazara/Core/Thread.hpp b/include/Nazara/Core/Thread.hpp index e129cbe40..c622fd309 100644 --- a/include/Nazara/Core/Thread.hpp +++ b/include/Nazara/Core/Thread.hpp @@ -9,10 +9,12 @@ #include #include +#include #include namespace Nz { + class String; class ThreadImpl; class NAZARA_CORE_API Thread @@ -25,7 +27,7 @@ namespace Nz template Thread(F function, Args&&... args); template Thread(void (C::*function)(), C* object); Thread(const Thread&) = delete; - Thread(Thread&& other) noexcept; + Thread(Thread&& other) noexcept = default; ~Thread(); void Detach(); @@ -35,7 +37,7 @@ namespace Nz void SetName(const String& name); Thread& operator=(const Thread&) = delete; - Thread& operator=(Thread&& thread); + Thread& operator=(Thread&& thread) noexcept = default; static unsigned int HardwareConcurrency(); static void SetCurrentThreadName(const String& name); @@ -44,7 +46,7 @@ namespace Nz private: void CreateImpl(Functor* functor); - ThreadImpl* m_impl; + MovablePtr m_impl; }; class NAZARA_CORE_API Thread::Id diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index 0e3b94f2f..173ea0142 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include namespace Nz @@ -23,6 +21,7 @@ namespace Nz class Material; class Texture; struct MeshData; + struct VertexStruct_XYZ_Color_UV; class NAZARA_GRAPHICS_API AbstractRenderQueue { diff --git a/include/Nazara/Graphics/AbstractRenderTechnique.hpp b/include/Nazara/Graphics/AbstractRenderTechnique.hpp index 4279a5f39..7dba6273c 100644 --- a/include/Nazara/Graphics/AbstractRenderTechnique.hpp +++ b/include/Nazara/Graphics/AbstractRenderTechnique.hpp @@ -8,16 +8,13 @@ #define NAZARA_ABSTRACTRENDERTECHNIQUE_HPP #include -#include #include -#include +#include #include -#include namespace Nz { - class AbstractViewer; - class Background; + class AbstractRenderQueue; struct SceneData; class NAZARA_GRAPHICS_API AbstractRenderTechnique diff --git a/include/Nazara/Graphics/Billboard.hpp b/include/Nazara/Graphics/Billboard.hpp index c82a5d2bf..d4c5b6bd8 100644 --- a/include/Nazara/Graphics/Billboard.hpp +++ b/include/Nazara/Graphics/Billboard.hpp @@ -32,17 +32,18 @@ namespace Nz void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; inline const Color& GetColor() const; - inline const MaterialRef& GetMaterial() const; inline float GetRotation() const; inline const Vector2f& GetSize() const; inline void SetColor(const Color& color); inline void SetDefaultMaterial(); inline void SetMaterial(MaterialRef material, bool resizeBillboard = true); + inline void SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeBillboard = true); inline void SetRotation(float rotation); inline void SetSize(const Vector2f& size); inline void SetSize(float sizeX, float sizeY); inline void SetTexture(TextureRef texture, bool resizeBillboard = true); + inline void SetTexture(std::size_t skinIndex, TextureRef texture, bool resizeBillboard = true); inline Billboard& operator=(const Billboard& billboard); Billboard& operator=(Billboard&&) = delete; @@ -53,7 +54,6 @@ namespace Nz void MakeBoundingVolume() const override; Color m_color; - MaterialRef m_material; Vector2f m_sinCos; Vector2f m_size; float m_rotation; diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index 137524e95..6bbf9b143 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include @@ -13,6 +14,8 @@ namespace Nz inline Billboard::Billboard() { + ResetMaterials(1); + SetColor(Color::White); SetDefaultMaterial(); SetRotation(0.f); @@ -27,6 +30,8 @@ namespace Nz inline Billboard::Billboard(MaterialRef material) { + ResetMaterials(1); + SetColor(Color::White); SetMaterial(std::move(material), true); SetRotation(0.f); @@ -41,6 +46,8 @@ namespace Nz inline Billboard::Billboard(Texture* texture) { + ResetMaterials(1); + SetColor(Color::White); SetRotation(0.f); SetSize(64.f, 64.f); @@ -56,7 +63,6 @@ namespace Nz inline Billboard::Billboard(const Billboard& billboard) : InstancedRenderable(billboard), m_color(billboard.m_color), - m_material(billboard.m_material), m_sinCos(billboard.m_sinCos), m_size(billboard.m_size), m_rotation(billboard.m_rotation) @@ -73,16 +79,6 @@ namespace Nz return m_color; } - /*! - * \brief Gets the material of the billboard - * \return Current material - */ - - inline const MaterialRef& Billboard::GetMaterial() const - { - return m_material; - } - /*! * \brief Gets the rotation of the billboard * \return Current rotation @@ -132,15 +128,30 @@ namespace Nz * \param material Material for the billboard * \param resizeBillboard Should billboard be resized to the material size (diffuse map) */ - inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard) { - m_material = std::move(material); - if (m_material && resizeBillboard) + SetMaterial(GetSkin(), std::move(material), resizeBillboard); + } + + /*! + * \brief Sets the material of the billboard + * + * \param skinIndex Skin index to change + * \param material Material for the billboard + * \param resizeBillboard Should billboard be resized to the material size (diffuse map) + */ + inline void Billboard::SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeBillboard) + { + InstancedRenderable::SetMaterial(skinIndex, 0, std::move(material)); + + if (resizeBillboard) { - Texture* diffuseMap = m_material->GetDiffuseMap(); - if (diffuseMap && diffuseMap->IsValid()) - SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + if (const MaterialRef& newMat = GetMaterial()) + { + const TextureRef& diffuseMap = newMat->GetDiffuseMap(); + if (diffuseMap && diffuseMap->IsValid()) + SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + } } } @@ -188,18 +199,36 @@ namespace Nz * \param texture Texture for the billboard * \param resizeBillboard Should billboard be resized to the texture size */ - inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard) { - if (!m_material) - SetDefaultMaterial(); - else if (m_material->GetReferenceCount() > 1) - m_material = Material::New(*m_material); // Copie + SetTexture(GetSkin(), std::move(texture), resizeBillboard); + } + /*! + * \brief Sets the texture of the billboard for a specific index + * + * This function changes the diffuse map of the material associated with the specified skin index + * + * \param skinIndex Skin index to change + * \param texture Texture for the billboard + * \param resizeBillboard Should billboard be resized to the texture size + */ + inline void Billboard::SetTexture(std::size_t skinIndex, TextureRef texture, bool resizeBillboard) + { if (resizeBillboard && texture && texture->IsValid()) SetSize(Vector2f(Vector2ui(texture->GetSize()))); - m_material->SetDiffuseMap(std::move(texture)); + const MaterialRef& material = GetMaterial(skinIndex); + + if (material->GetReferenceCount() > 1) + { + MaterialRef newMat = Material::New(*material); // Copy + newMat->SetDiffuseMap(std::move(texture)); + + SetMaterial(skinIndex, std::move(newMat)); + } + else + material->SetDiffuseMap(std::move(texture)); } /*! @@ -214,7 +243,6 @@ namespace Nz InstancedRenderable::operator=(billboard); m_color = billboard.m_color; - m_material = billboard.m_material; m_size = billboard.m_size; InvalidateBoundingVolume(); diff --git a/include/Nazara/Graphics/ConfigCheck.hpp b/include/Nazara/Graphics/ConfigCheck.hpp index 3ec60640d..8aa8164db 100644 --- a/include/Nazara/Graphics/ConfigCheck.hpp +++ b/include/Nazara/Graphics/ConfigCheck.hpp @@ -12,7 +12,7 @@ #include #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) -// We fore the value of MANAGE_MEMORY in debug +// We force the value of MANAGE_MEMORY in debug #if defined(NAZARA_DEBUG) && !NAZARA_GRAPHICS_MANAGE_MEMORY #undef NAZARA_GRAPHICS_MANAGE_MEMORY #define NAZARA_GRAPHICS_MANAGE_MEMORY 0 diff --git a/include/Nazara/Graphics/DeferredRenderPass.hpp b/include/Nazara/Graphics/DeferredRenderPass.hpp index 784ad3c29..77dff072e 100644 --- a/include/Nazara/Graphics/DeferredRenderPass.hpp +++ b/include/Nazara/Graphics/DeferredRenderPass.hpp @@ -9,18 +9,14 @@ #include #include -#include -#include #include namespace Nz { - class AbstractViewer; class DeferredRenderTechnique; class DeferredRenderQueue; - class RenderBuffer; + struct SceneData; class RenderTexture; - class Scene; class Texture; class NAZARA_GRAPHICS_API DeferredRenderPass diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 5f9f7538e..c6ffcacac 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -8,7 +8,6 @@ #define NAZARA_DEFERREDRENDERQUEUE_HPP #include -#include #include #include #include @@ -17,7 +16,6 @@ #include #include #include -#include namespace Nz { diff --git a/include/Nazara/Graphics/DeferredRenderTechnique.hpp b/include/Nazara/Graphics/DeferredRenderTechnique.hpp index bdac459e9..025fb1e52 100644 --- a/include/Nazara/Graphics/DeferredRenderTechnique.hpp +++ b/include/Nazara/Graphics/DeferredRenderTechnique.hpp @@ -9,21 +9,18 @@ #include #include -#include #include #include #include -#include -#include #include #include -#include -#include #include #include namespace Nz { + class DeferredRenderPass; + class NAZARA_GRAPHICS_API DeferredRenderTechnique : public AbstractRenderTechnique { friend class Graphics; diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp index 871cefa66..8de0a2bf2 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.hpp +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -8,15 +8,9 @@ #define NAZARA_DEPTHRENDERQUEUE_HPP #include -#include -#include #include #include #include -#include -#include -#include -#include namespace Nz { diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index d28b8a5c4..cc3b7bcd8 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 68a8ed95e..83f46dc22 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -122,6 +122,15 @@ namespace Nz RenderTechniqueType_Max = RenderTechniqueType_User }; + enum ReflectionMode + { + ReflectionMode_RealTime, + ReflectionMode_Probe, + ReflectionMode_Skybox, + + ReflectionMode_Max = ReflectionMode_Skybox + }; + enum SceneNodeType { SceneNodeType_Light, // Light diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index bc5c2456e..a51e617c3 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -18,7 +18,6 @@ #include #include #include -#include namespace Nz { diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index cadb60473..208b24ea0 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -77,6 +77,7 @@ namespace Nz // Other uniforms int eyePosition; + int reflectionMap; int sceneAmbient; int textureOverlay; }; @@ -91,6 +92,8 @@ namespace Nz unsigned int m_maxLightPassPerObject; static IndexBuffer s_quadIndexBuffer; + static Texture s_dummyReflection; + static TextureSampler s_reflectionSampler; static TextureSampler s_shadowSampler; static VertexBuffer s_quadVertexBuffer; static VertexDeclaration s_billboardInstanceDeclaration; diff --git a/include/Nazara/Graphics/Graphics.hpp b/include/Nazara/Graphics/Graphics.hpp index 499837466..f8687b80e 100644 --- a/include/Nazara/Graphics/Graphics.hpp +++ b/include/Nazara/Graphics/Graphics.hpp @@ -8,7 +8,6 @@ #define NAZARA_GRAPHICS_HPP #include -#include #include namespace Nz diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index 1f7ec8314..56e7bc0a1 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -7,13 +7,13 @@ #ifndef NAZARA_INSTANCEDRENDERABLE_HPP #define NAZARA_INSTANCEDRENDERABLE_HPP -#include #include #include #include #include #include #include +#include #include #include #include @@ -44,7 +44,18 @@ namespace Nz inline void EnsureBoundingVolumeUpdated() const; virtual const BoundingVolumef& GetBoundingVolume() const; + + inline const MaterialRef& GetMaterial(std::size_t matIndex = 0) const; + inline const MaterialRef& GetMaterial(std::size_t skinIndex, std::size_t matIndex) const; + inline std::size_t GetMaterialCount() const; + inline std::size_t GetSkin() const; + inline std::size_t GetSkinCount() const; + virtual void InvalidateData(InstanceData* instanceData, UInt32 flags) const; + + inline void SetSkin(std::size_t skinIndex); + inline void SetSkinCount(std::size_t skinCount); + virtual void UpdateBoundingVolume(InstanceData* instanceData) const; virtual void UpdateData(InstanceData* instanceData) const; @@ -54,7 +65,10 @@ namespace Nz // Signals: NazaraSignal(OnInstancedRenderableInvalidateBoundingVolume, const InstancedRenderable* /*instancedRenderable*/); NazaraSignal(OnInstancedRenderableInvalidateData, const InstancedRenderable* /*instancedRenderable*/, UInt32 /*flags*/); + NazaraSignal(OnInstancedRenderableInvalidateMaterial, const InstancedRenderable* /*instancedRenderable*/, std::size_t /*skinIndex*/, std::size_t /*matIndex*/, const MaterialRef& /*newMat*/); NazaraSignal(OnInstancedRenderableRelease, const InstancedRenderable* /*instancedRenderable*/); + NazaraSignal(OnInstancedRenderableResetMaterials, const InstancedRenderable* /*instancedRenderable*/, std::size_t /*newMaterialCount*/); + NazaraSignal(OnInstancedRenderableSkinChange, const InstancedRenderable* /*instancedRenderable*/, std::size_t /*newSkinIndex*/); struct InstanceData { @@ -89,14 +103,23 @@ namespace Nz protected: inline void InvalidateBoundingVolume(); inline void InvalidateInstanceData(UInt32 flags); - + virtual void MakeBoundingVolume() const = 0; + inline void ResetMaterials(std::size_t matCount, std::size_t skinCount = 1); + + inline void SetMaterial(std::size_t matIndex, MaterialRef material); + inline void SetMaterial(std::size_t skinIndex, std::size_t matIndex, MaterialRef material); + mutable BoundingVolumef m_boundingVolume; private: inline void UpdateBoundingVolume() const; - + + std::size_t m_matCount; + std::size_t m_skin; + std::size_t m_skinCount; + std::vector m_materials; mutable bool m_boundingVolumeUpdated; static InstancedRenderableLibrary::LibraryMap s_library; diff --git a/include/Nazara/Graphics/InstancedRenderable.inl b/include/Nazara/Graphics/InstancedRenderable.inl index 47e47eac1..c2a8f1b70 100644 --- a/include/Nazara/Graphics/InstancedRenderable.inl +++ b/include/Nazara/Graphics/InstancedRenderable.inl @@ -2,6 +2,9 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include +#include + namespace Nz { /*! @@ -20,6 +23,10 @@ namespace Nz inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) : RefCounted(), m_boundingVolume(renderable.m_boundingVolume), + m_matCount(renderable.m_matCount), + m_skin(renderable.m_skin), + m_skinCount(renderable.m_skinCount), + m_materials(renderable.m_materials), m_boundingVolumeUpdated(renderable.m_boundingVolumeUpdated) { } @@ -34,6 +41,116 @@ namespace Nz UpdateBoundingVolume(); } + /*! + * \brief Gets one of the material used by the object. + * \return A reference to the material. + * + * This function returns the active material at the specified index, depending on the current active skin. + * + * \param matIndex Material index to query + * + * \see GetSkin, GetMaterialCount, SetSkin + */ + inline const MaterialRef& InstancedRenderable::GetMaterial(std::size_t matIndex) const + { + return GetMaterial(m_skin, matIndex); + } + + /*! + * \brief Gets one of the material used by the object, independently from the active skin. + * \return A reference to the material. + * + * This function returns the active material at the specified index and the specified skin index. + * This function is the only way to query a material independently from the active skin. + * + * \param skinIndex Skin index to query + * \param matIndex Material index to query + * + * \see GetSkinCount, GetMaterialCount, SetSkin + */ + inline const MaterialRef& InstancedRenderable::GetMaterial(std::size_t skinIndex, std::size_t matIndex) const + { + NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds"); + NazaraAssert(matIndex < m_materials.size(), "Material index out of bounds"); + + return m_materials[m_matCount * skinIndex + matIndex]; + } + + /*! + * \brief Gets the number of material per skin. + * \return The current material count per skin + * + * This function returns how many different materials entries exists per skin + * and is independent from the number of skin. + */ + inline std::size_t InstancedRenderable::GetMaterialCount() const + { + return m_matCount; + } + + /*! + * \brief Gets the current active skin index + * \return Current skin index + * + * \see SetSkin + */ + inline std::size_t InstancedRenderable::GetSkin() const + { + return m_skin; + } + + /*! + * \brief Gets the number of skins this object has + * \return Skin count + * + * \see GetSkin, SetSkinCount + */ + inline std::size_t InstancedRenderable::GetSkinCount() const + { + return m_skinCount; + } + + /*! + * \brief Changes the active skin + * + * Each InstancedRenderable has the possibility to have multiples skins, which are sets of materials. + * Using this function allows you to have an object reference multiple materials, while using only some of thems (depending on the type of the object, see GetMaterialCount). + * + * \param skinIndex Skin index to change to + * + * \see SetSkinCount + */ + inline void InstancedRenderable::SetSkin(std::size_t skinIndex) + { + NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds"); + + if (m_skin != skinIndex) + { + OnInstancedRenderableSkinChange(this, skinIndex); + + m_skin = skinIndex; + + // Force render queue invalidation + InvalidateInstanceData(0); + } + } + + /*! + * \brief Changes the maximum skin count of the object + * + * This functions allows the object to store up to skinCount skins, which can then be switched to using SetSkin. + * Please note that the possibly new skins will be set to the default material, which should not be changed. + * + * \param skinCount Skin index to change to + * + * \see SetSkin + */ + inline void InstancedRenderable::SetSkinCount(std::size_t skinCount) + { + m_materials.resize(m_matCount * skinCount, Material::GetDefault()); + m_skinCount = skinCount; + } + /*! * \brief Invalidates the bounding volume */ @@ -56,6 +173,79 @@ namespace Nz OnInstancedRenderableInvalidateData(this, flags); } + /*! + * \brief Resets the materials, material count and skin count + * + * This function clears the materials in use by the InstancedRenderable and resets its material count per skin along with its skin count. + * This is the only way of setting the material count per skin and should be called at least by the constructor of the derived class. + * Please note that all materials will be set to the default material, which should not be changed. + * + * This function also resets the current skin to the first one. + * + * \param matCount The new material count per skin value, must be at least 1 + * \param skinCount The new skin count value + * + * \see GetMaterial, GetMaterialCount, GetSkinCount, SetSkinCount + */ + inline void InstancedRenderable::ResetMaterials(std::size_t matCount, std::size_t skinCount) + { + NazaraAssert(skinCount != 0, "Invalid skin count (cannot be zero)"); + + OnInstancedRenderableResetMaterials(this, matCount); + + m_materials.clear(); + m_materials.resize(matCount * skinCount, Material::GetDefault()); + + m_matCount = matCount; + m_skinCount = skinCount; + m_skin = 0; + } + + /*! + * \brief Changes the material used at the specified index by another one + * + * This function changes the active material at the specified index, depending on the current active skin, to the one passed as parameter. + * + * \param matIndex Material index + * \param material New material, cannot be null + * + * \remark If you wish to reset the material to the default one, use the default material (see Material::GetDefault) + * + * \see SetMaterial + */ + inline void InstancedRenderable::SetMaterial(std::size_t matIndex, MaterialRef material) + { + SetMaterial(m_skin, matIndex, std::move(material)); + } + + /*! + * \brief Changes the material used at the specified index by another one, independently from the active skin. + * + * This function changes the active material at the specified index and for the specified skin index, to the one passed as parameter. + * + * \param skinIndex Skin index + * \param matIndex Material index + * \param material New material, cannot be null + * + * \remark If you wish to reset the material to the default one, use the default material (see Material::GetDefault) + * + * \see SetMaterial + */ + inline void InstancedRenderable::SetMaterial(std::size_t skinIndex, std::size_t matIndex, MaterialRef material) + { + NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds"); + NazaraAssert(matIndex < m_materials.size(), "Material index out of bounds"); + NazaraAssert(material.IsValid(), "Material must be valid"); + + MaterialRef& matEntry = m_materials[m_matCount * skinIndex + matIndex]; + if (matEntry != material) + { + OnInstancedRenderableInvalidateMaterial(this, skinIndex, matIndex, material); + + matEntry = std::move(material); + } + } + /*! * \brief Sets the current instanced renderable with the content of the other one * \return A reference to this @@ -67,6 +257,10 @@ namespace Nz { m_boundingVolume = renderable.m_boundingVolume; m_boundingVolumeUpdated = renderable.m_boundingVolumeUpdated; + m_matCount = renderable.m_matCount; + m_materials = renderable.m_materials; + m_skin = renderable.m_skin; + m_skinCount = renderable.m_skinCount; return *this; } @@ -82,3 +276,5 @@ namespace Nz m_boundingVolumeUpdated = true; } } + +#include diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 8574bb783..77274b6ca 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -11,14 +11,10 @@ #include #include #include -#include #include namespace Nz { - class Light; - struct LightUniforms; - class NAZARA_GRAPHICS_API Light : public Renderable { public: diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index b30daaf60..f76bbe841 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include namespace Nz @@ -265,7 +265,8 @@ namespace Nz /*! * \brief Sets the inner angle in spot light - * \return innerAngle Inner angle + * + * \param innerAngle Inner angle */ inline void Light::SetInnerAngle(float innerAngle) @@ -289,7 +290,8 @@ namespace Nz /*! * \brief Sets the outer angle in spot light - * \return outerAngle Outer angle + * + * \param outerAngle Outer angle * * \remark Invalidates the bounding volume */ @@ -305,7 +307,8 @@ namespace Nz /*! * \brief Sets the radius of the light - * \return radius Light radius + * + * \param radius Light radius * * \remark Invalidates the bounding volume */ diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index bf14b1792..77b57c87e 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -24,7 +24,6 @@ #include #include #include -#include namespace Nz { @@ -79,6 +78,7 @@ namespace Nz inline void EnableDepthSorting(bool depthSorting); inline void EnableDepthWrite(bool depthWrite); inline void EnableFaceCulling(bool faceCulling); + inline void EnableReflectionMapping(bool reflection); inline void EnableScissorTest(bool scissorTest); inline void EnableShadowCasting(bool castShadows); inline void EnableShadowReceive(bool receiveShadows); @@ -105,6 +105,7 @@ namespace Nz inline const MaterialPipeline* GetPipeline() const; inline const MaterialPipelineInfo& GetPipelineInfo() const; inline float GetPointSize() const; + inline ReflectionMode GetReflectionMode() const; inline const UberShader* GetShader() const; inline float GetShininess() const; inline Color GetSpecularColor() const; @@ -128,6 +129,7 @@ namespace Nz inline bool IsDepthSortingEnabled() const; inline bool IsDepthWriteEnabled() const; inline bool IsFaceCullingEnabled() const; + inline bool IsReflectionMappingEnabled() const; inline bool IsScissorTestEnabled() const; inline bool IsStencilTestEnabled() const; inline bool IsShadowCastingEnabled() const; @@ -162,6 +164,7 @@ namespace Nz inline bool SetNormalMap(const String& textureName); inline void SetNormalMap(TextureRef textureName); inline void SetPointSize(float pointSize); + inline void SetReflectionMode(ReflectionMode reflectionMode); inline void SetShader(UberShaderConstRef uberShader); inline bool SetShader(const String& uberShaderName); inline void SetShininess(float shininess); @@ -178,6 +181,7 @@ namespace Nz template static MaterialRef New(Args&&... args); // Signals: + NazaraSignal(OnMaterialReflectionModeChange, const Material* /*material*/, ReflectionMode /*newReflectionMode*/); NazaraSignal(OnMaterialRelease, const Material* /*material*/); NazaraSignal(OnMaterialReset, const Material* /*material*/); @@ -195,6 +199,7 @@ namespace Nz MaterialRef m_depthMaterial; //< Materialception mutable const MaterialPipeline* m_pipeline; MaterialPipelineInfo m_pipelineInfo; + ReflectionMode m_reflectionMode; TextureSampler m_diffuseSampler; TextureSampler m_specularSampler; TextureRef m_alphaMap; @@ -207,6 +212,7 @@ namespace Nz bool m_shadowCastingEnabled; float m_alphaThreshold; float m_shininess; + unsigned int m_reflectionSize; static std::array s_textureUnits; static MaterialLibrary::LibraryMap s_library; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 61f2220d4..3831519a2 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -146,7 +146,7 @@ namespace Nz /*! * \brief Enable/Disable alpha test for this material * - * When enabled, all objects using this material will be rendered using alpha testing, + * When enabled, all objects using this material will be rendered using alpha testing, * rejecting pixels if their alpha component is under a defined threshold. * This allows some kind of transparency with a much cheaper cost as it doesn't prevent any optimization (as deferred rendering or batching). * @@ -252,7 +252,7 @@ namespace Nz * When enabled, and if depth buffer is enabled and present, all fragments generated with this material will write * to the depth buffer if they pass depth test. * - * This is usually disabled with translucent objects, as depth test is wanted to prevent them from rendering on top of opaque objects but + * This is usually disabled with translucent objects, as depth test is wanted to prevent them from rendering on top of opaque objects but * not depth writing (which could make other translucent fragments to fail depth test) * * \param depthBuffer Defines if this material will use depth write @@ -291,6 +291,31 @@ namespace Nz InvalidatePipeline(); } + /*! + * \brief Enable/Disable reflection mapping for this material + * + * When enabled, the material will render reflections from the object environment according to the reflection mode. + * Whether or not this is expensive depends of the reflection mode and size. + * + * Please note this is only a hint for the render technique, and reflections can be forcefully enabled or disabled depending on the material shader. + * + * Use SetReflectionMode and SetReflectionSize to control reflection quality. + * + * \param reflection Defines if this material should use reflection mapping + * + * \remark May invalidates the pipeline + * + * \see IsReflectionMappingEnabled + * \see SetReflectionMode + * \see SetReflectionSize + */ + inline void Material::EnableReflectionMapping(bool reflection) + { + m_pipelineInfo.reflectionMapping = reflection; + + InvalidatePipeline(); + } + /*! * \brief Enable/Disable scissor test for this material * @@ -593,6 +618,18 @@ namespace Nz return m_pipelineInfo.pointSize; } + /*! + * \brief Gets the reflection mode of the material + * + * \return Current reflection mode + * + * \see SetReflectionMode + */ + inline ReflectionMode Material::GetReflectionMode() const + { + return m_reflectionMode; + } + /*! * \brief Gets the über-shader used by this material * \return Constant pointer to the über-shader used @@ -782,6 +819,17 @@ namespace Nz return m_pipelineInfo.faceCulling; } + /*! + * \brief Checks whether this material has reflection mapping enabled + * \return true If it is the case + * + * \see EnableReflectionMapping + */ + inline bool Material::IsReflectionMappingEnabled() const + { + return m_pipelineInfo.reflectionMapping; + } + /*! * \brief Checks whether this material has scissor test enabled * \return true If it is the case @@ -1207,6 +1255,34 @@ namespace Nz InvalidatePipeline(); } + /*! + * \brief Changes reflection mode of the material + * + * When reflections are enabled, the material will render reflections from the object environment according to the reflection mode. + * This function does change the reflection mode used by the material. + * + * Skyboxes reflections are the cheapest but are static and thus can't reflect other objects. + * Probes reflections are cheap, depending on probes reflection mode, but require regular probe finding from objects using it. + * Real-time reflections are expensive but provide the most accurate reflection map (and can reflect other objects around). + * + * \param reflectionMode The new reflection mode this material should use + * + * \remark May invalidates the pipeline + * + * \see EnableReflectionMapping + * \see IsReflectionMappingEnabled + * \see SetReflectionSize + */ + inline void Material::SetReflectionMode(ReflectionMode reflectionMode) + { + if (m_reflectionMode != reflectionMode) + { + OnMaterialReflectionModeChange(this, reflectionMode); + + m_reflectionMode = reflectionMode; + } + } + /*! * \brief Sets the shader with a constant reference to a ubershader * @@ -1389,4 +1465,3 @@ namespace Nz } #include -#include "Material.hpp" diff --git a/include/Nazara/Graphics/MaterialPipeline.hpp b/include/Nazara/Graphics/MaterialPipeline.hpp index 79028ac45..372572264 100644 --- a/include/Nazara/Graphics/MaterialPipeline.hpp +++ b/include/Nazara/Graphics/MaterialPipeline.hpp @@ -10,25 +10,24 @@ #include #include #include -#include #include #include -#include #include namespace Nz { struct MaterialPipelineInfo : RenderStates { - bool alphaTest = false; - bool depthSorting = false; - bool hasAlphaMap = false; - bool hasDiffuseMap = false; - bool hasEmissiveMap = false; - bool hasHeightMap = false; - bool hasNormalMap = false; - bool hasSpecularMap = false; - bool shadowReceive = true; + bool alphaTest = false; + bool depthSorting = false; + bool hasAlphaMap = false; + bool hasDiffuseMap = false; + bool hasEmissiveMap = false; + bool hasHeightMap = false; + bool hasNormalMap = false; + bool hasSpecularMap = false; + bool reflectionMapping = false; + bool shadowReceive = true; UberShaderConstRef uberShader; }; diff --git a/include/Nazara/Graphics/MaterialPipeline.inl b/include/Nazara/Graphics/MaterialPipeline.inl index 263dbcad3..bc7ca1b72 100644 --- a/include/Nazara/Graphics/MaterialPipeline.inl +++ b/include/Nazara/Graphics/MaterialPipeline.inl @@ -2,9 +2,8 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include #include +#include #include #include @@ -72,6 +71,7 @@ namespace Nz NazaraPipelineBoolMember(hasHeightMap); NazaraPipelineBoolMember(hasNormalMap); NazaraPipelineBoolMember(hasSpecularMap); + NazaraPipelineBoolMember(reflectionMapping); NazaraPipelineBoolMember(shadowReceive); NazaraPipelineMember(uberShader); @@ -127,6 +127,7 @@ namespace std NazaraPipelineBoolMember(hasHeightMap); NazaraPipelineBoolMember(hasNormalMap); NazaraPipelineBoolMember(hasSpecularMap); + NazaraPipelineBoolMember(reflectionMapping); NazaraPipelineBoolMember(shadowReceive); NazaraPipelineMember(uberShader); diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index e512e5201..bffba9bab 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -39,7 +39,7 @@ namespace Nz friend ModelLoader; public: - Model(); + inline Model(); Model(const Model& model) = default; Model(Model&& model) = default; virtual ~Model(); @@ -47,13 +47,9 @@ namespace Nz void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; inline void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix, unsigned int renderOrder = 0); - Material* GetMaterial(const String& subMeshName) const; - Material* GetMaterial(unsigned int matIndex) const; - Material* GetMaterial(unsigned int skinIndex, const String& subMeshName) const; - Material* GetMaterial(unsigned int skinIndex, unsigned int matIndex) const; - unsigned int GetMaterialCount() const; - unsigned int GetSkin() const; - unsigned int GetSkinCount() const; + using InstancedRenderable::GetMaterial; + const MaterialRef& GetMaterial(const String& subMeshName) const; + const MaterialRef& GetMaterial(std::size_t skinIndex, const String& subMeshName) const; Mesh* GetMesh() const; virtual bool IsAnimated() const; @@ -62,15 +58,11 @@ namespace Nz bool LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params = ModelParameters()); bool LoadFromStream(Stream& stream, const ModelParameters& params = ModelParameters()); - void Reset(); + using InstancedRenderable::SetMaterial; + bool SetMaterial(const String& subMeshName, MaterialRef material); + bool SetMaterial(std::size_t skinIndex, const String& subMeshName, MaterialRef material); - bool SetMaterial(const String& subMeshName, Material* material); - void SetMaterial(unsigned int matIndex, Material* material); - bool SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material); - void SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material); virtual void SetMesh(Mesh* mesh); - void SetSkin(unsigned int skin); - void SetSkinCount(unsigned int skinCount); Model& operator=(const Model& node) = default; Model& operator=(Model&& node) = default; @@ -80,11 +72,7 @@ namespace Nz protected: void MakeBoundingVolume() const override; - std::vector m_materials; MeshRef m_mesh; - unsigned int m_matCount; - unsigned int m_skin; - unsigned int m_skinCount; static ModelLoader::LoaderList s_loaders; }; diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index 7925e9e70..fa1138f78 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -7,6 +7,14 @@ namespace Nz { + /*! + * \brief Constructs a Model object by default + */ + Model::Model() + { + ResetMaterials(0); + } + /*! * \brief Adds this model to a render queue, using user-specified transform matrix and render order * diff --git a/include/Nazara/Graphics/ParticleFunctionController.inl b/include/Nazara/Graphics/ParticleFunctionController.inl index 92e78e4af..ae2b2ca6d 100644 --- a/include/Nazara/Graphics/ParticleFunctionController.inl +++ b/include/Nazara/Graphics/ParticleFunctionController.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include diff --git a/include/Nazara/Graphics/ParticleFunctionGenerator.inl b/include/Nazara/Graphics/ParticleFunctionGenerator.inl index 787e1cdce..f52afaaf9 100644 --- a/include/Nazara/Graphics/ParticleFunctionGenerator.inl +++ b/include/Nazara/Graphics/ParticleFunctionGenerator.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include diff --git a/include/Nazara/Graphics/ParticleFunctionRenderer.inl b/include/Nazara/Graphics/ParticleFunctionRenderer.inl index 12b53bf88..e51178b7a 100644 --- a/include/Nazara/Graphics/ParticleFunctionRenderer.inl +++ b/include/Nazara/Graphics/ParticleFunctionRenderer.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include diff --git a/include/Nazara/Graphics/ParticleGroup.hpp b/include/Nazara/Graphics/ParticleGroup.hpp index 93d3f63d4..22f15432d 100644 --- a/include/Nazara/Graphics/ParticleGroup.hpp +++ b/include/Nazara/Graphics/ParticleGroup.hpp @@ -15,9 +15,7 @@ #include #include #include -#include #include -#include #include #include diff --git a/include/Nazara/Graphics/ParticleGroup.inl b/include/Nazara/Graphics/ParticleGroup.inl index 330d6546f..bc12fe145 100644 --- a/include/Nazara/Graphics/ParticleGroup.inl +++ b/include/Nazara/Graphics/ParticleGroup.inl @@ -2,8 +2,6 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include #include namespace Nz diff --git a/include/Nazara/Graphics/ParticleMapper.inl b/include/Nazara/Graphics/ParticleMapper.inl index 289fdf045..b60eab4bf 100644 --- a/include/Nazara/Graphics/ParticleMapper.inl +++ b/include/Nazara/Graphics/ParticleMapper.inl @@ -1,9 +1,10 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include +#include namespace Nz { @@ -26,7 +27,7 @@ namespace Nz std::size_t offset; m_declaration->GetComponent(component, &enabled, &type, &offset); - if (enabled) + if (enabled && GetComponentTypeOf() == type) { ///TODO: Check the ratio between the type of the attribute and the template type ? return SparsePtr(m_ptr + offset, m_declaration->GetStride()); @@ -57,7 +58,7 @@ namespace Nz std::size_t offset; m_declaration->GetComponent(component, &enabled, &type, &offset); - if (enabled) + if (enabled && GetComponentTypeOf() == type) { ///TODO: Check the ratio between the type of the attribute and the template type ? return SparsePtr(m_ptr + offset, m_declaration->GetStride()); diff --git a/include/Nazara/Graphics/SceneData.hpp b/include/Nazara/Graphics/SceneData.hpp index d6e54cc1b..d11ada35c 100644 --- a/include/Nazara/Graphics/SceneData.hpp +++ b/include/Nazara/Graphics/SceneData.hpp @@ -13,12 +13,14 @@ namespace Nz { class AbstractBackground; class AbstractViewer; + class Texture; struct SceneData { Color ambientColor; const AbstractBackground* background; const AbstractViewer* viewer; + Texture* globalReflectionTexture; }; } diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index bb427a3e2..2f7630af2 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -12,9 +12,7 @@ #include #include #include -#include -#include -#include +#include namespace Nz { @@ -61,8 +59,6 @@ namespace Nz bool LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params = SkeletalModelParameters()); bool LoadFromStream(Stream& stream, const SkeletalModelParameters& params = SkeletalModelParameters()); - void Reset(); - bool SetAnimation(Animation* animation); void SetMesh(Mesh* mesh) override; bool SetSequence(const String& sequenceName); diff --git a/include/Nazara/Graphics/SkyboxBackground.hpp b/include/Nazara/Graphics/SkyboxBackground.hpp index 4f433ed3e..1e80d7be4 100644 --- a/include/Nazara/Graphics/SkyboxBackground.hpp +++ b/include/Nazara/Graphics/SkyboxBackground.hpp @@ -9,14 +9,12 @@ #include #include -#include #include #include -#include -#include namespace Nz { + class AbstractViewer; class SkyboxBackground; using SkyboxBackgroundConstRef = ObjectRef; diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 3625708da..5b0702ed1 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Nz @@ -38,7 +37,6 @@ namespace Nz inline const Color& GetColor() const; inline const Color& GetCornerColor(RectCorner corner) const; - inline const MaterialRef& GetMaterial() const; inline const Vector3f& GetOrigin() const; inline const Vector2f& GetSize() const; inline const Rectf& GetTextureCoords() const; @@ -48,11 +46,15 @@ namespace Nz inline void SetDefaultMaterial(); inline void SetMaterial(MaterialRef material, bool resizeSprite = true); bool SetMaterial(String materialName, bool resizeSprite = true); + inline void SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeSprite = true); + bool SetMaterial(std::size_t skinIndex, String materialName, bool resizeSprite = true); inline void SetOrigin(const Vector3f& origin); inline void SetSize(const Vector2f& size); inline void SetSize(float sizeX, float sizeY); bool SetTexture(String textureName, bool resizeSprite = true); inline void SetTexture(TextureRef texture, bool resizeSprite = true); + bool SetTexture(std::size_t skinIndex, String textureName, bool resizeSprite = true); + inline void SetTexture(std::size_t skinIndex, TextureRef texture, bool resizeSprite = true); inline void SetTextureCoords(const Rectf& coords); inline void SetTextureRect(const Rectui& rect); @@ -71,7 +73,6 @@ namespace Nz std::array m_cornerColor; Color m_color; - MaterialRef m_material; Rectf m_textureCoords; Vector2f m_size; Vector3f m_origin; diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index c9f698371..7ecf80cf8 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -2,9 +2,10 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include -#include +#include namespace Nz { @@ -18,6 +19,8 @@ namespace Nz m_size(64.f, 64.f), m_origin(Nz::Vector3f::Zero()) { + ResetMaterials(1); + for (Color& color : m_cornerColor) color = Color::White; @@ -56,7 +59,6 @@ namespace Nz inline Sprite::Sprite(const Sprite& sprite) : InstancedRenderable(sprite), m_color(sprite.m_color), - m_material(sprite.m_material), m_textureCoords(sprite.m_textureCoords), m_size(sprite.m_size), m_origin(sprite.m_origin) @@ -94,15 +96,6 @@ namespace Nz return m_cornerColor[corner]; } - /*! - * \brief Gets the material of the sprite - * \return Current material - */ - inline const MaterialRef& Sprite::GetMaterial() const - { - return m_material; - } - /*! * \brief Gets the origin of the sprite * @@ -187,16 +180,32 @@ namespace Nz * \brief Changes the material of the sprite * * \param material Material for the sprite - * \param resizeSprite Should the sprite be resized to the texture size? + * \param resizeSprite Should billboard be resized to the material size (diffuse map) */ inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite) { - m_material = std::move(material); - if (m_material && resizeSprite) + SetMaterial(GetSkin(), std::move(material), resizeSprite); + } + + /*! + * \brief Sets the material of the sprite + * + * \param skinIndex Skin index to change + * \param material Material for the sprite + * \param resizeBillboard Should billboard be resized to the material size (diffuse map) + */ + inline void Sprite::SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeSprite) + { + InstancedRenderable::SetMaterial(skinIndex, 0, std::move(material)); + + if (resizeSprite) { - Texture* diffuseMap = m_material->GetDiffuseMap(); - if (diffuseMap && diffuseMap->IsValid()) - SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + if (const MaterialRef& newMat = GetMaterial()) + { + const TextureRef& diffuseMap = newMat->GetDiffuseMap(); + if (diffuseMap && diffuseMap->IsValid()) + SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + } } } @@ -246,9 +255,9 @@ namespace Nz } /*! - * \brief Sets the texture of the sprite + * \brief Sets the texture of the sprite for the current skin * - * Assign a texture to the sprite material + * This function changes the diffuse map of the material associated with the current skin * * \param texture Texture for the sprite * \param resizeSprite Should the sprite be resized to the texture size? @@ -257,15 +266,37 @@ namespace Nz */ inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite) { - if (!m_material) - SetDefaultMaterial(); - else if (m_material->GetReferenceCount() > 1) - m_material = Material::New(*m_material); // Copy the material + SetTexture(GetSkin(), std::move(texture), resizeSprite); + } - if (resizeSprite && texture && texture->IsValid()) - SetSize(Vector2f(Vector2ui(texture->GetSize()))); + /*! + * \brief Sets the texture of the sprite for a specific skin + * + * This function changes the diffuse map of the material associated with the specified skin + * + * \param skinIndex Skin index to change + * \param texture Texture for the sprite + * \param resizeSprite Should the sprite be resized to the texture size? + * + * \remark The sprite material gets copied to prevent accidentally changing other drawable materials + */ + inline void Sprite::SetTexture(std::size_t skinIndex, TextureRef texture, bool resizeSprite) + { + const MaterialRef& material = GetMaterial(skinIndex); - m_material->SetDiffuseMap(std::move(texture)); + if (material->GetReferenceCount() > 1) + { + MaterialRef newMat = Material::New(*material); // Copy + newMat->SetDiffuseMap(std::move(texture)); + + SetMaterial(skinIndex, std::move(newMat), resizeSprite); + } + else + { + material->SetDiffuseMap(std::move(texture)); + if (resizeSprite && texture && texture->IsValid()) + SetSize(Vector2f(Vector2ui(texture->GetSize()))); + } } /*! @@ -277,6 +308,7 @@ namespace Nz inline void Sprite::SetTextureCoords(const Rectf& coords) { m_textureCoords = coords; + InvalidateVertices(); } @@ -291,10 +323,10 @@ namespace Nz inline void Sprite::SetTextureRect(const Rectui& rect) { - NazaraAssert(m_material, "Sprite has no material"); - NazaraAssert(m_material->HasDiffuseMap(), "Sprite material has no diffuse map"); + const MaterialRef& material = GetMaterial(); + NazaraAssert(material->HasDiffuseMap(), "Sprite material has no diffuse map"); - Texture* diffuseMap = m_material->GetDiffuseMap(); + Texture* diffuseMap = material->GetDiffuseMap(); float invWidth = 1.f / diffuseMap->GetWidth(); float invHeight = 1.f / diffuseMap->GetHeight(); @@ -314,7 +346,6 @@ namespace Nz InstancedRenderable::operator=(sprite); m_color = sprite.m_color; - m_material = sprite.m_material; m_origin = sprite.m_origin; m_textureCoords = sprite.m_textureCoords; m_size = sprite.m_size; @@ -352,5 +383,4 @@ namespace Nz } } -#include -#include "Sprite.hpp" +#include diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 19a3ec1a7..c4f774774 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -11,13 +11,11 @@ #include #include #include -#include #include -#include -#include namespace Nz { + class AbstractTextDrawer; class TextSprite; using TextSpriteConstRef = ObjectRef; @@ -37,12 +35,12 @@ namespace Nz inline void Clear(); inline const Color& GetColor() const; - inline const MaterialRef& GetMaterial() const; inline float GetScale() const; inline void SetColor(const Color& color); inline void SetDefaultMaterial(); inline void SetMaterial(MaterialRef material); + inline void SetMaterial(std::size_t skinIndex, MaterialRef material); inline void SetScale(float scale); void Update(const AbstractTextDrawer& drawer); @@ -76,7 +74,6 @@ namespace Nz mutable std::unordered_map m_renderInfos; mutable std::vector m_localVertices; Color m_color; - MaterialRef m_material; Recti m_localBounds; float m_scale; diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index c7ba17585..2caec3254 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -2,8 +2,9 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include -#include +#include namespace Nz { @@ -15,6 +16,8 @@ namespace Nz m_color(Color::White), m_scale(1.f) { + ResetMaterials(1U); + SetDefaultMaterial(); } @@ -41,7 +44,6 @@ namespace Nz m_renderInfos(sprite.m_renderInfos), m_localVertices(sprite.m_localVertices), m_color(sprite.m_color), - m_material(sprite.m_material), m_localBounds(sprite.m_localBounds), m_scale(sprite.m_scale) { @@ -78,16 +80,6 @@ namespace Nz return m_color; } - /*! - * \brief Gets the material of the text sprite - * \return Current material - */ - - inline const MaterialRef& TextSprite::GetMaterial() const - { - return m_material; - } - /*! * \brief Gets the current scale of the text sprite * \return Current scale @@ -136,7 +128,12 @@ namespace Nz inline void TextSprite::SetMaterial(MaterialRef material) { - m_material = std::move(material); + InstancedRenderable::SetMaterial(0, std::move(material)); + } + + inline void TextSprite::SetMaterial(std::size_t skinIndex, MaterialRef material) + { + InstancedRenderable::SetMaterial(skinIndex, 0, std::move(material)); } /*! @@ -167,7 +164,6 @@ namespace Nz m_atlases.clear(); m_color = text.m_color; - m_material = text.m_material; m_renderInfos = text.m_renderInfos; m_localBounds = text.m_localBounds; m_localVertices = text.m_localVertices; @@ -216,4 +212,4 @@ namespace Nz } } -#include +#include diff --git a/include/Nazara/Graphics/TileMap.hpp b/include/Nazara/Graphics/TileMap.hpp index dbc36aff5..310d94afd 100644 --- a/include/Nazara/Graphics/TileMap.hpp +++ b/include/Nazara/Graphics/TileMap.hpp @@ -10,8 +10,6 @@ #include #include #include -#include -#include #include namespace Nz @@ -50,8 +48,6 @@ namespace Nz inline void EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U); inline void EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U); - inline const MaterialRef& GetMaterial(std::size_t index) const; - inline std::size_t GetMaterialCount() const; inline const Vector2ui& GetMapSize() const; inline Vector2f GetSize() const; inline const Tile& GetTile(const Vector2ui& tilePos) const; @@ -59,7 +55,7 @@ namespace Nz inline bool IsIsometricModeEnabled() const; - inline void SetMaterial(std::size_t index, MaterialRef material); + using InstancedRenderable::SetMaterial; inline TileMap& operator=(const TileMap& TileMap); TileMap& operator=(TileMap&& TileMap) = delete; @@ -83,7 +79,6 @@ namespace Nz struct Layer { - MaterialRef material; std::set tiles; }; diff --git a/include/Nazara/Graphics/TileMap.inl b/include/Nazara/Graphics/TileMap.inl index 0ed57a1be..23065d429 100644 --- a/include/Nazara/Graphics/TileMap.inl +++ b/include/Nazara/Graphics/TileMap.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include #include @@ -32,8 +31,7 @@ namespace Nz NazaraAssert(m_tileSize.x > 0 && m_tileSize.y > 0, "Invalid tile size"); NazaraAssert(m_layers.size() != 0U, "Invalid material count"); - for (Layer& layer : m_layers) - layer.material = Material::GetDefault(); + ResetMaterials(materialCount); InvalidateBoundingVolume(); } @@ -183,9 +181,11 @@ namespace Nz inline void TileMap::EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color, std::size_t materialIndex) { NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); - NazaraAssert(m_layers[materialIndex].material->HasDiffuseMap(), "Material has no diffuse map"); - Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + const MaterialRef& material = GetMaterial(materialIndex); + NazaraAssert(material->HasDiffuseMap(), "Material has no diffuse map"); + + Texture* diffuseMap = material->GetDiffuseMap(); float invWidth = 1.f / diffuseMap->GetWidth(); float invHeight = 1.f / diffuseMap->GetHeight(); @@ -246,7 +246,7 @@ namespace Nz { NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); - Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + Texture* diffuseMap = GetMaterial(materialIndex)->GetDiffuseMap(); float invWidth = 1.f / diffuseMap->GetWidth(); float invHeight = 1.f / diffuseMap->GetHeight(); @@ -321,9 +321,11 @@ namespace Nz inline void TileMap::EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color, std::size_t materialIndex) { NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); - NazaraAssert(m_layers[materialIndex].material->HasDiffuseMap(), "Material has no diffuse map"); - Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + const MaterialRef& material = GetMaterial(materialIndex); + NazaraAssert(material->HasDiffuseMap(), "Material has no diffuse map"); + + Texture* diffuseMap = material->GetDiffuseMap(); float invWidth = 1.f / diffuseMap->GetWidth(); float invHeight = 1.f / diffuseMap->GetHeight(); @@ -331,29 +333,6 @@ namespace Nz EnableTiles(tilesPos, tileCount, unnormalizedCoords, color, materialIndex); } - /*! - * \brief Gets the material at position index used by the TileMap - * - * \param index Index of the material to query - * - * \return Material at index - */ - inline const MaterialRef& TileMap::GetMaterial(std::size_t index) const - { - NazaraAssert(index < m_layers.size(), "Material out of bounds"); - - return m_layers[index].material; - } - - /*! - * \brief Gets the maximum material count this TileMap can use - * \return Material count - */ - inline std::size_t TileMap::GetMaterialCount() const - { - return m_layers.size(); - } - /*! * \brief Gets the tilemap size (i.e. number of tiles in each dimension) * \return Number of tiles in each dimension @@ -415,19 +394,6 @@ namespace Nz return m_isometricModeEnabled; } - /*! - * \brief Sets a material of the TileMap - * - * \param index Index of the material to change - * \param material Material for the TileMap - */ - inline void TileMap::SetMaterial(std::size_t index, MaterialRef material) - { - NazaraAssert(index < m_layers.size(), "Material out of bounds"); - - m_layers[index].material = std::move(material); - } - /*! * \brief Sets the current TileMap with the content of the other one * \return A reference to this diff --git a/include/Nazara/Lua/Lua.hpp b/include/Nazara/Lua/Lua.hpp index e1c084f8f..011b9e36f 100644 --- a/include/Nazara/Lua/Lua.hpp +++ b/include/Nazara/Lua/Lua.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jrme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -8,7 +8,6 @@ #define NAZARA_LUA_HPP #include -#include #include namespace Nz diff --git a/include/Nazara/Lua/LuaCoroutine.hpp b/include/Nazara/Lua/LuaCoroutine.hpp index a740f635b..71232791a 100644 --- a/include/Nazara/Lua/LuaCoroutine.hpp +++ b/include/Nazara/Lua/LuaCoroutine.hpp @@ -9,8 +9,6 @@ #include #include -#include -#include namespace Nz { diff --git a/include/Nazara/Lua/LuaCoroutine.inl b/include/Nazara/Lua/LuaCoroutine.inl index 7dcdd0e07..63c7d0eda 100644 --- a/include/Nazara/Lua/LuaCoroutine.inl +++ b/include/Nazara/Lua/LuaCoroutine.inl @@ -2,8 +2,6 @@ // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include - namespace Nz { inline LuaCoroutine::LuaCoroutine(LuaCoroutine&& instance) : diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 93374958b..64f998641 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -8,9 +8,9 @@ #define NAZARA_LUAINSTANCE_HPP #include +#include #include #include -#include namespace Nz { diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 59bf8d79e..1a37cf27a 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include namespace Nz diff --git a/include/Nazara/Lua/LuaState.hpp b/include/Nazara/Lua/LuaState.hpp index fe34d794a..a9e229d31 100644 --- a/include/Nazara/Lua/LuaState.hpp +++ b/include/Nazara/Lua/LuaState.hpp @@ -8,8 +8,6 @@ #define NAZARA_LUASTATE_HPP #include -#include -#include #include #include #include @@ -25,6 +23,7 @@ namespace Nz class LuaCoroutine; class LuaInstance; class LuaState; + class Stream; using LuaCFunction = int (*)(lua_State* internalState); using LuaFunction = std::function; @@ -33,7 +32,7 @@ namespace Nz { public: LuaState(const LuaState&) = default; - LuaState(LuaState&& instance) noexcept; + inline LuaState(LuaState&& instance) noexcept; ~LuaState() = default; void ArgCheck(bool condition, unsigned int argNum, const char* error) const; @@ -174,7 +173,7 @@ namespace Nz void* ToUserdata(int index, const String& tname) const; LuaState& operator=(const LuaState&) = default; - LuaState& operator=(LuaState&& instance) noexcept; + inline LuaState& operator=(LuaState&& instance) noexcept; static int GetIndexOfUpValue(int upValue); static LuaInstance& GetInstance(lua_State* internalState); diff --git a/include/Nazara/Lua/LuaState.inl b/include/Nazara/Lua/LuaState.inl index a5fa57f8c..b2f7a8731 100644 --- a/include/Nazara/Lua/LuaState.inl +++ b/include/Nazara/Lua/LuaState.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include #include @@ -20,6 +19,13 @@ namespace Nz { } + inline LuaState::LuaState(LuaState&& state) noexcept : + m_lastError(state.m_lastError), + m_state(state.m_state) + { + state.m_state = nullptr; + } + inline lua_State* LuaState::GetInternalState() const { return m_state; @@ -64,21 +70,21 @@ namespace Nz } template - std::enable_if_t::value && !EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) + std::enable_if_t::value && !IsEnumFlag::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) { using UnderlyingT = std::underlying_type_t; return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); } template - std::enable_if_t::value && !EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag) + std::enable_if_t::value && !IsEnumFlag::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag) { using UnderlyingT = std::underlying_type_t; return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); } template - std::enable_if_t::value && EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) + std::enable_if_t::value && IsEnumFlag::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) { using UnderlyingT = std::underlying_type_t; @@ -90,7 +96,7 @@ namespace Nz } template - std::enable_if_t::value && EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag) + std::enable_if_t::value && IsEnumFlag::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag) { using UnderlyingT = std::underlying_type_t; @@ -180,14 +186,14 @@ namespace Nz } template - std::enable_if_t::value && !EnumAsFlags::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + std::enable_if_t::value && !IsEnumFlag::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) { using EnumT = typename std::underlying_type::type; return LuaImplReplyVal(instance, static_cast(val), TypeTag()); } template - std::enable_if_t::value && EnumAsFlags::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + std::enable_if_t::value && IsEnumFlag::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) { Flags flags(val); return LuaImplReplyVal(instance, flags, TypeTag()); @@ -196,7 +202,7 @@ namespace Nz template int LuaImplReplyVal(const LuaState& instance, Flags val, TypeTag>) { - instance.PushInteger(UInt32(val)); + instance.PushInteger(typename Flags::BitField(val)); return 1; } @@ -770,6 +776,16 @@ namespace Nz SetMetatable(tname); } + inline LuaState& LuaState::operator=(LuaState&& state) noexcept + { + m_lastError = std::move(state.m_lastError); + m_state = state.m_state; + + state.m_state = nullptr; + + return *this; + } + template std::enable_if_t::value, T> LuaState::CheckBounds(int index, long long value) const { diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index e50385c78..195251a19 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -552,11 +552,11 @@ namespace Nz #endif const T twoLimit = limit * T(2); - angle = std::fmod(angle + limit, twoLimit); + angle = std::fmod(angle, twoLimit); if (angle < T(0)) angle += twoLimit; - return angle - limit; + return angle; } /*! diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index d2dee79f8..5bbd83f31 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -541,7 +541,7 @@ namespace Nz return Infinite(); case Extend_Null: - return from.obb * interpolation; + return to.obb * interpolation; } // If we arrive here, the extend is invalid diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index d903de52a..0fc972164 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -77,7 +77,6 @@ namespace Nz /*! * \brief Makes the euler angle (0, 0, 0) - * \return A reference to this euler angle with components (0, 0, 0) * * \see Zero */ @@ -276,7 +275,7 @@ namespace Nz * \brief Substracts the components of other euler angle to this euler angle * \return A reference to this euler angle where components are the difference of this euler angle and the other one * - * \param angle The other euler angle to substract components with + * \param angles The other euler angle to substract components with */ template diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index f3effcc5e..27b7d3183 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -664,9 +664,9 @@ namespace Nz template Vector3 Matrix4::GetSquaredScale() const { - return Vector3(m11*m11 + m21*m21 + m31*m31, - m12*m12 + m22*m22 + m32*m32, - m13*m13 + m23*m23 + m33*m33); + return Vector3(m11 * m11 + m12 * m12 + m13 * m13, + m21 * m21 + m22 * m22 + m23 * m23, + m31 * m31 + m32 * m32 + m33 * m33); } /*! @@ -1153,36 +1153,32 @@ namespace Nz * * \param rotation Quaternion representing a rotation of space * - * \remark 3rd column and row are unchanged + * \remark 3rd column and row are unchanged. Scale is removed. */ template Matrix4& Matrix4::SetRotation(const Quaternion& rotation) { - T tx = rotation.x + rotation.x; - T ty = rotation.y + rotation.y; - T tz = rotation.z + rotation.z; - T twx = tx * rotation.w; - T twy = ty * rotation.w; - T twz = tz * rotation.w; - T txx = tx * rotation.x; - T txy = ty * rotation.x; - T txz = tz * rotation.x; - T tyy = ty * rotation.y; - T tyz = tz * rotation.y; - T tzz = tz * rotation.z; + T qw = rotation.w; + T qx = rotation.x; + T qy = rotation.y; + T qz = rotation.z; - m11 = F(1.0) - (tyy + tzz); - m12 = txy + twz; - m13 = txz - twy; + T qx2 = qx * qx; + T qy2 = qy * qy; + T qz2 = qz * qz; - m21 = txy - twz; - m22 = F(1.0) - (txx + tzz); - m23 = tyz + twx; + m11 = F(1.0) - F(2.0) * qy2 - F(2.0) * qz2; + m21 = F(2.0) * qx * qy - F(2.0) * qz * qw; + m31 = F(2.0) * qx * qz + F(2.0) * qy * qw; - m31 = txz + twy; - m32 = tyz - twx; - m33 = F(1.0) - (txx + tyy); + m12 = F(2.0) * qx * qy + F(2.0) * qz * qw; + m22 = F(1.0) - F(2.0) * qx2 - F(2.0) * qz2; + m32 = F(2.0) * qy * qz - F(2.0) * qx * qw; + + m13 = F(2.0) * qx * qz - F(2.0) * qy * qw; + m23 = F(2.0) * qy * qz + F(2.0) * qx * qw; + m33 = F(1.0) - F(2.0) * qx2 - F(2.0) * qy2; return *this; } diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 15bf8cae7..d80809988 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -106,9 +106,9 @@ namespace Nz * \brief Returns the distance from the plane to the point * \return Distance to the point * - * \param X X position of the point - * \param Y Y position of the point - * \param Z Z position of the point + * \param x X position of the point + * \param y Y position of the point + * \param z Z position of the point * * \remark If T is negative, it means that the point is in the opposite direction of the normal * @@ -319,7 +319,7 @@ namespace Nz * \brief Compares the plane to other one * \return true if the planes are the same * - * \param vec Other vector to compare with + * \param plane Other vector to compare with * * \remark Plane with normal N and distance D is the same than with normal -N et distance -D */ diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index def663ee4..f07524c0f 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -251,35 +251,19 @@ namespace Nz * \param from Initial vector * \param to Target vector * + * \remark Vectors are not required to be normalized + * * \see RotationBetween */ template Quaternion& Quaternion::MakeRotationBetween(const Vector3& from, const Vector3& to) { - // TODO (Gawaboumga): Replace by http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors ? - - T dot = from.DotProduct(to); - if (NumberEquals(dot, F(-1.0))) - { - Vector3 cross = Vector3::CrossProduct(Vector3::UnitX(), from); - if (NumberEquals(cross.GetLength(), F(0.0))) - cross = Vector3::CrossProduct(Vector3::UnitY(), from); - - return Set(F(180.0), cross); - } - else if (NumberEquals(dot, F(1.0))) - return MakeIdentity(); - else - { - Vector3 a = from.CrossProduct(to); - x = a.x; - y = a.y; - z = a.z; - w = T(1.0) + dot; - - return Normalize(); - } + // Based on: http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors + T norm = std::sqrt(from.GetSquaredLength() * to.GetSquaredLength()); + Vector3 crossProduct = from.CrossProduct(to); + Set(norm + from.DotProduct(to), crossProduct.x, crossProduct.y, crossProduct.z); + return Normalize(); } /*! @@ -425,7 +409,7 @@ namespace Nz * \brief Sets the components of the quaternion from another quaternion * \return A reference to this quaternion * - * \param vec The other quaternion + * \param quat The other quaternion */ template @@ -481,11 +465,11 @@ namespace Nz T test = x * y + z * w; if (test > F(0.499)) // singularity at north pole - return EulerAngles(FromDegrees(F(90.0)), FromRadians(F(2.0) * std::atan2(x, w)), F(0.0)); + return EulerAngles(F(0.0), FromRadians(F(2.0) * std::atan2(x, w)), FromDegrees(F(90.0))); if (test < F(-0.499)) // singularity at south pole - return EulerAngles(FromDegrees(F(-90.0)), FromRadians(F(-2.0) * std::atan2(x, w)), F(0.0)); + return EulerAngles(F(0.0), FromRadians(F(-2.0) * std::atan2(x, w)), FromDegrees(F(-90.0))); return EulerAngles(FromRadians(std::atan2(F(2.0) * x * w - F(2.0) * y * z, F(1.0) - F(2.0) * x * x - F(2.0) * z * z)), FromRadians(std::atan2(F(2.0) * y * w - F(2.0) * x * z, F(1.0) - F(2.0) * y * y - F(2.0) * z * z)), @@ -647,7 +631,7 @@ namespace Nz * \brief Compares the quaternion to other one * \return true if the quaternions are the same * - * \param vec Other quaternion to compare with + * \param quat Other quaternion to compare with */ template @@ -663,7 +647,7 @@ namespace Nz * \brief Compares the quaternion to other one * \return false if the quaternions are the same * - * \param vec Other quaternion to compare with + * \param quat Other quaternion to compare with */ template diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 5aede77c2..48930be94 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -500,7 +500,7 @@ namespace Nz * \brief Multiplies the radius of the sphere with a scalar * \return A sphere where the center is the same and radius is the product of this radius and the scalar * - * \param scale The scalar to multiply radius with + * \param scalar The scalar to multiply radius with */ template @@ -513,7 +513,7 @@ namespace Nz * \brief Multiplies the radius of other sphere with a scalar * \return A reference to this sphere where the center is the same and radius is the product of this radius and the scalar * - * \param scale The scalar to multiply radius with + * \param scalar The scalar to multiply radius with */ template diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index ecbd5e4fe..5bb5573ba 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -24,7 +24,7 @@ namespace Nz Vector2() = default; Vector2(T X, T Y); explicit Vector2(T scale); - Vector2(const T vec[2]); + explicit Vector2(const T vec[2]); template explicit Vector2(const Vector2& vec); Vector2(const Vector2& vec) = default; explicit Vector2(const Vector3& vec); diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 1883ecfdc..2c9d87978 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -692,7 +692,7 @@ namespace Nz * \brief Multiplies the components of other vector with a scalar * \return A reference to this vector where components are the product of this vector and the scalar * - * \param vec The other vector to multiply components with + * \param scale The scalar to multiply components with */ template @@ -737,7 +737,7 @@ namespace Nz * \brief Divides the components of other vector with a scalar * \return A reference to this vector where components are the quotient of this vector and the scalar * - * \param vec The other vector to divide components with + * \param scale The scalar to divide components with * * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 8cfe59397..acb87d6c1 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -25,7 +25,7 @@ namespace Nz Vector3(T X, T Y, T Z); Vector3(T X, const Vector2& vec); explicit Vector3(T scale); - Vector3(const T vec[3]); + explicit Vector3(const T vec[3]); Vector3(const Vector2& vec, T Z = 0.0); template explicit Vector3(const Vector3& vec); Vector3(const Vector3& vec) = default; diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 37be47fba..9a74717ff 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -810,7 +810,7 @@ namespace Nz * \brief Multiplies the components of other vector with a scalar * \return A reference to this vector where components are the product of this vector and the scalar * - * \param vec The other vector to multiply components with + * \param scale The scalar to multiply components with */ template Vector3& Vector3::operator*=(T scale) @@ -853,7 +853,7 @@ namespace Nz * \brief Divides the components of other vector with a scalar * \return A reference to this vector where components are the quotient of this vector and the scalar * - * \param vec The other vector to divide components with + * \param scale The scalar to divide components with * * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index c39c0b250..de04884e1 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -27,7 +27,7 @@ namespace Nz Vector4(T X, const Vector2& vec, T W); Vector4(T X, const Vector3& vec); explicit Vector4(T scale); - Vector4(const T vec[4]); + explicit Vector4(const T vec[4]); Vector4(const Vector2& vec, T Z = 0.0, T W = 1.0); Vector4(const Vector3& vec, T W = 1.0); template explicit Vector4(const Vector4& vec); diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index b79e6a644..2263eb66a 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -728,7 +728,7 @@ namespace Nz * \brief Multiplies the components of other vector with a scalar * \return A reference to this vector where components are the product of this vector and the scalar * - * \param vec The other vector to multiply components with + * \param scale The scalar to multiply components with */ template @@ -777,7 +777,7 @@ namespace Nz * \brief Divides the components of other vector with a scalar * \return A reference to this vector where components are the quotient of this vector and the scalar * - * \param vec The other vector to divide components with + * \param scale The scalar to divide components with * * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null diff --git a/include/Nazara/Network.hpp b/include/Nazara/Network.hpp index 151bc3f52..1b27049e6 100644 --- a/include/Nazara/Network.hpp +++ b/include/Nazara/Network.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Network/ENetCompressor.hpp b/include/Nazara/Network/ENetCompressor.hpp new file mode 100644 index 000000000..5466c80b6 --- /dev/null +++ b/include/Nazara/Network/ENetCompressor.hpp @@ -0,0 +1,39 @@ +/* + Copyright(c) 2002 - 2016 Lee Salzman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ENETCOMPRESSOR_HPP +#define NAZARA_ENETCOMPRESSOR_HPP + +#include +#include +#include + +namespace Nz +{ + class ENetPeer; + + class NAZARA_NETWORK_API ENetCompressor + { + public: + ENetCompressor() = default; + ~ENetCompressor(); + + virtual std::size_t Compress(const ENetPeer* peer, const NetBuffer* buffers, std::size_t bufferCount, std::size_t totalInputSize, UInt8* output, std::size_t maxOutputSize) = 0; + virtual std::size_t Decompress(const ENetPeer* peer, const UInt8* input, std::size_t inputSize, UInt8* output, std::size_t maxOutputSize) = 0; + }; +} + +#endif // NAZARA_ENETCOMPRESSOR_HPP diff --git a/include/Nazara/Network/ENetHost.hpp b/include/Nazara/Network/ENetHost.hpp index eb5c7d6de..b15bd79b4 100644 --- a/include/Nazara/Network/ENetHost.hpp +++ b/include/Nazara/Network/ENetHost.hpp @@ -1,4 +1,4 @@ -/* +/* Copyright(c) 2002 - 2016 Lee Salzman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -28,11 +29,7 @@ #include #include #include -#include -#include #include -#include -#include namespace Nz { @@ -55,9 +52,9 @@ namespace Nz ENetPeer* Connect(const String& hostName, NetProtocol protocol = NetProtocol_Any, const String& service = "http", ResolveError* error = nullptr, std::size_t channelCount = 0, UInt32 data = 0); inline bool Create(NetProtocol protocol, UInt16 port, std::size_t peerCount, std::size_t channelCount = 0); - bool Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount = 0); - bool Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount, UInt32 incomingBandwidth, UInt32 outgoingBandwidth); - void Destroy(); + bool Create(const IpAddress& listenAddress, std::size_t peerCount, std::size_t channelCount = 0); + bool Create(const IpAddress& listenAddress, std::size_t peerCount, std::size_t channelCount, UInt32 incomingBandwidth, UInt32 outgoingBandwidth); + inline void Destroy(); void Flush(); @@ -66,6 +63,8 @@ namespace Nz int Service(ENetEvent* event, UInt32 timeout); + inline void SetCompressor(std::unique_ptr&& compressor); + void SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay); ENetHost& operator=(const ENetHost&) = delete; @@ -97,6 +96,8 @@ namespace Nz void ThrottleBandwidth(); + inline void UpdateServiceTime(); + static std::size_t GetCommandSize(UInt8 commandNumber); static bool Initialize(); static void Uninitialize(); @@ -130,6 +131,7 @@ namespace Nz std::size_t m_peerCount; std::size_t m_receivedDataLength; std::uniform_int_distribution m_packetDelayDistribution; + std::unique_ptr m_compressor; std::vector m_peers; std::vector m_pendingIncomingPackets; std::vector m_pendingOutgoingPackets; @@ -152,6 +154,7 @@ namespace Nz UInt32 m_totalReceivedPackets; UInt64 m_totalSentData; UInt64 m_totalReceivedData; + bool m_allowsIncomingConnections; bool m_continueSending; bool m_isSimulationEnabled; bool m_recalculateBandwidthLimits; diff --git a/include/Nazara/Network/ENetHost.inl b/include/Nazara/Network/ENetHost.inl index 3f35a8f39..667750ff0 100644 --- a/include/Nazara/Network/ENetHost.inl +++ b/include/Nazara/Network/ENetHost.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Network module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include @@ -52,16 +51,21 @@ namespace Nz m_socket.Close(); } - inline Nz::IpAddress ENetHost::GetBoundAddress() const + inline IpAddress ENetHost::GetBoundAddress() const { return m_address; } - inline UInt32 Nz::ENetHost::GetServiceTime() const + inline UInt32 ENetHost::GetServiceTime() const { return m_serviceTime; } + inline void ENetHost::SetCompressor(std::unique_ptr&& compressor) + { + m_compressor = std::move(compressor); + } + inline ENetPacketRef ENetHost::AllocatePacket(ENetPacketFlags flags, NetPacket&& data) { ENetPacketRef ref = AllocatePacket(flags); @@ -69,6 +73,12 @@ namespace Nz return ref; } + + inline void ENetHost::UpdateServiceTime() + { + // Compute service time as microseconds for extra precision + m_serviceTime = static_cast(GetElapsedMicroseconds() / 1000); + } } #include diff --git a/include/Nazara/Network/ENetPacket.hpp b/include/Nazara/Network/ENetPacket.hpp index 54b0c42c6..8d224a0f4 100644 --- a/include/Nazara/Network/ENetPacket.hpp +++ b/include/Nazara/Network/ENetPacket.hpp @@ -22,8 +22,7 @@ namespace Nz template<> struct EnumAsFlags { - static constexpr bool value = true; - static constexpr int max = ENetPacketFlag_UnreliableFragment; + static constexpr ENetPacketFlag max = ENetPacketFlag_UnreliableFragment; }; using ENetPacketFlags = Flags; diff --git a/include/Nazara/Network/ENetPeer.hpp b/include/Nazara/Network/ENetPeer.hpp index 4e36378a5..b8aa0fead 100644 --- a/include/Nazara/Network/ENetPeer.hpp +++ b/include/Nazara/Network/ENetPeer.hpp @@ -19,12 +19,9 @@ #include #include -#include #include #include #include -#include -#include #include #include #include @@ -82,7 +79,6 @@ namespace Nz void InitIncoming(std::size_t channelCount, const IpAddress& address, ENetProtocolConnect& incomingCommand); void InitOutgoing(std::size_t channelCount, const IpAddress& address, UInt32 connectId, UInt32 windowSize); - struct Acknowledgement; struct Channel; struct IncomingCommmand; struct OutgoingCommand; diff --git a/include/Nazara/Network/ENetPeer.inl b/include/Nazara/Network/ENetPeer.inl index d831b4d0d..c3ede0978 100644 --- a/include/Nazara/Network/ENetPeer.inl +++ b/include/Nazara/Network/ENetPeer.inl @@ -2,8 +2,6 @@ // This file is part of the "Nazara Engine - Network module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include #include namespace Nz diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 39bce0dd0..42089b6a4 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -102,8 +102,7 @@ namespace Nz template<> struct EnumAsFlags { - static constexpr bool value = true; - static constexpr int max = SocketPollEvent_Max; + static constexpr SocketPollEvent max = SocketPollEvent_Max; }; using SocketPollEventFlags = Flags; diff --git a/include/Nazara/Network/NetPacket.hpp b/include/Nazara/Network/NetPacket.hpp index 9d5bb99a4..8de3d9258 100644 --- a/include/Nazara/Network/NetPacket.hpp +++ b/include/Nazara/Network/NetPacket.hpp @@ -11,7 +11,6 @@ #include #include #include -#include #include namespace Nz diff --git a/include/Nazara/Network/Network.hpp b/include/Nazara/Network/Network.hpp index ca6ca9ee6..bcda5a83e 100644 --- a/include/Nazara/Network/Network.hpp +++ b/include/Nazara/Network/Network.hpp @@ -8,7 +8,6 @@ #define NAZARA_MODULENAME_HPP #include -#include #include namespace Nz diff --git a/include/Nazara/Network/RUdpConnection.hpp b/include/Nazara/Network/RUdpConnection.hpp index 3cdb6c3be..d04211d07 100644 --- a/include/Nazara/Network/RUdpConnection.hpp +++ b/include/Nazara/Network/RUdpConnection.hpp @@ -22,8 +22,6 @@ namespace Nz { - class RUdpClient; - class NAZARA_NETWORK_API RUdpConnection { friend class Network; diff --git a/include/Nazara/Network/RUdpConnection.inl b/include/Nazara/Network/RUdpConnection.inl index eaf4a0e7a..fa61ec136 100644 --- a/include/Nazara/Network/RUdpConnection.inl +++ b/include/Nazara/Network/RUdpConnection.inl @@ -2,8 +2,6 @@ // This file is part of the "Nazara Engine - Network module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include #include namespace Nz diff --git a/include/Nazara/Network/SocketPoller.hpp b/include/Nazara/Network/SocketPoller.hpp index 5b583fa0f..9e7d34a61 100644 --- a/include/Nazara/Network/SocketPoller.hpp +++ b/include/Nazara/Network/SocketPoller.hpp @@ -8,8 +8,8 @@ #define NAZARA_SOCKETPOLLER_HPP #include +#include #include -#include namespace Nz { @@ -19,7 +19,7 @@ namespace Nz { public: SocketPoller(); - inline SocketPoller(SocketPoller&& socketPoller); + SocketPoller(SocketPoller&&) noexcept = default; ~SocketPoller(); void Clear(); @@ -33,10 +33,10 @@ namespace Nz bool Wait(int msTimeout); - inline SocketPoller& operator=(SocketPoller&& socketPoller); + SocketPoller& operator=(SocketPoller&&) noexcept = default; private: - SocketPollerImpl* m_impl; + MovablePtr m_impl; }; } diff --git a/include/Nazara/Network/SocketPoller.inl b/include/Nazara/Network/SocketPoller.inl index 66331b9cb..7c9dfe7cb 100644 --- a/include/Nazara/Network/SocketPoller.inl +++ b/include/Nazara/Network/SocketPoller.inl @@ -2,36 +2,10 @@ // This file is part of the "Nazara Engine - Network module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include #include namespace Nz { - /*! - * \brief Constructs a SocketPoller object with another one by move semantic - * - * \param socketPoller SocketPoller to move into this - */ - inline SocketPoller::SocketPoller(SocketPoller&& socketPoller) : - m_impl(socketPoller.m_impl) - { - socketPoller.m_impl = nullptr; - } - - /*! - * \brief Moves the SocketPoller into this - * \return A reference to this - * - * \param socketPoller SocketPoller to move in this - */ - inline SocketPoller& SocketPoller::operator=(SocketPoller&& socketPoller) - { - m_impl = socketPoller.m_impl; - socketPoller.m_impl = nullptr; - - return *this; - } } #include diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index a3b229bda..8acdc0b5d 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -9,14 +9,13 @@ #include #include -#include #include #include #include -#include namespace Nz { + struct NetBuffer; class NetPacket; class NAZARA_NETWORK_API TcpClient : public AbstractSocket, public Stream diff --git a/include/Nazara/Network/TcpClient.inl b/include/Nazara/Network/TcpClient.inl index 0ab267436..2d410d4f3 100644 --- a/include/Nazara/Network/TcpClient.inl +++ b/include/Nazara/Network/TcpClient.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Network module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include namespace Nz diff --git a/include/Nazara/Network/UdpSocket.hpp b/include/Nazara/Network/UdpSocket.hpp index 2934758aa..ec4228bd3 100644 --- a/include/Nazara/Network/UdpSocket.hpp +++ b/include/Nazara/Network/UdpSocket.hpp @@ -10,10 +10,10 @@ #include #include #include -#include namespace Nz { + struct NetBuffer; class NetPacket; class NAZARA_NETWORK_API UdpSocket : public AbstractSocket diff --git a/include/Nazara/Noise/FBM.hpp b/include/Nazara/Noise/FBM.hpp index 41cbc5758..3f573f630 100644 --- a/include/Nazara/Noise/FBM.hpp +++ b/include/Nazara/Noise/FBM.hpp @@ -6,7 +6,6 @@ #define NAZARA_FBM_HPP #include -#include #include namespace Nz diff --git a/include/Nazara/Noise/MixerBase.hpp b/include/Nazara/Noise/MixerBase.hpp index 954932114..06d658282 100644 --- a/include/Nazara/Noise/MixerBase.hpp +++ b/include/Nazara/Noise/MixerBase.hpp @@ -7,7 +7,6 @@ #include #include -#include namespace Nz { diff --git a/include/Nazara/Noise/Noise.hpp b/include/Nazara/Noise/Noise.hpp index 8138ee41b..49ddcedd3 100644 --- a/include/Nazara/Noise/Noise.hpp +++ b/include/Nazara/Noise/Noise.hpp @@ -8,7 +8,6 @@ #define NAZARA_NOISE_HPP #include -#include #include namespace Nz diff --git a/include/Nazara/Noise/Perlin.hpp b/include/Nazara/Noise/Perlin.hpp index 64211c4e4..f5af29bcf 100644 --- a/include/Nazara/Noise/Perlin.hpp +++ b/include/Nazara/Noise/Perlin.hpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace Nz { diff --git a/include/Nazara/Noise/Simplex.hpp b/include/Nazara/Noise/Simplex.hpp index 2b6309671..90bab5ec5 100644 --- a/include/Nazara/Noise/Simplex.hpp +++ b/include/Nazara/Noise/Simplex.hpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace Nz { diff --git a/include/Nazara/Noise/Worley.hpp b/include/Nazara/Noise/Worley.hpp index 1b820e513..421f192a5 100644 --- a/include/Nazara/Noise/Worley.hpp +++ b/include/Nazara/Noise/Worley.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Nz diff --git a/include/Nazara/Physics2D.hpp b/include/Nazara/Physics2D.hpp index 2c908ca79..074578140 100644 --- a/include/Nazara/Physics2D.hpp +++ b/include/Nazara/Physics2D.hpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/include/Nazara/Physics2D/Collider2D.hpp b/include/Nazara/Physics2D/Collider2D.hpp index 06d55300b..633d556a8 100644 --- a/include/Nazara/Physics2D/Collider2D.hpp +++ b/include/Nazara/Physics2D/Collider2D.hpp @@ -19,7 +19,6 @@ #include struct cpShape; -struct cpSpace; namespace Nz { diff --git a/include/Nazara/Physics2D/Collider2D.inl b/include/Nazara/Physics2D/Collider2D.inl index dee95687a..79af0942d 100644 --- a/include/Nazara/Physics2D/Collider2D.inl +++ b/include/Nazara/Physics2D/Collider2D.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include @@ -114,6 +113,15 @@ namespace Nz return object.release(); } + template + ConvexCollider2DRef ConvexCollider2D::New(Args&&... args) + { + std::unique_ptr object(new ConvexCollider2D(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } + template NullCollider2DRef NullCollider2D::New(Args&&... args) { diff --git a/include/Nazara/Physics2D/Constraint2D.hpp b/include/Nazara/Physics2D/Constraint2D.hpp new file mode 100644 index 000000000..761742348 --- /dev/null +++ b/include/Nazara/Physics2D/Constraint2D.hpp @@ -0,0 +1,189 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Physics 2D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_CONSTRAINT2D_HPP +#define NAZARA_CONSTRAINT2D_HPP + +#include +#include +#include +#include +#include +#include + +struct cpConstraint; + +namespace Nz +{ + class NAZARA_PHYSICS2D_API Constraint2D + { + public: + Constraint2D(const Constraint2D&) = delete; + Constraint2D(Constraint2D&& rhs); + virtual ~Constraint2D(); + + void EnableBodyCollision(bool enable); + + RigidBody2D& GetBodyA(); + const RigidBody2D& GetBodyA() const; + RigidBody2D& GetBodyB(); + const RigidBody2D& GetBodyB() const; + float GetErrorBias() const; + float GetMaxBias() const; + float GetMaxForce() const; + PhysWorld2D& GetWorld(); + const PhysWorld2D& GetWorld() const; + + bool IsBodyCollisionEnabled() const; + + void SetErrorBias(float bias); + void SetMaxBias(float bias); + void SetMaxForce(float force); + + Constraint2D& operator=(const Constraint2D&) = delete; + Constraint2D& operator=(Constraint2D&& rhs); + + protected: + Constraint2D(PhysWorld2D& world, cpConstraint* constraint); + + MovablePtr m_constraint; + }; + + class NAZARA_PHYSICS2D_API DampedSpring2D : public Constraint2D + { + public: + DampedSpring2D(PhysWorld2D& world, RigidBody2D& first, const Vector2f& firstAnchor, RigidBody2D& second, const Vector2f& secondAnchor, float restLength, float stiffness, float damping); + ~DampedSpring2D() = default; + + float GetDamping() const; + Vector2f GetFirstAnchor() const; + float GetRestLength() const; + Vector2f GetSecondAnchor() const; + float GetStiffness() const; + + void SetDamping(float newDamping); + void SetFirstAnchor(const Vector2f& firstAnchor); + void SetRestLength(float newLength); + void SetSecondAnchor(const Vector2f& firstAnchor); + void SetStiffness(float newStiffness); + }; + + class NAZARA_PHYSICS2D_API DampedRotarySpring2D : public Constraint2D + { + public: + DampedRotarySpring2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float restAngle, float stiffness, float damping); + ~DampedRotarySpring2D() = default; + + float GetDamping() const; + float GetRestAngle() const; + float GetStiffness() const; + + void SetDamping(float newDamping); + void SetRestAngle(float newAngle); + void SetStiffness(float newStiffness); + }; + + class NAZARA_PHYSICS2D_API GearJoint2D : public Constraint2D + { + public: + GearJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float phase, float ratio); + ~GearJoint2D() = default; + + float GetPhase() const; + float GetRatio() const; + + void SetPhase(float phase); + void SetRatio(float ratio); + }; + + class NAZARA_PHYSICS2D_API MotorJoint2D : public Constraint2D + { + public: + MotorJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float rate); + ~MotorJoint2D() = default; + + float GetRate() const; + void SetRate(float rate); + }; + + class NAZARA_PHYSICS2D_API PinJoint2D : public Constraint2D + { + public: + PinJoint2D(PhysWorld2D& world, RigidBody2D& first, const Vector2f& firstAnchor, RigidBody2D& second, const Vector2f& secondAnchor); + ~PinJoint2D() = default; + + float GetDistance() const; + Vector2f GetFirstAnchor() const; + Vector2f GetSecondAnchor() const; + + void SetDistance(float newDistance); + void SetFirstAnchor(const Vector2f& firstAnchor); + void SetSecondAnchor(const Vector2f& firstAnchor); + }; + + class NAZARA_PHYSICS2D_API PivotJoint2D : public Constraint2D + { + public: + PivotJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, const Vector2f& anchor); + PivotJoint2D(PhysWorld2D& world, RigidBody2D& first, const Vector2f& firstAnchor, RigidBody2D& second, const Vector2f& secondAnchor); + ~PivotJoint2D() = default; + + Vector2f GetFirstAnchor() const; + Vector2f GetSecondAnchor() const; + + void SetFirstAnchor(const Vector2f& firstAnchor); + void SetSecondAnchor(const Vector2f& firstAnchor); + }; + + class NAZARA_PHYSICS2D_API RatchetJoint2D : public Constraint2D + { + public: + RatchetJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float phase, float ratchet); + ~RatchetJoint2D() = default; + + float GetAngle() const; + float GetPhase() const; + float GetRatchet() const; + + void SetAngle(float angle); + void SetPhase(float phase); + void SetRatchet(float ratchet); + }; + + class NAZARA_PHYSICS2D_API RotaryLimitJoint2D : public Constraint2D + { + public: + RotaryLimitJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float minAngle, float maxAngle); + ~RotaryLimitJoint2D() = default; + + float GetMaxAngle() const; + float GetMinAngle() const; + + void SetMaxAngle(float maxAngle); + void SetMinAngle(float minAngle); + }; + + class NAZARA_PHYSICS2D_API SlideJoint2D : public Constraint2D + { + public: + SlideJoint2D(PhysWorld2D& world, RigidBody2D& first, const Vector2f& firstAnchor, RigidBody2D& second, const Vector2f& secondAnchor, float min, float max); + ~SlideJoint2D() = default; + + Vector2f GetFirstAnchor() const; + float GetMaxDistance() const; + float GetMinDistance() const; + Vector2f GetSecondAnchor() const; + + void SetFirstAnchor(const Vector2f& firstAnchor); + void SetMaxDistance(float newMaxDistance); + void SetMinDistance(float newMinDistance); + void SetSecondAnchor(const Vector2f& firstAnchor); + }; +} + +#include + +#endif // NAZARA_CONSTRAINT2D_HPP diff --git a/include/Nazara/Physics2D/Constraint2D.inl b/include/Nazara/Physics2D/Constraint2D.inl new file mode 100644 index 000000000..2ed7744f3 --- /dev/null +++ b/include/Nazara/Physics2D/Constraint2D.inl @@ -0,0 +1,13 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Physics 2D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ +} + +#include diff --git a/include/Nazara/Physics2D/PhysWorld2D.hpp b/include/Nazara/Physics2D/PhysWorld2D.hpp index 36a0c5c42..e0fa516d3 100644 --- a/include/Nazara/Physics2D/PhysWorld2D.hpp +++ b/include/Nazara/Physics2D/PhysWorld2D.hpp @@ -8,6 +8,7 @@ #define NAZARA_PHYSWORLD2D_HPP #include +#include #include #include #include @@ -30,8 +31,16 @@ namespace Nz using ContactPostSolveCallback = std::function; using ContactStartCallback = std::function; + using DebugDrawCircleCallback = std::function; + using DebugDrawDotCallback = std::function; + using DebugDrawPolygonCallback = std::function; + using DebugDrawSegmentCallback = std::function; + using DebugDrawTickSegmentCallback = std::function; + using DebugDrawGetColorCallback = std::function; + public: struct Callback; + struct DebugDrawOptions; struct NearestQueryResult; struct RaycastHit; @@ -40,6 +49,9 @@ namespace Nz PhysWorld2D(PhysWorld2D&&) = delete; ///TODO ~PhysWorld2D(); + void DebugDraw(const DebugDrawOptions& options, bool drawShapes = true, bool drawConstraints = true, bool drawCollisions = true); + + float GetDamping() const; Vector2f GetGravity() const; cpSpace* GetHandle() const; float GetStepSize() const; @@ -55,6 +67,7 @@ namespace Nz void RegisterCallbacks(unsigned int collisionId, const Callback& callbacks); void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks); + void SetDamping(float dampingValue); void SetGravity(const Vector2f& gravity); void SetStepSize(float stepSize); @@ -72,6 +85,22 @@ namespace Nz void* userdata; }; + struct DebugDrawOptions + { + Color constraintColor; + Color collisionPointColor; + Color shapeOutlineColor; + + DebugDrawCircleCallback circleCallback; + DebugDrawGetColorCallback colorCallback; + DebugDrawDotCallback dotCallback; + DebugDrawPolygonCallback polygonCallback; + DebugDrawSegmentCallback segmentCallback; + DebugDrawTickSegmentCallback thickSegmentCallback; + + void* userdata; + }; + struct NearestQueryResult { Nz::RigidBody2D* nearestBody; diff --git a/include/Nazara/Physics2D/Physics2D.hpp b/include/Nazara/Physics2D/Physics2D.hpp index 3a9f2b731..73387980e 100644 --- a/include/Nazara/Physics2D/Physics2D.hpp +++ b/include/Nazara/Physics2D/Physics2D.hpp @@ -8,7 +8,6 @@ #define NAZARA_PHYSICS2D_HPP #include -#include #include namespace Nz diff --git a/include/Nazara/Physics2D/RigidBody2D.hpp b/include/Nazara/Physics2D/RigidBody2D.hpp index f2b3da2d7..4494c690c 100644 --- a/include/Nazara/Physics2D/RigidBody2D.hpp +++ b/include/Nazara/Physics2D/RigidBody2D.hpp @@ -10,12 +10,10 @@ #include #include #include -#include -#include #include -#include #include #include +#include struct cpBody; @@ -44,22 +42,26 @@ namespace Nz const Collider2DRef& GetGeom() const; cpBody* GetHandle() const; float GetMass() const; + float GetMomentOfInertia() const; Vector2f GetPosition() const; float GetRotation() const; + std::size_t GetShapeIndex(cpShape* shape) const; void* GetUserdata() const; Vector2f GetVelocity() const; PhysWorld2D* GetWorld() const; - bool IsMoveable() const; + bool IsKinematic() const; bool IsSleeping() const; + bool IsStatic() const; void SetAngularVelocity(float angularVelocity); - void SetGeom(Collider2DRef geom); - void SetMass(float mass); + void SetGeom(Collider2DRef geom, bool recomputeMoment = true); + void SetMass(float mass, bool recomputeMoment = true); void SetMassCenter(const Vector2f& center); void SetMomentOfInertia(float moment); void SetPosition(const Vector2f& position); void SetRotation(float rotation); + void SetStatic(bool setStaticBody = true); void SetUserdata(void* ud); void SetVelocity(const Vector2f& velocity); @@ -69,8 +71,11 @@ namespace Nz NazaraSignal(OnRigidBody2DMove, RigidBody2D* /*oldPointer*/, RigidBody2D* /*newPointer*/); NazaraSignal(OnRigidBody2DRelease, RigidBody2D* /*rigidBody*/); + static constexpr std::size_t InvalidShapeIndex = std::numeric_limits::max(); + private: - void Create(float mass = 1.f, float moment = 1.f); + void CopyBodyData(cpBody* body); + cpBody* Create(float mass = 1.f, float moment = 1.f); void Destroy(); std::vector m_shapes; @@ -78,9 +83,10 @@ namespace Nz cpBody* m_handle; void* m_userData; PhysWorld2D* m_world; + bool m_isStatic; float m_gravityFactor; float m_mass; }; } -#endif // NAZARA_RIGIDBODY3D_HPP +#endif // NAZARA_RIGIDBODY2D_HPP diff --git a/include/Nazara/Physics3D/Collider3D.hpp b/include/Nazara/Physics3D/Collider3D.hpp index d8300bdf2..b7a5fe08c 100644 --- a/include/Nazara/Physics3D/Collider3D.hpp +++ b/include/Nazara/Physics3D/Collider3D.hpp @@ -8,7 +8,6 @@ #define NAZARA_COLLIDER3D_HPP #include -#include #include #include #include @@ -32,6 +31,7 @@ namespace Nz ///TODO: TreeGeom class Collider3D; + class PrimitiveList; class PhysWorld3D; using Collider3DConstRef = ObjectRef; diff --git a/include/Nazara/Physics3D/PhysWorld3D.hpp b/include/Nazara/Physics3D/PhysWorld3D.hpp index 633be2b61..db6c5af00 100644 --- a/include/Nazara/Physics3D/PhysWorld3D.hpp +++ b/include/Nazara/Physics3D/PhysWorld3D.hpp @@ -8,7 +8,6 @@ #define NAZARA_PHYSWORLD_HPP #include -#include #include #include diff --git a/include/Nazara/Physics3D/Physics3D.hpp b/include/Nazara/Physics3D/Physics3D.hpp index b0d6f69f5..d97e7405d 100644 --- a/include/Nazara/Physics3D/Physics3D.hpp +++ b/include/Nazara/Physics3D/Physics3D.hpp @@ -8,7 +8,6 @@ #define NAZARA_PHYSICS3D_HPP #include -#include #include namespace Nz diff --git a/include/Nazara/Platform.hpp b/include/Nazara/Platform.hpp new file mode 100644 index 000000000..51d4e0a32 --- /dev/null +++ b/include/Nazara/Platform.hpp @@ -0,0 +1,47 @@ +// This file was automatically generated + +/* + Nazara Engine - Platform module + + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_GLOBAL_PLATFORM_HPP +#define NAZARA_GLOBAL_PLATFORM_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // NAZARA_GLOBAL_PLATFORM_HPP diff --git a/include/Nazara/Platform/Config.hpp b/include/Nazara/Platform/Config.hpp new file mode 100644 index 000000000..6bb056f27 --- /dev/null +++ b/include/Nazara/Platform/Config.hpp @@ -0,0 +1,54 @@ +/* + Nazara Engine - Platform module + + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_CONFIG_PLATFORM_HPP +#define NAZARA_CONFIG_PLATFORM_HPP + +/// Each modification of a parameter needs a recompilation of the module + +// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower) +#define NAZARA_PLATFORM_MANAGE_MEMORY 0 + +// Activate the security tests based on the code (Advised for development) +#define NAZARA_PLATFORM_SAFE 1 + +// Protect the classes against data race +//#define NAZARA_PLATFORM_THREADSAFE 1 + +// On Windows, ALT and F10 keys do not activate the window menu +#define NAZARA_PLATFORM_WINDOWS_DISABLE_MENU_KEYS 1 + +#if defined(NAZARA_STATIC) + #define NAZARA_PLATFORM_API +#else + #ifdef NAZARA_PLATFORM_BUILD + #define NAZARA_PLATFORM_API NAZARA_EXPORT + #else + #define NAZARA_PLATFORM_API NAZARA_IMPORT + #endif +#endif + +#endif // NAZARA_CONFIG_PLATFORM_HPP diff --git a/include/Nazara/Platform/ConfigCheck.hpp b/include/Nazara/Platform/ConfigCheck.hpp new file mode 100644 index 000000000..2b58e4586 --- /dev/null +++ b/include/Nazara/Platform/ConfigCheck.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Platform module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_CONFIG_CHECK_PLATFORM_HPP +#define NAZARA_CONFIG_CHECK_PLATFORM_HPP + +/// This file is used to check the constant values defined in Config.hpp + +#include +#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) + +// We force the value of MANAGE_MEMORY in debug +#if defined(NAZARA_DEBUG) && !NAZARA_PLATFORM_MANAGE_MEMORY + #undef NAZARA_PLATFORM_MANAGE_MEMORY + #define NAZARA_PLATFORM_MANAGE_MEMORY 0 +#endif + +#undef NazaraCheckTypeAndVal + +#endif // NAZARA_CONFIG_CHECK_PLATFORM_HPP diff --git a/include/Nazara/Utility/Cursor.hpp b/include/Nazara/Platform/Cursor.hpp similarity index 85% rename from include/Nazara/Utility/Cursor.hpp rename to include/Nazara/Platform/Cursor.hpp index 870b17b55..7cf5c979d 100644 --- a/include/Nazara/Utility/Cursor.hpp +++ b/include/Nazara/Platform/Cursor.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -10,7 +10,8 @@ #include #include #include -#include +#include +#include #include #include @@ -23,9 +24,9 @@ namespace Nz using CursorConstRef = ObjectRef; using CursorRef = ObjectRef; - class NAZARA_UTILITY_API Cursor : public RefCounted + class NAZARA_PLATFORM_API Cursor : public RefCounted { - friend class Utility; + friend class Platform; friend class WindowImpl; public: @@ -66,6 +67,6 @@ namespace Nz }; } -#include +#include #endif // NAZARA_CURSOR_HPP diff --git a/include/Nazara/Utility/Cursor.inl b/include/Nazara/Platform/Cursor.inl similarity index 88% rename from include/Nazara/Utility/Cursor.inl rename to include/Nazara/Platform/Cursor.inl index 58d15bdec..5177faeea 100644 --- a/include/Nazara/Utility/Cursor.inl +++ b/include/Nazara/Platform/Cursor.inl @@ -1,10 +1,9 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include -#include +#include namespace Nz { @@ -66,4 +65,4 @@ namespace Nz } } -#include +#include diff --git a/include/Nazara/Utility/CursorController.hpp b/include/Nazara/Platform/CursorController.hpp similarity index 85% rename from include/Nazara/Utility/CursorController.hpp rename to include/Nazara/Platform/CursorController.hpp index 0c2943356..07c86e92b 100644 --- a/include/Nazara/Utility/CursorController.hpp +++ b/include/Nazara/Platform/CursorController.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include namespace Nz { @@ -37,6 +37,6 @@ namespace Nz }; } -#include +#include #endif // NAZARA_CURSORCONTROLLER_HPP diff --git a/include/Nazara/Utility/CursorController.inl b/include/Nazara/Platform/CursorController.inl similarity index 56% rename from include/Nazara/Utility/CursorController.inl rename to include/Nazara/Platform/CursorController.inl index b1f54d05a..75260b66d 100644 --- a/include/Nazara/Utility/CursorController.inl +++ b/include/Nazara/Platform/CursorController.inl @@ -1,9 +1,9 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include +#include +#include namespace Nz { @@ -13,4 +13,4 @@ namespace Nz } } -#include +#include diff --git a/include/Nazara/Platform/Debug.hpp b/include/Nazara/Platform/Debug.hpp new file mode 100644 index 000000000..94d6e9134 --- /dev/null +++ b/include/Nazara/Platform/Debug.hpp @@ -0,0 +1,8 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Platform module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#if NAZARA_PLATFORM_MANAGE_MEMORY + #include +#endif diff --git a/include/Nazara/Platform/DebugOff.hpp b/include/Nazara/Platform/DebugOff.hpp new file mode 100644 index 000000000..d6072e479 --- /dev/null +++ b/include/Nazara/Platform/DebugOff.hpp @@ -0,0 +1,9 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Platform module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +// We suppose that Debug.hpp is already included, same goes for Config.hpp +#if NAZARA_PLATFORM_MANAGE_MEMORY + #undef delete + #undef new +#endif diff --git a/include/Nazara/Platform/Enums.hpp b/include/Nazara/Platform/Enums.hpp new file mode 100644 index 000000000..77b69f65e --- /dev/null +++ b/include/Nazara/Platform/Enums.hpp @@ -0,0 +1,84 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Platform module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ENUMS_PLATFORM_HPP +#define NAZARA_ENUMS_PLATFORM_HPP + +#include + +namespace Nz +{ + enum SystemCursor + { + SystemCursor_Crosshair, + SystemCursor_Default, + SystemCursor_Hand, + SystemCursor_Help, + SystemCursor_Move, + SystemCursor_None, + SystemCursor_Pointer, + SystemCursor_Progress, + SystemCursor_ResizeE, + SystemCursor_ResizeN, + SystemCursor_ResizeNE, + SystemCursor_ResizeNW, + SystemCursor_ResizeS, + SystemCursor_ResizeSE, + SystemCursor_ResizeSW, + SystemCursor_ResizeW, + SystemCursor_Text, + SystemCursor_Wait, + + SystemCursor_Max = SystemCursor_Wait + }; + + enum WindowEventType + { + WindowEventType_GainedFocus, + WindowEventType_LostFocus, + WindowEventType_KeyPressed, + WindowEventType_KeyReleased, + WindowEventType_MouseButtonDoubleClicked, + WindowEventType_MouseButtonPressed, + WindowEventType_MouseButtonReleased, + WindowEventType_MouseEntered, + WindowEventType_MouseLeft, + WindowEventType_MouseMoved, + WindowEventType_MouseWheelMoved, + WindowEventType_Moved, + WindowEventType_Quit, + WindowEventType_Resized, + WindowEventType_TextEntered, + + WindowEventType_Max = WindowEventType_TextEntered + }; + + enum WindowStyle + { + WindowStyle_None, ///< Window has no border nor titlebar. + WindowStyle_Fullscreen, ///< At the window creation, the OS tries to set it in fullscreen. + + WindowStyle_Closable, ///< Allows the window to be closed by a button in the titlebar, generating a Quit event. + WindowStyle_Resizable, ///< Allows the window to be resized by dragging its corners or by a button of the titlebar. + WindowStyle_Titlebar, ///< Adds a titlebar to the window, this option is automatically enabled if buttons of the titlebar are enabled. + + WindowStyle_Threaded, ///< Runs the window into a thread, allowing the application to keep updating while resizing/dragging the window. + + WindowStyle_Max = WindowStyle_Threaded + }; + + template<> + struct EnumAsFlags + { + static constexpr WindowStyle max = WindowStyle_Max; + }; + + using WindowStyleFlags = Flags; + + constexpr WindowStyleFlags WindowStyle_Default = WindowStyle_Closable | WindowStyle_Resizable | WindowStyle_Titlebar; +} + +#endif // NAZARA_ENUMS_PLATFORM_HPP diff --git a/include/Nazara/Utility/Event.hpp b/include/Nazara/Platform/Event.hpp similarity index 77% rename from include/Nazara/Utility/Event.hpp rename to include/Nazara/Platform/Event.hpp index b67eedc0c..ece401890 100644 --- a/include/Nazara/Utility/Event.hpp +++ b/include/Nazara/Platform/Event.hpp @@ -1,23 +1,23 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Interface inspirée de la SFML par Laurent Gomila +// Interface inspired by the SFML of Laurent Gomila (and its team) #pragma once #ifndef NAZARA_EVENT_HPP #define NAZARA_EVENT_HPP -#include -#include -#include +#include +#include +#include namespace Nz { struct WindowEvent { - // Utilisé par: + // Used by: // -WindowEventType_KeyPressed // -WindowEventType_KeyReleased struct KeyEvent @@ -30,7 +30,7 @@ namespace Nz bool system; }; - // Utilisé par: + // Used by: // -WindowEventType_MouseButtonDoubleClicked // -WindowEventType_MouseButtonPressed struct MouseButtonEvent @@ -40,7 +40,7 @@ namespace Nz unsigned int y; }; - // Utilisé par: + // Used by: // -WindowEventType_MouseMoved struct MouseMoveEvent { @@ -50,14 +50,14 @@ namespace Nz unsigned int y; }; - // Utilisé par: + // Used by: // -WindowEventType_MouseWheelMoved struct MouseWheelEvent { float delta; }; - // Utilisé par: + // Used by: // -WindowEventType_Moved struct PositionEvent { @@ -65,7 +65,7 @@ namespace Nz int y; }; - // Utilisé par: + // Used by: // -WindowEventType_Resized struct SizeEvent { @@ -73,7 +73,7 @@ namespace Nz unsigned int width; }; - // Utilisé par: + // Used by: // -WindowEventType_TextEntered struct TextEvent { @@ -85,33 +85,33 @@ namespace Nz union { - // Utilisé par: + // Used by: // -WindowEventType_KeyPressed // -WindowEventType_KeyReleased KeyEvent key; - // Utilisé par: + // Used by: // -WindowEventType_MouseButtonDoubleClicked // -WindowEventType_MouseButtonPressed MouseButtonEvent mouseButton; - // Utilisé par: + // Used by: // -WindowEventType_MouseMoved MouseMoveEvent mouseMove; - // Utilisé par: + // Used by: // -WindowEventType_MouseWheelMoved MouseWheelEvent mouseWheel; - // Utilisé par: + // Used by: // -WindowEventType_Moved PositionEvent position; - // Utilisé par: + // Used by: // -WindowEventType_Resized SizeEvent size; - // Utilisé par: + // Used by: // -WindowEventType_TextEntered TextEvent text; }; diff --git a/include/Nazara/Utility/EventHandler.hpp b/include/Nazara/Platform/EventHandler.hpp similarity index 93% rename from include/Nazara/Utility/EventHandler.hpp rename to include/Nazara/Platform/EventHandler.hpp index 78cba94bc..b2390c35e 100644 --- a/include/Nazara/Utility/EventHandler.hpp +++ b/include/Nazara/Platform/EventHandler.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include namespace Nz { @@ -52,6 +52,6 @@ namespace Nz }; } -#include +#include #endif // NAZARA_EVENTHANDLER_HPP diff --git a/include/Nazara/Utility/EventHandler.inl b/include/Nazara/Platform/EventHandler.inl similarity index 90% rename from include/Nazara/Utility/EventHandler.inl rename to include/Nazara/Platform/EventHandler.inl index 39191300d..6cc31efe5 100644 --- a/include/Nazara/Utility/EventHandler.inl +++ b/include/Nazara/Platform/EventHandler.inl @@ -1,10 +1,10 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include -#include +#include namespace Nz { @@ -82,4 +82,4 @@ namespace Nz } } -#include +#include diff --git a/include/Nazara/Utility/Icon.hpp b/include/Nazara/Platform/Icon.hpp similarity index 76% rename from include/Nazara/Utility/Icon.hpp rename to include/Nazara/Platform/Icon.hpp index db93e9495..7426cf265 100644 --- a/include/Nazara/Utility/Icon.hpp +++ b/include/Nazara/Platform/Icon.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -9,8 +9,7 @@ #include #include -#include -#include +#include namespace Nz { @@ -21,7 +20,7 @@ namespace Nz using IconRef = ObjectRef; - class NAZARA_UTILITY_API Icon : public RefCounted + class NAZARA_PLATFORM_API Icon : public RefCounted { friend class WindowImpl; @@ -42,6 +41,6 @@ namespace Nz }; } -#include +#include #endif // NAZARA_ICON_HPP diff --git a/include/Nazara/Utility/Icon.inl b/include/Nazara/Platform/Icon.inl similarity index 78% rename from include/Nazara/Utility/Icon.inl rename to include/Nazara/Platform/Icon.inl index 5c6b60068..d2b1a5318 100644 --- a/include/Nazara/Utility/Icon.inl +++ b/include/Nazara/Platform/Icon.inl @@ -1,10 +1,9 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include -#include +#include namespace Nz { @@ -39,4 +38,4 @@ namespace Nz } } -#include +#include diff --git a/include/Nazara/Utility/Joystick.hpp b/include/Nazara/Platform/Joystick.hpp similarity index 82% rename from include/Nazara/Utility/Joystick.hpp rename to include/Nazara/Platform/Joystick.hpp index f80b4b590..eb961b87d 100644 --- a/include/Nazara/Utility/Joystick.hpp +++ b/include/Nazara/Platform/Joystick.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -12,7 +12,7 @@ namespace Nz { - class NAZARA_UTILITY_API Joystick + class NAZARA_PLATFORM_API Joystick { public: Joystick() = delete; diff --git a/include/Nazara/Utility/Keyboard.hpp b/include/Nazara/Platform/Keyboard.hpp similarity index 81% rename from include/Nazara/Utility/Keyboard.hpp rename to include/Nazara/Platform/Keyboard.hpp index bfd050d73..df0513c2d 100644 --- a/include/Nazara/Utility/Keyboard.hpp +++ b/include/Nazara/Platform/Keyboard.hpp @@ -1,8 +1,8 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Interface inspirée de la SFML par Laurent Gomila +// Interface inspired by the SFML of Laurent Gomila (and its team) #pragma once @@ -11,11 +11,11 @@ #include #include -#include +#include namespace Nz { - class NAZARA_UTILITY_API Keyboard + class NAZARA_PLATFORM_API Keyboard { public: enum Key @@ -50,7 +50,7 @@ namespace Nz Y, Z, - // Touches de fonction + // Functional keys F1, F2, F3, @@ -67,13 +67,13 @@ namespace Nz F14, F15, - // Flèches directionnelles + // Directional keys Down, Left, Right, Up, - // Pavé numérique + // Numerical pad Add, Decimal, Divide, @@ -90,7 +90,7 @@ namespace Nz Numpad9, Subtract, - // Divers + // Various Backslash, Backspace, Clear, @@ -136,7 +136,7 @@ namespace Nz Tab, Tilde, - // Touches navigateur + // Navigator keys Browser_Back, Browser_Favorites, Browser_Forward, @@ -145,18 +145,18 @@ namespace Nz Browser_Search, Browser_Stop, - // Touches de contrôle de lecture + // Lecture control keys Media_Next, Media_Play, Media_Previous, Media_Stop, - // Touches de contrôle du volume + // Volume control keys Volume_Down, Volume_Mute, Volume_Up, - // Touches à verrouillage + // Locking keys CapsLock, NumLock, ScrollLock, diff --git a/include/Nazara/Utility/Mouse.hpp b/include/Nazara/Platform/Mouse.hpp similarity index 82% rename from include/Nazara/Utility/Mouse.hpp rename to include/Nazara/Platform/Mouse.hpp index 552011904..74af3a419 100644 --- a/include/Nazara/Utility/Mouse.hpp +++ b/include/Nazara/Platform/Mouse.hpp @@ -1,8 +1,8 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Interface inspirée de la SFML par Laurent Gomila +// Interface inspired by the SFML of Laurent Gomila (and its team) #pragma once @@ -11,13 +11,13 @@ #include #include -#include +#include namespace Nz { class Window; - class NAZARA_UTILITY_API Mouse + class NAZARA_PLATFORM_API Mouse { public: enum Button diff --git a/include/Nazara/Platform/Platform.hpp b/include/Nazara/Platform/Platform.hpp new file mode 100644 index 000000000..59a36ebc5 --- /dev/null +++ b/include/Nazara/Platform/Platform.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Platform module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_PLATFORM_HPP +#define NAZARA_PLATFORM_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_PLATFORM_API Platform + { + public: + Platform() = delete; + ~Platform() = delete; + + static bool Initialize(); + + static bool IsInitialized(); + + static void Uninitialize(); + + private: + static unsigned int s_moduleReferenceCounter; + }; +} + +#endif // NAZARA_PLATFORM_HPP diff --git a/include/Nazara/Utility/VideoMode.hpp b/include/Nazara/Platform/VideoMode.hpp similarity index 88% rename from include/Nazara/Utility/VideoMode.hpp rename to include/Nazara/Platform/VideoMode.hpp index 4d6a77768..364da9488 100644 --- a/include/Nazara/Utility/VideoMode.hpp +++ b/include/Nazara/Platform/VideoMode.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp // Interface inspirée de la SFML par Laurent Gomila @@ -10,12 +10,12 @@ #define NAZARA_VIDEOMODE_HPP #include -#include +#include #include namespace Nz { - class NAZARA_UTILITY_API VideoMode + class NAZARA_PLATFORM_API VideoMode { public: VideoMode(); diff --git a/include/Nazara/Utility/Window.hpp b/include/Nazara/Platform/Window.hpp similarity index 84% rename from include/Nazara/Utility/Window.hpp rename to include/Nazara/Platform/Window.hpp index b9cbdb6fb..28c77d76f 100644 --- a/include/Nazara/Utility/Window.hpp +++ b/include/Nazara/Platform/Window.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp // Interface inspirée de la SFML par Laurent Gomila @@ -11,36 +11,36 @@ #include #include +#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include namespace Nz { - class Image; class WindowImpl; - class NAZARA_UTILITY_API Window + class NAZARA_PLATFORM_API Window { friend WindowImpl; friend class Mouse; - friend class Utility; + friend class Platform; public: Window(); inline Window(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default); inline explicit Window(WindowHandle handle); Window(const Window&) = delete; - inline Window(Window&& window) noexcept; + Window(Window&&) = default; virtual ~Window(); inline void Close(); @@ -62,12 +62,10 @@ namespace Nz inline CursorController& GetCursorController(); inline EventHandler& GetEventHandler(); WindowHandle GetHandle() const; - unsigned int GetHeight() const; Vector2i GetPosition() const; Vector2ui GetSize() const; WindowStyleFlags GetStyle() const; String GetTitle() const; - unsigned int GetWidth() const; bool HasFocus() const; @@ -103,14 +101,14 @@ namespace Nz bool WaitEvent(WindowEvent* event); Window& operator=(const Window&) = delete; - inline Window& operator=(Window&& window); + Window& operator=(Window&&) = default; protected: virtual bool OnWindowCreated(); virtual void OnWindowDestroy(); virtual void OnWindowResized(); - WindowImpl* m_impl; + MovablePtr m_impl; private: void IgnoreNextMouseEvent(int mouseX, int mouseY) const; @@ -138,6 +136,6 @@ namespace Nz }; } -#include +#include #endif // NAZARA_WINDOW_HPP diff --git a/include/Nazara/Utility/Window.inl b/include/Nazara/Platform/Window.inl similarity index 57% rename from include/Nazara/Utility/Window.inl rename to include/Nazara/Platform/Window.inl index c81c89b80..9ce95a78a 100644 --- a/include/Nazara/Utility/Window.inl +++ b/include/Nazara/Platform/Window.inl @@ -1,11 +1,10 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include -#include +#include namespace Nz { @@ -27,26 +26,6 @@ namespace Nz Create(handle); } - /*! - * \brief Constructs a Window object by moving another one - */ - inline Window::Window(Window&& window) noexcept : - m_impl(window.m_impl), - m_events(std::move(window.m_events)), - m_pendingEvents(std::move(window.m_pendingEvents)), - m_eventCondition(std::move(window.m_eventCondition)), - m_eventHandler(std::move(window.m_eventHandler)), - m_eventMutex(std::move(window.m_eventMutex)), - m_eventConditionMutex(std::move(window.m_eventConditionMutex)), - m_closed(window.m_closed), - m_closeOnQuit(window.m_closeOnQuit), - m_eventPolling(window.m_eventPolling), - m_ownsWindow(window.m_ownsWindow), - m_waitForEvent(window.m_waitForEvent) - { - window.m_impl = nullptr; - } - inline void Window::Close() { m_closed = true; // The window will be closed at the next non-const IsOpen() call @@ -145,32 +124,6 @@ namespace Nz } } } - - /*! - * \brief Moves a window to another window object - * \return A reference to the object - */ - inline Window& Window::operator=(Window&& window) - { - Destroy(); - - m_closed = window.m_closed; - m_closeOnQuit = window.m_closeOnQuit; - m_eventCondition = std::move(window.m_eventCondition); - m_eventConditionMutex = std::move(window.m_eventConditionMutex); - m_eventHandler = std::move(window.m_eventHandler); - m_eventMutex = std::move(window.m_eventMutex); - m_eventPolling = window.m_eventPolling; - m_impl = window.m_impl; - m_events = std::move(window.m_events); - m_pendingEvents = std::move(window.m_pendingEvents); - m_ownsWindow = window.m_ownsWindow; - m_waitForEvent = window.m_waitForEvent; - - window.m_impl = nullptr; - - return *this; - } } -#include +#include diff --git a/include/Nazara/Utility/WindowHandle.hpp b/include/Nazara/Platform/WindowHandle.hpp similarity index 91% rename from include/Nazara/Utility/WindowHandle.hpp rename to include/Nazara/Platform/WindowHandle.hpp index f49a400e0..ea034d4e8 100644 --- a/include/Nazara/Utility/WindowHandle.hpp +++ b/include/Nazara/Platform/WindowHandle.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once diff --git a/include/Nazara/Renderer.hpp b/include/Nazara/Renderer.hpp index b7262434a..d733c1032 100644 --- a/include/Nazara/Renderer.hpp +++ b/include/Nazara/Renderer.hpp @@ -30,13 +30,30 @@ #define NAZARA_GLOBAL_RENDERER_HPP #include +#include +#include #include +#include +#include +#include #include +#include #include #include +#include #include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include #endif // NAZARA_GLOBAL_RENDERER_HPP diff --git a/include/Nazara/Renderer/DebugDrawer.hpp b/include/Nazara/Renderer/DebugDrawer.hpp new file mode 100644 index 000000000..ad893cf35 --- /dev/null +++ b/include/Nazara/Renderer/DebugDrawer.hpp @@ -0,0 +1,61 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_DEBUGDRAWER_HPP +#define NAZARA_DEBUGDRAWER_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class Skeleton; + class StaticMesh; + + class NAZARA_RENDERER_API DebugDrawer + { + public: + static void Draw(const BoundingVolumef& volume); + static void Draw(const Boxf& box); + static void Draw(const Boxi& box); + static void Draw(const Boxui& box); + static void Draw(const Frustumf& frustum); + static void Draw(const OrientedBoxf& orientedBox); + static void Draw(const Skeleton* skeleton); + static void Draw(const Vector3f& position, float size = 0.1f); + static void DrawAxes(const Vector3f& position = Vector3f::Zero(), float size = 1.f); + static void DrawBinormals(const StaticMesh* subMesh); + static void DrawCone(const Vector3f& origin, const Quaternionf& rotation, float angle, float length); + static void DrawLine(const Vector3f& p1, const Vector3f& p2); + static void DrawPoints(const Vector3f* ptr, unsigned int pointCount); + static void DrawNormals(const StaticMesh* subMesh); + static void DrawTangents(const StaticMesh* subMesh); + + static void EnableDepthBuffer(bool depthBuffer); + + static float GetLineWidth(); + static float GetPointSize(); + static Color GetPrimaryColor(); + static Color GetSecondaryColor(); + + static bool Initialize(); + static bool IsDepthBufferEnabled(); + + static void SetLineWidth(float width); + static void SetPointSize(float size); + static void SetPrimaryColor(const Color& color); + static void SetSecondaryColor(const Color& color); + + static void Uninitialize(); + }; +} + +#endif // NAZARA_DEBUG_DRAWER_HPP diff --git a/include/Nazara/Renderer/GlslWriter.hpp b/include/Nazara/Renderer/GlslWriter.hpp new file mode 100644 index 000000000..3767846b9 --- /dev/null +++ b/include/Nazara/Renderer/GlslWriter.hpp @@ -0,0 +1,88 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_GLSLWRITER_HPP +#define NAZARA_GLSLWRITER_HPP + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_RENDERER_API GlslWriter : public ShaderWriter + { + public: + GlslWriter(); + GlslWriter(const GlslWriter&) = delete; + GlslWriter(GlslWriter&&) = delete; + ~GlslWriter() = default; + + Nz::String Generate(const ShaderAst::StatementPtr& node) override; + + void RegisterFunction(const String& name, ShaderAst::StatementPtr statement, std::initializer_list parameters, ShaderAst::ExpressionType ret) override; + void RegisterVariable(ShaderAst::VariableType kind, const String& name, ShaderAst::ExpressionType type) override; + + void SetGlslVersion(unsigned int version); + + void Write(const ShaderAst::AssignOp& node) override; + void Write(const ShaderAst::Branch& node) override; + void Write(const ShaderAst::BinaryOp& node) override; + void Write(const ShaderAst::BuiltinVariable& node) override; + void Write(const ShaderAst::Cast& node) override; + void Write(const ShaderAst::Constant& node) override; + void Write(const ShaderAst::ExpressionStatement& node) override; + void Write(const ShaderAst::NamedVariable& node) override; + void Write(const ShaderAst::NodePtr& node) override; + void Write(const ShaderAst::StatementBlock& node) override; + void Write(const ShaderAst::SwizzleOp& node) override; + + private: + struct Function; + using VariableContainer = std::set>; + + void Append(ShaderAst::BuiltinEntry builtin); + void Append(ShaderAst::ExpressionType type); + void Append(const String& txt); + void AppendCommentSection(const String& section); + void AppendFunction(Function& func); + void AppendLine(const String& txt = String()); + + void DeclareVariables(const VariableContainer& variables, const String& keyword = String(), const String& section = String()); + + void EnterScope(); + void LeaveScope(); + + + struct Function + { + VariableContainer variables; + std::vector parameters; + ShaderAst::ExpressionType retType; + ShaderAst::StatementPtr node; + String name; + }; + + struct State + { + VariableContainer inputs; + VariableContainer outputs; + VariableContainer uniforms; + StringStream stream; + unsigned int indentLevel = 0; + }; + + std::unordered_map m_functions; + Function* m_currentFunction; + State* m_currentState; + unsigned int m_glslVersion; + }; +} + +#endif // NAZARA_GLSLWRITER_HPP diff --git a/include/Nazara/Renderer/RenderWindow.hpp b/include/Nazara/Renderer/RenderWindow.hpp index ce9f76026..b6bd9edf9 100644 --- a/include/Nazara/Renderer/RenderWindow.hpp +++ b/include/Nazara/Renderer/RenderWindow.hpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include namespace Nz diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp new file mode 100644 index 000000000..8db02e356 --- /dev/null +++ b/include/Nazara/Renderer/Shader.hpp @@ -0,0 +1,134 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SHADER_HPP +#define NAZARA_SHADER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class Color; + class Shader; + class ShaderStage; + + using ShaderConstRef = ObjectRef; + using ShaderLibrary = ObjectLibrary; + using ShaderRef = ObjectRef; + + class NAZARA_RENDERER_API Shader : public RefCounted + { + friend ShaderLibrary; + friend class Renderer; + + public: + Shader(); + Shader(const Shader&) = delete; + Shader(Shader&&) = delete; + ~Shader(); + + void AttachStage(ShaderStageType stage, const ShaderStage& shaderStage); + bool AttachStageFromFile(ShaderStageType stage, const String& filePath); + bool AttachStageFromSource(ShaderStageType stage, const char* source, unsigned int length); + bool AttachStageFromSource(ShaderStageType stage, const String& source); + + void Bind() const; + + bool Create(); + void Destroy(); + + ByteArray GetBinary() const; + String GetLog() const; + String GetSourceCode(ShaderStageType stage) const; + int GetUniformLocation(const String& name) const; + int GetUniformLocation(ShaderUniform shaderUniform) const; + + bool HasStage(ShaderStageType stage) const; + + bool IsBinaryRetrievable() const; + bool IsLinked() const; + bool IsValid() const; + + bool Link(); + + bool LoadFromBinary(const void* buffer, unsigned int size); + bool LoadFromBinary(const ByteArray& byteArray); + + void SendBoolean(int location, bool value) const; + void SendColor(int location, const Color& color) const; + void SendDouble(int location, double value) const; + void SendDoubleArray(int location, const double* values, unsigned int count) const; + void SendFloat(int location, float value) const; + void SendFloatArray(int location, const float* values, unsigned int count) const; + void SendInteger(int location, int value) const; + void SendIntegerArray(int location, const int* values, unsigned int count) const; + void SendMatrix(int location, const Matrix4d& matrix) const; + void SendMatrix(int location, const Matrix4f& matrix) const; + void SendVector(int location, const Vector2d& vector) const; + void SendVector(int location, const Vector2f& vector) const; + void SendVector(int location, const Vector2i& vector) const; + void SendVector(int location, const Vector3d& vector) const; + void SendVector(int location, const Vector3f& vector) const; + void SendVector(int location, const Vector3i& vector) const; + void SendVector(int location, const Vector4d& vector) const; + void SendVector(int location, const Vector4f& vector) const; + void SendVector(int location, const Vector4i& vector) const; + void SendVectorArray(int location, const Vector2d* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector2f* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector2i* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector3d* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector3f* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector3i* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector4d* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector4f* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector4i* vectors, unsigned int count) const; + + bool Validate() const; + + // Fonctions OpenGL + unsigned int GetOpenGLID() const; + + Shader& operator=(const Shader&) = delete; + Shader& operator=(Shader&&) = delete; + + static bool IsStageSupported(ShaderStageType stage); + template static ShaderRef New(Args&&... args); + + // Signals: + NazaraSignal(OnShaderDestroy, const Shader* /*shader*/); + NazaraSignal(OnShaderRelease, const Shader* /*shader*/); + NazaraSignal(OnShaderUniformInvalidated, const Shader* /*shader*/); + + private: + bool PostLinkage(); + + static bool Initialize(); + static void Uninitialize(); + + std::vector m_attachedShaders[ShaderStageType_Max+1]; + bool m_linked; + int m_uniformLocations[ShaderUniform_Max+1]; + unsigned int m_program; + + static ShaderLibrary::LibraryMap s_library; + }; +} + +#include + +#endif // NAZARA_SHADER_HPP diff --git a/include/Nazara/Renderer/ShaderAst.hpp b/include/Nazara/Renderer/ShaderAst.hpp new file mode 100644 index 000000000..fd7c6dd30 --- /dev/null +++ b/include/Nazara/Renderer/ShaderAst.hpp @@ -0,0 +1,292 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SHADER_AST_HPP +#define NAZARA_SHADER_AST_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class ShaderWriter; + + namespace ShaderAst + { + enum class AssignType + { + Simple //< = + }; + + enum class BinaryType + { + Add, //< + + Substract, //< - + Multiply, //< * + Divide, //< / + Equality //< == + }; + + enum class BuiltinEntry + { + VertexPosition, // gl_Position + }; + + enum class ExpressionType + { + Boolean, // bool + Float1, // float + Float2, // vec2 + Float3, // vec3 + Float4, // vec4 + Mat4x4, // mat4 + + Void // void + }; + + enum class SwizzleComponent + { + First, + Second, + Third, + Fourth + }; + + enum class VariableType + { + Builtin, + Input, + Output, + Parameter, + Uniform, + Variable + }; + + ////////////////////////////////////////////////////////////////////////// + + class Node; + + using NodePtr = std::shared_ptr; + + class NAZARA_RENDERER_API Node + { + public: + virtual ~Node() = default; + + virtual void Register(ShaderWriter& visitor) = 0; + virtual void Visit(ShaderWriter& visitor) = 0; + + static inline unsigned int GetComponentCount(ExpressionType type); + static inline ExpressionType GetComponentType(ExpressionType type); + }; + + class Statement; + + using StatementPtr = std::shared_ptr; + + class NAZARA_RENDERER_API Statement : public Node + { + }; + + class Expression; + + using ExpressionPtr = std::shared_ptr; + + class NAZARA_RENDERER_API Expression : public Node + { + public: + virtual ExpressionType GetExpressionType() const = 0; + }; + + class NAZARA_RENDERER_API ExpressionStatement : public Statement + { + public: + inline explicit ExpressionStatement(ExpressionPtr expr); + + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + ExpressionPtr expression; + }; + + ////////////////////////////////////////////////////////////////////////// + + class NAZARA_RENDERER_API ConditionalStatement : public Statement + { + public: + inline ConditionalStatement(const String& condition, StatementPtr statementPtr); + + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + String conditionName; + StatementPtr statement; + }; + + class NAZARA_RENDERER_API StatementBlock : public Statement + { + public: + template explicit StatementBlock(Args&&... args); + + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + std::vector statements; + }; + + class Variable; + + using VariablePtr = std::shared_ptr; + + class NAZARA_RENDERER_API Variable : public Expression + { + public: + inline Variable(VariableType varKind, ExpressionType varType); + + ExpressionType GetExpressionType() const override; + + ExpressionType type; + VariableType kind; + }; + + + class NAZARA_RENDERER_API BuiltinVariable : public Variable + { + public: + inline BuiltinVariable(BuiltinEntry variable, ExpressionType varType); + + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + BuiltinEntry var; + }; + + + class NamedVariable; + + using NamedVariablePtr = std::shared_ptr; + + class NAZARA_RENDERER_API NamedVariable : public Variable + { + public: + inline NamedVariable(VariableType varKind, const Nz::String& varName, ExpressionType varType); + + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + Nz::String name; + }; + + ////////////////////////////////////////////////////////////////////////// + + class NAZARA_RENDERER_API AssignOp : public Expression + { + public: + inline AssignOp(AssignType Op, VariablePtr Var, ExpressionPtr Right); + + ExpressionType GetExpressionType() const override; + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + AssignType op; + VariablePtr variable; + ExpressionPtr right; + }; + + class NAZARA_RENDERER_API BinaryOp : public Expression + { + public: + inline BinaryOp(BinaryType Op, ExpressionPtr Left, ExpressionPtr Right); + + ExpressionType GetExpressionType() const override; + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + BinaryType op; + ExpressionPtr left; + ExpressionPtr right; + }; + + class NAZARA_RENDERER_API Branch : public Statement + { + public: + inline Branch(ExpressionPtr condition, StatementPtr trueStatement, StatementPtr falseStatement = nullptr); + + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + struct ConditionalStatement + { + ExpressionPtr condition; + StatementPtr statement; + }; + + std::vector condStatements; + StatementPtr elseStatement; + }; + + class NAZARA_RENDERER_API Cast : public Expression + { + public: + inline Cast(ExpressionType castTo, ExpressionPtr first, ExpressionPtr second = nullptr, ExpressionPtr third = nullptr, ExpressionPtr fourth = nullptr); + + ExpressionType GetExpressionType() const override; + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + ExpressionType exprType; + std::array expressions; + }; + + class NAZARA_RENDERER_API Constant : public Expression + { + public: + inline explicit Constant(bool value); + inline explicit Constant(float value); + inline explicit Constant(const Vector2f& value); + inline explicit Constant(const Vector3f& value); + inline explicit Constant(const Vector4f& value); + + ExpressionType GetExpressionType() const override; + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + ExpressionType exprType; + + union + { + bool bool1; + float vec1; + Vector2f vec2; + Vector3f vec3; + Vector4f vec4; + } values; + }; + + class NAZARA_RENDERER_API SwizzleOp : public Expression + { + public: + inline SwizzleOp(ExpressionPtr expressionPtr, std::initializer_list swizzleComponents); + + ExpressionType GetExpressionType() const override; + void Register(ShaderWriter& visitor) override; + void Visit(ShaderWriter& visitor) override; + + std::array components; + std::size_t componentCount; + ExpressionPtr expression; + }; + } +} + +#include + +#endif // NAZARA_SHADER_AST_HPP diff --git a/include/Nazara/Renderer/ShaderAst.inl b/include/Nazara/Renderer/ShaderAst.inl new file mode 100644 index 000000000..35bdab9fe --- /dev/null +++ b/include/Nazara/Renderer/ShaderAst.inl @@ -0,0 +1,231 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + namespace ShaderAst + { + inline unsigned int Node::GetComponentCount(ExpressionType type) + { + switch (type) + { + case ExpressionType::Float2: + return 2; + + case ExpressionType::Float3: + return 3; + + case ExpressionType::Float4: + return 4; + + case ExpressionType::Mat4x4: + return 4; + + default: + return 1; + } + } + + inline ExpressionType Node::GetComponentType(ExpressionType type) + { + switch (type) + { + case ExpressionType::Float2: + case ExpressionType::Float3: + case ExpressionType::Float4: + return ExpressionType::Float1; + + case ExpressionType::Mat4x4: + return ExpressionType::Float4; + + default: + return type; + } + } + + inline ExpressionStatement::ExpressionStatement(ExpressionPtr expr) : + expression(std::move(expr)) + { + } + + inline ConditionalStatement::ConditionalStatement(const String& condition, StatementPtr statementPtr) : + conditionName(condition), + statement(std::move(statementPtr)) + { + } + + template + StatementBlock::StatementBlock(Args&& ...args) : + statements({std::forward(args)...}) + { + } + + inline Variable::Variable(VariableType varKind, ExpressionType varType) : + type(varType), + kind(varKind) + { + } + + inline BuiltinVariable::BuiltinVariable(BuiltinEntry variable, ExpressionType varType) : + Variable(VariableType::Builtin, varType), + var(variable) + { + } + + inline NamedVariable::NamedVariable(VariableType varKind, const Nz::String& varName, ExpressionType varType) : + Variable(varKind, varType), + name(varName) + { + } + + inline AssignOp::AssignOp(AssignType Op, VariablePtr Var, ExpressionPtr Right) : + op(Op), + variable(std::move(Var)), + right(std::move(Right)) + { + } + + inline BinaryOp::BinaryOp(BinaryType Op, ExpressionPtr Left, ExpressionPtr Right) : + op(Op), + left(std::move(Left)), + right(std::move(Right)) + { + ExpressionType leftType = left->GetExpressionType(); + ExpressionType rightType = right->GetExpressionType(); + + if (leftType != rightType) + { + switch (op) + { + case BinaryType::Add: + case BinaryType::Equality: + case BinaryType::Substract: + { + //TODO: AstParseError + throw std::runtime_error("Left expression type must match right expression type"); + } + + case BinaryType::Multiply: + case BinaryType::Divide: + { + switch (leftType) + { + case ExpressionType::Float2: + case ExpressionType::Float3: + case ExpressionType::Float4: + { + if (rightType != ExpressionType::Float1) + throw std::runtime_error("Left expression type is not compatible with right expression type"); + + break; + } + + case ExpressionType::Mat4x4: + { + switch (rightType) + { + case ExpressionType::Float1: + case ExpressionType::Float4: + case ExpressionType::Mat4x4: + break; + + //TODO: AstParseError + default: + throw std::runtime_error("Left expression type is not compatible with right expression type"); + } + + break; + } + + default: + //TODO: AstParseError + throw std::runtime_error("Left expression type must match right expression type"); + } + } + } + } + } + + inline Branch::Branch(ExpressionPtr condition, StatementPtr trueStatement, StatementPtr falseStatement) + { + condStatements.emplace_back(ConditionalStatement{ std::move(condition), std::move(trueStatement) }); + elseStatement = std::move(falseStatement); + } + + inline Cast::Cast(ExpressionType castTo, ExpressionPtr first, ExpressionPtr second, ExpressionPtr third, ExpressionPtr fourth) : + exprType(castTo), + expressions({ {first, second, third, fourth} }) + { + unsigned int componentCount = 0; + unsigned int requiredComponents = GetComponentCount(exprType); + for (const auto& exprPtr : expressions) + { + if (!exprPtr) + break; + + componentCount += GetComponentCount(exprPtr->GetExpressionType()); + } + + //TODO: AstParseError + if (componentCount != requiredComponents) + throw std::runtime_error("Component count doesn't match required component count"); + } + + inline Constant::Constant(bool value) : + exprType(ExpressionType::Boolean) + { + values.bool1 = value; + } + + inline Constant::Constant(float value) : + exprType(ExpressionType::Float1) + { + values.vec1 = value; + } + + inline Constant::Constant(const Vector2f& value) : + exprType(ExpressionType::Float2) + { + values.vec2 = value; + } + + inline Constant::Constant(const Vector3f& value) : + exprType(ExpressionType::Float3) + { + values.vec3 = value; + } + + inline Constant::Constant(const Vector4f& value) : + exprType(ExpressionType::Float4) + { + values.vec4 = value; + } + + inline SwizzleOp::SwizzleOp(ExpressionPtr expressionPtr, std::initializer_list swizzleComponents) : + componentCount(swizzleComponents.size()), + expression(expressionPtr) + { + if (componentCount > 4) + throw std::runtime_error("Cannot swizzle more than four elements"); + + switch (expressionPtr->GetExpressionType()) + { + case ExpressionType::Float1: + case ExpressionType::Float2: + case ExpressionType::Float3: + case ExpressionType::Float4: + break; + + default: + throw std::runtime_error("Cannot swizzle this type"); + } + + std::copy(swizzleComponents.begin(), swizzleComponents.end(), components.begin()); + } + } +} + +#include diff --git a/include/Nazara/Renderer/ShaderBuilder.hpp b/include/Nazara/Renderer/ShaderBuilder.hpp new file mode 100644 index 000000000..97eddde62 --- /dev/null +++ b/include/Nazara/Renderer/ShaderBuilder.hpp @@ -0,0 +1,79 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SHADER_BUILDER_HPP +#define NAZARA_SHADER_BUILDER_HPP + +#include +#include +#include + +namespace Nz { namespace ShaderBuilder +{ + template + struct AssignOpBuilder + { + constexpr AssignOpBuilder() {} + + std::shared_ptr operator()(const ShaderAst::VariablePtr& left, const ShaderAst::ExpressionPtr& right) const; + }; + + template + struct BinOpBuilder + { + constexpr BinOpBuilder() {} + + std::shared_ptr operator()(const ShaderAst::ExpressionPtr& left, const ShaderAst::ExpressionPtr& right) const; + }; + + struct BuiltinBuilder + { + constexpr BuiltinBuilder() {} + + inline std::shared_ptr operator()(ShaderAst::BuiltinEntry builtin) const; + }; + + template + struct GenBuilder + { + constexpr GenBuilder() {} + + template std::shared_ptr operator()(Args&&... args) const; + }; + + template + struct VarBuilder + { + constexpr VarBuilder() {} + + template std::shared_ptr operator()(Args&&... args) const; + }; + + constexpr BinOpBuilder Add; + constexpr AssignOpBuilder Assign; + constexpr BuiltinBuilder Builtin; + constexpr GenBuilder Block; + constexpr GenBuilder Branch; + constexpr GenBuilder ConditionalStatement; + constexpr GenBuilder Constant; + constexpr BinOpBuilder Divide; + constexpr BinOpBuilder Equal; + constexpr GenBuilder ExprStatement; + constexpr VarBuilder Input; + constexpr BinOpBuilder Multiply; + constexpr VarBuilder Output; + constexpr VarBuilder Parameter; + constexpr GenBuilder Swizzle; + constexpr BinOpBuilder Substract; + constexpr VarBuilder Uniform; + constexpr VarBuilder Variable; + + template std::shared_ptr Cast(Args&&... args); +} } + +#include + +#endif // NAZARA_SHADER_BUILDER_HPP diff --git a/include/Nazara/Renderer/ShaderBuilder.inl b/include/Nazara/Renderer/ShaderBuilder.inl new file mode 100644 index 000000000..0de69b676 --- /dev/null +++ b/include/Nazara/Renderer/ShaderBuilder.inl @@ -0,0 +1,59 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz { namespace ShaderBuilder +{ + template + template + std::shared_ptr GenBuilder::operator()(Args&&... args) const + { + return std::make_shared(std::forward(args)...); + } + + template + std::shared_ptr AssignOpBuilder::operator()(const ShaderAst::VariablePtr& left, const ShaderAst::ExpressionPtr& right) const + { + return std::make_shared(op, left, right); + } + + template + std::shared_ptr BinOpBuilder::operator()(const ShaderAst::ExpressionPtr& left, const ShaderAst::ExpressionPtr& right) const + { + return std::make_shared(op, left, right); + } + + inline std::shared_ptr BuiltinBuilder::operator()(ShaderAst::BuiltinEntry builtin) const + { + ShaderAst::ExpressionType exprType = ShaderAst::ExpressionType::Void; + + switch (builtin) + { + case ShaderAst::BuiltinEntry::VertexPosition: + exprType = ShaderAst::ExpressionType::Float4; + break; + } + + NazaraAssert(exprType != ShaderAst::ExpressionType::Void, "Unhandled builtin"); + + return std::make_shared(builtin, exprType); + } + + template + template + std::shared_ptr VarBuilder::operator()(Args&&... args) const + { + return std::make_shared(type, std::forward(args)...); + } + + template + std::shared_ptr Cast(Args&&... args) + { + return std::make_shared(Type, std::forward(args)...); + } +} } + +#include diff --git a/include/Nazara/Renderer/ShaderWriter.hpp b/include/Nazara/Renderer/ShaderWriter.hpp new file mode 100644 index 000000000..13ef6e367 --- /dev/null +++ b/include/Nazara/Renderer/ShaderWriter.hpp @@ -0,0 +1,52 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SHADERWRITER_HPP +#define NAZARA_SHADERWRITER_HPP + +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_RENDERER_API ShaderWriter + { + public: + ShaderWriter() = default; + ShaderWriter(const ShaderWriter&) = delete; + ShaderWriter(ShaderWriter&&) = delete; + virtual ~ShaderWriter(); + + void EnableCondition(const String& name, bool cond); + + bool IsConditionEnabled(const String& name) const; + + virtual Nz::String Generate(const ShaderAst::StatementPtr& node) = 0; + + virtual void RegisterFunction(const String& name, ShaderAst::StatementPtr node, std::initializer_list parameters, ShaderAst::ExpressionType ret) = 0; + virtual void RegisterVariable(ShaderAst::VariableType kind, const String& name, ShaderAst::ExpressionType type) = 0; + + virtual void Write(const ShaderAst::AssignOp& node) = 0; + virtual void Write(const ShaderAst::Branch& node) = 0; + virtual void Write(const ShaderAst::BinaryOp& node) = 0; + virtual void Write(const ShaderAst::BuiltinVariable& node) = 0; + virtual void Write(const ShaderAst::Cast& node) = 0; + virtual void Write(const ShaderAst::Constant& node) = 0; + virtual void Write(const ShaderAst::ExpressionStatement& node) = 0; + virtual void Write(const ShaderAst::NamedVariable& node) = 0; + virtual void Write(const ShaderAst::NodePtr& node) = 0; + virtual void Write(const ShaderAst::StatementBlock& node) = 0; + virtual void Write(const ShaderAst::SwizzleOp& node) = 0; + + private: + std::unordered_set m_conditions; + }; +} + +#endif // NAZARA_SHADERWRITER_HPP diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 7c5f9ab6e..638d1da15 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/include/Nazara/Utility.hpp b/include/Nazara/Utility.hpp index fbb100476..2ccf84080 100644 --- a/include/Nazara/Utility.hpp +++ b/include/Nazara/Utility.hpp @@ -39,27 +39,19 @@ #include #include #include -#include -#include #include -#include -#include #include #include #include #include -#include #include #include #include #include #include -#include -#include #include #include #include -#include #include #include #include @@ -75,8 +67,5 @@ #include #include #include -#include -#include -#include #endif // NAZARA_GLOBAL_UTILITY_HPP diff --git a/include/Nazara/Utility/AbstractAtlas.hpp b/include/Nazara/Utility/AbstractAtlas.hpp index 49565cdf2..95890a248 100644 --- a/include/Nazara/Utility/AbstractAtlas.hpp +++ b/include/Nazara/Utility/AbstractAtlas.hpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include namespace Nz { diff --git a/include/Nazara/Utility/AbstractImage.inl b/include/Nazara/Utility/AbstractImage.inl index fe456669f..98dbabfdd 100644 --- a/include/Nazara/Utility/AbstractImage.inl +++ b/include/Nazara/Utility/AbstractImage.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include namespace Nz diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 1652976c3..9c275021d 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -8,17 +8,25 @@ #define NAZARA_ALGORITHM_UTILITY_HPP #include +#include #include #include #include +#include #include #include +#include #include -#include -#include namespace Nz { + class Joint; + struct VertexStruct_XYZ_Normal_UV_Tangent; + struct VertexStruct_XYZ_Normal_UV_Tangent_Skinning; + + using MeshVertex = VertexStruct_XYZ_Normal_UV_Tangent; + using SkeletalMeshVertex = VertexStruct_XYZ_Normal_UV_Tangent_Skinning; + struct SkinningData { const Joint* joints; @@ -57,6 +65,10 @@ namespace Nz NAZARA_UTILITY_API void SkinPositionNormalTangent(const SkinningData& data, unsigned int startVertex, unsigned int vertexCount); NAZARA_UTILITY_API void TransformVertices(VertexPointers vertexPointers, unsigned int vertexCount, const Matrix4f& matrix); + + template constexpr ComponentType ComponentTypeId(); + template constexpr ComponentType GetComponentTypeOf(); } +#include #endif // NAZARA_ALGORITHM_UTILITY_HPP diff --git a/include/Nazara/Utility/Algorithm.inl b/include/Nazara/Utility/Algorithm.inl new file mode 100644 index 000000000..829276bfb --- /dev/null +++ b/include/Nazara/Utility/Algorithm.inl @@ -0,0 +1,47 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + namespace Detail + { + template + struct IsSuitableForComponent + { + constexpr static bool value = false; + }; + } + + template constexpr ComponentType ComponentTypeId() + { + static_assert(Detail::IsSuitableForComponent::value, "This type cannot be used as a component."); + return ComponentType{}; + } + + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Color; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Double1; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Double2; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Double3; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Double4; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Float1; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Float2; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Float3; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Float4; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Int1; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Int2; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Int3; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Int4; } + template<> constexpr ComponentType ComponentTypeId() { return ComponentType_Quaternion; } + + template + constexpr ComponentType GetComponentTypeOf() + { + return ComponentTypeId>(); + } +} + +#include diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index 7f7595bbd..2e1753c6a 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -8,6 +8,7 @@ #define NAZARA_ANIMATION_HPP #include +#include #include #include #include @@ -19,7 +20,6 @@ #include #include #include -#include namespace Nz { @@ -34,6 +34,8 @@ namespace Nz }; class Animation; + struct Sequence; + struct SequenceJoint; class Skeleton; using AnimationConstRef = ObjectRef; @@ -98,7 +100,7 @@ namespace Nz static bool Initialize(); static void Uninitialize(); - AnimationImpl* m_impl = nullptr; + MovablePtr m_impl = nullptr; static AnimationLibrary::LibraryMap s_library; static AnimationLoader::LoaderList s_loaders; diff --git a/include/Nazara/Utility/Config.hpp b/include/Nazara/Utility/Config.hpp index 39aa014af..489a6192b 100644 --- a/include/Nazara/Utility/Config.hpp +++ b/include/Nazara/Utility/Config.hpp @@ -27,32 +27,29 @@ #ifndef NAZARA_CONFIG_UTILITY_HPP #define NAZARA_CONFIG_UTILITY_HPP -/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci +/// Each modification of a parameter needs a recompilation of the module -// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) +// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower) #define NAZARA_UTILITY_MANAGE_MEMORY 0 -// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +// Activate the security tests based on the code (Advised for development) #define NAZARA_UTILITY_SAFE 1 -// Lors du parsage d'une ressource, déclenche un avertissement si une erreur non-critique est repérée dans une ressource (Plus lent) +// When a resource is being parsed, it triggers a warning if a non-critical error is found in the resource (Slower) #define NAZARA_UTILITY_STRICT_RESOURCE_PARSING 1 -// Protège les classes des accès concurrentiels +// Protect the classes against data race //#define NAZARA_UTILITY_THREADSAFE 1 -// Force les buffers à posséder un stride multiple de 32 bytes (Gain de performances sur certaines cartes/plus de consommation mémoire) -#define NAZARA_UTILITY_VERTEX_DECLARATION_FORCE_STRIDE_MULTIPLE_OF_32 0 ///FIXME: Ne peut pas être utilisé pour l'instant +// Force the buffers to have a stride which is a multiple of 32 bytes (Gain of performances on certain cards/more memory consumption) +#define NAZARA_UTILITY_VERTEX_DECLARATION_FORCE_STRIDE_MULTIPLE_OF_32 0 ///FIXME: Can not be used for the moment -// Sous Windows, fait en sorte que les touches ALT et F10 n'activent pas le menu de la fenêtre -#define NAZARA_UTILITY_WINDOWS_DISABLE_MENU_KEYS 1 +/// Each modification of a parameter following implies a modification (often minor) of the code -/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code - -// Le nombre maximum de poids affectant un sommet (En cas de dépassement, les poids supplémentaires seront ignorés et les autres renormalisés) +// The maximal number of weights acting on a vertex (In case of overflow, the surnumerous weights would be ignored and the others renormalized) #define NAZARA_UTILITY_SKINNING_MAX_WEIGHTS 4 -/// Vérification des valeurs et types de certaines constantes +/// Checking the values and types of certain constants #include #if defined(NAZARA_STATIC) diff --git a/include/Nazara/Utility/ConfigCheck.hpp b/include/Nazara/Utility/ConfigCheck.hpp index bbfd6ea66..42aa5f92c 100644 --- a/include/Nazara/Utility/ConfigCheck.hpp +++ b/include/Nazara/Utility/ConfigCheck.hpp @@ -7,12 +7,12 @@ #ifndef NAZARA_CONFIG_CHECK_UTILITY_HPP #define NAZARA_CONFIG_CHECK_UTILITY_HPP -/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp +/// This file is used to check the constant values defined in Config.hpp #include #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) -// On force la valeur de MANAGE_MEMORY en mode debug +// We force the value of MANAGE_MEMORY in debug #if defined(NAZARA_DEBUG) && !NAZARA_UTILITY_MANAGE_MEMORY #undef NAZARA_UTILITY_MANAGE_MEMORY #define NAZARA_UTILITY_MANAGE_MEMORY 0 diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index d72b90d6c..d6fee2127 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -64,8 +64,7 @@ namespace Nz template<> struct EnumAsFlags { - static constexpr bool value = true; - static constexpr int max = BufferUsage_Max; + static constexpr BufferUsage max = BufferUsage_Max; }; using BufferUsageFlags = Flags; @@ -92,8 +91,8 @@ namespace Nz enum CubemapFace { - // Cette énumération est prévue pour remplacer l'argument "z" des méthodes de Image contenant un cubemap - // L'ordre est X, -X, Y, -Y, Z, -Z + // This enumeration is intended to replace the "z" argument of Image's methods containing cubemap + // The order is X, -X, Y, -Y, Z, -Z CubemapFace_PositiveX = 0, CubemapFace_PositiveY = 2, CubemapFace_PositiveZ = 4, @@ -307,30 +306,6 @@ namespace Nz SamplerWrap_Max = SamplerWrap_Repeat }; - enum SystemCursor - { - SystemCursor_Crosshair, - SystemCursor_Default, - SystemCursor_Hand, - SystemCursor_Help, - SystemCursor_Move, - SystemCursor_None, - SystemCursor_Pointer, - SystemCursor_Progress, - SystemCursor_ResizeE, - SystemCursor_ResizeN, - SystemCursor_ResizeNE, - SystemCursor_ResizeNW, - SystemCursor_ResizeS, - SystemCursor_ResizeSE, - SystemCursor_ResizeSW, - SystemCursor_ResizeW, - SystemCursor_Text, - SystemCursor_Wait, - - SystemCursor_Max = SystemCursor_Wait - }; - enum StencilOperation { StencilOperation_Decrement, @@ -370,7 +345,7 @@ namespace Nz { VertexComponent_Unused = -1, - // Nous nous limitons à 16 composants de sommets car c'est le minimum supporté par le GPU + // We limit to 16 components by vertex since it's the minimal number supported by the GPU VertexComponent_InstanceData0, VertexComponent_InstanceData1, VertexComponent_InstanceData2, @@ -398,7 +373,7 @@ namespace Nz enum VertexLayout { - // Déclarations destinées au rendu + // Declarations meant for the rendering VertexLayout_XY, VertexLayout_XY_Color, VertexLayout_XY_UV, @@ -411,57 +386,11 @@ namespace Nz VertexLayout_XYZ_Normal_UV_Tangent_Skinning, VertexLayout_XYZ_UV, - // Déclarations destinées à l'instancing + // Declarations meant for the instancing VertexLayout_Matrix4, VertexLayout_Max = VertexLayout_Matrix4 }; - - enum WindowEventType - { - WindowEventType_GainedFocus, - WindowEventType_LostFocus, - WindowEventType_KeyPressed, - WindowEventType_KeyReleased, - WindowEventType_MouseButtonDoubleClicked, - WindowEventType_MouseButtonPressed, - WindowEventType_MouseButtonReleased, - WindowEventType_MouseEntered, - WindowEventType_MouseLeft, - WindowEventType_MouseMoved, - WindowEventType_MouseWheelMoved, - WindowEventType_Moved, - WindowEventType_Quit, - WindowEventType_Resized, - WindowEventType_TextEntered, - - WindowEventType_Max = WindowEventType_TextEntered - }; - - enum WindowStyle - { - WindowStyle_None, ///< Window has no border nor titlebar. - WindowStyle_Fullscreen, ///< At the window creation, the OS tries to set it in fullscreen. - - WindowStyle_Closable, ///< Allows the window to be closed by a button in the titlebar, generating a Quit event. - WindowStyle_Resizable, ///< Allows the window to be resized by dragging its corners or by a button of the titlebar. - WindowStyle_Titlebar, ///< Adds a titlebar to the window, this option is automatically enabled if buttons of the titlebar are enabled. - - WindowStyle_Threaded, ///< Runs the window into a thread, allowing the application to keep updating while resizing/dragging the window. - - WindowStyle_Max = WindowStyle_Threaded - }; - - template<> - struct EnumAsFlags - { - static constexpr bool value = true; - static constexpr int max = WindowStyle_Max; - }; - - using WindowStyleFlags = Flags; - - constexpr WindowStyleFlags WindowStyle_Default = WindowStyle_Closable | WindowStyle_Resizable | WindowStyle_Titlebar; } #endif // NAZARA_ENUMS_UTILITY_HPP diff --git a/include/Nazara/Utility/Formats/MD5AnimParser.hpp b/include/Nazara/Utility/Formats/MD5AnimParser.hpp index d62cdaae8..ca61876b3 100644 --- a/include/Nazara/Utility/Formats/MD5AnimParser.hpp +++ b/include/Nazara/Utility/Formats/MD5AnimParser.hpp @@ -8,11 +8,10 @@ #define NAZARA_FORMATS_MD5ANIMPARSER_HPP #include -#include +#include #include #include #include -#include #include namespace Nz @@ -70,12 +69,12 @@ namespace Nz std::vector m_frames; std::vector m_joints; Stream& m_stream; + StreamOptionFlags m_streamFlags; String m_currentLine; bool m_keepLastLine; unsigned int m_frameIndex; unsigned int m_frameRate; unsigned int m_lineCount; - unsigned int m_streamFlags; }; } diff --git a/include/Nazara/Utility/Formats/MD5MeshParser.hpp b/include/Nazara/Utility/Formats/MD5MeshParser.hpp index dce6bcc72..880236ac4 100644 --- a/include/Nazara/Utility/Formats/MD5MeshParser.hpp +++ b/include/Nazara/Utility/Formats/MD5MeshParser.hpp @@ -8,11 +8,11 @@ #define NAZARA_FORMATS_MD5MESHPARSER_HPP #include -#include #include #include +#include #include -#include +#include #include namespace Nz @@ -75,11 +75,11 @@ namespace Nz std::vector m_joints; std::vector m_meshes; Stream& m_stream; + StreamOptionFlags m_streamFlags; String m_currentLine; bool m_keepLastLine; unsigned int m_lineCount; unsigned int m_meshIndex; - unsigned int m_streamFlags; }; } diff --git a/include/Nazara/Utility/Formats/MTLParser.hpp b/include/Nazara/Utility/Formats/MTLParser.hpp index ec50f2137..272d67062 100644 --- a/include/Nazara/Utility/Formats/MTLParser.hpp +++ b/include/Nazara/Utility/Formats/MTLParser.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include diff --git a/include/Nazara/Utility/Formats/MTLParser.inl b/include/Nazara/Utility/Formats/MTLParser.inl index 00e9e8b89..cde870fee 100644 --- a/include/Nazara/Utility/Formats/MTLParser.inl +++ b/include/Nazara/Utility/Formats/MTLParser.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include @@ -80,4 +79,3 @@ namespace Nz } #include -#include "MTLParser.hpp" diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index c01f7724a..86b0e9f12 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -8,7 +8,6 @@ #define NAZARA_FORMATS_OBJPARSER_HPP #include -#include #include #include #include @@ -20,8 +19,6 @@ namespace Nz class NAZARA_UTILITY_API OBJParser { public: - struct Face; - struct FaceVertex; struct Mesh; OBJParser() = default; diff --git a/include/Nazara/Utility/Formats/OBJParser.inl b/include/Nazara/Utility/Formats/OBJParser.inl index 4b780672b..e1d821a44 100644 --- a/include/Nazara/Utility/Formats/OBJParser.inl +++ b/include/Nazara/Utility/Formats/OBJParser.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index cbae97f9a..53c3efbb4 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -10,14 +10,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include diff --git a/include/Nazara/Utility/IndexBuffer.inl b/include/Nazara/Utility/IndexBuffer.inl index 0ae918db7..1bcf60b26 100644 --- a/include/Nazara/Utility/IndexBuffer.inl +++ b/include/Nazara/Utility/IndexBuffer.inl @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include diff --git a/include/Nazara/Utility/IndexMapper.hpp b/include/Nazara/Utility/IndexMapper.hpp index b18e8989f..fe7ab318c 100644 --- a/include/Nazara/Utility/IndexMapper.hpp +++ b/include/Nazara/Utility/IndexMapper.hpp @@ -13,7 +13,6 @@ namespace Nz { - class IndexBuffer; class IndexIterator; class SubMesh; diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index a05f7c9f4..ca0971aa2 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -10,18 +10,17 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include -#include -#include +#include +#include +#include #include namespace Nz @@ -30,22 +29,38 @@ namespace Nz { MeshParams(); + BufferUsageFlags indexBufferFlags = 0; ///< Buffer usage flags used to build the index buffers + BufferUsageFlags vertexBufferFlags = 0; ///< Buffer usage flags used to build the vertex buffers Matrix4f matrix = Matrix4f::Identity(); ///< A matrix which will transform every vertex position DataStorage storage = DataStorage_Hardware; ///< The place where the buffers will be allocated Vector2f texCoordOffset = {0.f, 0.f}; ///< Offset to apply on the texture coordinates (not scaled) Vector2f texCoordScale = {1.f, 1.f}; ///< Scale to apply on the texture coordinates bool animated = true; ///< If true, will load an animated version of the model if possible bool center = false; ///< If true, will center the mesh vertices around the origin + #ifndef NAZARA_DEBUG bool optimizeIndexBuffers = true; ///< Optimize the index buffers after loading, improve cache locality (and thus rendering speed) but increase loading time. + #else + bool optimizeIndexBuffers = false; ///< Since this optimization take a lot of time, especially in debug mode, don't enable it by default in debug. + #endif + + /* The declaration must have a Vector3f position component enabled + * If the declaration has a Vector2f UV component enabled, UV are generated + * If the declaration has a Vector3f Normals component enabled, Normals are generated. + * If the declaration has a Vector3f Tangents component enabled, Tangents are generated. + */ + VertexDeclaration* vertexDeclaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent); bool IsValid() const; }; class Mesh; + struct Primitive; class PrimitiveList; + class Skeleton; + class SubMesh; - typedef VertexStruct_XYZ_Normal_UV_Tangent MeshVertex; - typedef VertexStruct_XYZ_Normal_UV_Tangent_Skinning SkeletalMeshVertex; + using MeshVertex = VertexStruct_XYZ_Normal_UV_Tangent; + using SkeletalMeshVertex = VertexStruct_XYZ_Normal_UV_Tangent_Skinning; using MeshConstRef = ObjectRef; using MeshLibrary = ObjectLibrary; diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index e70732837..22a96eed2 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -14,7 +14,6 @@ #include #include #include -#include #include namespace Nz diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index 4fe75c8b5..7fe11d1a4 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -2,9 +2,7 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include -#include #include #include #include diff --git a/include/Nazara/Utility/SkeletalMesh.hpp b/include/Nazara/Utility/SkeletalMesh.hpp index d67210c74..0dc436588 100644 --- a/include/Nazara/Utility/SkeletalMesh.hpp +++ b/include/Nazara/Utility/SkeletalMesh.hpp @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include namespace Nz { diff --git a/include/Nazara/Utility/Skeleton.hpp b/include/Nazara/Utility/Skeleton.hpp index 0ed6c6691..f2c2fb5a8 100644 --- a/include/Nazara/Utility/Skeleton.hpp +++ b/include/Nazara/Utility/Skeleton.hpp @@ -13,11 +13,11 @@ #include #include #include -#include -#include +#include namespace Nz { + class Joint; class Skeleton; using SkeletonConstRef = ObjectRef; diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index d9d5cd2bf..c3c6e4dbb 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -14,7 +14,6 @@ #include #include #include -#include namespace Nz { diff --git a/include/Nazara/Utility/Utility.hpp b/include/Nazara/Utility/Utility.hpp index d78121f2c..8f4556de6 100644 --- a/include/Nazara/Utility/Utility.hpp +++ b/include/Nazara/Utility/Utility.hpp @@ -8,8 +8,6 @@ #define NAZARA_UTILITY_HPP #include -#include -#include #include #include @@ -25,15 +23,12 @@ namespace Nz static bool IsInitialized(); - static void SetParameters(const ParameterList& parameters); - static void Uninitialize(); static unsigned int ComponentCount[ComponentType_Max+1]; static std::size_t ComponentStride[ComponentType_Max+1]; private: - static ParameterList s_initializationParameters; static unsigned int s_moduleReferenceCounter; }; } diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 594f1b5f0..1490857cf 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -38,6 +38,8 @@ namespace Nz void EnableComponent(VertexComponent component, ComponentType type, std::size_t offset); void GetComponent(VertexComponent component, bool* enabled, ComponentType* type, std::size_t* offset) const; + bool HasComponent(VertexComponent component) const; + template bool HasComponentOfType(VertexComponent component) const; std::size_t GetStride() const; void SetStride(std::size_t stride); diff --git a/include/Nazara/Utility/VertexDeclaration.inl b/include/Nazara/Utility/VertexDeclaration.inl index 26cd39736..8f8e74179 100644 --- a/include/Nazara/Utility/VertexDeclaration.inl +++ b/include/Nazara/Utility/VertexDeclaration.inl @@ -1,9 +1,10 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include +#include namespace Nz { @@ -15,6 +16,17 @@ namespace Nz return object.release(); } + + template + bool VertexDeclaration::HasComponentOfType(VertexComponent component) const + { + bool enabled; + Nz::ComponentType type; + + GetComponent(component, &enabled, &type, nullptr); + + return enabled && GetComponentTypeOf() == type; + } } #include diff --git a/include/Nazara/Utility/VertexMapper.hpp b/include/Nazara/Utility/VertexMapper.hpp index 486d000fd..050bdf500 100644 --- a/include/Nazara/Utility/VertexMapper.hpp +++ b/include/Nazara/Utility/VertexMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -27,6 +27,10 @@ namespace Nz ~VertexMapper(); template SparsePtr GetComponentPtr(VertexComponent component); + inline const VertexBuffer* GetVertexBuffer() const; + inline UInt32 GetVertexCount() const; + + template bool HasComponentOfType(VertexComponent component) const; void Unmap(); diff --git a/include/Nazara/Utility/VertexMapper.inl b/include/Nazara/Utility/VertexMapper.inl index 6892f9091..f3861541c 100644 --- a/include/Nazara/Utility/VertexMapper.inl +++ b/include/Nazara/Utility/VertexMapper.inl @@ -1,7 +1,9 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include +#include #include #include @@ -19,16 +21,26 @@ namespace Nz std::size_t offset; declaration->GetComponent(component, &enabled, &type, &offset); - if (enabled) - { - ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? + if (enabled && GetComponentTypeOf() == type) return SparsePtr(static_cast(m_mapper.GetPointer()) + offset, declaration->GetStride()); - } else - { - NazaraError("Attribute 0x" + String::Number(component, 16) + " is not enabled"); return SparsePtr(); - } + } + + inline const VertexBuffer* VertexMapper::GetVertexBuffer() const + { + return m_mapper.GetBuffer(); + } + + inline UInt32 VertexMapper::GetVertexCount() const + { + return GetVertexBuffer()->GetVertexCount(); + } + + template + bool VertexMapper::HasComponentOfType(VertexComponent component) const + { + return m_mapper.GetBuffer()->GetVertexDeclaration()->HasComponentOfType(component); } } diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 744434137..61e290bca 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -28,8 +28,11 @@ SOFTWARE. #include #include #include +#include #include +#include #include +#include #include #include #include @@ -117,13 +120,27 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) long long vertexLimit = 1'000'000; parameters.custom.GetIntegerParameter("AssimpLoader_VertexLimit", &vertexLimit); + int excludedComponents = 0; + + if (!parameters.vertexDeclaration->HasComponent(VertexComponent_Color)) + excludedComponents |= aiComponent_COLORS; + + if (!parameters.vertexDeclaration->HasComponent(VertexComponent_Normal)) + excludedComponents |= aiComponent_NORMALS; + + if (!parameters.vertexDeclaration->HasComponent(VertexComponent_Tangent)) + excludedComponents |= aiComponent_TANGENTS_AND_BITANGENTS; + + if (!parameters.vertexDeclaration->HasComponent(VertexComponent_TexCoord)) + excludedComponents |= aiComponent_TEXCOORDS; + aiPropertyStore* properties = aiCreatePropertyStore(); aiSetImportPropertyFloat(properties, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, float(smoothingAngle)); aiSetImportPropertyInteger(properties, AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4); aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SBP_REMOVE, ~aiPrimitiveType_TRIANGLE); //< We only want triangles aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, int(triangleLimit)); aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_VERTEX_LIMIT, int(vertexLimit)); - aiSetImportPropertyInteger(properties, AI_CONFIG_PP_RVC_FLAGS, aiComponent_COLORS); + aiSetImportPropertyInteger(properties, AI_CONFIG_PP_RVC_FLAGS, excludedComponents); const aiScene* scene = aiImportFileExWithProperties(userdata.originalFilePath, postProcess, &fileIO, properties); aiReleasePropertyStore(properties); @@ -184,7 +201,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) // Index buffer bool largeIndices = (vertexCount > std::numeric_limits::max()); - IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage, 0); + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage, parameters.indexBufferFlags); IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); IndexIterator index = indexMapper.begin(); @@ -202,22 +219,62 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) indexMapper.Unmap(); // Vertex buffer - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, 0); - BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); - MeshVertex* vertex = static_cast(vertexMapper.GetPointer()); + // Make sure the normal/tangent matrix won't rescale our vectors + Nz::Matrix4f normalTangentMatrix = parameters.matrix; + if (normalTangentMatrix.HasScale()) + normalTangentMatrix.ApplyScale(1.f / normalTangentMatrix.GetScale()); + + VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, vertexCount, parameters.storage, parameters.vertexBufferFlags); + + VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); + + auto posPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); for (unsigned int j = 0; j < vertexCount; ++j) { aiVector3D position = iMesh->mVertices[j]; - aiVector3D normal = iMesh->mNormals[j]; - aiVector3D tangent = (iMesh->HasTangentsAndBitangents()) ? iMesh->mTangents[j] : aiVector3D(0.f, 1.f, 0.f); - aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f); + *posPtr++ = parameters.matrix * Vector3f(position.x, position.y, position.z); + } - vertex->position = parameters.matrix * Vector3f(position.x, position.y, position.z); - vertex->normal.Set(normal.x, normal.y, normal.z); - vertex->tangent.Set(tangent.x, tangent.y, tangent.z); - vertex->uv.Set(parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale); - vertex++; + if (auto normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal)) + { + for (unsigned int j = 0; j < vertexCount; ++j) + { + aiVector3D normal = iMesh->mNormals[j]; + *normalPtr++ = normalTangentMatrix.Transform({normal.x, normal.y, normal.z}, 0.f); + } + } + + bool generateTangents = false; + if (auto tangentPtr = vertexMapper.GetComponentPtr(VertexComponent_Tangent)) + { + if (iMesh->HasTangentsAndBitangents()) + { + for (unsigned int j = 0; j < vertexCount; ++j) + { + aiVector3D tangent = iMesh->mTangents[j]; + *tangentPtr++ = normalTangentMatrix.Transform({tangent.x, tangent.y, tangent.z}, 0.f); + } + } + else + generateTangents = true; + } + + if (auto uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord)) + { + if (iMesh->HasTextureCoords(0)) + { + for (unsigned int j = 0; j < vertexCount; ++j) + { + aiVector3D uv = iMesh->mTextureCoords[0][j]; + *uvPtr++ = parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale; + } + } + else + { + for (unsigned int j = 0; j < vertexCount; ++j) + *uvPtr++ = Vector2f::Zero(); + } } vertexMapper.Unmap(); @@ -230,6 +287,9 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) subMesh->GenerateAABB(); subMesh->SetMaterialIndex(iMesh->mMaterialIndex); + if (generateTangents) + subMesh->GenerateTangents(); + auto matIt = materials.find(iMesh->mMaterialIndex); if (matIt == materials.end()) { diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index cdfe4caac..185b911b6 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include #include diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 87e15ee2c..a3beac029 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -3,13 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include #include -#include -#include -#include #include namespace Nz diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index 4402af91d..a6556c6d2 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -3,8 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include #include namespace Nz diff --git a/src/Nazara/Core/ByteStream.cpp b/src/Nazara/Core/ByteStream.cpp index 489f90338..a61cae520 100644 --- a/src/Nazara/Core/ByteStream.cpp +++ b/src/Nazara/Core/ByteStream.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Core/Clock.cpp b/src/Nazara/Core/Clock.cpp index 881d7c40e..92183674c 100644 --- a/src/Nazara/Core/Clock.cpp +++ b/src/Nazara/Core/Clock.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #if defined(NAZARA_PLATFORM_WINDOWS) #include diff --git a/src/Nazara/Core/ConditionVariable.cpp b/src/Nazara/Core/ConditionVariable.cpp index 86ecb11ed..f4314870c 100644 --- a/src/Nazara/Core/ConditionVariable.cpp +++ b/src/Nazara/Core/ConditionVariable.cpp @@ -102,18 +102,4 @@ namespace Nz NazaraAssert(mutex != nullptr, "Mutex must be valid"); return m_impl->Wait(mutex->m_impl, timeout); } - - /*! - * \brief Moves a condition to another ConditionVariable object - * \return A reference to the object - */ - ConditionVariable& ConditionVariable::operator=(ConditionVariable&& condition) noexcept - { - delete m_impl; - - m_impl = condition.m_impl; - condition.m_impl = nullptr; - - return *this; - } } diff --git a/src/Nazara/Core/Core.cpp b/src/Nazara/Core/Core.cpp index 4a27bd482..614d6217b 100644 --- a/src/Nazara/Core/Core.cpp +++ b/src/Nazara/Core/Core.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/src/Nazara/Core/Directory.cpp b/src/Nazara/Core/Directory.cpp index 1470a0f3d..3a65c1153 100644 --- a/src/Nazara/Core/Directory.cpp +++ b/src/Nazara/Core/Directory.cpp @@ -312,7 +312,7 @@ namespace Nz /*! * \brief Sets the pattern of the directory * - * \param dirPath Pattern of the directory + * \param pattern Pattern of the directory */ void Directory::SetPattern(const String& pattern) @@ -327,7 +327,7 @@ namespace Nz * \return true if copy is successful * * \param sourcePath Path of the original directory - * \param targetPath Path of the copied directory + * \param destPath Path of the copied directory * * \remark Produces a NazaraError if could not create destination directory * \remark Produces a NazaraError if could not open origin directory diff --git a/src/Nazara/Core/DynLib.cpp b/src/Nazara/Core/DynLib.cpp index 10e5d4247..1558f5a37 100644 --- a/src/Nazara/Core/DynLib.cpp +++ b/src/Nazara/Core/DynLib.cpp @@ -40,19 +40,6 @@ namespace Nz { } - /*! - * \brief Constructs a DynLib object by move semantic - * - * \param lib DynLib to move into this - */ - - DynLib::DynLib(DynLib&& lib) : - m_lastError(std::move(lib.m_lastError)), - m_impl(lib.m_impl) - { - lib.m_impl = nullptr; - } - /*! * \brief Destructs the object and calls Unload * @@ -150,23 +137,4 @@ namespace Nz m_impl = nullptr; } } - - /*! - * \brief Moves the other lib into this - * \return A reference to this - * - * \param lib DynLib to move in this - */ - - DynLib& DynLib::operator=(DynLib&& lib) - { - Unload(); - - m_impl = lib.m_impl; - m_lastError = std::move(lib.m_lastError); - - lib.m_impl = nullptr; - - return *this; - } } diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 9aa9374e0..6181f7d1b 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -5,12 +5,11 @@ #include #include #include +#include #include #include #include -#include #include -#include #if defined(NAZARA_PLATFORM_WINDOWS) #include @@ -70,20 +69,6 @@ namespace Nz Open(filePath, openMode); } - /*! - * \brief Constructs a File object by move semantic - * - * \param file File to move into this - */ - - File::File(File&& file) noexcept : - Stream(std::move(file)), - m_filePath(std::move(file.m_filePath)), - m_impl(file.m_impl) - { - file.m_impl = nullptr; - } - /*! * \brief Destructs the object and calls Close * @@ -487,23 +472,6 @@ namespace Nz return *this; } - /*! - * \brief Moves the other file into this - * \return A reference to this - * - * \param file File to move in this - */ - - File& File::operator=(File&& file) noexcept - { - NazaraLock(m_mutex) - - std::swap(m_filePath, file.m_filePath); - std::swap(m_impl, file.m_impl); - - return *this; - } - /*! * \brief Gets the absolute path of the file * \return Absolute path of the file diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index 85270a562..9ebae4bbb 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -9,8 +9,6 @@ #include #include #include -#include -#include #include #include @@ -295,7 +293,7 @@ namespace Nz * * \param rects List of rectangles * \param flipped List of flipped rectangles - * \param flipped List of inserted rectangles + * \param inserted List of inserted rectangles * \param count Count of rectangles * \param merge Merge possible * \param rectChoice Heuristic to use to free diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp index a4bec3194..a22bbbdf6 100644 --- a/src/Nazara/Core/HardwareInfo.cpp +++ b/src/Nazara/Core/HardwareInfo.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #if defined(NAZARA_PLATFORM_WINDOWS) diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index aaf6bc520..ad175126e 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -5,9 +5,9 @@ #include #include #include +#include #include #include -#include #if defined(NAZARA_PLATFORM_WINDOWS) #include @@ -94,7 +94,7 @@ namespace Nz * \return Raw memory allocated * * \param size Size to allocate - * \parma multi Array or not + * \param multi Array or not * \param file File of the allocation * \param line Line of the allocation in the file */ diff --git a/src/Nazara/Core/Mutex.cpp b/src/Nazara/Core/Mutex.cpp index 953568ecc..473ee233e 100644 --- a/src/Nazara/Core/Mutex.cpp +++ b/src/Nazara/Core/Mutex.cpp @@ -77,18 +77,4 @@ namespace Nz NazaraAssert(m_impl, "Cannot unlock a moved mutex"); m_impl->Unlock(); } - - /*! - * \brief Moves a mutex to another mutex object - * \return A reference to the object - */ - Mutex& Mutex::operator=(Mutex&& mutex) noexcept - { - delete m_impl; - - m_impl = mutex.m_impl; - mutex.m_impl = nullptr; - - return *this; - } } diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 89fdb4591..25298b950 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -7,8 +7,6 @@ #include #include #include -#include -#include #include namespace Nz @@ -720,7 +718,6 @@ namespace Nz * \brief Create an uninitialized value of a set name * * \param name Name of the parameter - * \param value Value of the parameter * * \remark The previous value if any gets destroyed */ diff --git a/src/Nazara/Core/PluginManager.cpp b/src/Nazara/Core/PluginManager.cpp index 2a7fa8eee..14bc6744e 100644 --- a/src/Nazara/Core/PluginManager.cpp +++ b/src/Nazara/Core/PluginManager.cpp @@ -190,7 +190,7 @@ namespace Nz /*! * \brief Unmounts the plugin with a path * - * \param pluginPath Path to the plugin + * \param plugin Path to the plugin * * \remark Produces a NazaraError if not initialized * \remark Produces a NazaraError if plugin is not loaded diff --git a/src/Nazara/Core/Posix/ClockImpl.cpp b/src/Nazara/Core/Posix/ClockImpl.cpp index 73b45b6e7..203b1fbbb 100644 --- a/src/Nazara/Core/Posix/ClockImpl.cpp +++ b/src/Nazara/Core/Posix/ClockImpl.cpp @@ -3,8 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include #include #include diff --git a/src/Nazara/Core/Posix/ConditionVariableImpl.cpp b/src/Nazara/Core/Posix/ConditionVariableImpl.cpp index c1c6e891d..69eb691fa 100644 --- a/src/Nazara/Core/Posix/ConditionVariableImpl.cpp +++ b/src/Nazara/Core/Posix/ConditionVariableImpl.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include namespace Nz diff --git a/src/Nazara/Core/Posix/ConditionVariableImpl.hpp b/src/Nazara/Core/Posix/ConditionVariableImpl.hpp index 1781711c4..a5dea1e8b 100644 --- a/src/Nazara/Core/Posix/ConditionVariableImpl.hpp +++ b/src/Nazara/Core/Posix/ConditionVariableImpl.hpp @@ -11,8 +11,6 @@ #include #include -#include -#include namespace Nz { diff --git a/src/Nazara/Core/Posix/DirectoryImpl.cpp b/src/Nazara/Core/Posix/DirectoryImpl.cpp index e23c82626..805a44232 100644 --- a/src/Nazara/Core/Posix/DirectoryImpl.cpp +++ b/src/Nazara/Core/Posix/DirectoryImpl.cpp @@ -4,10 +4,12 @@ #include #include -#include - +#include #include #include +#include +#include +#include namespace Nz { diff --git a/src/Nazara/Core/Posix/DirectoryImpl.hpp b/src/Nazara/Core/Posix/DirectoryImpl.hpp index 5f77fbb43..af857fada 100644 --- a/src/Nazara/Core/Posix/DirectoryImpl.hpp +++ b/src/Nazara/Core/Posix/DirectoryImpl.hpp @@ -9,9 +9,6 @@ #include #include -#include -#include -#include namespace Nz { diff --git a/src/Nazara/Core/Posix/DynLibImpl.cpp b/src/Nazara/Core/Posix/DynLibImpl.cpp index dbb8463fa..f519c916f 100644 --- a/src/Nazara/Core/Posix/DynLibImpl.cpp +++ b/src/Nazara/Core/Posix/DynLibImpl.cpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include namespace Nz @@ -42,7 +42,7 @@ namespace Nz { String path = libraryPath; - unsigned int pos = path.FindLast(".so"); + size_t pos = path.FindLast(".so"); if (pos == String::npos || (path.GetLength() > pos+3 && path[pos+3] != '.')) path += ".so"; diff --git a/src/Nazara/Core/Posix/DynLibImpl.hpp b/src/Nazara/Core/Posix/DynLibImpl.hpp index 1f36fa9e3..e101abc84 100644 --- a/src/Nazara/Core/Posix/DynLibImpl.hpp +++ b/src/Nazara/Core/Posix/DynLibImpl.hpp @@ -8,7 +8,6 @@ #define NAZARA_DYNLIBIMPL_HPP #include -#include namespace Nz { diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index 75b2275cc..59935dd35 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -4,8 +4,10 @@ #include #include +#include +#include +#include #include -#include #include namespace Nz diff --git a/src/Nazara/Core/Posix/FileImpl.hpp b/src/Nazara/Core/Posix/FileImpl.hpp index 51f966980..cf396e0fa 100644 --- a/src/Nazara/Core/Posix/FileImpl.hpp +++ b/src/Nazara/Core/Posix/FileImpl.hpp @@ -12,12 +12,8 @@ #endif #include -#include +#include #include -#include -#include -#include -#include namespace Nz { diff --git a/src/Nazara/Core/Posix/HardwareInfoImpl.cpp b/src/Nazara/Core/Posix/HardwareInfoImpl.cpp index 20ea4950f..6e23c2f8b 100644 --- a/src/Nazara/Core/Posix/HardwareInfoImpl.cpp +++ b/src/Nazara/Core/Posix/HardwareInfoImpl.cpp @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include namespace Nz diff --git a/src/Nazara/Core/Posix/HardwareInfoImpl.hpp b/src/Nazara/Core/Posix/HardwareInfoImpl.hpp index 671802c52..fec00ec93 100644 --- a/src/Nazara/Core/Posix/HardwareInfoImpl.hpp +++ b/src/Nazara/Core/Posix/HardwareInfoImpl.hpp @@ -8,7 +8,6 @@ #define NAZARA_HARDWAREINFOIMPL_POSIX_HPP #include -#include namespace Nz { diff --git a/src/Nazara/Core/Posix/SemaphoreImpl.cpp b/src/Nazara/Core/Posix/SemaphoreImpl.cpp index eb1b7d1dd..c53928407 100644 --- a/src/Nazara/Core/Posix/SemaphoreImpl.cpp +++ b/src/Nazara/Core/Posix/SemaphoreImpl.cpp @@ -3,9 +3,8 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include -#include +#include #include #include diff --git a/src/Nazara/Core/Posix/TaskSchedulerImpl.cpp b/src/Nazara/Core/Posix/TaskSchedulerImpl.cpp index b04fdcfd9..e8cbb3de8 100644 --- a/src/Nazara/Core/Posix/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Posix/TaskSchedulerImpl.cpp @@ -3,8 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include +#include #include namespace Nz diff --git a/src/Nazara/Core/Posix/TaskSchedulerImpl.hpp b/src/Nazara/Core/Posix/TaskSchedulerImpl.hpp index e132e4686..43ce552b6 100644 --- a/src/Nazara/Core/Posix/TaskSchedulerImpl.hpp +++ b/src/Nazara/Core/Posix/TaskSchedulerImpl.hpp @@ -8,7 +8,6 @@ #define NAZARA_TASKSCHEDULERIMPL_HPP #include -#include #include #include #include @@ -16,6 +15,8 @@ namespace Nz { + struct Functor; + class TaskSchedulerImpl { public: diff --git a/src/Nazara/Core/Posix/ThreadImpl.cpp b/src/Nazara/Core/Posix/ThreadImpl.cpp index aa0b87c5d..3793ddcf5 100644 --- a/src/Nazara/Core/Posix/ThreadImpl.cpp +++ b/src/Nazara/Core/Posix/ThreadImpl.cpp @@ -5,9 +5,10 @@ #include #include #include +#include +#include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Core/Posix/ThreadImpl.hpp b/src/Nazara/Core/Posix/ThreadImpl.hpp index ba3d4ed84..fe3e593fe 100644 --- a/src/Nazara/Core/Posix/ThreadImpl.hpp +++ b/src/Nazara/Core/Posix/ThreadImpl.hpp @@ -8,7 +8,6 @@ #define NAZARA_THREADIMPL_HPP #include -#include #if defined(__GNUC__) && !defined(_GNU_SOURCE) #define _GNU_SOURCE @@ -19,6 +18,7 @@ namespace Nz { struct Functor; + class String; class ThreadImpl { diff --git a/src/Nazara/Core/RefCounted.cpp b/src/Nazara/Core/RefCounted.cpp index 9532e5d86..42fbe5aaa 100644 --- a/src/Nazara/Core/RefCounted.cpp +++ b/src/Nazara/Core/RefCounted.cpp @@ -5,13 +5,6 @@ #include #include #include - -#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_REFCOUNTED - #include -#else - #include -#endif - #include namespace Nz diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 98a8b882c..ba29d0916 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -295,7 +295,7 @@ namespace Nz } /*! - * \Brief Checks whether the string contains the character + * \brief Checks whether the string contains the character * \return true if found in the string * * \param character Single character @@ -311,7 +311,7 @@ namespace Nz } /*! - * \Brief Checks whether the string contains the "C string" + * \brief Checks whether the string contains the "C string" * \return true if found in the string * * \param string String to search @@ -327,7 +327,7 @@ namespace Nz } /*! - * \Brief Checks whether the string contains the string + * \brief Checks whether the string contains the string * \return true if found in the string * * \param string String to search @@ -2244,7 +2244,7 @@ namespace Nz * \brief Gets the word until next separator * \return Word string * - * \param start Index to begin the search + * \param index Index to begin the search * \param flags Flag for the look up */ @@ -2289,7 +2289,7 @@ namespace Nz * \brief Gets the word position * \return Position of the beginning of the word * - * \param start Index to begin the search + * \param index Index to begin the search * \param flags Flag for the look up */ @@ -2729,8 +2729,8 @@ namespace Nz * \brief Replaces the old "C string" by the new one * \return Number of changes * - * \param oldCharacter Pattern to find - * \param newCharacter Pattern to change for + * \param oldString Pattern to find + * \param replaceString Pattern to change for * \param start Index to begin the search * \param flags Flag for the look up */ @@ -2744,10 +2744,10 @@ namespace Nz * \brief Replaces the old "C string" by the new one * \return Number of changes * - * \param oldCharacter Pattern to find + * \param oldString Pattern to find * \param oldLength Length of the old string - * \param newCharacter Pattern to change for - * \param Length of the new string + * \param replaceString Pattern to change for + * \param replaceLength of the new string * \param start Index to begin the search * \param flags Flag for the look up */ @@ -2822,8 +2822,8 @@ namespace Nz * \brief Replaces the old string by the new one * \return Number of changes * - * \param oldCharacter Pattern to find - * \param newCharacter Pattern to change for + * \param oldString Pattern to find + * \param replaceString Pattern to change for * \param start Index to begin the search * \param flags Flag for the look up */ @@ -2838,7 +2838,7 @@ namespace Nz * \return Number of changes * * \param oldCharacters Pattern to find - * \param newCharacter Pattern to change for + * \param replaceCharacter Pattern to change for * \param start Index to begin the search * \param flags Flag for the look up * @@ -3646,7 +3646,7 @@ namespace Nz * \return The number of splits * * \param result Resulting tokens - * \param separation List of characters of separation + * \param separations List of characters for separation * \param start Index for the beginning of the search * \param flags Flag for the look up */ @@ -3687,7 +3687,7 @@ namespace Nz * \return The number of splits * * \param result Resulting tokens - * \param separation List of characters of separation + * \param separations List of characters for separation * \param start Index for the beginning of the search * \param flags Flag for the look up */ @@ -3885,7 +3885,7 @@ namespace Nz * \brief Returns a sub string of the string from a character * \return SubString * - * \param charater Pattern to find + * \param character Pattern to find * \param startPos Index for the beginning of the search * \param fromLast beginning by the end * \param include Include the character @@ -3975,7 +3975,7 @@ namespace Nz * \brief Returns a sub string of the string up to a character * \return SubString * - * \param charater Pattern to find + * \param character Pattern to find * \param startPos Index for the beginning of the search * \param toLast beginning by the end * \param include Include the character @@ -4124,7 +4124,6 @@ namespace Nz * \return true if successful * * \param value Double to convert to - * \param flags Flag for the look up */ bool String::ToDouble(double* value) const @@ -4143,7 +4142,7 @@ namespace Nz * \return true if successful * * \param value Integer to convert to - * \param flags Flag for the look up + * \param base Base to convert the integer to */ bool String::ToInteger(long long* value, UInt8 base) const @@ -5483,7 +5482,7 @@ namespace Nz * \brief Output operator * \return The stream * - * \param out The stream + * \param os The stream * \param str The string to output */ @@ -5523,7 +5522,7 @@ namespace Nz * \return String which is the result of the concatenation * * \param string String to add - * \param string String in the right hand side + * \param nstring String in the right hand side */ String operator+(const char* string, const String& nstring) @@ -5549,7 +5548,7 @@ namespace Nz * \return String which is the result of the concatenation * * \param string String to add - * \param string String in the right hand side + * \param nstring String in the right hand side */ String operator+(const std::string& string, const String& nstring) @@ -5667,7 +5666,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator==(char character, const String& nstring) @@ -5680,7 +5679,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator==(const char* string, const String& nstring) @@ -5693,7 +5692,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator==(const std::string& string, const String& nstring) @@ -5706,7 +5705,7 @@ namespace Nz * \return false if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator!=(char character, const String& nstring) @@ -5719,7 +5718,7 @@ namespace Nz * \return false if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator!=(const char* string, const String& nstring) @@ -5732,7 +5731,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator!=(const std::string& string, const String& nstring) @@ -5745,7 +5744,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<(char character, const String& nstring) @@ -5758,7 +5757,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<(const char* string, const String& nstring) @@ -5771,7 +5770,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<(const std::string& string, const String& nstring) @@ -5784,7 +5783,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<=(char character, const String& nstring) @@ -5797,7 +5796,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<=(const char* string, const String& nstring) @@ -5810,7 +5809,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<=(const std::string& string, const String& nstring) @@ -5823,7 +5822,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>(char character, const String& nstring) @@ -5836,7 +5835,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>(const char* string, const String& nstring) @@ -5849,7 +5848,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>(const std::string& string, const String& nstring) @@ -5862,7 +5861,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>=(char character, const String& nstring) @@ -5875,7 +5874,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>=(const char* string, const String& nstring) @@ -5888,7 +5887,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>=(const std::string& string, const String& nstring) @@ -5975,20 +5974,7 @@ namespace std istream& getline(istream& is, Nz::String& str) { - str.Clear(); - - char c; - - for (;;) - { - is.get(c); - if (c != '\n' && c != '\0') - str += c; - else - break; - } - - return is; + return getline(is, str, is.widen('\n')); } /*! @@ -6012,7 +5998,11 @@ namespace std if (c != delim && c != '\0') str += c; else + { + if (c == '\0') + is.setstate(std::ios_base::eofbit); break; + } } return is; diff --git a/src/Nazara/Core/StringStream.cpp b/src/Nazara/Core/StringStream.cpp index d39b3afb8..4b206489e 100644 --- a/src/Nazara/Core/StringStream.cpp +++ b/src/Nazara/Core/StringStream.cpp @@ -3,6 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include +#include #include namespace Nz @@ -13,23 +16,14 @@ namespace Nz * \brief Core class that represents a stream of strings */ - /*! - * \brief Constructs a StringStream object by default - */ - StringStream::StringStream() : - m_bufferSize(0) - { - } - /*! * \brief Constructs a StringStream object with a string * * \param str First value of the stream */ - StringStream::StringStream(const String& str) : - m_bufferSize(str.GetSize()) + StringStream::StringStream(String str) : + m_result(std::move(str)) { - m_strings.push_back(str); } /*! @@ -37,8 +31,7 @@ namespace Nz */ void StringStream::Clear() { - m_bufferSize = 0; - m_strings.clear(); + m_result.Clear(); } /*! @@ -47,7 +40,7 @@ namespace Nz */ std::size_t StringStream::GetBufferSize() const { - return m_bufferSize; + return m_result.GetSize(); } /*! @@ -56,13 +49,7 @@ namespace Nz */ String StringStream::ToString() const { - String string; - string.Reserve(m_bufferSize); - - for (const String& str : m_strings) - string += str; - - return string; + return m_result; } /*! @@ -73,8 +60,10 @@ namespace Nz */ StringStream& StringStream::operator<<(bool boolean) { - m_strings.push_back(String::Boolean(boolean)); - m_bufferSize += m_strings.back().GetSize(); + std::size_t size = (boolean) ? 4 : 5; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + size); + std::memcpy(&m_result[start], (boolean) ? "true" : "false", size); return *this; } @@ -87,8 +76,11 @@ namespace Nz */ StringStream& StringStream::operator<<(short number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = std::numeric_limits::digits10 + 2; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%hd", number); + m_result.Resize(start + written); return *this; } @@ -101,8 +93,11 @@ namespace Nz */ StringStream& StringStream::operator<<(unsigned short number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = std::numeric_limits::digits10 + 1; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%hu", number); + m_result.Resize(start + written); return *this; } @@ -115,8 +110,11 @@ namespace Nz */ StringStream& StringStream::operator<<(int number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = std::numeric_limits::digits10 + 2; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%d", number); + m_result.Resize(start + written); return *this; } @@ -129,8 +127,11 @@ namespace Nz */ StringStream& StringStream::operator<<(unsigned int number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = std::numeric_limits::digits10 + 1; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%u", number); + m_result.Resize(start + written); return *this; } @@ -143,8 +144,11 @@ namespace Nz */ StringStream& StringStream::operator<<(long number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = std::numeric_limits::digits10 + 2; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%ld", number); + m_result.Resize(start + written); return *this; } @@ -157,8 +161,12 @@ namespace Nz */ StringStream& StringStream::operator<<(unsigned long number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = std::numeric_limits::digits10 + 1; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%lu", number); + m_result.Resize(start + written); + return *this; } @@ -171,8 +179,11 @@ namespace Nz */ StringStream& StringStream::operator<<(long long number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = std::numeric_limits::digits10 + 2; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%lld", number); + m_result.Resize(start + written); return *this; } @@ -185,8 +196,11 @@ namespace Nz */ StringStream& StringStream::operator<<(unsigned long long number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = std::numeric_limits::digits10 + 1; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%llu", number); + m_result.Resize(start + written); return *this; } @@ -199,10 +213,7 @@ namespace Nz */ StringStream& StringStream::operator<<(float number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; + return operator<<(double(number)); //< snprintf doesn't support float anyway } /*! @@ -213,8 +224,16 @@ namespace Nz */ StringStream& StringStream::operator<<(double number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + // https://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value + const std::size_t maxSize = 3 + std::numeric_limits::digits - std::numeric_limits::min_exponent; + + // Use a temporary buffer to prevent 1kb string capacity growth + std::array buffer; + std::size_t written = std::snprintf(buffer.data(), buffer.size(), "%.6f", number); + + std::size_t start = m_result.GetSize(); + m_result.Resize(start + written); + std::memcpy(&m_result[start], buffer.data(), written); return *this; } @@ -227,8 +246,16 @@ namespace Nz */ StringStream& StringStream::operator<<(long double number) { - m_strings.push_back(String::Number(number)); - m_bufferSize += m_strings.back().GetSize(); + // https://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value + const std::size_t maxSize = 3 + std::numeric_limits::digits - std::numeric_limits::min_exponent; + + // Use a temporary buffer to prevent 1kb string capacity growth + std::array buffer; + std::size_t written = std::snprintf(buffer.data(), buffer.size(), "%.6Lf", number); + + std::size_t start = m_result.GetSize(); + m_result.Resize(start + written); + std::memcpy(&m_result[start], buffer.data(), written); return *this; } @@ -241,9 +268,7 @@ namespace Nz */ StringStream& StringStream::operator<<(char character) { - m_strings.push_back(String(character)); - m_bufferSize++; - + m_result.Append(character); return *this; } @@ -255,9 +280,7 @@ namespace Nz */ StringStream& StringStream::operator<<(unsigned char character) { - m_strings.push_back(String(static_cast(character))); - m_bufferSize++; - + m_result.Append(static_cast(character)); return *this; } @@ -269,9 +292,7 @@ namespace Nz */ StringStream& StringStream::operator<<(const char* string) { - m_strings.push_back(string); - m_bufferSize += m_strings.back().GetSize(); - + m_result.Append(string); return *this; } @@ -283,9 +304,7 @@ namespace Nz */ StringStream& StringStream::operator<<(const std::string& string) { - m_strings.push_back(string); - m_bufferSize += string.size(); - + m_result.Append(string.data(), string.size()); return *this; } @@ -297,8 +316,7 @@ namespace Nz */ StringStream& StringStream::operator<<(const String& string) { - m_strings.push_back(string); - m_bufferSize += string.GetSize(); + m_result.Append(string); return *this; } @@ -311,8 +329,11 @@ namespace Nz */ StringStream& StringStream::operator<<(const void* ptr) { - m_strings.push_back(String::Pointer(ptr)); - m_bufferSize += m_strings.back().GetSize(); + constexpr std::size_t maxSize = sizeof(void*) * 2 + 2; + std::size_t start = m_result.GetSize(); + m_result.Resize(start + maxSize); + std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "0x%p", ptr); + m_result.Resize(start + written); return *this; } diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp index d8b0ebd42..8f9f0b5b6 100644 --- a/src/Nazara/Core/Thread.cpp +++ b/src/Nazara/Core/Thread.cpp @@ -6,8 +6,7 @@ #include #include #include -#include -#include +#include #if defined(NAZARA_PLATFORM_WINDOWS) #include @@ -36,18 +35,6 @@ namespace Nz { } - /*! - * \brief Constructs a Thread object by move semantic - * - * \param other Thread to move into this - */ - - Thread::Thread(Thread&& other) noexcept : - m_impl(other.m_impl) - { - other.m_impl = nullptr; - } - /*! * \brief Waits that the thread ends and then destroys this */ @@ -136,30 +123,6 @@ namespace Nz m_impl->SetName(name); } - /*! - * \brief Moves the other thread into this - * \return A reference to this - * - * \param thread Thread to move in this - * - * \remark Produce a NazaraError if no functor was assigned and NAZARA_CORE_SAFE is defined - * \remark And call std::terminate if no functor was assigned and NAZARA_CORE_SAFE is defined - */ - - Thread& Thread::operator=(Thread&& thread) - { - #if NAZARA_CORE_SAFE - if (m_impl) - { - NazaraError("This thread cannot be joined"); - std::terminate(); - } - #endif - - std::swap(m_impl, thread.m_impl); - return *this; - } - /*! * \brief Gets the number of simulatenous threads that can run on the same cpu * \return The number of simulatenous threads diff --git a/src/Nazara/Core/Win32/ThreadImpl.cpp b/src/Nazara/Core/Win32/ThreadImpl.cpp index cae997874..134e5472a 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.cpp +++ b/src/Nazara/Core/Win32/ThreadImpl.cpp @@ -63,6 +63,7 @@ namespace Nz void ThreadImpl::SetThreadName(DWORD threadId, const char* threadName) { + #ifdef NAZARA_COMPILER_MSVC // https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx constexpr DWORD MS_VC_EXCEPTION = 0x406D1388; @@ -72,8 +73,8 @@ namespace Nz info.dwThreadID = threadId; info.dwFlags = 0; -#pragma warning(push) -#pragma warning(disable: 6320 6322) + #pragma warning(push) + #pragma warning(disable: 6320 6322) __try { RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast(&info)); @@ -81,7 +82,10 @@ namespace Nz __except (EXCEPTION_EXECUTE_HANDLER) { } -#pragma warning(pop) + #pragma warning(pop) + #else + NazaraWarning("SetThreadName on Windows is only supported with MSVC for now"); + #endif } unsigned int __stdcall ThreadImpl::ThreadProc(void* userdata) diff --git a/src/Nazara/Graphics/AbstractRenderTechnique.cpp b/src/Nazara/Graphics/AbstractRenderTechnique.cpp index 8a33b7b46..963582d45 100644 --- a/src/Nazara/Graphics/AbstractRenderTechnique.cpp +++ b/src/Nazara/Graphics/AbstractRenderTechnique.cpp @@ -3,9 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index c4382eefb..e228a2a59 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -4,10 +4,6 @@ #include #include -#include -#include -#include -#include #include namespace Nz @@ -27,11 +23,8 @@ namespace Nz void Billboard::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - if (!m_material) - return; - Nz::Vector3f position = instanceData.transformMatrix.GetTranslation(); - renderQueue->AddBillboards(instanceData.renderOrder, m_material, 1, &position, &m_size, &m_sinCos, &m_color); + renderQueue->AddBillboards(instanceData.renderOrder, GetMaterial(), 1, &position, &m_size, &m_sinCos, &m_color); } /* diff --git a/src/Nazara/Graphics/ColorBackground.cpp b/src/Nazara/Graphics/ColorBackground.cpp index 52653a8e7..6004783ac 100644 --- a/src/Nazara/Graphics/ColorBackground.cpp +++ b/src/Nazara/Graphics/ColorBackground.cpp @@ -3,8 +3,10 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include -#include +#include +#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredBloomPass.cpp b/src/Nazara/Graphics/DeferredBloomPass.cpp index e51543641..380bf532d 100644 --- a/src/Nazara/Graphics/DeferredBloomPass.cpp +++ b/src/Nazara/Graphics/DeferredBloomPass.cpp @@ -4,7 +4,6 @@ #include #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredDOFPass.cpp b/src/Nazara/Graphics/DeferredDOFPass.cpp index 9760ff300..1aebdcaa6 100644 --- a/src/Nazara/Graphics/DeferredDOFPass.cpp +++ b/src/Nazara/Graphics/DeferredDOFPass.cpp @@ -3,10 +3,8 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredFXAAPass.cpp b/src/Nazara/Graphics/DeferredFXAAPass.cpp index fa2d80d46..91174aaa7 100644 --- a/src/Nazara/Graphics/DeferredFXAAPass.cpp +++ b/src/Nazara/Graphics/DeferredFXAAPass.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredFinalPass.cpp b/src/Nazara/Graphics/DeferredFinalPass.cpp index 228e9d035..265989233 100644 --- a/src/Nazara/Graphics/DeferredFinalPass.cpp +++ b/src/Nazara/Graphics/DeferredFinalPass.cpp @@ -3,9 +3,12 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include +#include #include -#include +#include +#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredFogPass.cpp b/src/Nazara/Graphics/DeferredFogPass.cpp index c6fbfddf9..77432f6d2 100644 --- a/src/Nazara/Graphics/DeferredFogPass.cpp +++ b/src/Nazara/Graphics/DeferredFogPass.cpp @@ -4,9 +4,9 @@ #include #include +#include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredForwardPass.cpp b/src/Nazara/Graphics/DeferredForwardPass.cpp index 55780708f..e4685d3ae 100644 --- a/src/Nazara/Graphics/DeferredForwardPass.cpp +++ b/src/Nazara/Graphics/DeferredForwardPass.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 6d5883c48..b679c873a 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -8,12 +8,9 @@ #include #include #include +#include #include #include -#include -#include -#include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp index 2eff9abc9..3902c9d9d 100644 --- a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp +++ b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp @@ -3,12 +3,13 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include +#include #include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredRenderPass.cpp b/src/Nazara/Graphics/DeferredRenderPass.cpp index c4c265b58..8b0b7fde5 100644 --- a/src/Nazara/Graphics/DeferredRenderPass.cpp +++ b/src/Nazara/Graphics/DeferredRenderPass.cpp @@ -3,8 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include +#include +#include #include namespace Nz diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index a0455fe11..76bc666be 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -3,9 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include -#include #include ///TODO: Render billboards using Deferred Shading if possible diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index 01a0d1fa8..f930871fe 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -18,18 +17,13 @@ #include #include #include -#include -#include -#include -#include +#include #include #include #include #include #include -#include #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index a2acdf4bb..775276c37 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace Nz diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 4acbbc56d..c58b4e4ee 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -5,19 +5,14 @@ #include #include #include -#include -#include #include -#include #include -#include +#include #include #include #include -#include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index ad5d58736..439039cad 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -3,13 +3,11 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include #include #include #include -#include #include namespace Nz @@ -77,7 +75,6 @@ namespace Nz return false; } - model->Reset(); model->SetMesh(mesh); if (parameters.loadMaterials) @@ -114,7 +111,6 @@ namespace Nz return false; } - model->Reset(); model->SetMesh(mesh); if (parameters.loadMaterials) diff --git a/src/Nazara/Graphics/Formats/TextureLoader.cpp b/src/Nazara/Graphics/Formats/TextureLoader.cpp index d3667a945..02f51d5ad 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.cpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 840875ea3..d55901de0 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include ///TODO: Replace sinus/cosinus by a lookup table (which will lead to a speed up about 10x) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 1d202c837..99452eaa1 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -10,14 +10,12 @@ #include #include #include -#include +#include #include #include #include -#include #include #include -#include #include namespace Nz @@ -217,8 +215,15 @@ namespace Nz s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(ForwardRenderQueue::BillboardData, size)); // Englobe sincos s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData2, ComponentType_Color, NazaraOffsetOf(ForwardRenderQueue::BillboardData, color)); + s_reflectionSampler.SetFilterMode(SamplerFilter_Bilinear); + s_reflectionSampler.SetWrapMode(SamplerWrap_Clamp); + s_shadowSampler.SetFilterMode(SamplerFilter_Bilinear); s_shadowSampler.SetWrapMode(SamplerWrap_Clamp); + + std::array whitePixels = { { 255, 255, 255, 255, 255, 255 } }; + s_dummyReflection.Create(ImageType_Cubemap, PixelFormatType_L8, 1, 1); + s_dummyReflection.Update(whitePixels.data()); } catch (const std::exception& e) { @@ -235,6 +240,7 @@ namespace Nz void ForwardRenderTechnique::Uninitialize() { + s_dummyReflection.Destroy(); s_quadIndexBuffer.Reset(); s_quadVertexBuffer.Reset(); } @@ -587,6 +593,10 @@ namespace Nz const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; + Texture* reflectionMap = sceneData.globalReflectionTexture; + if (!reflectionMap) + reflectionMap = &s_dummyReflection; + for (auto& pipelinePair : layer.opaqueModels) { const MaterialPipeline* pipeline = pipelinePair.first; @@ -622,6 +632,14 @@ namespace Nz { material->Apply(pipelineInstance); + if (shaderUniforms->reflectionMap != -1) + { + unsigned int textureUnit = Material::GetTextureUnit(TextureMap_ReflectionCube); + + Renderer::SetTexture(textureUnit, reflectionMap); + Renderer::SetTextureSampler(textureUnit, s_reflectionSampler); + } + ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; // Meshes @@ -1035,6 +1053,7 @@ namespace Nz uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &ForwardRenderTechnique::OnShaderInvalidated); uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.reflectionMap = shader->GetUniformLocation("ReflectionMap"); uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); @@ -1175,6 +1194,8 @@ namespace Nz } IndexBuffer ForwardRenderTechnique::s_quadIndexBuffer; + Texture ForwardRenderTechnique::s_dummyReflection; + TextureSampler ForwardRenderTechnique::s_reflectionSampler; TextureSampler ForwardRenderTechnique::s_shadowSampler; VertexBuffer ForwardRenderTechnique::s_quadVertexBuffer; VertexDeclaration ForwardRenderTechnique::s_billboardInstanceDeclaration; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index e1b202716..5ae1d8554 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -173,7 +173,7 @@ namespace Nz } /*! - * \brief Uninitializes the Core module + * \brief Uninitializes the Graphics module * * \remark Produces a NazaraNotice */ diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp index 0699b7fcf..16ae46be4 100644 --- a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index a2b188006..c891204a7 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -8,9 +8,6 @@ #include #include #include -#include -#include -#include #include ///TODO: Use of UBOs diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 0e865038a..e88ad6100 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -5,8 +5,7 @@ #include #include #include -#include -#include +#include #include namespace Nz @@ -388,6 +387,7 @@ namespace Nz m_ambientColor = Color(128, 128, 128); m_diffuseColor = Color::White; m_diffuseSampler = TextureSampler(); + m_reflectionMode = ReflectionMode_Skybox; m_shadowCastingEnabled = true; m_shininess = 50.f; m_specularColor = Color::White; @@ -395,6 +395,7 @@ namespace Nz m_pipelineInfo = MaterialPipelineInfo(); m_pipelineInfo.depthBuffer = true; m_pipelineInfo.faceCulling = true; + m_reflectionSize = 256; SetShader("Basic"); diff --git a/src/Nazara/Graphics/MaterialPipeline.cpp b/src/Nazara/Graphics/MaterialPipeline.cpp index e9a100ad2..01d29cafb 100644 --- a/src/Nazara/Graphics/MaterialPipeline.cpp +++ b/src/Nazara/Graphics/MaterialPipeline.cpp @@ -79,19 +79,20 @@ namespace Nz NazaraAssert(m_pipelineInfo.uberShader, "Material pipeline has no uber shader"); ParameterList list; - list.SetParameter("ALPHA_MAPPING", m_pipelineInfo.hasAlphaMap); - list.SetParameter("ALPHA_TEST", m_pipelineInfo.alphaTest); - list.SetParameter("COMPUTE_TBNMATRIX", m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap); - list.SetParameter("DIFFUSE_MAPPING", m_pipelineInfo.hasDiffuseMap); - list.SetParameter("EMISSIVE_MAPPING", m_pipelineInfo.hasEmissiveMap); - list.SetParameter("NORMAL_MAPPING", m_pipelineInfo.hasNormalMap); - list.SetParameter("PARALLAX_MAPPING", m_pipelineInfo.hasHeightMap); - list.SetParameter("SHADOW_MAPPING", m_pipelineInfo.shadowReceive); - list.SetParameter("SPECULAR_MAPPING", m_pipelineInfo.hasSpecularMap); - list.SetParameter("TEXTURE_MAPPING", m_pipelineInfo.hasAlphaMap || m_pipelineInfo.hasDiffuseMap || m_pipelineInfo.hasEmissiveMap || - m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap || m_pipelineInfo.hasSpecularMap || - flags & ShaderFlags_TextureOverlay); - list.SetParameter("TRANSFORM", true); + list.SetParameter("ALPHA_MAPPING", m_pipelineInfo.hasAlphaMap); + list.SetParameter("ALPHA_TEST", m_pipelineInfo.alphaTest); + list.SetParameter("COMPUTE_TBNMATRIX", m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap); + list.SetParameter("DIFFUSE_MAPPING", m_pipelineInfo.hasDiffuseMap); + list.SetParameter("EMISSIVE_MAPPING", m_pipelineInfo.hasEmissiveMap); + list.SetParameter("NORMAL_MAPPING", m_pipelineInfo.hasNormalMap); + list.SetParameter("PARALLAX_MAPPING", m_pipelineInfo.hasHeightMap); + list.SetParameter("REFLECTION_MAPPING", m_pipelineInfo.reflectionMapping); + list.SetParameter("SHADOW_MAPPING", m_pipelineInfo.shadowReceive); + list.SetParameter("SPECULAR_MAPPING", m_pipelineInfo.hasSpecularMap); + list.SetParameter("TEXTURE_MAPPING", m_pipelineInfo.hasAlphaMap || m_pipelineInfo.hasDiffuseMap || m_pipelineInfo.hasEmissiveMap || + m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap || m_pipelineInfo.hasSpecularMap || + m_pipelineInfo.reflectionMapping || flags & ShaderFlags_TextureOverlay); + list.SetParameter("TRANSFORM", true); list.SetParameter("FLAG_BILLBOARD", static_cast((flags & ShaderFlags_Billboard) != 0)); list.SetParameter("FLAG_DEFERRED", static_cast((flags & ShaderFlags_Deferred) != 0)); @@ -177,7 +178,7 @@ namespace Nz OverrideShader("Shaders/PhongLighting/core.vert", &vertexShader); #endif - uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING NORMAL_MAPPING PARALLAX_MAPPING SHADOW_MAPPING SPECULAR_MAPPING"); + uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING NORMAL_MAPPING PARALLAX_MAPPING REFLECTION_MAPPING SHADOW_MAPPING SPECULAR_MAPPING"); uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX PARALLAX_MAPPING SHADOW_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); UberShaderLibrary::Register("PhongLighting", uberShader); diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index a8e277d68..217211f01 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -41,26 +41,9 @@ namespace Nz } /*! - * \brief Constructs a Model object by default + * \brief Destructs the object and cleans resources */ - - Model::Model() : - m_matCount(0), - m_skin(0), - m_skinCount(1) - { - } - - /*! - * \brief Destructs the object and calls Reset - * - * \see Reset - */ - - Model::~Model() - { - Reset(); - } + Model::~Model() = default; /*! * \brief Adds this model to the render queue @@ -75,7 +58,7 @@ namespace Nz for (unsigned int i = 0; i < submeshCount; ++i) { const StaticMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); - Material* material = m_materials[mesh->GetMaterialIndex()]; + const MaterialRef& material = GetMaterial(mesh->GetMaterialIndex()); MeshData meshData; meshData.indexBuffer = mesh->GetIndexBuffer(); @@ -96,54 +79,20 @@ namespace Nz * \remark Produces a NazaraError if there is no subMesh with that name * \remark Produces a NazaraError if material is invalid */ - - Material* Model::GetMaterial(const String& subMeshName) const + const MaterialRef& Model::GetMaterial(const String& subMeshName) const { - #if NAZARA_GRAPHICS_SAFE - if (!m_mesh) - { - NazaraError("Model has no mesh"); - return nullptr; - } - #endif + NazaraAssert(m_mesh, "Model has no mesh"); SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { NazaraError("Mesh has no submesh \"" + subMeshName + '"'); - return nullptr; + + static MaterialRef Invalid; + return Invalid; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return nullptr; - } - - return m_materials[m_skin * m_matCount + matIndex]; - } - - /*! - * \brief Gets the material by index - * \return Pointer to the current material - * - * \param matIndex Index of the material - * - * \remark Produces a NazaraError if index is invalid - */ - - Material* Model::GetMaterial(unsigned int matIndex) const - { - #if NAZARA_GRAPHICS_SAFE - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return nullptr; - } - #endif - - return m_materials[m_skin * m_matCount + matIndex]; + return GetMaterial(subMesh->GetMaterialIndex()); } /*! @@ -157,72 +106,20 @@ namespace Nz * \remark Produces a NazaraError if there is no subMesh with that name * \remark Produces a NazaraError if material index is invalid */ - - Material* Model::GetMaterial(unsigned int skinIndex, const String& subMeshName) const + const MaterialRef& Model::GetMaterial(std::size_t skinIndex, const String& subMeshName) const { - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount) + ')'); - return nullptr; - } - #endif + NazaraAssert(m_mesh, "Model has no mesh"); SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { NazaraError("Mesh has no submesh \"" + subMeshName + '"'); - return nullptr; + + static MaterialRef Invalid; + return Invalid; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return nullptr; - } - - return m_materials[skinIndex * m_matCount + matIndex]; - } - - /*! - * \brief Gets the material by index with skin - * \return Pointer to the current material - * - * \param skinIndex Index of the skin - * \param matIndex Index of the material - * - * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid - * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if matIndex is invalid - */ - - Material* Model::GetMaterial(unsigned int skinIndex, unsigned int matIndex) const - { - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount) + ')'); - return nullptr; - } - - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return nullptr; - } - #endif - - return m_materials[skinIndex * m_matCount + matIndex]; - } - - /*! - * \brief Gets the number of materials - * \return Current number of materials - */ - - unsigned int Model::GetMaterialCount() const - { - return m_matCount; + return GetMaterial(subMesh->GetMaterialIndex()); } /*! @@ -235,26 +132,6 @@ namespace Nz return m_mesh; } - /*! - * \brief Gets the skin - * \return Current skin - */ - - unsigned int Model::GetSkin() const - { - return m_skin; - } - - /*! - * \brief Gets the number of skins - * \return Current number of skins - */ - - unsigned int Model::GetSkinCount() const - { - return m_skinCount; - } - /*! * \brief Checks whether the model is animated * \return false @@ -305,22 +182,6 @@ namespace Nz return ModelLoader::LoadFromStream(this, stream, params); } - /*! - * \brief Resets the model, cleans everything - */ - - void Model::Reset() - { - m_matCount = 0; - m_skinCount = 0; - - if (m_mesh) - { - m_mesh.Reset(); - m_materials.clear(); - } - } - /*! * \brief Sets the material of the named submesh * \return true If successful @@ -332,7 +193,7 @@ namespace Nz * \remark Produces a NazaraError if material index is invalid */ - bool Model::SetMaterial(const String& subMeshName, Material* material) + bool Model::SetMaterial(const String& subMeshName, MaterialRef material) { SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) @@ -341,51 +202,10 @@ namespace Nz return false; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return false; - } - - unsigned int index = m_skin * m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = Material::GetDefault(); - + SetMaterial(subMesh->GetMaterialIndex(), std::move(material)); return true; } - /*! - * \brief Sets the material by index - * \return true If successful - * - * \param matIndex Index of the material - * \param material Pointer to the material - * - * \remark Produces a NazaraError with if NAZARA_GRAPHICS_SAFE defined index is invalid - */ - - void Model::SetMaterial(unsigned int matIndex, Material* material) - { - #if NAZARA_GRAPHICS_SAFE - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); - return; - } - #endif - - unsigned int index = m_skin * m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = Material::GetDefault(); - } - /*! * \brief Sets the material by index of the named submesh * \return true If successful @@ -398,17 +218,8 @@ namespace Nz * \remark Produces a NazaraError if there is no subMesh with that name * \remark Produces a NazaraError if material index is invalid */ - - bool Model::SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material) + bool Model::SetMaterial(std::size_t skinIndex, const String& subMeshName, MaterialRef material) { - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount)); - return false; - } - #endif - SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { @@ -416,59 +227,10 @@ namespace Nz return false; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); - return false; - } - - unsigned int index = skinIndex * m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = Material::GetDefault(); - + SetMaterial(skinIndex, subMesh->GetMaterialIndex(), std::move(material)); return true; } - /*! - * \brief Sets the material by index with skin - * \return true If successful - * - * \param skinIndex Index of the skin - * \param matIndex Index of the material - * \param material Pointer to the material - * - * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid - * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if matIndex is invalid - */ - - void Model::SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material) - { - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount)); - return; - } - - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); - return; - } - #endif - - unsigned int index = skinIndex * m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = Material::GetDefault(); - } - /*! * \brief Sets the mesh * @@ -490,65 +252,13 @@ namespace Nz m_mesh = mesh; if (m_mesh) - { - m_matCount = mesh->GetMaterialCount(); - m_materials.clear(); - m_materials.resize(m_matCount, Material::GetDefault()); - m_skinCount = 1; - } + ResetMaterials(mesh->GetMaterialCount()); else - { - m_matCount = 0; - m_materials.clear(); - m_skinCount = 0; - } + ResetMaterials(0); InvalidateBoundingVolume(); } - /*! - * \brief Sets the skin - * - * \param skin Skin to use - * - * \remark Produces a NazaraError if skin is invalid - */ - - void Model::SetSkin(unsigned int skin) - { - #if NAZARA_GRAPHICS_SAFE - if (skin >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skin) + " >= " + String::Number(m_skinCount) + ')'); - return; - } - #endif - - m_skin = skin; - } - - /*! - * \brief Sets the number of skins - * - * \param skinCount Number of skins - * - * \remark Produces a NazaraError if skinCount equals zero - */ - - void Model::SetSkinCount(unsigned int skinCount) - { - #if NAZARA_GRAPHICS_SAFE - if (skinCount == 0) - { - NazaraError("Skin count must be over zero"); - return; - } - #endif - - m_materials.resize(m_matCount*skinCount, Material::GetDefault()); - m_skinCount = skinCount; - } - /* * \brief Makes the bounding volume of this billboard */ diff --git a/src/Nazara/Graphics/ParticleDeclaration.cpp b/src/Nazara/Graphics/ParticleDeclaration.cpp index 63b329aa4..a9a8e983d 100644 --- a/src/Nazara/Graphics/ParticleDeclaration.cpp +++ b/src/Nazara/Graphics/ParticleDeclaration.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Nz @@ -287,7 +286,7 @@ namespace Nz // ParticleLayout_Billboard : ParticleStruct_Billboard declaration = &s_declarations[ParticleLayout_Billboard]; declaration->EnableComponent(ParticleComponent_Color, ComponentType_Color, NazaraOffsetOf(ParticleStruct_Billboard, color)); - declaration->EnableComponent(ParticleComponent_Life, ComponentType_Int1, NazaraOffsetOf(ParticleStruct_Billboard, life)); + declaration->EnableComponent(ParticleComponent_Life, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Billboard, life)); declaration->EnableComponent(ParticleComponent_Normal, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, normal)); declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, position)); declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Billboard, rotation)); @@ -298,7 +297,7 @@ namespace Nz // ParticleLayout_Model : ParticleStruct_Model declaration = &s_declarations[ParticleLayout_Model]; - declaration->EnableComponent(ParticleComponent_Life, ComponentType_Int1, NazaraOffsetOf(ParticleStruct_Model, life)); + declaration->EnableComponent(ParticleComponent_Life, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Model, life)); declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Model, position)); declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Quaternion, NazaraOffsetOf(ParticleStruct_Model, rotation)); declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Model, velocity)); @@ -308,7 +307,7 @@ namespace Nz // ParticleLayout_Sprite : ParticleStruct_Sprite declaration = &s_declarations[ParticleLayout_Sprite]; declaration->EnableComponent(ParticleComponent_Color, ComponentType_Color, NazaraOffsetOf(ParticleStruct_Sprite, color)); - declaration->EnableComponent(ParticleComponent_Life, ComponentType_Int1, NazaraOffsetOf(ParticleStruct_Sprite, life)); + declaration->EnableComponent(ParticleComponent_Life, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Sprite, life)); declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Sprite, position)); declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Sprite, rotation)); declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Sprite, velocity)); diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 89811dd53..fe1b17e82 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -3,13 +3,8 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include -#include #include #include -#include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/ParticleGroup.cpp b/src/Nazara/Graphics/ParticleGroup.cpp index 34a46089b..0bad010a4 100644 --- a/src/Nazara/Graphics/ParticleGroup.cpp +++ b/src/Nazara/Graphics/ParticleGroup.cpp @@ -7,8 +7,6 @@ #include #include #include -#include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/ParticleMapper.cpp b/src/Nazara/Graphics/ParticleMapper.cpp index 05932abaa..ef48e8c14 100644 --- a/src/Nazara/Graphics/ParticleMapper.cpp +++ b/src/Nazara/Graphics/ParticleMapper.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include namespace Nz diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h index 0491fca4a..7b1439d81 100644 --- a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h @@ -1 +1 @@ -35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,76,117,109,105,110,97,110,99,101,32,61,32,48,46,56,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,77,105,100,100,108,101,71,114,101,121,32,61,32,48,46,53,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,32,61,32,48,46,56,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,13,10,9,99,111,108,111,114,32,42,61,32,66,114,105,103,104,116,77,105,100,100,108,101,71,114,101,121,47,66,114,105,103,104,116,76,117,109,105,110,97,110,99,101,59,13,10,9,99,111,108,111,114,32,42,61,32,49,46,48,32,43,32,40,99,111,108,111,114,32,47,32,40,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,42,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,41,41,59,13,10,9,99,111,108,111,114,32,45,61,32,48,46,53,59,13,10,9,99,111,108,111,114,32,47,61,32,40,49,46,48,32,43,32,99,111,108,111,114,41,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,99,111,108,111,114,44,32,49,46,48,41,59,13,10,125,13,10, \ No newline at end of file +35,118,101,114,115,105,111,110,32,49,52,48,10,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,76,117,109,105,110,97,110,99,101,32,61,32,48,46,56,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,77,105,100,100,108,101,71,114,101,121,32,61,32,48,46,53,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,32,61,32,48,46,56,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,10,9,118,101,99,51,32,99,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,10,10,9,99,111,108,111,114,32,42,61,32,66,114,105,103,104,116,77,105,100,100,108,101,71,114,101,121,47,66,114,105,103,104,116,76,117,109,105,110,97,110,99,101,59,10,9,99,111,108,111,114,32,42,61,32,49,46,48,32,43,32,40,99,111,108,111,114,32,47,32,40,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,42,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,41,41,59,10,9,99,111,108,111,114,32,45,61,32,48,46,53,59,10,9,99,111,108,111,114,32,47,61,32,40,49,46,48,32,43,32,99,111,108,111,114,41,59,10,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,99,111,108,111,114,44,32,49,46,48,41,59,10,125,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h index 822e2795d..63f3c0e13 100644 --- a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h @@ -1 +1 @@ -35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,66,108,111,111,109,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,98,108,111,111,109,67,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,66,108,111,111,109,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,9,118,101,99,51,32,111,114,105,103,105,110,97,108,67,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,111,114,105,103,105,110,97,108,67,111,108,111,114,32,43,32,98,108,111,111,109,67,111,108,111,114,44,32,49,46,48,41,59,13,10,125,13,10, \ No newline at end of file +35,118,101,114,115,105,111,110,32,49,52,48,10,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,66,108,111,111,109,84,101,120,116,117,114,101,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,10,9,118,101,99,51,32,98,108,111,111,109,67,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,66,108,111,111,109,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,10,9,118,101,99,51,32,111,114,105,103,105,110,97,108,67,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,10,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,111,114,105,103,105,110,97,108,67,111,108,111,114,32,43,32,98,108,111,111,109,67,111,108,111,114,44,32,49,46,48,41,59,10,125,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h index c6af64a3d..4722dd840 100644 --- a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h @@ -1 +1 @@ -35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,70,88,65,65,82,101,100,117,99,101,77,117,108,32,61,32,48,46,48,59,32,47,47,32,49,46,48,47,56,46,48,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,70,88,65,65,83,112,97,110,77,97,120,32,61,32,56,46,48,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,32,32,32,32,35,100,101,102,105,110,101,32,70,88,65,65,95,82,69,68,85,67,69,95,77,73,78,32,32,32,40,49,46,48,47,49,50,56,46,48,41,13,10,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,32,32,32,32,118,101,99,51,32,114,103,98,78,87,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,45,49,44,45,49,41,41,46,114,103,98,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,78,69,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,49,44,45,49,41,41,46,114,103,98,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,83,87,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,45,49,44,49,41,41,46,114,103,98,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,83,69,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,49,44,49,41,41,46,114,103,98,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,77,32,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,13,10,32,32,32,32,118,101,99,51,32,108,117,109,97,32,61,32,118,101,99,51,40,48,46,50,57,57,44,32,48,46,53,56,55,44,32,48,46,49,49,52,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,78,87,32,61,32,100,111,116,40,114,103,98,78,87,44,32,108,117,109,97,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,78,69,32,61,32,100,111,116,40,114,103,98,78,69,44,32,108,117,109,97,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,83,87,32,61,32,100,111,116,40,114,103,98,83,87,44,32,108,117,109,97,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,83,69,32,61,32,100,111,116,40,114,103,98,83,69,44,32,108,117,109,97,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,32,32,61,32,100,111,116,40,114,103,98,77,44,32,32,108,117,109,97,41,59,13,10,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,105,110,32,61,32,109,105,110,40,108,117,109,97,77,44,32,109,105,110,40,109,105,110,40,108,117,109,97,78,87,44,32,108,117,109,97,78,69,41,44,32,109,105,110,40,108,117,109,97,83,87,44,32,108,117,109,97,83,69,41,41,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,97,120,32,61,32,109,97,120,40,108,117,109,97,77,44,32,109,97,120,40,109,97,120,40,108,117,109,97,78,87,44,32,108,117,109,97,78,69,41,44,32,109,97,120,40,108,117,109,97,83,87,44,32,108,117,109,97,83,69,41,41,41,59,13,10,13,10,32,32,32,32,118,101,99,50,32,100,105,114,59,32,13,10,32,32,32,32,100,105,114,46,120,32,61,32,45,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,78,69,41,32,45,32,40,108,117,109,97,83,87,32,43,32,108,117,109,97,83,69,41,41,59,13,10,32,32,32,32,100,105,114,46,121,32,61,32,32,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,83,87,41,32,45,32,40,108,117,109,97,78,69,32,43,32,108,117,109,97,83,69,41,41,59,13,10,13,10,32,32,32,32,102,108,111,97,116,32,100,105,114,82,101,100,117,99,101,32,61,32,109,97,120,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,78,69,32,43,32,108,117,109,97,83,87,32,43,32,108,117,109,97,83,69,41,32,42,32,40,48,46,50,53,32,42,32,70,88,65,65,82,101,100,117,99,101,77,117,108,41,44,32,70,88,65,65,95,82,69,68,85,67,69,95,77,73,78,41,59,13,10,32,32,32,32,102,108,111,97,116,32,114,99,112,68,105,114,77,105,110,32,61,32,49,46,48,47,40,109,105,110,40,97,98,115,40,100,105,114,46,120,41,44,32,97,98,115,40,100,105,114,46,121,41,41,32,43,32,100,105,114,82,101,100,117,99,101,41,59,13,10,32,32,32,32,100,105,114,32,61,32,109,105,110,40,118,101,99,50,40,70,88,65,65,83,112,97,110,77,97,120,44,32,70,88,65,65,83,112,97,110,77,97,120,41,44,32,109,97,120,40,118,101,99,50,40,45,70,88,65,65,83,112,97,110,77,97,120,44,32,45,70,88,65,65,83,112,97,110,77,97,120,41,44,32,100,105,114,32,42,32,114,99,112,68,105,114,77,105,110,41,41,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,32,32,32,32,118,101,99,51,32,114,103,98,65,32,61,32,40,49,46,48,47,50,46,48,41,32,42,32,40,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,49,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,32,43,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,50,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,41,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,66,32,61,32,114,103,98,65,32,42,32,49,46,48,47,50,46,48,32,43,32,49,46,48,47,52,46,48,32,42,32,40,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,48,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,32,43,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,51,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,66,32,61,32,100,111,116,40,114,103,98,66,44,32,108,117,109,97,41,59,13,10,13,10,9,118,101,99,51,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,40,108,117,109,97,66,32,60,32,108,117,109,97,77,105,110,32,124,124,32,108,117,109,97,66,32,62,32,108,117,109,97,77,97,120,41,32,63,32,114,103,98,65,32,58,32,114,103,98,66,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,102,114,97,103,109,101,110,116,67,111,108,111,114,44,32,49,46,48,41,59,13,10,125, \ No newline at end of file +35,118,101,114,115,105,111,110,32,49,52,48,10,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,70,88,65,65,82,101,100,117,99,101,77,117,108,32,61,32,48,46,48,59,32,47,47,32,49,46,48,47,56,46,48,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,70,88,65,65,83,112,97,110,77,97,120,32,61,32,56,46,48,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,32,32,32,32,35,100,101,102,105,110,101,32,70,88,65,65,95,82,69,68,85,67,69,95,77,73,78,32,32,32,40,49,46,48,47,49,50,56,46,48,41,10,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,10,32,32,32,32,118,101,99,51,32,114,103,98,78,87,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,45,49,44,45,49,41,41,46,114,103,98,59,10,32,32,32,32,118,101,99,51,32,114,103,98,78,69,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,49,44,45,49,41,41,46,114,103,98,59,10,32,32,32,32,118,101,99,51,32,114,103,98,83,87,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,45,49,44,49,41,41,46,114,103,98,59,10,32,32,32,32,118,101,99,51,32,114,103,98,83,69,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,49,44,49,41,41,46,114,103,98,59,10,32,32,32,32,118,101,99,51,32,114,103,98,77,32,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,10,10,32,32,32,32,118,101,99,51,32,108,117,109,97,32,61,32,118,101,99,51,40,48,46,50,57,57,44,32,48,46,53,56,55,44,32,48,46,49,49,52,41,59,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,78,87,32,61,32,100,111,116,40,114,103,98,78,87,44,32,108,117,109,97,41,59,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,78,69,32,61,32,100,111,116,40,114,103,98,78,69,44,32,108,117,109,97,41,59,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,83,87,32,61,32,100,111,116,40,114,103,98,83,87,44,32,108,117,109,97,41,59,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,83,69,32,61,32,100,111,116,40,114,103,98,83,69,44,32,108,117,109,97,41,59,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,32,32,61,32,100,111,116,40,114,103,98,77,44,32,32,108,117,109,97,41,59,10,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,105,110,32,61,32,109,105,110,40,108,117,109,97,77,44,32,109,105,110,40,109,105,110,40,108,117,109,97,78,87,44,32,108,117,109,97,78,69,41,44,32,109,105,110,40,108,117,109,97,83,87,44,32,108,117,109,97,83,69,41,41,41,59,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,97,120,32,61,32,109,97,120,40,108,117,109,97,77,44,32,109,97,120,40,109,97,120,40,108,117,109,97,78,87,44,32,108,117,109,97,78,69,41,44,32,109,97,120,40,108,117,109,97,83,87,44,32,108,117,109,97,83,69,41,41,41,59,10,10,32,32,32,32,118,101,99,50,32,100,105,114,59,32,10,32,32,32,32,100,105,114,46,120,32,61,32,45,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,78,69,41,32,45,32,40,108,117,109,97,83,87,32,43,32,108,117,109,97,83,69,41,41,59,10,32,32,32,32,100,105,114,46,121,32,61,32,32,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,83,87,41,32,45,32,40,108,117,109,97,78,69,32,43,32,108,117,109,97,83,69,41,41,59,10,10,32,32,32,32,102,108,111,97,116,32,100,105,114,82,101,100,117,99,101,32,61,32,109,97,120,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,78,69,32,43,32,108,117,109,97,83,87,32,43,32,108,117,109,97,83,69,41,32,42,32,40,48,46,50,53,32,42,32,70,88,65,65,82,101,100,117,99,101,77,117,108,41,44,32,70,88,65,65,95,82,69,68,85,67,69,95,77,73,78,41,59,10,32,32,32,32,102,108,111,97,116,32,114,99,112,68,105,114,77,105,110,32,61,32,49,46,48,47,40,109,105,110,40,97,98,115,40,100,105,114,46,120,41,44,32,97,98,115,40,100,105,114,46,121,41,41,32,43,32,100,105,114,82,101,100,117,99,101,41,59,10,32,32,32,32,100,105,114,32,61,32,109,105,110,40,118,101,99,50,40,70,88,65,65,83,112,97,110,77,97,120,44,32,70,88,65,65,83,112,97,110,77,97,120,41,44,32,109,97,120,40,118,101,99,50,40,45,70,88,65,65,83,112,97,110,77,97,120,44,32,45,70,88,65,65,83,112,97,110,77,97,120,41,44,32,100,105,114,32,42,32,114,99,112,68,105,114,77,105,110,41,41,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,10,32,32,32,32,118,101,99,51,32,114,103,98,65,32,61,32,40,49,46,48,47,50,46,48,41,32,42,32,40,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,49,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,32,43,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,50,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,41,59,10,32,32,32,32,118,101,99,51,32,114,103,98,66,32,61,32,114,103,98,65,32,42,32,49,46,48,47,50,46,48,32,43,32,49,46,48,47,52,46,48,32,42,32,40,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,48,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,32,43,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,51,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,41,59,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,66,32,61,32,100,111,116,40,114,103,98,66,44,32,108,117,109,97,41,59,10,10,9,118,101,99,51,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,40,108,117,109,97,66,32,60,32,108,117,109,97,77,105,110,32,124,124,32,108,117,109,97,66,32,62,32,108,117,109,97,77,97,120,41,32,63,32,114,103,98,65,32,58,32,114,103,98,66,59,10,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,102,114,97,103,109,101,110,116,67,111,108,111,114,44,32,49,46,48,41,59,10,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GBufferClear.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GBufferClear.frag.h index b63b360f8..b81786f2d 100644 --- a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GBufferClear.frag.h +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GBufferClear.frag.h @@ -1 +1 @@ -35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,49,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,13,10,9,103,108,95,70,114,97,103,68,101,112,116,104,32,61,32,49,46,48,59,13,10,125,13,10, \ No newline at end of file +35,118,101,114,115,105,111,110,32,49,52,48,10,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,49,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,10,9,103,108,95,70,114,97,103,68,101,112,116,104,32,61,32,49,46,48,59,10,125,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h index 368c99770..6b805bbb5 100644 --- a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h @@ -1 +1 @@ -47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,101,101,107,115,51,100,46,99,111,109,47,50,48,49,48,48,57,48,57,47,115,104,97,100,101,114,45,108,105,98,114,97,114,121,45,103,97,117,115,115,105,97,110,45,98,108,117,114,45,112,111,115,116,45,112,114,111,99,101,115,115,105,110,103,45,102,105,108,116,101,114,45,105,110,45,103,108,115,108,47,13,10,35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,70,105,108,116,101,114,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,102,108,111,97,116,32,111,102,102,115,101,116,91,51,93,32,61,32,102,108,111,97,116,91,93,40,48,46,48,44,32,49,46,51,56,52,54,49,53,51,56,52,54,44,32,51,46,50,51,48,55,54,57,50,51,48,56,41,59,13,10,102,108,111,97,116,32,119,101,105,103,104,116,91,51,93,32,61,32,102,108,111,97,116,91,93,40,48,46,50,50,55,48,50,55,48,50,55,48,44,32,48,46,51,49,54,50,49,54,50,49,54,50,44,32,48,46,48,55,48,50,55,48,50,55,48,51,41,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,9,118,101,99,51,32,99,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,48,93,59,13,10,13,10,9,102,111,114,32,40,105,110,116,32,105,32,61,32,49,59,32,105,32,60,32,51,59,32,105,43,43,41,13,10,9,123,13,10,9,9,99,111,108,111,114,32,43,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,70,105,108,116,101,114,42,118,101,99,50,40,111,102,102,115,101,116,91,105,93,41,42,73,110,118,84,97,114,103,101,116,83,105,122,101,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,105,93,59,13,10,9,9,99,111,108,111,114,32,43,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,45,32,70,105,108,116,101,114,42,118,101,99,50,40,111,102,102,115,101,116,91,105,93,41,42,73,110,118,84,97,114,103,101,116,83,105,122,101,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,105,93,59,13,10,9,125,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,99,111,108,111,114,44,32,49,46,48,41,59,13,10,125,13,10, \ No newline at end of file +47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,101,101,107,115,51,100,46,99,111,109,47,50,48,49,48,48,57,48,57,47,115,104,97,100,101,114,45,108,105,98,114,97,114,121,45,103,97,117,115,115,105,97,110,45,98,108,117,114,45,112,111,115,116,45,112,114,111,99,101,115,115,105,110,103,45,102,105,108,116,101,114,45,105,110,45,103,108,115,108,47,10,35,118,101,114,115,105,111,110,32,49,52,48,10,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,70,105,108,116,101,114,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,10,102,108,111,97,116,32,111,102,102,115,101,116,91,51,93,32,61,32,102,108,111,97,116,91,93,40,48,46,48,44,32,49,46,51,56,52,54,49,53,51,56,52,54,44,32,51,46,50,51,48,55,54,57,50,51,48,56,41,59,10,102,108,111,97,116,32,119,101,105,103,104,116,91,51,93,32,61,32,102,108,111,97,116,91,93,40,48,46,50,50,55,48,50,55,48,50,55,48,44,32,48,46,51,49,54,50,49,54,50,49,54,50,44,32,48,46,48,55,48,50,55,48,50,55,48,51,41,59,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,9,118,101,99,51,32,99,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,48,93,59,10,10,9,102,111,114,32,40,105,110,116,32,105,32,61,32,49,59,32,105,32,60,32,51,59,32,105,43,43,41,10,9,123,10,9,9,99,111,108,111,114,32,43,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,70,105,108,116,101,114,42,118,101,99,50,40,111,102,102,115,101,116,91,105,93,41,42,73,110,118,84,97,114,103,101,116,83,105,122,101,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,105,93,59,10,9,9,99,111,108,111,114,32,43,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,45,32,70,105,108,116,101,114,42,118,101,99,50,40,111,102,102,115,101,116,91,105,93,41,42,73,110,118,84,97,114,103,101,116,83,105,122,101,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,105,93,59,10,9,125,10,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,99,111,108,111,114,44,32,49,46,48,41,59,10,125,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h index c6eff909e..0d9530d13 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h @@ -1 +1 @@ -35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,125, \ No newline at end of file +35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,10,35,101,110,100,105,102,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,10,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,35,101,108,115,101,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,105,102,32,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,35,101,110,100,105,102,10,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,10,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h index 7c3081f31..993c7291b 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h @@ -1 +1 @@ -47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,13,10,35,101,108,115,101,13,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,35,101,110,100,105,102,13,10,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,35,101,108,115,101,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,13,10,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,13,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,13,10,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,13,10,9,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,9,35,101,110,100,105,102,13,10,9,116,101,120,67,111,111,114,100,115,46,121,32,61,32,49,46,48,32,45,32,116,101,120,67,111,111,114,100,115,46,121,59,13,10,35,101,108,115,101,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,108,115,101,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,13,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,59,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file +47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,10,35,101,108,115,101,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,35,101,110,100,105,102,10,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,10,35,101,108,115,101,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,10,35,101,110,100,105,102,10,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,10,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,10,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,10,9,35,101,108,115,101,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,10,9,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,9,35,101,110,100,105,102,10,9,116,101,120,67,111,111,114,100,115,46,121,32,61,32,49,46,48,32,45,32,116,101,120,67,111,111,114,100,115,46,121,59,10,35,101,108,115,101,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,108,115,101,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,110,100,105,102,10,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,59,10,35,101,110,100,105,102,10,125,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index e37df3fa3..560ca4c29 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -63,6 +63,7 @@ uniform float ParallaxBias = -0.03; uniform float ParallaxScale = 0.02; uniform vec2 InvTargetSize; uniform vec3 EyePosition; +uniform samplerCube ReflectionMap; uniform vec4 SceneAmbient; uniform sampler2D TextureOverlay; @@ -451,6 +452,14 @@ void main() #endif vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); + + #if REFLECTION_MAPPING + vec3 eyeVec = normalize(vWorldPos - EyePosition); + + vec3 reflected = normalize(reflect(eyeVec, normal)); + lightColor *= texture(ReflectionMap, reflected).rgb; + #endif + vec4 fragmentColor = vec4(lightColor, 1.0) * diffuseColor; #if EMISSIVE_MAPPING diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index b9e39fa11..555144993 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h @@ -1 +1 @@ -35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,47,47,32,72,65,67,75,32,85,78,84,73,76,32,80,82,79,80,69,82,32,70,73,88,13,10,35,105,102,32,71,76,83,76,95,86,69,82,83,73,79,78,32,60,32,52,48,48,13,10,9,35,117,110,100,101,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,35,100,101,102,105,110,101,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,32,48,13,10,35,101,110,100,105,102,13,10,47,47,32,72,65,67,75,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,13,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,13,10,13,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,13,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125,13,10,13,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,9,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,9,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,13,10,13,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,13,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,13,10,125,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,13,10,125,13,10,13,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,13,10,125,13,10,13,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,13,10,9,102,108,111,97,116,32,118,105,115,105,98,105,108,105,116,121,32,61,32,49,46,48,59,13,10,9,102,108,111,97,116,32,120,44,121,59,13,10,9,102,111,114,32,40,121,32,61,32,45,51,46,53,59,32,121,32,60,61,32,51,46,53,59,32,121,43,61,32,49,46,48,41,13,10,9,9,102,111,114,32,40,120,32,61,32,45,51,46,53,59,32,120,32,60,61,32,51,46,53,59,32,120,43,61,32,49,46,48,41,13,10,9,9,9,118,105,115,105,98,105,108,105,116,121,32,43,61,32,40,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,32,43,32,118,101,99,51,40,120,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,121,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,48,46,48,41,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,41,32,63,32,49,46,48,32,58,32,48,46,48,59,13,10,13,10,9,118,105,115,105,98,105,108,105,116,121,32,47,61,32,54,52,46,48,59,13,10,9,13,10,9,114,101,116,117,114,110,32,118,105,115,105,98,105,108,105,116,121,59,13,10,125,13,10,35,101,110,100,105,102,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,13,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,13,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,13,10,13,10,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,47,42,13,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,13,10,9,42,47,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,13,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,125,13,10,13,10, \ No newline at end of file +35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,47,47,32,72,65,67,75,32,85,78,84,73,76,32,80,82,79,80,69,82,32,70,73,88,13,10,35,105,102,32,71,76,83,76,95,86,69,82,83,73,79,78,32,60,32,52,48,48,13,10,9,35,117,110,100,101,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,35,100,101,102,105,110,101,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,32,48,13,10,35,101,110,100,105,102,13,10,47,47,32,72,65,67,75,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,82,101,102,108,101,99,116,105,111,110,77,97,112,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,13,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,13,10,13,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,13,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125,13,10,13,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,9,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,9,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,13,10,13,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,13,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,13,10,125,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,13,10,125,13,10,13,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,13,10,125,13,10,13,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,13,10,9,102,108,111,97,116,32,118,105,115,105,98,105,108,105,116,121,32,61,32,49,46,48,59,13,10,9,102,108,111,97,116,32,120,44,121,59,13,10,9,102,111,114,32,40,121,32,61,32,45,51,46,53,59,32,121,32,60,61,32,51,46,53,59,32,121,43,61,32,49,46,48,41,13,10,9,9,102,111,114,32,40,120,32,61,32,45,51,46,53,59,32,120,32,60,61,32,51,46,53,59,32,120,43,61,32,49,46,48,41,13,10,9,9,9,118,105,115,105,98,105,108,105,116,121,32,43,61,32,40,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,32,43,32,118,101,99,51,40,120,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,121,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,48,46,48,41,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,41,32,63,32,49,46,48,32,58,32,48,46,48,59,13,10,13,10,9,118,105,115,105,98,105,108,105,116,121,32,47,61,32,54,52,46,48,59,13,10,9,13,10,9,114,101,116,117,114,110,32,118,105,115,105,98,105,108,105,116,121,59,13,10,125,13,10,35,101,110,100,105,102,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,13,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,13,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,13,10,13,10,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,47,42,13,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,13,10,9,42,47,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,13,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,13,10,9,9,9,9,9,123,13,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,13,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,13,10,9,35,105,102,32,82,69,70,76,69,67,84,73,79,78,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,118,87,111,114,108,100,80,111,115,32,45,32,69,121,101,80,111,115,105,116,105,111,110,41,59,13,10,13,10,9,118,101,99,51,32,114,101,102,108,101,99,116,101,100,32,61,32,110,111,114,109,97,108,105,122,101,40,114,101,102,108,101,99,116,40,101,121,101,86,101,99,44,32,110,111,114,109,97,108,41,41,59,13,10,9,108,105,103,104,116,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,82,101,102,108,101,99,116,105,111,110,77,97,112,44,32,114,101,102,108,101,99,116,101,100,41,46,114,103,98,59,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,125,13,10,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h index bed6edcab..7e63feb08 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h @@ -1 +1 @@ -47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,13,10,35,101,108,115,101,13,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,35,101,110,100,105,102,13,10,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,13,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,111,117,116,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,111,117,116,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,73,110,118,86,105,101,119,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,51,93,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,35,101,108,115,101,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,13,10,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,13,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,13,10,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,13,10,9,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,9,35,101,110,100,105,102,13,10,9,116,101,120,67,111,111,114,100,115,46,121,32,61,32,49,46,48,32,45,32,116,101,120,67,111,111,114,100,115,46,121,59,13,10,35,101,108,115,101,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,108,115,101,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,13,10,13,10,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,41,59,13,10,35,101,108,115,101,13,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,87,111,114,108,100,77,97,116,114,105,120,41,59,13,10,35,101,110,100,105,102,13,10,9,13,10,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,13,10,9,118,101,99,51,32,98,105,110,111,114,109,97,108,32,61,32,99,114,111,115,115,40,86,101,114,116,101,120,78,111,114,109,97,108,44,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,48,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,49,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,98,105,110,111,114,109,97,108,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,50,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,13,10,35,101,108,115,101,13,10,9,118,78,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,105,93,32,61,32,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,105,93,32,42,32,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,118,86,105,101,119,68,105,114,32,61,32,69,121,101,80,111,115,105,116,105,111,110,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,32,13,10,9,118,86,105,101,119,68,105,114,32,42,61,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,33,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file +47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,10,35,101,108,115,101,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,35,101,110,100,105,102,10,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,10,111,117,116,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,10,111,117,116,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,73,110,118,86,105,101,119,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,51,93,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,10,35,101,108,115,101,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,10,35,101,110,100,105,102,10,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,10,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,10,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,10,9,35,101,108,115,101,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,10,9,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,9,35,101,110,100,105,102,10,9,116,101,120,67,111,111,114,100,115,46,121,32,61,32,49,46,48,32,45,32,116,101,120,67,111,111,114,100,115,46,121,59,10,35,101,108,115,101,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,108,115,101,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,110,100,105,102,10,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,10,10,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,41,59,10,35,101,108,115,101,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,87,111,114,108,100,77,97,116,114,105,120,41,59,10,35,101,110,100,105,102,10,9,10,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,10,9,118,101,99,51,32,98,105,110,111,114,109,97,108,32,61,32,99,114,111,115,115,40,86,101,114,116,101,120,78,111,114,109,97,108,44,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,48,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,49,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,98,105,110,111,114,109,97,108,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,50,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,10,35,101,108,115,101,10,9,118,78,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,105,93,32,61,32,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,105,93,32,42,32,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,10,9,118,84,101,120,67,111,111,114,100,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,10,9,118,86,105,101,119,68,105,114,32,61,32,69,121,101,80,111,115,105,116,105,111,110,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,32,10,9,118,86,105,101,119,68,105,114,32,42,61,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,33,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,10,9,35,101,108,115,101,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,10,9,35,101,110,100,105,102,10,35,101,110,100,105,102,10,125,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index b571cb9dc..433a748f6 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -62,7 +62,7 @@ namespace Nz for (unsigned int i = 0; i < submeshCount; ++i) { const SkeletalMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); - const Material* material = m_materials[mesh->GetMaterialIndex()]; + const Material* material = GetMaterial(mesh->GetMaterialIndex()); MeshData meshData; meshData.indexBuffer = mesh->GetIndexBuffer(); @@ -261,17 +261,6 @@ namespace Nz return SkeletalModelLoader::LoadFromStream(this, stream, params); } - /*! - * \brief Resets the model - */ - - void SkeletalModel::Reset() - { - Model::Reset(); - - m_skeleton.Destroy(); - } - /*! * \brief Sets the animation for the model * \return true If successful diff --git a/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index 3472238b9..6460a1f1c 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -6,10 +6,11 @@ #include #include #include +#include +#include #include +#include #include -#include -#include #include #include diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index 0a2459b7f..85fe3559b 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -6,10 +6,11 @@ #include #include #include +#include +#include #include #include #include -#include #include namespace Nz @@ -154,7 +155,7 @@ namespace Nz "{\n" " vec4 WVPVertex = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n" " gl_Position = WVPVertex.xyww;\n" - " vTexCoord = vec3(VertexPosition.x, VertexPosition.y, -VertexPosition.z);\n" + " vTexCoord = VertexPosition;\n" "}\n"; try diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 04e648991..5d51a1ae1 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -4,9 +4,7 @@ #include #include -#include -#include -#include +#include #include namespace Nz @@ -26,11 +24,8 @@ namespace Nz void Sprite::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - if (!m_material) - return; - const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(instanceData.renderOrder, m_material, vertices, 1); + renderQueue->AddSprites(instanceData.renderOrder, GetMaterial(), vertices, 1); } /*! @@ -73,7 +68,37 @@ namespace Nz } /*! - * \brief Sets the texture of the sprite from a name + * \brief Sets the material of the sprite from a name for a specific skin + * + * Tries to get a material from the MaterialLibrary and then the MaterialManager (which will treat the name as a path) + * Fails if the texture name is not a part of the MaterialLibrary nor the MaterialManager (which fails if it couldn't load the texture from its filepath) + * + * \param skinIndex Skin index to change + * \param materialName Named texture for the material + * \param resizeSprite Should the sprite be resized to the material diffuse map size? + * + * \return True if the material was found or loaded from its name/path, false if it couldn't + */ + bool Sprite::SetMaterial(std::size_t skinIndex, String materialName, bool resizeSprite) + { + MaterialRef material = MaterialLibrary::Query(materialName); + if (!material) + { + material = MaterialManager::Get(materialName); + if (!material) + { + NazaraError("Failed to get material \"" + materialName + "\""); + return false; + } + } + + SetMaterial(skinIndex, std::move(material), resizeSprite); + return true; + } + + /*! + * \brief Sets the texture of the sprite from a name for the current skin + * \return True if the texture was found or loaded from its name/path, false if it couldn't * * Tries to get a texture from the TextureLibrary and then the TextureManager (which will treat the name as a path) * Fails if the texture name is not a part of the TextureLibrary nor the TextureManager (which fails if it couldn't load the texture from its filepath) @@ -81,8 +106,6 @@ namespace Nz * \param textureName Named texture for the sprite * \param resizeSprite Should the sprite be resized to the texture size? * - * \return True if the texture was found or loaded from its name/path, false if it couldn't - * * \remark The sprite material gets copied to prevent accidentally changing other drawable materials */ bool Sprite::SetTexture(String textureName, bool resizeSprite) @@ -102,6 +125,36 @@ namespace Nz return true; } + /*! + * \brief Sets the texture of the sprite from a name for a specific skin + * \return True if the texture was found or loaded from its name/path, false if it couldn't + * + * Tries to get a texture from the TextureLibrary and then the TextureManager (which will treat the name as a path) + * Fails if the texture name is not a part of the TextureLibrary nor the TextureManager (which fails if it couldn't load the texture from its filepath) + * + * \param skinIndex Named texture for the sprite + * \param textureName Named texture for the sprite + * \param resizeSprite Should the sprite be resized to the texture size? + * + * \remark The sprite material gets copied to prevent accidentally changing other drawable materials + */ + bool Sprite::SetTexture(std::size_t skinIndex, String textureName, bool resizeSprite) + { + TextureRef texture = TextureLibrary::Query(textureName); + if (!texture) + { + texture = TextureManager::Get(textureName); + if (!texture) + { + NazaraError("Failed to get texture \"" + textureName + "\""); + return false; + } + } + + SetTexture(skinIndex, std::move(texture), resizeSprite); + return true; + } + /*! * \brief Updates the data of the sprite * diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 70975929f..3d82037d4 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -6,9 +6,9 @@ #include #include #include -#include -#include +#include #include +#include #include namespace Nz @@ -28,9 +28,6 @@ namespace Nz void TextSprite::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - if (!m_material) - return; - for (auto& pair : m_renderInfos) { Texture* overlay = pair.first; @@ -39,7 +36,7 @@ namespace Nz if (indices.count > 0) { const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(instanceData.renderOrder, m_material, &vertices[indices.first * 4], indices.count, overlay); + renderQueue->AddSprites(instanceData.renderOrder, GetMaterial(), &vertices[indices.first * 4], indices.count, overlay); } } } diff --git a/src/Nazara/Graphics/TextureBackground.cpp b/src/Nazara/Graphics/TextureBackground.cpp index cd6c68c05..25de25d9e 100644 --- a/src/Nazara/Graphics/TextureBackground.cpp +++ b/src/Nazara/Graphics/TextureBackground.cpp @@ -4,7 +4,8 @@ #include #include -#include +#include +#include #include namespace Nz diff --git a/src/Nazara/Graphics/TileMap.cpp b/src/Nazara/Graphics/TileMap.cpp index 7fe358fb8..192341472 100644 --- a/src/Nazara/Graphics/TileMap.cpp +++ b/src/Nazara/Graphics/TileMap.cpp @@ -4,10 +4,8 @@ #include #include -#include #include -#include -#include +#include #include namespace Nz @@ -29,11 +27,11 @@ namespace Nz { const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); + std::size_t matCount = 0; std::size_t spriteCount = 0; for (const Layer& layer : m_layers) { - if (layer.material) - renderQueue->AddSprites(instanceData.renderOrder, layer.material, &vertices[spriteCount], layer.tiles.size()); + renderQueue->AddSprites(instanceData.renderOrder, GetMaterial(matCount++), &vertices[spriteCount], layer.tiles.size()); spriteCount += layer.tiles.size(); } diff --git a/src/Nazara/Lua/LuaCoroutine.cpp b/src/Nazara/Lua/LuaCoroutine.cpp index 197244134..bccf8d7fc 100644 --- a/src/Nazara/Lua/LuaCoroutine.cpp +++ b/src/Nazara/Lua/LuaCoroutine.cpp @@ -3,9 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include -#include #include #include diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index cd47ac5c7..366ccab27 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -8,14 +8,9 @@ #include #include #include -#include -#include -#include -#include #include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Lua/LuaState.cpp b/src/Nazara/Lua/LuaState.cpp index 4821b1d09..67bf8efa0 100644 --- a/src/Nazara/Lua/LuaState.cpp +++ b/src/Nazara/Lua/LuaState.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -14,9 +13,6 @@ #include #include #include -#include -#include -#include #include namespace Nz @@ -126,12 +122,6 @@ namespace Nz static_assert(sizeof(s_types)/sizeof(int) == LuaType_Max+1, "Lua type array is incomplete"); } - LuaState::LuaState(LuaState&& state) noexcept : - m_lastError(state.m_lastError), - m_state(state.m_state) - { - } - void LuaState::ArgCheck(bool condition, unsigned int argNum, const char* error) const { luaL_argcheck(m_state, condition, argNum, error); @@ -789,14 +779,6 @@ namespace Nz return luaL_testudata(m_state, index, tname.GetConstBuffer()); } - LuaState& LuaState::operator=(LuaState&& state) noexcept - { - m_lastError = std::move(state.m_lastError); - m_state = state.m_state; - - return *this; - } - bool LuaState::Run(int argCount, int resultCount) { LuaInstance& instance = GetInstance(m_state); diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index 3b3d9cb56..b070a93cb 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #if defined(NAZARA_PLATFORM_WINDOWS) diff --git a/src/Nazara/Network/ENetCompressor.cpp b/src/Nazara/Network/ENetCompressor.cpp new file mode 100644 index 000000000..373389ecc --- /dev/null +++ b/src/Nazara/Network/ENetCompressor.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + ENetCompressor::~ENetCompressor() = default; +} diff --git a/src/Nazara/Network/ENetHost.cpp b/src/Nazara/Network/ENetHost.cpp index 9fdfe284f..b967519b8 100644 --- a/src/Nazara/Network/ENetHost.cpp +++ b/src/Nazara/Network/ENetHost.cpp @@ -13,7 +13,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include #include @@ -86,7 +85,7 @@ namespace Nz return nullptr; } - m_channelLimit = Clamp(channelCount, ENetConstants::ENetProtocol_MinimumChannelCount, ENetConstants::ENetProtocol_MaximumChannelCount); + channelCount = Clamp(channelCount, ENetConstants::ENetProtocol_MinimumChannelCount, ENetConstants::ENetProtocol_MaximumChannelCount); UInt32 windowSize; if (m_outgoingBandwidth == 0) @@ -143,14 +142,14 @@ namespace Nz return Connect(hostnameAddress, channelCount, data); } - bool ENetHost::Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount) + bool ENetHost::Create(const IpAddress& listenAddress, std::size_t peerCount, std::size_t channelCount) { - return Create(address, peerCount, channelCount, 0, 0); + return Create(listenAddress, peerCount, channelCount, 0, 0); } - bool ENetHost::Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount, UInt32 incomingBandwidth, UInt32 outgoingBandwidth) + bool ENetHost::Create(const IpAddress& listenAddress, std::size_t peerCount, std::size_t channelCount, UInt32 incomingBandwidth, UInt32 outgoingBandwidth) { - NazaraAssert(address.IsValid(), "Invalid listening address"); + NazaraAssert(listenAddress.IsValid(), "Invalid listening address"); if (peerCount > ENetConstants::ENetProtocol_MaximumPeerId) { @@ -158,10 +157,11 @@ namespace Nz return false; } - if (!InitSocket(address)) + if (!InitSocket(listenAddress)) return false; - m_address = address; + m_address = listenAddress; + m_allowsIncomingConnections = (listenAddress.IsValid() && !listenAddress.IsLoopback()); m_randomSeed = *reinterpret_cast(this); m_randomSeed += s_randomGenerator(); m_randomSeed = (m_randomSeed << 16) | (m_randomSeed >> 16); @@ -198,9 +198,9 @@ namespace Nz void ENetHost::Flush() { - m_serviceTime = GetElapsedMilliseconds(); + UpdateServiceTime(); - SendOutgoingCommands(nullptr, 0); + SendOutgoingCommands(nullptr, false); } int ENetHost::Service(ENetEvent* event, UInt32 timeout) @@ -215,7 +215,8 @@ namespace Nz return 1; } - m_serviceTime = GetElapsedMilliseconds(); + UpdateServiceTime(); + timeout += m_serviceTime; do @@ -236,6 +237,10 @@ namespace Nz break; } + // Receiving on an unbound socket which has never sent data is an invalid operation + if (!m_allowsIncomingConnections && m_totalSentData == 0) + return 0; + switch (ReceiveIncomingCommands(event)) { case 1: @@ -274,7 +279,7 @@ namespace Nz for (;;) { - m_serviceTime = GetElapsedMilliseconds(); + UpdateServiceTime(); if (ENetTimeGreaterEqual(m_serviceTime, timeout)) return 0; @@ -283,7 +288,7 @@ namespace Nz break; } - m_serviceTime = GetElapsedMilliseconds(); + UpdateServiceTime(); } while (m_poller.IsReadyToRead(m_socket)); @@ -323,7 +328,7 @@ namespace Nz m_socket.SetReceiveBufferSize(ENetConstants::ENetHost_ReceiveBufferSize); m_socket.SetSendBufferSize(ENetConstants::ENetHost_SendBufferSize); - if (!address.IsLoopback()) + if (address.IsValid() && !address.IsLoopback()) { if (m_socket.Bind(address) != SocketState_Bound) { @@ -407,6 +412,9 @@ namespace Nz ENetPeer* ENetHost::HandleConnect(ENetProtocolHeader* /*header*/, ENetProtocol* command) { + if (!m_allowsIncomingConnections) + return nullptr; + UInt32 channelCount = NetToHost(command->connect.channelCount); if (channelCount < ENetProtocol_MinimumChannelCount || channelCount > ENetProtocol_MaximumChannelCount) @@ -513,6 +521,19 @@ namespace Nz } // Compression handling + if (flags & ENetProtocolHeaderFlag_Compressed) + { + if (!m_compressor) + return false; + + std::size_t newSize = m_compressor->Decompress(peer, m_receivedData + headerSize, m_receivedDataLength - headerSize, m_packetData[1].data() + headerSize, m_packetData[1].size() - headerSize); + if (newSize == 0 || newSize > m_packetData[1].size() - headerSize) + return false; + + std::memcpy(m_packetData[1].data(), header, headerSize); + m_receivedData = m_packetData[1].data(); + m_receivedDataLength = headerSize + newSize; + } // Checksum @@ -873,8 +894,6 @@ namespace Nz break; } - ++currentCommand; - if (channel && outgoingCommand->sendAttempts < 1) { channel->usedReliableWindows |= 1 << reliableWindow; @@ -893,7 +912,7 @@ namespace Nz peer->m_nextTimeout = m_serviceTime + outgoingCommand->roundTripTimeout; peer->m_sentReliableCommands.emplace_back(std::move(*outgoingCommand)); - peer->m_outgoingReliableCommands.erase(outgoingCommand); + currentCommand = peer->m_outgoingReliableCommands.erase(outgoingCommand); outgoingCommand = peer->m_sentReliableCommands.end(); --outgoingCommand; @@ -916,7 +935,7 @@ namespace Nz ++m_bufferCount; NetBuffer& packetBuffer = m_buffers[m_bufferCount]; - packetBuffer.data = outgoingCommand->packet->data.GetData() + Nz::NetPacket::HeaderSize + outgoingCommand->fragmentOffset; + packetBuffer.data = outgoingCommand->packet->data.GetData() + NetPacket::HeaderSize + outgoingCommand->fragmentOffset; packetBuffer.dataLength = outgoingCommand->fragmentLength; m_packetSize += packetBuffer.dataLength; @@ -1018,11 +1037,27 @@ namespace Nz else m_buffers[0].dataLength = NazaraOffsetOf(ENetProtocolHeader, sentTime); + // Compress packet buffers if possible + std::size_t compressedSize = 0; + if (m_compressor) + { + compressedSize = m_compressor->Compress(currentPeer, &m_buffers[1], m_bufferCount - 1, m_packetSize - sizeof(ENetProtocolHeader), m_packetData[1].data(), m_packetData[1].size()); + if (compressedSize > 0) + m_headerFlags |= ENetProtocolHeaderFlag_Compressed; + } + if (currentPeer->m_outgoingPeerID < ENetConstants::ENetProtocol_MaximumPeerId) m_headerFlags |= currentPeer->m_outgoingSessionID << ENetProtocolHeaderSessionShift; header->peerID = HostToNet(static_cast(currentPeer->m_outgoingPeerID | m_headerFlags)); + if (compressedSize > 0) + { + m_buffers[1].data = m_packetData[1].data(); + m_buffers[1].dataLength = compressedSize; + m_bufferCount = 2; + } + currentPeer->m_lastSendTime = m_serviceTime; // Simulate network by adding delay to packet sending and losing some packets @@ -1032,7 +1067,7 @@ namespace Nz sendNow = false; if (!currentPeer->m_packetLossProbability(s_randomGenerator)) { - Nz::UInt16 delay = currentPeer->m_packetDelayDistribution(s_randomGenerator); + UInt16 delay = currentPeer->m_packetDelayDistribution(s_randomGenerator); if (delay == 0) sendNow = true; else @@ -1146,6 +1181,8 @@ namespace Nz buffer.data = &command; buffer.dataLength = commandSize; + m_packetSize += buffer.dataLength; + command = outgoingCommand->command; if (outgoingCommand->packet) @@ -1153,7 +1190,7 @@ namespace Nz ++m_bufferCount; NetBuffer& packetBuffer = m_buffers[m_bufferCount]; - packetBuffer.data = outgoingCommand->packet->data.GetData() + Nz::NetPacket::HeaderSize + outgoingCommand->fragmentOffset; + packetBuffer.data = outgoingCommand->packet->data.GetData() + NetPacket::HeaderSize + outgoingCommand->fragmentOffset; packetBuffer.dataLength = outgoingCommand->fragmentLength; m_packetSize += packetBuffer.dataLength; diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp index fc63be189..aee2550f3 100644 --- a/src/Nazara/Network/IpAddress.cpp +++ b/src/Nazara/Network/IpAddress.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #if defined(NAZARA_PLATFORM_WINDOWS) #include diff --git a/src/Nazara/Network/Linux/SocketPollerImpl.cpp b/src/Nazara/Network/Linux/SocketPollerImpl.cpp index 6e902a587..d3287a815 100644 --- a/src/Nazara/Network/Linux/SocketPollerImpl.cpp +++ b/src/Nazara/Network/Linux/SocketPollerImpl.cpp @@ -111,9 +111,6 @@ namespace Nz if (m_events[i].events & (EPOLLOUT | EPOLLERR)) m_readyToWriteSockets.insert(m_events[i].data.fd); - - if (m_events[i].events & EPOLLERR) - NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll with EPOLLERR status"); } else { diff --git a/src/Nazara/Network/Network.cpp b/src/Nazara/Network/Network.cpp index 57ddfd83b..392b196b6 100644 --- a/src/Nazara/Network/Network.cpp +++ b/src/Nazara/Network/Network.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #if defined(NAZARA_PLATFORM_WINDOWS) #include diff --git a/src/Nazara/Network/Posix/SocketImpl.cpp b/src/Nazara/Network/Posix/SocketImpl.cpp index 7ca69ae29..9d1f7bd0c 100644 --- a/src/Nazara/Network/Posix/SocketImpl.cpp +++ b/src/Nazara/Network/Posix/SocketImpl.cpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include #include #include @@ -566,8 +566,7 @@ namespace Nz NazaraAssert(handle != InvalidHandle, "Invalid handle"); NazaraAssert(buffers && bufferCount > 0, "Invalid buffers"); - StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(iovec)); - struct iovec* sysBuffers = static_cast(memory.GetPtr()); + StackArray sysBuffers = NazaraStackAllocation(iovec, bufferCount); for (std::size_t i = 0; i < bufferCount; ++i) { sysBuffers[i].iov_base = buffers[i].data; @@ -577,7 +576,7 @@ namespace Nz struct msghdr msgHdr; std::memset(&msgHdr, 0, sizeof(msgHdr)); - msgHdr.msg_iov = sysBuffers; + msgHdr.msg_iov = sysBuffers.data(); msgHdr.msg_iovlen = static_cast(bufferCount); IpAddressImpl::SockAddrBuffer nameBuffer; @@ -689,8 +688,7 @@ namespace Nz NazaraAssert(handle != InvalidHandle, "Invalid handle"); NazaraAssert(buffers && bufferCount > 0, "Invalid buffers"); - StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(iovec)); - struct iovec* sysBuffers = static_cast(memory.GetPtr()); + StackArray sysBuffers = NazaraStackAllocation(iovec, bufferCount); for (std::size_t i = 0; i < bufferCount; ++i) { sysBuffers[i].iov_base = buffers[i].data; @@ -703,7 +701,7 @@ namespace Nz IpAddressImpl::SockAddrBuffer nameBuffer; msgHdr.msg_namelen = IpAddressImpl::ToSockAddr(to, nameBuffer.data()); msgHdr.msg_name = nameBuffer.data(); - msgHdr.msg_iov = sysBuffers; + msgHdr.msg_iov = sysBuffers.data(); msgHdr.msg_iovlen = static_cast(bufferCount); int byteSent = sendmsg(handle, &msgHdr, MSG_NOSIGNAL); diff --git a/src/Nazara/Network/Posix/SocketImpl.hpp b/src/Nazara/Network/Posix/SocketImpl.hpp index abba97e4f..e9f094cc3 100644 --- a/src/Nazara/Network/Posix/SocketImpl.hpp +++ b/src/Nazara/Network/Posix/SocketImpl.hpp @@ -10,12 +10,13 @@ #include #include #include -#include #define NAZARA_NETWORK_POLL_SUPPORT 1 namespace Nz { + struct NetBuffer; + struct PollSocket { SocketHandle fd; diff --git a/src/Nazara/Network/Posix/SocketPollerImpl.cpp b/src/Nazara/Network/Posix/SocketPollerImpl.cpp index ed391c6f3..810427933 100644 --- a/src/Nazara/Network/Posix/SocketPollerImpl.cpp +++ b/src/Nazara/Network/Posix/SocketPollerImpl.cpp @@ -90,12 +90,15 @@ namespace Nz int socketRemaining = activeSockets; for (PollSocket& entry : m_sockets) { - if (entry.revents != 0) + if (!entry.revents) + continue; + + if (entry.revents & (POLLRDNORM | POLLWRNORM | POLLHUP | POLLERR)) { - if (entry.revents & POLLRDNORM) + if (entry.revents & (POLLRDNORM | POLLHUP | POLLERR)) m_readyToReadSockets.insert(entry.fd); - if (entry.revents & POLLWRNORM) + if (entry.revents & (POLLWRNORM | POLLERR)) m_readyToWriteSockets.insert(entry.fd); entry.revents = 0; @@ -103,6 +106,11 @@ namespace Nz if (--socketRemaining == 0) break; } + else + { + NazaraWarning("Socket " + String::Number(entry.fd) + " was returned by WSAPoll without POLLRDNORM nor POLLWRNORM events (events: 0x" + String::Number(entry.revents, 16) + ')'); + activeSockets--; + } } } diff --git a/src/Nazara/Network/Posix/SocketPollerImpl.hpp b/src/Nazara/Network/Posix/SocketPollerImpl.hpp index 1ded2dabc..5c4ad1743 100644 --- a/src/Nazara/Network/Posix/SocketPollerImpl.hpp +++ b/src/Nazara/Network/Posix/SocketPollerImpl.hpp @@ -7,7 +7,6 @@ #ifndef NAZARA_SOCKETPOLLERIMPL_HPP #define NAZARA_SOCKETPOLLERIMPL_HPP -#include #include #include #include diff --git a/src/Nazara/Network/TcpServer.cpp b/src/Nazara/Network/TcpServer.cpp index 95aaaf098..ebeb2392e 100644 --- a/src/Nazara/Network/TcpServer.cpp +++ b/src/Nazara/Network/TcpServer.cpp @@ -3,10 +3,8 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include -#include #include #if defined(NAZARA_PLATFORM_WINDOWS) diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 6c82f0505..fbc8beec3 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -596,8 +596,7 @@ namespace Nz IpAddress senderIp; - StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(WSABUF)); - WSABUF* winBuffers = static_cast(memory.GetPtr()); + StackArray winBuffers = NazaraStackAllocation(WSABUF, bufferCount); for (std::size_t i = 0; i < bufferCount; ++i) { winBuffers[i].buf = static_cast(buffers[i].data); @@ -606,7 +605,7 @@ namespace Nz DWORD flags = 0; DWORD byteRead; - if (WSARecvFrom(handle, winBuffers, static_cast(bufferCount), &byteRead, &flags, reinterpret_cast(nameBuffer.data()), &bufferLength, nullptr, nullptr) == SOCKET_ERROR) + if (WSARecvFrom(handle, winBuffers.data(), static_cast(bufferCount), &byteRead, &flags, reinterpret_cast(nameBuffer.data()), &bufferLength, nullptr, nullptr) == SOCKET_ERROR) { int errorCode = WSAGetLastError(); switch (errorCode) @@ -696,8 +695,7 @@ namespace Nz IpAddressImpl::SockAddrBuffer nameBuffer; int bufferLength = IpAddressImpl::ToSockAddr(to, nameBuffer.data()); - StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(WSABUF)); - WSABUF* winBuffers = static_cast(memory.GetPtr()); + StackArray winBuffers = NazaraStackAllocation(WSABUF, bufferCount); for (std::size_t i = 0; i < bufferCount; ++i) { winBuffers[i].buf = static_cast(buffers[i].data); @@ -705,7 +703,7 @@ namespace Nz } DWORD byteSent; - if (WSASendTo(handle, winBuffers, static_cast(bufferCount), &byteSent, 0, reinterpret_cast(nameBuffer.data()), bufferLength, nullptr, nullptr) == SOCKET_ERROR) + if (WSASendTo(handle, winBuffers.data(), static_cast(bufferCount), &byteSent, 0, reinterpret_cast(nameBuffer.data()), bufferLength, nullptr, nullptr) == SOCKET_ERROR) { int errorCode = WSAGetLastError(); switch (errorCode) diff --git a/src/Nazara/Network/Win32/SocketPollerImpl.cpp b/src/Nazara/Network/Win32/SocketPollerImpl.cpp index 6789f35f4..43dc9fec2 100644 --- a/src/Nazara/Network/Win32/SocketPollerImpl.cpp +++ b/src/Nazara/Network/Win32/SocketPollerImpl.cpp @@ -143,12 +143,15 @@ namespace Nz int socketRemaining = activeSockets; for (PollSocket& entry : m_sockets) { - if (entry.revents != 0) + if (!entry.revents) + continue; + + if (entry.revents & (POLLRDNORM | POLLWRNORM | POLLHUP | POLLERR)) { - if (entry.revents & POLLRDNORM) + if (entry.revents & (POLLRDNORM | POLLHUP | POLLERR)) m_readyToReadSockets.insert(entry.fd); - if (entry.revents & POLLWRNORM) + if (entry.revents & (POLLWRNORM | POLLERR)) m_readyToWriteSockets.insert(entry.fd); entry.revents = 0; @@ -156,9 +159,13 @@ namespace Nz if (--socketRemaining == 0) break; } + else + { + NazaraWarning("Socket " + String::Number(entry.fd) + " was returned by WSAPoll without POLLRDNORM nor POLLWRNORM events (events: 0x" + String::Number(entry.revents, 16) + ')'); + activeSockets--; + } } } - #else fd_set* readSet = nullptr; fd_set* writeSet = nullptr; diff --git a/src/Nazara/Noise/Perlin.cpp b/src/Nazara/Noise/Perlin.cpp index 9d0249759..d80bf7c84 100644 --- a/src/Nazara/Noise/Perlin.cpp +++ b/src/Nazara/Noise/Perlin.cpp @@ -4,8 +4,6 @@ #include #include -#include -#include #include namespace Nz diff --git a/src/Nazara/Noise/Simplex.cpp b/src/Nazara/Noise/Simplex.cpp index d73465c70..b9e6ba957 100644 --- a/src/Nazara/Noise/Simplex.cpp +++ b/src/Nazara/Noise/Simplex.cpp @@ -4,8 +4,6 @@ #include #include -#include -#include #include namespace Nz diff --git a/src/Nazara/Noise/Worley.cpp b/src/Nazara/Noise/Worley.cpp index 81fd8aad0..82366234b 100644 --- a/src/Nazara/Noise/Worley.cpp +++ b/src/Nazara/Noise/Worley.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include diff --git a/src/Nazara/Physics2D/Collider2D.cpp b/src/Nazara/Physics2D/Collider2D.cpp index 9c7d964a5..95cd633af 100644 --- a/src/Nazara/Physics2D/Collider2D.cpp +++ b/src/Nazara/Physics2D/Collider2D.cpp @@ -31,7 +31,7 @@ namespace Nz /******************************** BoxCollider2D *********************************/ BoxCollider2D::BoxCollider2D(const Vector2f& size, float radius) : - BoxCollider2D(Rectf(-size.x / 2.f, -size.y / 2.f, size.x / 2.f, size.y / 2.f), radius) + BoxCollider2D(Rectf(-size.x / 2.f, -size.y / 2.f, size.x, size.y), radius) { } @@ -143,9 +143,9 @@ namespace Nz return ColliderType2D_Null; } - float NullCollider2D::ComputeMomentOfInertia(float /*mass*/) const + float NullCollider2D::ComputeMomentOfInertia(float mass) const { - return 0.f; + return (mass > 0.f) ? 1.f : 0.f; //< Null inertia is only possible for static/kinematic objects } void NullCollider2D::CreateShapes(RigidBody2D* /*body*/, std::vector& /*shapes*/) const diff --git a/src/Nazara/Physics2D/Constraint2D.cpp b/src/Nazara/Physics2D/Constraint2D.cpp new file mode 100644 index 000000000..39aa6a9f9 --- /dev/null +++ b/src/Nazara/Physics2D/Constraint2D.cpp @@ -0,0 +1,424 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Physics 2D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + Constraint2D::Constraint2D(PhysWorld2D& world, cpConstraint* constraint) : + m_constraint(constraint) + { + cpConstraintSetUserData(m_constraint, this); + cpSpaceAddConstraint(world.GetHandle(), m_constraint); + } + + Constraint2D::Constraint2D(Constraint2D&& rhs) : + m_constraint(std::move(rhs.m_constraint)) + { + cpConstraintSetUserData(m_constraint, this); + } + + Constraint2D::~Constraint2D() + { + cpSpaceRemoveConstraint(cpConstraintGetSpace(m_constraint), m_constraint); + } + + void Constraint2D::EnableBodyCollision(bool enable) + { + cpConstraintSetCollideBodies(m_constraint, (enable) ? cpTrue : cpFalse); + } + + RigidBody2D& Constraint2D::GetBodyA() + { + return *static_cast(cpBodyGetUserData(cpConstraintGetBodyA(m_constraint))); + } + + const RigidBody2D& Constraint2D::GetBodyA() const + { + return *static_cast(cpBodyGetUserData(cpConstraintGetBodyA(m_constraint))); + } + + RigidBody2D& Constraint2D::GetBodyB() + { + return *static_cast(cpBodyGetUserData(cpConstraintGetBodyB(m_constraint))); + } + + const RigidBody2D& Constraint2D::GetBodyB() const + { + return *static_cast(cpBodyGetUserData(cpConstraintGetBodyB(m_constraint))); + } + + float Constraint2D::GetErrorBias() const + { + return float(cpConstraintGetErrorBias(m_constraint)); + } + + float Constraint2D::GetMaxBias() const + { + return float(cpConstraintGetMaxBias(m_constraint)); + } + + float Constraint2D::GetMaxForce() const + { + return float(cpConstraintGetMaxForce(m_constraint)); + } + + PhysWorld2D& Constraint2D::GetWorld() + { + return *static_cast(cpSpaceGetUserData(cpConstraintGetSpace(m_constraint))); + } + + const PhysWorld2D& Constraint2D::GetWorld() const + { + return *static_cast(cpSpaceGetUserData(cpConstraintGetSpace(m_constraint))); + } + + bool Constraint2D::IsBodyCollisionEnabled() const + { + return cpConstraintGetCollideBodies(m_constraint) == cpTrue; + } + + void Constraint2D::SetErrorBias(float bias) + { + cpConstraintSetErrorBias(m_constraint, bias); + } + + void Constraint2D::SetMaxBias(float bias) + { + cpConstraintSetMaxBias(m_constraint, bias); + } + + void Constraint2D::SetMaxForce(float force) + { + cpConstraintSetMaxForce(m_constraint, force); + } + + Constraint2D& Constraint2D::operator=(Constraint2D && rhs) + { + m_constraint = std::move(rhs.m_constraint); + cpConstraintSetUserData(m_constraint, this); + + return *this; + } + + + DampedSpring2D::DampedSpring2D(PhysWorld2D& world, RigidBody2D& first, const Vector2f& firstAnchor, RigidBody2D& second, const Vector2f& secondAnchor, float restLength, float stiffness, float damping) : + Constraint2D(world, cpDampedSpringNew(first.GetHandle(), second.GetHandle(), cpv(firstAnchor.x, firstAnchor.y), cpv(secondAnchor.x, secondAnchor.y), restLength, stiffness, damping)) + { + } + + float DampedSpring2D::GetDamping() const + { + return float(cpDampedSpringGetDamping(m_constraint)); + } + + Vector2f DampedSpring2D::GetFirstAnchor() const + { + cpVect anchor = cpDampedSpringGetAnchorA(m_constraint); + return Vector2f(static_cast(anchor.x), static_cast(anchor.y)); + } + + float DampedSpring2D::GetRestLength() const + { + return float(cpDampedSpringGetRestLength(m_constraint)); + } + + Vector2f DampedSpring2D::GetSecondAnchor() const + { + cpVect anchor = cpDampedSpringGetAnchorB(m_constraint); + return Vector2f(static_cast(anchor.x), static_cast(anchor.y)); + } + + float DampedSpring2D::GetStiffness() const + { + return float(cpDampedSpringGetStiffness(m_constraint)); + } + + void DampedSpring2D::SetDamping(float newDamping) + { + cpDampedSpringSetDamping(m_constraint, newDamping); + } + + void DampedSpring2D::SetFirstAnchor(const Vector2f& firstAnchor) + { + cpDampedSpringSetAnchorA(m_constraint, cpv(firstAnchor.x, firstAnchor.y)); + } + + void DampedSpring2D::SetRestLength(float newLength) + { + cpDampedSpringSetRestLength(m_constraint, newLength); + } + + void DampedSpring2D::SetSecondAnchor(const Vector2f& firstAnchor) + { + cpDampedSpringSetAnchorB(m_constraint, cpv(firstAnchor.x, firstAnchor.y)); + } + + void DampedSpring2D::SetStiffness(float newStiffness) + { + cpDampedSpringSetStiffness(m_constraint, newStiffness); + } + + + DampedRotarySpring2D::DampedRotarySpring2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float restAngle, float stiffness, float damping) : + Constraint2D(world, cpDampedRotarySpringNew(first.GetHandle(), second.GetHandle(), restAngle, stiffness, damping)) + { + } + + float DampedRotarySpring2D::GetDamping() const + { + return float(cpDampedRotarySpringGetDamping(m_constraint)); + } + + float DampedRotarySpring2D::GetRestAngle() const + { + return float(cpDampedRotarySpringGetRestAngle(m_constraint)); + } + + float DampedRotarySpring2D::GetStiffness() const + { + return float(cpDampedRotarySpringGetStiffness(m_constraint)); + } + + void DampedRotarySpring2D::SetDamping(float newDamping) + { + cpDampedSpringSetDamping(m_constraint, newDamping); + } + + void DampedRotarySpring2D::SetRestAngle(float newAngle) + { + cpDampedRotarySpringSetRestAngle(m_constraint, newAngle); + } + + void DampedRotarySpring2D::SetStiffness(float newStiffness) + { + cpDampedRotarySpringSetStiffness(m_constraint, newStiffness); + } + + + GearJoint2D::GearJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float phase, float ratio) : + Constraint2D(world, cpGearJointNew(first.GetHandle(), second.GetHandle(), phase, ratio)) + { + } + + float GearJoint2D::GetPhase() const + { + return float(cpGearJointGetPhase(m_constraint)); + } + + float GearJoint2D::GetRatio() const + { + return float(cpGearJointGetRatio(m_constraint)); + } + + void GearJoint2D::SetPhase(float phase) + { + cpGearJointSetPhase(m_constraint, phase); + } + + void GearJoint2D::SetRatio(float ratio) + { + cpGearJointSetRatio(m_constraint, ratio); + } + + + MotorJoint2D::MotorJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float rate) : + Constraint2D(world, cpSimpleMotorNew(first.GetHandle(), second.GetHandle(), rate)) + { + } + + float MotorJoint2D::GetRate() const + { + return float(cpSimpleMotorGetRate(m_constraint)); + } + + void MotorJoint2D::SetRate(float rate) + { + cpSimpleMotorSetRate(m_constraint, rate); + } + + + PinJoint2D::PinJoint2D(PhysWorld2D& world, RigidBody2D& first, const Vector2f& firstAnchor, RigidBody2D& second, const Vector2f& secondAnchor) : + Constraint2D(world, cpPinJointNew(first.GetHandle(), second.GetHandle(), cpv(firstAnchor.x, firstAnchor.y), cpv(secondAnchor.x, secondAnchor.y))) + { + } + + float PinJoint2D::GetDistance() const + { + return float(cpPinJointGetDist(m_constraint)); + } + + Vector2f PinJoint2D::GetFirstAnchor() const + { + cpVect anchor = cpPinJointGetAnchorA(m_constraint); + return Vector2f(static_cast(anchor.x), static_cast(anchor.y)); + } + + Vector2f PinJoint2D::GetSecondAnchor() const + { + cpVect anchor = cpPinJointGetAnchorB(m_constraint); + return Vector2f(static_cast(anchor.x), static_cast(anchor.y)); + } + + void PinJoint2D::SetDistance(float newDistance) + { + cpPinJointSetDist(m_constraint, newDistance); + } + + void PinJoint2D::SetFirstAnchor(const Vector2f& firstAnchor) + { + cpPinJointSetAnchorA(m_constraint, cpv(firstAnchor.x, firstAnchor.y)); + } + + void PinJoint2D::SetSecondAnchor(const Vector2f& firstAnchor) + { + cpPinJointSetAnchorB(m_constraint, cpv(firstAnchor.x, firstAnchor.y)); + } + + + PivotJoint2D::PivotJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, const Vector2f& anchor) : + Constraint2D(world, cpPivotJointNew(first.GetHandle(), second.GetHandle(), cpv(anchor.x, anchor.y))) + { + } + + PivotJoint2D::PivotJoint2D(PhysWorld2D& world, RigidBody2D& first, const Vector2f& firstAnchor, RigidBody2D& second, const Vector2f& secondAnchor) : + Constraint2D(world, cpPivotJointNew2(first.GetHandle(), second.GetHandle(), cpv(firstAnchor.x, firstAnchor.y), cpv(secondAnchor.x, secondAnchor.y))) + { + } + + Vector2f PivotJoint2D::GetFirstAnchor() const + { + cpVect anchor = cpPivotJointGetAnchorA(m_constraint); + return Vector2f(static_cast(anchor.x), static_cast(anchor.y)); + } + + Vector2f PivotJoint2D::GetSecondAnchor() const + { + cpVect anchor = cpPivotJointGetAnchorB(m_constraint); + return Vector2f(static_cast(anchor.x), static_cast(anchor.y)); + } + + void PivotJoint2D::SetFirstAnchor(const Vector2f& firstAnchor) + { + cpPivotJointSetAnchorA(m_constraint, cpv(firstAnchor.x, firstAnchor.y)); + } + + void PivotJoint2D::SetSecondAnchor(const Vector2f& firstAnchor) + { + cpPivotJointSetAnchorB(m_constraint, cpv(firstAnchor.x, firstAnchor.y)); + } + + + RatchetJoint2D::RatchetJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float phase, float ratchet) : + Constraint2D(world, cpRatchetJointNew(first.GetHandle(), second.GetHandle(), phase, ratchet)) + { + } + + float RatchetJoint2D::GetAngle() const + { + return float(cpRatchetJointGetAngle(m_constraint)); + } + + float RatchetJoint2D::GetPhase() const + { + return float(cpRatchetJointGetPhase(m_constraint)); + } + + float RatchetJoint2D::GetRatchet() const + { + return float(cpRatchetJointGetRatchet(m_constraint)); + } + + void RatchetJoint2D::SetAngle(float angle) + { + cpRatchetJointSetAngle(m_constraint, angle); + } + + void RatchetJoint2D::SetPhase(float phase) + { + cpRatchetJointSetPhase(m_constraint, phase); + } + + void RatchetJoint2D::SetRatchet(float ratchet) + { + cpRatchetJointSetRatchet(m_constraint, ratchet); + } + + + RotaryLimitJoint2D::RotaryLimitJoint2D(PhysWorld2D& world, RigidBody2D& first, RigidBody2D& second, float minAngle, float maxAngle) : + Constraint2D(world, cpRotaryLimitJointNew(first.GetHandle(), second.GetHandle(), minAngle, maxAngle)) + { + } + + float RotaryLimitJoint2D::GetMaxAngle() const + { + return float(cpRotaryLimitJointGetMax(m_constraint)); + } + + float RotaryLimitJoint2D::GetMinAngle() const + { + return float(cpRotaryLimitJointGetMax(m_constraint)); + } + + void RotaryLimitJoint2D::SetMaxAngle(float maxAngle) + { + cpRotaryLimitJointSetMax(m_constraint, maxAngle); + } + + void RotaryLimitJoint2D::SetMinAngle(float minAngle) + { + cpRotaryLimitJointSetMin(m_constraint, minAngle); + } + + + SlideJoint2D::SlideJoint2D(PhysWorld2D& world, RigidBody2D& first, const Vector2f& firstAnchor, RigidBody2D& second, const Vector2f& secondAnchor, float min, float max) : + Constraint2D(world, cpSlideJointNew(first.GetHandle(), second.GetHandle(), cpv(firstAnchor.x, firstAnchor.y), cpv(secondAnchor.x, secondAnchor.y), min, max)) + { + } + + Vector2f SlideJoint2D::GetFirstAnchor() const + { + cpVect anchor = cpSlideJointGetAnchorA(m_constraint); + return Vector2f(static_cast(anchor.x), static_cast(anchor.y)); + } + + float SlideJoint2D::GetMaxDistance() const + { + return float(cpSlideJointGetMax(m_constraint)); + } + + float SlideJoint2D::GetMinDistance() const + { + return float(cpSlideJointGetMin(m_constraint)); + } + + Vector2f SlideJoint2D::GetSecondAnchor() const + { + cpVect anchor = cpSlideJointGetAnchorB(m_constraint); + return Vector2f(static_cast(anchor.x), static_cast(anchor.y)); + } + + void SlideJoint2D::SetFirstAnchor(const Vector2f& firstAnchor) + { + cpSlideJointSetAnchorA(m_constraint, cpv(firstAnchor.x, firstAnchor.y)); + } + + void SlideJoint2D::SetMaxDistance(float newMaxDistance) + { + cpSlideJointSetMax(m_constraint, newMaxDistance); + } + + void SlideJoint2D::SetMinDistance(float newMinDistance) + { + cpSlideJointSetMin(m_constraint, newMinDistance); + } + + void SlideJoint2D::SetSecondAnchor(const Vector2f& firstAnchor) + { + cpSlideJointSetAnchorB(m_constraint, cpv(firstAnchor.x, firstAnchor.y)); + } + +} diff --git a/src/Nazara/Physics2D/PhysWorld2D.cpp b/src/Nazara/Physics2D/PhysWorld2D.cpp index 997b53468..c0db3749f 100644 --- a/src/Nazara/Physics2D/PhysWorld2D.cpp +++ b/src/Nazara/Physics2D/PhysWorld2D.cpp @@ -3,11 +3,82 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include namespace Nz { + namespace + { + Color CpDebugColorToColor(cpSpaceDebugColor c) + { + return Color{ static_cast(c.r * 255.f), static_cast(c.g * 255.f), static_cast(c.b * 255.f), static_cast(c.a * 255.f) }; + } + + cpSpaceDebugColor ColorToCpDebugColor(Color c) + { + return cpSpaceDebugColor{ c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f }; + } + + void DrawCircle(cpVect pos, cpFloat angle, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer userdata) + { + auto drawOptions = static_cast(userdata); + if (drawOptions->circleCallback) + drawOptions->circleCallback(Vector2f(float(pos.x), float(pos.y)), float(angle), float(radius), CpDebugColorToColor(outlineColor), CpDebugColorToColor(fillColor), drawOptions->userdata); + } + + void DrawDot(cpFloat size, cpVect pos, cpSpaceDebugColor color, cpDataPointer userdata) + { + auto drawOptions = static_cast(userdata); + if (drawOptions->dotCallback) + drawOptions->dotCallback(Vector2f(float(pos.x), float(pos.y)), float(size), CpDebugColorToColor(color), drawOptions->userdata); + } + + using DebugDrawPolygonCallback = std::function; + + void DrawPolygon(int vertexCount, const cpVect* vertices, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer userdata) + { + auto drawOptions = static_cast(userdata); + if (drawOptions->polygonCallback) + { + //TODO: constexpr if to prevent copy/cast if sizeof(cpVect) == sizeof(Vector2f) + + StackArray nVertices = NazaraStackAllocation(Vector2f, vertexCount); + for (int i = 0; i < vertexCount; ++i) + nVertices[i].Set(float(vertices[i].x), float(vertices[i].y)); + + drawOptions->polygonCallback(nVertices.data(), vertexCount, float(radius), CpDebugColorToColor(outlineColor), CpDebugColorToColor(fillColor), drawOptions->userdata); + } + } + + void DrawSegment(cpVect a, cpVect b, cpSpaceDebugColor color, cpDataPointer userdata) + { + auto drawOptions = static_cast(userdata); + if (drawOptions->segmentCallback) + drawOptions->segmentCallback(Vector2f(float(a.x), float(a.y)), Vector2f(float(b.x), float(b.y)), CpDebugColorToColor(color), drawOptions->userdata); + } + + void DrawThickSegment(cpVect a, cpVect b, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer userdata) + { + auto drawOptions = static_cast(userdata); + if (drawOptions->thickSegmentCallback) + drawOptions->thickSegmentCallback(Vector2f(float(a.x), float(a.y)), Vector2f(float(b.x), float(b.y)), float(radius), CpDebugColorToColor(outlineColor), CpDebugColorToColor(fillColor), drawOptions->userdata); + } + + cpSpaceDebugColor GetColorForShape(cpShape* shape, cpDataPointer userdata) + { + auto drawOptions = static_cast(userdata); + if (drawOptions->colorCallback) + { + RigidBody2D& rigidBody = *static_cast(cpShapeGetUserData(shape)); + return ColorToCpDebugColor(drawOptions->colorCallback(rigidBody, rigidBody.GetShapeIndex(shape), drawOptions->userdata)); + } + else + return cpSpaceDebugColor{255.f, 0.f, 0.f, 255.f}; + } + } + PhysWorld2D::PhysWorld2D() : m_stepSize(0.005f), m_timestepAccumulator(0.f) @@ -21,6 +92,47 @@ namespace Nz cpSpaceFree(m_handle); } + void PhysWorld2D::DebugDraw(const DebugDrawOptions& options, bool drawShapes, bool drawConstraints, bool drawCollisions) + { + auto ColorToCpDebugColor = [](Color c) -> cpSpaceDebugColor + { + return cpSpaceDebugColor{ c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f }; + }; + + cpSpaceDebugDrawOptions drawOptions; + drawOptions.collisionPointColor = ColorToCpDebugColor(options.collisionPointColor); + drawOptions.constraintColor = ColorToCpDebugColor(options.constraintColor); + drawOptions.shapeOutlineColor = ColorToCpDebugColor(options.shapeOutlineColor); + drawOptions.data = const_cast(&options); //< Yeah, I know, shame :bell: but it won't be used for writing anyway + + std::underlying_type_t drawFlags = 0; + if (drawCollisions) + drawFlags |= CP_SPACE_DEBUG_DRAW_COLLISION_POINTS; + + if (drawConstraints) + drawFlags |= CP_SPACE_DEBUG_DRAW_CONSTRAINTS; + + if (drawShapes) + drawFlags |= CP_SPACE_DEBUG_DRAW_SHAPES; + + drawOptions.flags = static_cast(drawFlags); + + // Callback trampoline + drawOptions.colorForShape = GetColorForShape; + drawOptions.drawCircle = DrawCircle; + drawOptions.drawDot = DrawDot; + drawOptions.drawFatSegment = DrawThickSegment; + drawOptions.drawPolygon = DrawPolygon; + drawOptions.drawSegment = DrawSegment; + + cpSpaceDebugDraw(m_handle, &drawOptions); + } + + float PhysWorld2D::GetDamping() const + { + return float(cpSpaceGetDamping(m_handle)); + } + Vector2f PhysWorld2D::GetGravity() const { cpVect gravity = cpSpaceGetGravity(m_handle); @@ -159,6 +271,11 @@ namespace Nz InitCallbacks(cpSpaceAddCollisionHandler(m_handle, collisionIdA, collisionIdB), callbacks); } + void PhysWorld2D::SetDamping(float dampingValue) + { + cpSpaceSetDamping(m_handle, dampingValue); + } + void PhysWorld2D::SetGravity(const Vector2f& gravity) { cpSpaceSetGravity(m_handle, cpv(gravity.x, gravity.y)); diff --git a/src/Nazara/Physics2D/RigidBody2D.cpp b/src/Nazara/Physics2D/RigidBody2D.cpp index 370b01b3b..0931e0a45 100644 --- a/src/Nazara/Physics2D/RigidBody2D.cpp +++ b/src/Nazara/Physics2D/RigidBody2D.cpp @@ -3,8 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include #include #include #include @@ -22,31 +20,34 @@ namespace Nz m_geom(), m_userData(nullptr), m_world(world), + m_isStatic(false), m_gravityFactor(1.f), - m_mass(1.f) + m_mass(mass) { NazaraAssert(m_world, "Invalid world"); - Create(); - + m_handle = Create(mass); SetGeom(geom); - SetMass(mass); } RigidBody2D::RigidBody2D(const RigidBody2D& object) : m_geom(object.m_geom), m_userData(object.m_userData), m_world(object.m_world), + m_isStatic(object.m_isStatic), m_gravityFactor(object.m_gravityFactor), - m_mass(0.f) + m_mass(object.GetMass()) { NazaraAssert(m_world, "Invalid world"); NazaraAssert(m_geom, "Invalid geometry"); - Create(); + m_handle = Create(m_mass, object.GetMomentOfInertia()); + SetGeom(object.GetGeom(), false); - SetGeom(object.GetGeom()); - SetMass(object.GetMass()); + CopyBodyData(object.GetHandle()); + + for (std::size_t i = 0; i < m_shapes.size(); ++i) + m_shapes[i]->bb = cpShapeCacheBB(object.m_shapes[i]); } RigidBody2D::RigidBody2D(RigidBody2D&& object) : @@ -54,9 +55,10 @@ namespace Nz OnRigidBody2DRelease(std::move(object.OnRigidBody2DRelease)), m_shapes(std::move(object.m_shapes)), m_geom(std::move(object.m_geom)), - m_userData(object.m_userData), m_handle(object.m_handle), + m_userData(object.m_userData), m_world(object.m_world), + m_isStatic(object.m_isStatic), m_gravityFactor(object.m_gravityFactor), m_mass(object.m_mass) { @@ -93,7 +95,7 @@ namespace Nz cpBodyApplyForceAtLocalPoint(m_handle, cpv(force.x, force.y), cpv(point.x, point.y)); break; } - } +} void RigidBody2D::AddImpulse(const Vector2f& impulse, CoordSys coordSys) { @@ -116,7 +118,7 @@ namespace Nz void RigidBody2D::AddTorque(float torque) { - cpBodySetTorque(m_handle, cpBodyGetTorque(m_handle) + torque); + cpBodySetTorque(m_handle, cpBodyGetTorque(m_handle) + ToRadians(torque)); } Rectf RigidBody2D::GetAABB() const @@ -134,7 +136,7 @@ namespace Nz float RigidBody2D::GetAngularVelocity() const { - return static_cast(cpBodyGetAngularVelocity(m_handle)); + return FromRadians(static_cast(cpBodyGetAngularVelocity(m_handle))); } const Collider2DRef& RigidBody2D::GetGeom() const @@ -152,6 +154,11 @@ namespace Nz return m_mass; } + float RigidBody2D::GetMomentOfInertia() const + { + return float(cpBodyGetMoment(m_handle)); + } + Vector2f RigidBody2D::GetCenterOfGravity(CoordSys coordSys) const { cpVect cog = cpBodyGetCenterOfGravity(m_handle); @@ -177,7 +184,16 @@ namespace Nz float RigidBody2D::GetRotation() const { - return static_cast(cpBodyGetAngle(m_handle)); + return FromRadians(static_cast(cpBodyGetAngle(m_handle))); + } + + std::size_t RigidBody2D::GetShapeIndex(cpShape* shape) const + { + auto it = std::find(m_shapes.begin(), m_shapes.end(), shape); + if (it == m_shapes.end()) + return InvalidShapeIndex; + + return std::distance(m_shapes.begin(), it); } void* RigidBody2D::GetUserdata() const @@ -196,9 +212,9 @@ namespace Nz return m_world; } - bool RigidBody2D::IsMoveable() const + bool RigidBody2D::IsKinematic() const { - return m_mass > 0.f; + return m_mass <= 0.f; } bool RigidBody2D::IsSleeping() const @@ -206,29 +222,31 @@ namespace Nz return cpBodyIsSleeping(m_handle) != 0; } - void RigidBody2D::SetAngularVelocity(float angularVelocity) + bool RigidBody2D::IsStatic() const { - cpBodySetAngularVelocity(m_handle, angularVelocity); + return m_isStatic; } - void RigidBody2D::SetGeom(Collider2DRef geom) + void RigidBody2D::SetAngularVelocity(float angularVelocity) + { + cpBodySetAngularVelocity(m_handle, ToRadians(angularVelocity)); + } + + void RigidBody2D::SetGeom(Collider2DRef geom, bool recomputeMoment) { // We have no public way of getting rid of an existing geom without removing the whole body // So let's save some attributes of the body, destroy it and rebuild it if (m_geom) { - cpVect pos = cpBodyGetPosition(m_handle); cpFloat mass = cpBodyGetMass(m_handle); cpFloat moment = cpBodyGetMoment(m_handle); - cpFloat rot = cpBodyGetAngle(m_handle); - cpVect vel = cpBodyGetVelocity(m_handle); + cpBody* newHandle = Create(static_cast(mass), static_cast(moment)); + + CopyBodyData(m_handle); Destroy(); - Create(float(mass), float(moment)); - cpBodySetAngle(m_handle, rot); - cpBodySetPosition(m_handle, pos); - cpBodySetVelocity(m_handle, vel); + m_handle = newHandle; } if (geom) @@ -245,33 +263,41 @@ namespace Nz cpSpaceAddShape(space, shape); } - cpBodySetMoment(m_handle, m_geom->ComputeMomentOfInertia(m_mass)); + if (recomputeMoment) + { + if (!IsStatic() && !IsKinematic()) + cpBodySetMoment(m_handle, m_geom->ComputeMomentOfInertia(m_mass)); + } } - void RigidBody2D::SetMass(float mass) + void RigidBody2D::SetMass(float mass, bool recomputeMoment) { if (m_mass > 0.f) { if (mass > 0.f) { - m_world->RegisterPostStep(this, [mass](Nz::RigidBody2D* body) + m_world->RegisterPostStep(this, [mass, recomputeMoment](Nz::RigidBody2D* body) { cpBodySetMass(body->GetHandle(), mass); - cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeMomentOfInertia(mass)); + + if (recomputeMoment) + cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeMomentOfInertia(mass)); }); } else - m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) { cpBodySetType(body->GetHandle(), CP_BODY_TYPE_STATIC); } ); + m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) { cpBodySetType(body->GetHandle(), (body->IsStatic()) ? CP_BODY_TYPE_STATIC : CP_BODY_TYPE_KINEMATIC); } ); } else if (mass > 0.f) { - m_world->RegisterPostStep(this, [mass](Nz::RigidBody2D* body) + m_world->RegisterPostStep(this, [mass, recomputeMoment](Nz::RigidBody2D* body) { - if (cpBodyGetType(body->GetHandle()) == CP_BODY_TYPE_STATIC) + if (cpBodyGetType(body->GetHandle()) != CP_BODY_TYPE_DYNAMIC) { cpBodySetType(body->GetHandle(), CP_BODY_TYPE_DYNAMIC); cpBodySetMass(body->GetHandle(), mass); - cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeMomentOfInertia(mass)); + + if (recomputeMoment) + cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeMomentOfInertia(mass)); } }); } @@ -281,12 +307,12 @@ namespace Nz void RigidBody2D::SetMassCenter(const Vector2f& center) { - if (m_mass > 0.f) - cpBodySetCenterOfGravity(m_handle, cpv(center.x, center.y)); + cpBodySetCenterOfGravity(m_handle, cpv(center.x, center.y)); } void RigidBody2D::SetMomentOfInertia(float moment) { + // Even though Chipmunk allows us to change this anytime, we need to do it in a post-step to prevent other post-steps to override this m_world->RegisterPostStep(this, [moment] (Nz::RigidBody2D* body) { cpBodySetMoment(body->GetHandle(), moment); @@ -296,13 +322,42 @@ namespace Nz void RigidBody2D::SetPosition(const Vector2f& position) { cpBodySetPosition(m_handle, cpv(position.x, position.y)); - if (cpBodyGetType(m_handle) == CP_BODY_TYPE_STATIC) - cpSpaceReindexShapesForBody(m_world->GetHandle(), m_handle); + if (m_isStatic) + { + m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) + { + cpSpaceReindexShapesForBody(body->GetWorld()->GetHandle(), body->GetHandle()); + }); + } } void RigidBody2D::SetRotation(float rotation) { - cpBodySetAngle(m_handle, rotation); + cpBodySetAngle(m_handle, ToRadians(rotation)); + if (m_isStatic) + { + m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) + { + cpSpaceReindexShapesForBody(body->GetWorld()->GetHandle(), body->GetHandle()); + }); + } + } + + void RigidBody2D::SetStatic(bool setStaticBody) + { + m_isStatic = setStaticBody; + m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) + { + if (body->IsStatic()) + { + cpBodySetType(body->GetHandle(), CP_BODY_TYPE_STATIC); + cpSpaceReindexShapesForBody(body->GetWorld()->GetHandle(), body->GetHandle()); + } + else if (cpBodyGetMass(body->GetHandle()) > 0.f) + cpBodySetType(body->GetHandle(), CP_BODY_TYPE_KINEMATIC); + else + cpBodySetType(body->GetHandle(), CP_BODY_TYPE_DYNAMIC); + }); } void RigidBody2D::SetUserdata(void* ud) @@ -329,6 +384,7 @@ namespace Nz OnRigidBody2DRelease = std::move(object.OnRigidBody2DRelease); m_handle = object.m_handle; + m_isStatic = object.m_isStatic; m_geom = std::move(object.m_geom); m_gravityFactor = object.m_gravityFactor; m_mass = object.m_mass; @@ -347,12 +403,28 @@ namespace Nz return *this; } - void RigidBody2D::Create(float mass, float moment) + void RigidBody2D::CopyBodyData(cpBody* body) { - m_handle = cpBodyNew(mass, moment); - cpBodySetUserData(m_handle, this); + cpBodySetAngle(m_handle, cpBodyGetAngle(body)); + cpBodySetAngularVelocity(m_handle, cpBodyGetAngularVelocity(body)); + cpBodySetCenterOfGravity(m_handle, cpBodyGetCenterOfGravity(body)); + cpBodySetForce(m_handle, cpBodyGetForce(body)); + cpBodySetPosition(m_handle, cpBodyGetPosition(body)); + cpBodySetTorque(m_handle, cpBodyGetTorque(body)); + cpBodySetVelocity(m_handle, cpBodyGetVelocity(body)); + } - cpSpaceAddBody(m_world->GetHandle(), m_handle); + cpBody* RigidBody2D::Create(float mass, float moment) + { + cpBody* handle = cpBodyNew(mass, moment); + cpBodySetUserData(handle, this); + + if (mass <= 0.f) + cpBodySetType(handle, CP_BODY_TYPE_KINEMATIC); + + cpSpaceAddBody(m_world->GetHandle(), handle); + + return handle; } void RigidBody2D::Destroy() @@ -369,5 +441,6 @@ namespace Nz cpSpaceRemoveBody(space, m_handle); cpBodyFree(m_handle); } + m_shapes.clear(); } } diff --git a/src/Nazara/Physics3D/Collider3D.cpp b/src/Nazara/Physics3D/Collider3D.cpp index 857ec4ba8..454c18037 100644 --- a/src/Nazara/Physics3D/Collider3D.cpp +++ b/src/Nazara/Physics3D/Collider3D.cpp @@ -3,9 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include -#include #include namespace Nz @@ -50,7 +50,7 @@ namespace Nz { Vector3f min, max; - // Si nous n'avons aucune instance, nous en crons une temporaire + // Si nous n'avons aucune instance, nous en cr�ons une temporaire if (m_handles.empty()) { PhysWorld3D world; @@ -61,7 +61,7 @@ namespace Nz } NewtonDestroyCollision(collision); } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute faon) + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute fa�on) NewtonCollisionCalculateAABB(m_handles.begin()->second, offsetMatrix, min, max); return Boxf(scale * min, scale * max); @@ -72,7 +72,7 @@ namespace Nz float inertiaMatrix[3]; float origin[3]; - // Si nous n'avons aucune instance, nous en crons une temporaire + // Si nous n'avons aucune instance, nous en cr�ons une temporaire if (m_handles.empty()) { PhysWorld3D world; @@ -83,7 +83,7 @@ namespace Nz } NewtonDestroyCollision(collision); } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute faon) + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute fa�on) NewtonConvexCollisionCalculateInertialMatrix(m_handles.begin()->second, inertiaMatrix, origin); if (inertia) @@ -97,7 +97,7 @@ namespace Nz { float volume; - // Si nous n'avons aucune instance, nous en crons une temporaire + // Si nous n'avons aucune instance, nous en cr�ons une temporaire if (m_handles.empty()) { PhysWorld3D world; @@ -108,7 +108,7 @@ namespace Nz } NewtonDestroyCollision(collision); } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute faon) + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute fa�on) volume = NewtonConvexCollisionCalculateVolume(m_handles.begin()->second); return volume; diff --git a/src/Nazara/Physics3D/RigidBody3D.cpp b/src/Nazara/Physics3D/RigidBody3D.cpp index 3d697aa8c..af4b91a32 100644 --- a/src/Nazara/Physics3D/RigidBody3D.cpp +++ b/src/Nazara/Physics3D/RigidBody3D.cpp @@ -3,8 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include #include #include #include diff --git a/src/Nazara/Utility/Cursor.cpp b/src/Nazara/Platform/Cursor.cpp similarity index 86% rename from src/Nazara/Utility/Cursor.cpp rename to src/Nazara/Platform/Cursor.cpp index e8b3e0b21..7d68a460b 100644 --- a/src/Nazara/Utility/Cursor.cpp +++ b/src/Nazara/Platform/Cursor.cpp @@ -1,18 +1,18 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #if defined(NAZARA_PLATFORM_WINDOWS) - #include + #include #elif defined(NAZARA_PLATFORM_X11) - #include + #include #else #error Lack of implementation: Cursor #endif -#include +#include namespace Nz { diff --git a/src/Nazara/Platform/Debug/NewOverload.cpp b/src/Nazara/Platform/Debug/NewOverload.cpp new file mode 100644 index 000000000..c5522beb8 --- /dev/null +++ b/src/Nazara/Platform/Debug/NewOverload.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Platform module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#if NAZARA_PLATFORM_MANAGE_MEMORY + +#include +#include // Needed ? + +void* operator new(std::size_t size) +{ + return Nz::MemoryManager::Allocate(size, false); +} + +void* operator new[](std::size_t size) +{ + return Nz::MemoryManager::Allocate(size, true); +} + +void operator delete(void* pointer) noexcept +{ + Nz::MemoryManager::Free(pointer, false); +} + +void operator delete[](void* pointer) noexcept +{ + Nz::MemoryManager::Free(pointer, true); +} + +#endif // NAZARA_PLATFORM_MANAGE_MEMORY diff --git a/src/Nazara/Utility/Icon.cpp b/src/Nazara/Platform/Icon.cpp similarity index 73% rename from src/Nazara/Utility/Icon.cpp rename to src/Nazara/Platform/Icon.cpp index 843e64456..010e9dfc2 100644 --- a/src/Nazara/Utility/Icon.cpp +++ b/src/Nazara/Platform/Icon.cpp @@ -1,18 +1,18 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #if defined(NAZARA_PLATFORM_WINDOWS) - #include + #include #elif defined(NAZARA_PLATFORM_X11) - #include + #include #else #error Lack of implementation: Icon #endif -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/Keyboard.cpp b/src/Nazara/Platform/Keyboard.cpp similarity index 64% rename from src/Nazara/Utility/Keyboard.cpp rename to src/Nazara/Platform/Keyboard.cpp index 08f4b05a7..be1341eb6 100644 --- a/src/Nazara/Utility/Keyboard.cpp +++ b/src/Nazara/Platform/Keyboard.cpp @@ -1,18 +1,18 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #if defined(NAZARA_PLATFORM_WINDOWS) - #include + #include #elif defined(NAZARA_PLATFORM_X11) - #include + #include #else #error Lack of implementation: Keyboard #endif -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/Mouse.cpp b/src/Nazara/Platform/Mouse.cpp similarity index 82% rename from src/Nazara/Utility/Mouse.cpp rename to src/Nazara/Platform/Mouse.cpp index b25ce2506..6d589697e 100644 --- a/src/Nazara/Utility/Mouse.cpp +++ b/src/Nazara/Platform/Mouse.cpp @@ -1,19 +1,19 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include +#include +#include #if defined(NAZARA_PLATFORM_WINDOWS) - #include + #include #elif defined(NAZARA_PLATFORM_X11) - #include + #include #else #error Lack of implementation: Mouse #endif -#include +#include namespace Nz { diff --git a/src/Nazara/Platform/Platform.cpp b/src/Nazara/Platform/Platform.cpp new file mode 100644 index 000000000..5151ed123 --- /dev/null +++ b/src/Nazara/Platform/Platform.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Platform module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + /*! + * \ingroup system + * \class Nz::Platform + * \brief Platform class that represents the module initializer of Platform + */ + + /*! + * \brief Initializes the Platform module + * \return true if initialization is successful + * + * \remark Produces a NazaraNotice + * \remark Produces a NazaraError if one submodule failed + */ + + bool Platform::Initialize() + { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Already initialized + } + + // Initialize module dependencies + if (!Utility::Initialize()) + { + NazaraError("Failed to initialize utility module"); + return false; + } + + s_moduleReferenceCounter++; + + // Initialisation of the module + CallOnExit onExit(Platform::Uninitialize); + + if (!Window::Initialize()) + { + NazaraError("Failed to initialize window's system"); + return false; + } + + // Must be initialized after Window + if (!Cursor::Initialize()) + { + NazaraError("Failed to initialize cursors"); + return false; + } + + onExit.Reset(); + + NazaraNotice("Initialized: Platform module"); + return true; + } + + /*! + * \brief Checks whether the module is initialized + * \return true if module is initialized + */ + + bool Platform::IsInitialized() + { + return s_moduleReferenceCounter != 0; + } + + /*! + * \brief Uninitializes the Platform module + * + * \remark Produces a NazaraNotice + */ + + void Platform::Uninitialize() + { + if (s_moduleReferenceCounter != 1) + { + // The module is still in use, or can not be uninitialized + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; + + return; + } + + // Free of module + s_moduleReferenceCounter = 0; + + Cursor::Uninitialize(); //< Must be done before Window + Window::Uninitialize(); + + NazaraNotice("Uninitialized: Platform module"); + + // Free of dependances + Utility::Uninitialize(); + } + + unsigned int Platform::s_moduleReferenceCounter = 0; +} diff --git a/src/Nazara/Utility/VideoMode.cpp b/src/Nazara/Platform/VideoMode.cpp similarity index 90% rename from src/Nazara/Utility/VideoMode.cpp rename to src/Nazara/Platform/VideoMode.cpp index 7d1f3beec..5cc78d981 100644 --- a/src/Nazara/Utility/VideoMode.cpp +++ b/src/Nazara/Platform/VideoMode.cpp @@ -1,20 +1,20 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include #if defined(NAZARA_PLATFORM_WINDOWS) - #include + #include #elif defined(NAZARA_PLATFORM_X11) - #include + #include #else #error Lack of implementation: Window #endif -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/VideoModeImpl.hpp b/src/Nazara/Platform/VideoModeImpl.hpp similarity index 86% rename from src/Nazara/Utility/VideoModeImpl.hpp rename to src/Nazara/Platform/VideoModeImpl.hpp index e5c5c0118..b5be4b3b1 100644 --- a/src/Nazara/Utility/VideoModeImpl.hpp +++ b/src/Nazara/Platform/VideoModeImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once diff --git a/src/Nazara/Utility/Win32/CursorImpl.cpp b/src/Nazara/Platform/Win32/CursorImpl.cpp similarity index 94% rename from src/Nazara/Utility/Win32/CursorImpl.cpp rename to src/Nazara/Platform/Win32/CursorImpl.cpp index c2fff0a40..399320c59 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.cpp +++ b/src/Nazara/Platform/Win32/CursorImpl.cpp @@ -1,12 +1,12 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/Win32/CursorImpl.hpp b/src/Nazara/Platform/Win32/CursorImpl.hpp similarity index 88% rename from src/Nazara/Utility/Win32/CursorImpl.hpp rename to src/Nazara/Platform/Win32/CursorImpl.hpp index a8f82377c..ad0324d79 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.hpp +++ b/src/Nazara/Platform/Win32/CursorImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -8,7 +8,7 @@ #define NAZARA_CURSORIMPL_HPP #include -#include +#include #include #include diff --git a/src/Nazara/Utility/Win32/IconImpl.cpp b/src/Nazara/Platform/Win32/IconImpl.cpp similarity index 89% rename from src/Nazara/Utility/Win32/IconImpl.cpp rename to src/Nazara/Platform/Win32/IconImpl.cpp index 19e7fffb0..14a67cfba 100644 --- a/src/Nazara/Utility/Win32/IconImpl.cpp +++ b/src/Nazara/Platform/Win32/IconImpl.cpp @@ -1,11 +1,11 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/Win32/IconImpl.hpp b/src/Nazara/Platform/Win32/IconImpl.hpp similarity index 88% rename from src/Nazara/Utility/Win32/IconImpl.hpp rename to src/Nazara/Platform/Win32/IconImpl.hpp index 7ba9acc7a..48644198c 100644 --- a/src/Nazara/Utility/Win32/IconImpl.hpp +++ b/src/Nazara/Platform/Win32/IconImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once diff --git a/src/Nazara/Utility/Win32/InputImpl.cpp b/src/Nazara/Platform/Win32/InputImpl.cpp similarity index 97% rename from src/Nazara/Utility/Win32/InputImpl.cpp rename to src/Nazara/Platform/Win32/InputImpl.cpp index e250ae8be..f44594fa4 100644 --- a/src/Nazara/Utility/Win32/InputImpl.cpp +++ b/src/Nazara/Platform/Win32/InputImpl.cpp @@ -1,12 +1,12 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include -#include +#include #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/Win32/InputImpl.hpp b/src/Nazara/Platform/Win32/InputImpl.hpp similarity index 83% rename from src/Nazara/Utility/Win32/InputImpl.hpp rename to src/Nazara/Platform/Win32/InputImpl.hpp index e91bfd889..fc5e226a5 100644 --- a/src/Nazara/Utility/Win32/InputImpl.hpp +++ b/src/Nazara/Platform/Win32/InputImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -9,8 +9,8 @@ #include #include -#include -#include +#include +#include namespace Nz { diff --git a/src/Nazara/Utility/Win32/VideoModeImpl.cpp b/src/Nazara/Platform/Win32/VideoModeImpl.cpp similarity index 83% rename from src/Nazara/Utility/Win32/VideoModeImpl.cpp rename to src/Nazara/Platform/Win32/VideoModeImpl.cpp index 95a964790..6102a568e 100644 --- a/src/Nazara/Utility/Win32/VideoModeImpl.cpp +++ b/src/Nazara/Platform/Win32/VideoModeImpl.cpp @@ -1,12 +1,12 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include +#include +#include #include #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/Win32/VideoModeImpl.hpp b/src/Nazara/Platform/Win32/VideoModeImpl.hpp similarity index 79% rename from src/Nazara/Utility/Win32/VideoModeImpl.hpp rename to src/Nazara/Platform/Win32/VideoModeImpl.hpp index 460cec364..39579b9a2 100644 --- a/src/Nazara/Utility/Win32/VideoModeImpl.hpp +++ b/src/Nazara/Platform/Win32/VideoModeImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -7,7 +7,7 @@ #ifndef NAZARA_VIDEOMODEIMPL_HPP #define NAZARA_VIDEOMODEIMPL_HPP -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Platform/Win32/WindowImpl.cpp similarity index 98% rename from src/Nazara/Utility/Win32/WindowImpl.cpp rename to src/Nazara/Platform/Win32/WindowImpl.cpp index c9e94876e..0eb2c670d 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Platform/Win32/WindowImpl.cpp @@ -1,24 +1,24 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp // Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation -#include +#include #include #include #include #include -#include -#include +#include +#include +#include +#include +#include #include -#include -#include -#include #include #include #include -#include +#include #ifdef _WIN64 #define GCL_HCURSOR GCLP_HCURSOR @@ -218,11 +218,6 @@ namespace Nz return m_handle; } - unsigned int WindowImpl::GetHeight() const - { - return m_size.y; - } - Vector2i WindowImpl::GetPosition() const { return m_position; @@ -252,11 +247,6 @@ namespace Nz return String::Unicode(wTitle.get()); } - unsigned int WindowImpl::GetWidth() const - { - return m_size.x; - } - bool WindowImpl::HasFocus() const { return GetForegroundWindow() == m_handle; @@ -369,7 +359,7 @@ namespace Nz void WindowImpl::SetPosition(int x, int y) { - SetWindowPos(m_handle, nullptr, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + SetWindowPos(m_handle, nullptr, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_ASYNCWINDOWPOS); } void WindowImpl::SetSize(unsigned int width, unsigned int height) @@ -378,15 +368,15 @@ namespace Nz RECT rect = {0, 0, static_cast(width), static_cast(height)}; AdjustWindowRect(&rect, static_cast(GetWindowLongPtr(m_handle, GWL_STYLE)), false); - SetWindowPos(m_handle, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER); + SetWindowPos(m_handle, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_ASYNCWINDOWPOS); } void WindowImpl::SetStayOnTop(bool stayOnTop) { if (stayOnTop) - SetWindowPos(m_handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + SetWindowPos(m_handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS); else - SetWindowPos(m_handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + SetWindowPos(m_handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_ASYNCWINDOWPOS); } void WindowImpl::SetTitle(const String& title) @@ -907,7 +897,7 @@ namespace Nz } } - #if NAZARA_UTILITY_WINDOWS_DISABLE_MENU_KEYS + #if NAZARA_PLATFORM_WINDOWS_DISABLE_MENU_KEYS // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx if (message == WM_SYSCOMMAND && wParam == SC_KEYMENU) return true; diff --git a/src/Nazara/Utility/Win32/WindowImpl.hpp b/src/Nazara/Platform/Win32/WindowImpl.hpp similarity index 90% rename from src/Nazara/Utility/Win32/WindowImpl.hpp rename to src/Nazara/Platform/Win32/WindowImpl.hpp index 83056f825..6e10a5283 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.hpp +++ b/src/Nazara/Platform/Win32/WindowImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp // Interface inspirée de la SFML par Laurent Gomila @@ -14,11 +14,11 @@ #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include namespace Nz @@ -46,12 +46,10 @@ namespace Nz void EnableSmoothScrolling(bool enable); WindowHandle GetHandle() const; - unsigned int GetHeight() const; Vector2i GetPosition() const; Vector2ui GetSize() const; WindowStyleFlags GetStyle() const; String GetTitle() const; - unsigned int GetWidth() const; bool HasFocus() const; diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Platform/Window.cpp similarity index 85% rename from src/Nazara/Utility/Window.cpp rename to src/Nazara/Platform/Window.cpp index 3130c6641..69758cdb0 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Platform/Window.cpp @@ -1,26 +1,23 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include -#include #include -#include -#include -#include -#include +#include +#include #if defined(NAZARA_PLATFORM_WINDOWS) - #include + #include #elif defined(NAZARA_PLATFORM_X11) - #include + #include #else #error Lack of implementation: Window #endif -#include +#include namespace Nz { @@ -50,7 +47,7 @@ namespace Nz bool Window::Create(VideoMode mode, const String& title, WindowStyleFlags style) { - // Si la fenêtre est déjà ouverte, nous conservons sa position + // If the window is already open, we keep its position bool opened = IsOpen(); Vector2i position; if (opened) @@ -58,7 +55,7 @@ namespace Nz Destroy(); - // Inspiré du code de la SFML par Laurent Gomila + // Inspired by the code of the SFML by Laurent Gomila (and its team) if (style & WindowStyle_Fullscreen) { if (fullscreenWindow) @@ -101,7 +98,7 @@ namespace Nz return false; } - // Paramètres par défaut + // Default parameters m_impl->EnableKeyRepeat(true); m_impl->EnableSmoothScrolling(false); m_impl->SetMaximumSize(-1, -1); @@ -169,7 +166,7 @@ namespace Nz void Window::EnableKeyRepeat(bool enable) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -182,7 +179,7 @@ namespace Nz void Window::EnableSmoothScrolling(bool enable) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -195,7 +192,7 @@ namespace Nz WindowHandle Window::GetHandle() const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -206,22 +203,9 @@ namespace Nz return m_impl->GetHandle(); } - unsigned int Window::GetHeight() const - { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return 0; - } - #endif - - return m_impl->GetHeight(); - } - Vector2i Window::GetPosition() const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -234,7 +218,7 @@ namespace Nz Vector2ui Window::GetSize() const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -247,7 +231,7 @@ namespace Nz WindowStyleFlags Window::GetStyle() const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -260,7 +244,7 @@ namespace Nz String Window::GetTitle() const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -271,22 +255,9 @@ namespace Nz return m_impl->GetTitle(); } - unsigned int Window::GetWidth() const - { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return 0; - } - #endif - - return m_impl->GetWidth(); - } - bool Window::HasFocus() const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -299,7 +270,7 @@ namespace Nz bool Window::IsMinimized() const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -312,7 +283,7 @@ namespace Nz bool Window::IsVisible() const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -325,7 +296,7 @@ namespace Nz bool Window::PollEvent(WindowEvent* event) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -378,7 +349,7 @@ namespace Nz void Window::SetEventListener(bool listener) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -397,7 +368,7 @@ namespace Nz void Window::SetFocus() { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -419,7 +390,7 @@ namespace Nz void Window::SetMaximumSize(const Vector2i& maxSize) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -432,7 +403,7 @@ namespace Nz void Window::SetMaximumSize(int width, int height) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -445,7 +416,7 @@ namespace Nz void Window::SetMinimumSize(const Vector2i& minSize) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -458,7 +429,7 @@ namespace Nz void Window::SetMinimumSize(int width, int height) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -471,7 +442,7 @@ namespace Nz void Window::SetPosition(const Vector2i& position) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -484,7 +455,7 @@ namespace Nz void Window::SetPosition(int x, int y) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -497,7 +468,7 @@ namespace Nz void Window::SetSize(const Vector2i& size) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -510,7 +481,7 @@ namespace Nz void Window::SetSize(unsigned int width, unsigned int height) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -523,7 +494,7 @@ namespace Nz void Window::SetStayOnTop(bool stayOnTop) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -536,7 +507,7 @@ namespace Nz void Window::SetTitle(const String& title) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -549,7 +520,7 @@ namespace Nz void Window::SetVisible(bool visible) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -562,7 +533,7 @@ namespace Nz bool Window::WaitEvent(WindowEvent* event) { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); @@ -626,7 +597,7 @@ namespace Nz void Window::IgnoreNextMouseEvent(int mouseX, int mouseY) const { - #if NAZARA_UTILITY_SAFE + #if NAZARA_PLATFORM_SAFE if (!m_impl) { NazaraError("Window not created"); diff --git a/src/Nazara/Utility/X11/CursorImpl.cpp b/src/Nazara/Platform/X11/CursorImpl.cpp similarity index 96% rename from src/Nazara/Utility/X11/CursorImpl.cpp rename to src/Nazara/Platform/X11/CursorImpl.cpp index aa59290b3..cee8cea88 100644 --- a/src/Nazara/Utility/X11/CursorImpl.cpp +++ b/src/Nazara/Platform/X11/CursorImpl.cpp @@ -1,13 +1,13 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include #include -#include -#include +#include +#include #include // Some older versions of xcb/util-renderutil (notably the one available on Travis CI) use `template` as an argument name @@ -20,7 +20,7 @@ extern "C" } #undef template -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/CursorImpl.hpp b/src/Nazara/Platform/X11/CursorImpl.hpp similarity index 89% rename from src/Nazara/Utility/X11/CursorImpl.hpp rename to src/Nazara/Platform/X11/CursorImpl.hpp index 4041b81ed..85b0bf4ef 100644 --- a/src/Nazara/Utility/X11/CursorImpl.hpp +++ b/src/Nazara/Platform/X11/CursorImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -8,7 +8,7 @@ #define NAZARA_CURSORIMPL_HPP #include -#include +#include #include #include diff --git a/src/Nazara/Utility/X11/Display.cpp b/src/Nazara/Platform/X11/Display.cpp similarity index 97% rename from src/Nazara/Utility/X11/Display.cpp rename to src/Nazara/Platform/X11/Display.cpp index 1232cea64..e24c1ef2f 100644 --- a/src/Nazara/Utility/X11/Display.cpp +++ b/src/Nazara/Platform/X11/Display.cpp @@ -1,14 +1,14 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include -#include #include +#include #include #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/Display.hpp b/src/Nazara/Platform/X11/Display.hpp similarity index 88% rename from src/Nazara/Utility/X11/Display.hpp rename to src/Nazara/Platform/X11/Display.hpp index 88f80f2ee..37ee8877d 100644 --- a/src/Nazara/Utility/X11/Display.hpp +++ b/src/Nazara/Platform/X11/Display.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -8,8 +8,9 @@ #define NAZARA_X11DISPLAY_HPP #include -#include -#include +#include +#include +#include typedef struct _XCBKeySymbols xcb_key_symbols_t; @@ -17,7 +18,7 @@ namespace Nz { class String; - class NAZARA_UTILITY_API X11 + class NAZARA_PLATFORM_API X11 { public: X11() = delete; diff --git a/src/Nazara/Utility/X11/IconImpl.cpp b/src/Nazara/Platform/X11/IconImpl.cpp similarity index 91% rename from src/Nazara/Utility/X11/IconImpl.cpp rename to src/Nazara/Platform/X11/IconImpl.cpp index 030cbdf8b..5eb266122 100644 --- a/src/Nazara/Utility/X11/IconImpl.cpp +++ b/src/Nazara/Platform/X11/IconImpl.cpp @@ -1,14 +1,13 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include #include -#include -#include -#include +#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/IconImpl.hpp b/src/Nazara/Platform/X11/IconImpl.hpp similarity index 82% rename from src/Nazara/Utility/X11/IconImpl.hpp rename to src/Nazara/Platform/X11/IconImpl.hpp index 1e8b301bc..e72faa26a 100644 --- a/src/Nazara/Utility/X11/IconImpl.hpp +++ b/src/Nazara/Platform/X11/IconImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -8,7 +8,7 @@ #define NAZARA_ICONIMPL_HPP #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/InputImpl.cpp b/src/Nazara/Platform/X11/InputImpl.cpp similarity index 97% rename from src/Nazara/Utility/X11/InputImpl.cpp rename to src/Nazara/Platform/X11/InputImpl.cpp index 7083100db..152ba0337 100644 --- a/src/Nazara/Utility/X11/InputImpl.cpp +++ b/src/Nazara/Platform/X11/InputImpl.cpp @@ -1,16 +1,17 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include -#include -#include +#include +#include +#include #include #include #include #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/InputImpl.hpp b/src/Nazara/Platform/X11/InputImpl.hpp similarity index 84% rename from src/Nazara/Utility/X11/InputImpl.hpp rename to src/Nazara/Platform/X11/InputImpl.hpp index 608585b1e..b6c30df0a 100644 --- a/src/Nazara/Utility/X11/InputImpl.hpp +++ b/src/Nazara/Platform/X11/InputImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -10,8 +10,8 @@ #include #include #include -#include -#include +#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/ScopedXCB.cpp b/src/Nazara/Platform/X11/ScopedXCB.cpp similarity index 95% rename from src/Nazara/Utility/X11/ScopedXCB.cpp rename to src/Nazara/Platform/X11/ScopedXCB.cpp index 49bd76b26..9911fa760 100644 --- a/src/Nazara/Utility/X11/ScopedXCB.cpp +++ b/src/Nazara/Platform/X11/ScopedXCB.cpp @@ -1,12 +1,12 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include -#include +#include #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/ScopedXCB.hpp b/src/Nazara/Platform/X11/ScopedXCB.hpp similarity index 93% rename from src/Nazara/Utility/X11/ScopedXCB.hpp rename to src/Nazara/Platform/X11/ScopedXCB.hpp index 452379bc4..3e6131db2 100644 --- a/src/Nazara/Utility/X11/ScopedXCB.hpp +++ b/src/Nazara/Platform/X11/ScopedXCB.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -10,6 +10,7 @@ #include #include #include +#include namespace Nz { @@ -95,6 +96,6 @@ namespace Nz }; } -#include +#include #endif // NAZARA_SCOPEDXCB_HPP diff --git a/src/Nazara/Utility/X11/ScopedXCB.inl b/src/Nazara/Platform/X11/ScopedXCB.inl similarity index 79% rename from src/Nazara/Utility/X11/ScopedXCB.inl rename to src/Nazara/Platform/X11/ScopedXCB.inl index d9881b9af..13c62bd56 100644 --- a/src/Nazara/Utility/X11/ScopedXCB.inl +++ b/src/Nazara/Platform/X11/ScopedXCB.inl @@ -1,9 +1,8 @@ // Copyright (C) 2017 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include +#include namespace Nz { @@ -44,4 +43,4 @@ namespace Nz } } -#include +#include diff --git a/src/Nazara/Utility/X11/VideoModeImpl.cpp b/src/Nazara/Platform/X11/VideoModeImpl.cpp similarity index 94% rename from src/Nazara/Utility/X11/VideoModeImpl.cpp rename to src/Nazara/Platform/X11/VideoModeImpl.cpp index e0b9a5ce7..26a2bc32c 100644 --- a/src/Nazara/Utility/X11/VideoModeImpl.cpp +++ b/src/Nazara/Platform/X11/VideoModeImpl.cpp @@ -1,14 +1,15 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include -#include -#include +#include +#include +#include #include #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/VideoModeImpl.hpp b/src/Nazara/Platform/X11/VideoModeImpl.hpp similarity index 80% rename from src/Nazara/Utility/X11/VideoModeImpl.hpp rename to src/Nazara/Platform/X11/VideoModeImpl.hpp index 2e63e8a09..fd502b828 100644 --- a/src/Nazara/Utility/X11/VideoModeImpl.hpp +++ b/src/Nazara/Platform/X11/VideoModeImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once @@ -8,7 +8,7 @@ #define NAZARA_VIDEOMODEIMPL_HPP #include -#include +#include namespace Nz { diff --git a/src/Nazara/Utility/X11/WindowImpl.cpp b/src/Nazara/Platform/X11/WindowImpl.cpp similarity index 97% rename from src/Nazara/Utility/X11/WindowImpl.cpp rename to src/Nazara/Platform/X11/WindowImpl.cpp index 884244287..4a5f8208e 100644 --- a/src/Nazara/Utility/X11/WindowImpl.cpp +++ b/src/Nazara/Platform/X11/WindowImpl.cpp @@ -1,26 +1,25 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp // Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include #include -#include #include -#include +#include /* Things to do left: @@ -1035,7 +1034,16 @@ namespace Nz case XCB_FOCUS_IN: { const uint32_t value_list[] = { eventMask }; - xcb_change_window_attributes(connection, m_window, XCB_CW_EVENT_MASK, value_list); + if (!X11::CheckCookie( + connection, + xcb_change_window_attributes( + connection, + m_window, + XCB_CW_EVENT_MASK, + value_list + )) + ) + NazaraError("Failed to change event mask"); WindowEvent event; event.type = Nz::WindowEventType_GainedFocus; @@ -1052,8 +1060,17 @@ namespace Nz m_parent->PushEvent(event); const uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE }; - xcb_change_window_attributes(connection, m_window, XCB_CW_EVENT_MASK, values); - + if (!X11::CheckCookie( + connection, + xcb_change_window_attributes( + connection, + m_window, + XCB_CW_EVENT_MASK, + values + )) + ) + NazaraError("Failed to change event mask"); + break; } @@ -1245,6 +1262,7 @@ namespace Nz { xcb_motion_notify_event_t* motionNotifyEvent = (xcb_motion_notify_event_t*)windowEvent; + // We use the sequence to determine whether the motion is linked to a Mouse::SetPosition if (m_mousePos.x == motionNotifyEvent->event_x && m_mousePos.y == motionNotifyEvent->event_y) break; @@ -1254,11 +1272,12 @@ namespace Nz event.mouseMove.deltaY = motionNotifyEvent->event_y - m_mousePos.y; event.mouseMove.x = motionNotifyEvent->event_x; event.mouseMove.y = motionNotifyEvent->event_y; - m_parent->PushEvent(event); m_mousePos.x = motionNotifyEvent->event_x; m_mousePos.y = motionNotifyEvent->event_y; + m_parent->PushEvent(event); + break; } diff --git a/src/Nazara/Utility/X11/WindowImpl.hpp b/src/Nazara/Platform/X11/WindowImpl.hpp similarity index 94% rename from src/Nazara/Utility/X11/WindowImpl.hpp rename to src/Nazara/Platform/X11/WindowImpl.hpp index d82ff06cc..0bd286944 100644 --- a/src/Nazara/Utility/X11/WindowImpl.hpp +++ b/src/Nazara/Platform/X11/WindowImpl.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" +// This file is part of the "Nazara Engine - Platform module" // For conditions of distribution and use, see copyright notice in Config.hpp // Interface inspirée de la SFML par Laurent Gomila @@ -12,9 +12,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/src/Nazara/Renderer/GlslWriter.cpp b/src/Nazara/Renderer/GlslWriter.cpp new file mode 100644 index 000000000..074082165 --- /dev/null +++ b/src/Nazara/Renderer/GlslWriter.cpp @@ -0,0 +1,451 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + GlslWriter::GlslWriter() : + m_currentFunction(nullptr), + m_currentState(nullptr), + m_glslVersion(110) + { + } + + String GlslWriter::Generate(const ShaderAst::StatementPtr& node) + { + State state; + m_currentState = &state; + CallOnExit onExit([this]() + { + m_currentState = nullptr; + }); + + // Register global variables (uniforms, varying, ..) + node->Register(*this); + + // Header + Append("#version "); + AppendLine(String::Number(m_glslVersion)); + AppendLine(); + + // Global variables (uniforms, input and outputs) + DeclareVariables(state.uniforms, "uniform", "Uniforms"); + DeclareVariables(state.inputs, "in", "Inputs"); + DeclareVariables(state.outputs, "out", "Outputs"); + + Function entryPoint; + entryPoint.name = "main"; //< GLSL has only one entry point name possible + entryPoint.node = node; + entryPoint.retType = ShaderAst::ExpressionType::Void; + + AppendFunction(entryPoint); + + return state.stream; + } + + void GlslWriter::RegisterFunction(const String& name, ShaderAst::StatementPtr statement, std::initializer_list parameters, ShaderAst::ExpressionType retType) + { + Function func; + func.retType = retType; + func.name = name; + func.node = std::move(statement); + func.parameters.assign(parameters); + + m_functions[name] = std::move(func); + } + + void GlslWriter::RegisterVariable(ShaderAst::VariableType kind, const String& name, ShaderAst::ExpressionType type) + { + NazaraAssert(m_currentState, "This function should only be called while processing an AST"); + NazaraAssert(kind != ShaderAst::VariableType::Builtin, "Builtin variables should not be registered"); + + switch (kind) + { + case ShaderAst::VariableType::Builtin: //< Only there to make compiler happy + break; + + case ShaderAst::VariableType::Input: + m_currentState->inputs.insert(std::make_pair(type, name)); + break; + + case ShaderAst::VariableType::Output: + m_currentState->outputs.insert(std::make_pair(type, name)); + break; + + case ShaderAst::VariableType::Parameter: + { + if (m_currentFunction) + { + bool found = false; + for (const auto& varPtr : m_currentFunction->parameters) + { + if (varPtr->name == name) + { + found = true; + if (varPtr->type != type) + { + //TODO: AstParseError + throw std::runtime_error("Function uses parameter \"" + name + "\" with a different type than specified in the function arguments"); + } + + break; + } + } + + if (!found) + //TODO: AstParseError + throw std::runtime_error("Function has no parameter \"" + name + "\""); + } + + break; + } + + case ShaderAst::VariableType::Uniform: + m_currentState->uniforms.insert(std::make_pair(type, name)); + break; + + case ShaderAst::VariableType::Variable: + { + if (m_currentFunction) + m_currentFunction->variables.insert(std::make_pair(type, name)); + + break; + } + } + } + + void GlslWriter::SetGlslVersion(unsigned int version) + { + m_glslVersion = version; + } + + void GlslWriter::Write(const ShaderAst::NodePtr& node) + { + node->Visit(*this); + } + + void GlslWriter::Write(const ShaderAst::AssignOp& node) + { + Write(node.variable); + + switch (node.op) + { + case ShaderAst::AssignType::Simple: + Append(" = "); + break; + } + + Write(node.right); + } + + void GlslWriter::Write(const ShaderAst::Branch& node) + { + bool first = true; + for (const auto& statement : node.condStatements) + { + if (!first) + Append("else "); + + Append("if ("); + Write(statement.condition); + AppendLine(")"); + + EnterScope(); + Write(statement.statement); + LeaveScope(); + + first = false; + } + + if (node.elseStatement) + { + AppendLine("else"); + + EnterScope(); + Write(node.elseStatement); + LeaveScope(); + } + } + + void GlslWriter::Write(const ShaderAst::BinaryOp& node) + { + Write(node.left); + + switch (node.op) + { + case ShaderAst::BinaryType::Add: + Append(" + "); + break; + case ShaderAst::BinaryType::Substract: + Append(" - "); + break; + case ShaderAst::BinaryType::Multiply: + Append(" * "); + break; + case ShaderAst::BinaryType::Divide: + Append(" / "); + break; + case ShaderAst::BinaryType::Equality: + Append(" == "); + break; + } + + Write(node.right); + } + + void GlslWriter::Write(const ShaderAst::BuiltinVariable& node) + { + Append(node.var); + } + + void GlslWriter::Write(const ShaderAst::Cast& node) + { + Append(node.exprType); + Append("("); + + unsigned int i = 0; + unsigned int requiredComponents = ShaderAst::Node::GetComponentCount(node.exprType); + while (requiredComponents > 0) + { + if (i != 0) + m_currentState->stream << ", "; + + const auto& exprPtr = node.expressions[i++]; + NazaraAssert(exprPtr, "Invalid expression"); + + Write(exprPtr); + requiredComponents -= ShaderAst::Node::GetComponentCount(exprPtr->GetExpressionType()); + } + + Append(")"); + } + + void GlslWriter::Write(const ShaderAst::Constant& node) + { + switch (node.exprType) + { + case ShaderAst::ExpressionType::Boolean: + Append((node.values.bool1) ? "true" : "false"); + break; + + case ShaderAst::ExpressionType::Float1: + Append(String::Format("%F", node.values.vec1)); + break; + + case ShaderAst::ExpressionType::Float2: + Append(String::Format("vec2(%F, %F)", node.values.vec2.x, node.values.vec2.y)); + break; + + case ShaderAst::ExpressionType::Float3: + Append(String::Format("vec3(%F, %F, %F)", node.values.vec3.x, node.values.vec3.y, node.values.vec3.z)); + break; + + case ShaderAst::ExpressionType::Float4: + Append(String::Format("vec4(%F, %F, %F, %F)", node.values.vec4.x, node.values.vec4.y, node.values.vec4.z, node.values.vec4.w)); + break; + + default: + throw std::runtime_error("Unhandled expression type"); + } + } + + void GlslWriter::Write(const ShaderAst::ExpressionStatement& node) + { + Write(node.expression); + Append(";"); + } + + void GlslWriter::Write(const ShaderAst::NamedVariable& node) + { + Append(node.name); + } + + void GlslWriter::Write(const ShaderAst::StatementBlock& node) + { + bool first = true; + for (const ShaderAst::StatementPtr& statement : node.statements) + { + if (!first) + AppendLine(); + + Write(statement); + + first = false; + } + } + + void GlslWriter::Write(const ShaderAst::SwizzleOp& node) + { + Write(node.expression); + Append("."); + + for (std::size_t i = 0; i < node.componentCount; ++i) + { + switch (node.components[i]) + { + case ShaderAst::SwizzleComponent::First: + Append("x"); + break; + + case ShaderAst::SwizzleComponent::Second: + Append("y"); + break; + + case ShaderAst::SwizzleComponent::Third: + Append("z"); + break; + + case ShaderAst::SwizzleComponent::Fourth: + Append("w"); + break; + } + } + } + + void GlslWriter::Append(ShaderAst::BuiltinEntry builtin) + { + switch (builtin) + { + case ShaderAst::BuiltinEntry::VertexPosition: + Append("gl_Position"); + break; + } + } + + void GlslWriter::Append(ShaderAst::ExpressionType type) + { + switch (type) + { + case ShaderAst::ExpressionType::Boolean: + Append("bool"); + break; + case ShaderAst::ExpressionType::Float1: + Append("float"); + break; + case ShaderAst::ExpressionType::Float2: + Append("vec2"); + break; + case ShaderAst::ExpressionType::Float3: + Append("vec3"); + break; + case ShaderAst::ExpressionType::Float4: + Append("vec4"); + break; + case ShaderAst::ExpressionType::Mat4x4: + Append("mat4"); + break; + case ShaderAst::ExpressionType::Void: + Append("void"); + break; + } + } + + void GlslWriter::Append(const String& txt) + { + NazaraAssert(m_currentState, "This function should only be called while processing an AST"); + + m_currentState->stream << txt; + } + + void GlslWriter::AppendCommentSection(const String& section) + { + NazaraAssert(m_currentState, "This function should only be called while processing an AST"); + + String stars((section.GetSize() < 33) ? (36 - section.GetSize()) / 2 : 3, '*'); + m_currentState->stream << "/*" << stars << ' ' << section << ' ' << stars << "*/"; + AppendLine(); + } + + void GlslWriter::AppendFunction(Function& func) + { + NazaraAssert(!m_currentFunction, "A function is already being processed"); + NazaraAssert(m_currentState, "This function should only be called while processing an AST"); + + m_currentFunction = &func; + CallOnExit onExit([this] () + { + m_currentFunction = nullptr; + }); + + func.node->Register(*this); + + Append(func.retType); + + m_currentState->stream << ' '; + Append(func.name); + + m_currentState->stream << '('; + for (std::size_t i = 0; i < func.parameters.size(); ++i) + { + if (i != 0) + m_currentState->stream << ", "; + + Append(func.parameters[i]->type); + m_currentState->stream << ' '; + Append(func.parameters[i]->name); + } + m_currentState->stream << ")\n"; + + EnterScope(); + { + DeclareVariables(func.variables); + + Write(func.node); + } + LeaveScope(); + } + + void GlslWriter::AppendLine(const String& txt) + { + NazaraAssert(m_currentState, "This function should only be called while processing an AST"); + + m_currentState->stream << txt << '\n' << String(m_currentState->indentLevel, '\t'); + } + + void GlslWriter::DeclareVariables(const VariableContainer& variables, const String& keyword, const String& section) + { + if (!variables.empty()) + { + if (!section.IsEmpty()) + AppendCommentSection(section); + + for (const auto& pair : variables) + { + if (!keyword.IsEmpty()) + { + Append(keyword); + Append(" "); + } + + Append(pair.first); + Append(" "); + Append(pair.second); + AppendLine(";"); + } + + AppendLine(); + } + } + + void GlslWriter::EnterScope() + { + NazaraAssert(m_currentState, "This function should only be called while processing an AST"); + + m_currentState->indentLevel++; + AppendLine("{"); + } + + void GlslWriter::LeaveScope() + { + NazaraAssert(m_currentState, "This function should only be called while processing an AST"); + + m_currentState->indentLevel--; + AppendLine(); + AppendLine("}"); + } + +} diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 843e7ae94..6b4ca5400 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -37,7 +37,7 @@ namespace Nz } auto impl = Renderer::GetRendererImpl()->CreateRenderWindowImpl(); - if (!impl->Create(surface.get(), Vector2ui(GetWidth(), GetHeight()), m_parameters)) + if (!impl->Create(surface.get(), GetSize(), m_parameters)) { NazaraError("Failed to create render window implementation: " + Error::GetLastError()); return false; diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 424cf0daa..ab9b07f13 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,12 @@ namespace Nz return false; } + if (!Platform::Initialize()) + { + NazaraError("Failed to initialize Platform module"); + return false; + } + s_moduleReferenceCounter++; CallOnExit onExit(Renderer::Uninitialize); @@ -124,6 +131,7 @@ namespace Nz NazaraNotice("Uninitialized: Renderer module"); // Free module dependencies + Platform::Uninitialize(); Utility::Uninitialize(); } diff --git a/src/Nazara/Renderer/ShaderAst.cpp b/src/Nazara/Renderer/ShaderAst.cpp new file mode 100644 index 000000000..ef6860d68 --- /dev/null +++ b/src/Nazara/Renderer/ShaderAst.cpp @@ -0,0 +1,196 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz { namespace ShaderAst +{ + void ExpressionStatement::Register(ShaderWriter& visitor) + { + expression->Register(visitor); + } + + void ExpressionStatement::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + + void ConditionalStatement::Register(ShaderWriter& visitor) + { + if (visitor.IsConditionEnabled(conditionName)) + statement->Register(visitor); + } + + void ConditionalStatement::Visit(ShaderWriter& visitor) + { + if (visitor.IsConditionEnabled(conditionName)) + statement->Visit(visitor); + } + + + void StatementBlock::Register(ShaderWriter& visitor) + { + for (auto& statementPtr : statements) + statementPtr->Register(visitor); + } + + void StatementBlock::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + + ExpressionType Variable::GetExpressionType() const + { + return type; + } + + void NamedVariable::Register(ShaderWriter& visitor) + { + visitor.RegisterVariable(kind, name, type); + } + + void NamedVariable::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + + void BuiltinVariable::Register(ShaderWriter& visitor) + { + } + + void BuiltinVariable::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + + ExpressionType AssignOp::GetExpressionType() const + { + return variable->GetExpressionType(); + } + + void AssignOp::Register(ShaderWriter& visitor) + { + variable->Register(visitor); + right->Register(visitor); + } + + void AssignOp::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + + ExpressionType BinaryOp::GetExpressionType() const + { + ShaderAst::ExpressionType exprType = ShaderAst::ExpressionType::Void; + + switch (op) + { + case ShaderAst::BinaryType::Add: + case ShaderAst::BinaryType::Divide: + case ShaderAst::BinaryType::Multiply: + case ShaderAst::BinaryType::Substract: + exprType = left->GetExpressionType(); + break; + + case ShaderAst::BinaryType::Equality: + exprType = ExpressionType::Boolean; + } + + NazaraAssert(exprType != ShaderAst::ExpressionType::Void, "Unhandled builtin"); + + return exprType; + } + + void BinaryOp::Register(ShaderWriter& visitor) + { + left->Register(visitor); + right->Register(visitor); + } + + void BinaryOp::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + + void Branch::Register(ShaderWriter& visitor) + { + for (ConditionalStatement& statement : condStatements) + { + statement.condition->Register(visitor); + statement.statement->Register(visitor); + } + + if (elseStatement) + elseStatement->Register(visitor); + } + + void Branch::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + + ExpressionType Constant::GetExpressionType() const + { + return exprType; + } + + void Constant::Register(ShaderWriter&) + { + } + + void Constant::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + ExpressionType Cast::GetExpressionType() const + { + return exprType; + } + + void Cast::Register(ShaderWriter& visitor) + { + auto it = expressions.begin(); + (*it)->Register(visitor); + + for (; it != expressions.end(); ++it) + { + if (!*it) + break; + + (*it)->Register(visitor); + } + } + + void Cast::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } + + + ExpressionType ShaderAst::SwizzleOp::GetExpressionType() const + { + return GetComponentType(expression->GetExpressionType()); + } + + void SwizzleOp::Register(ShaderWriter& visitor) + { + expression->Register(visitor); + } + + void SwizzleOp::Visit(ShaderWriter& visitor) + { + visitor.Write(*this); + } +} +} diff --git a/src/Nazara/Renderer/ShaderWriter.cpp b/src/Nazara/Renderer/ShaderWriter.cpp new file mode 100644 index 000000000..c862572ab --- /dev/null +++ b/src/Nazara/Renderer/ShaderWriter.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + ShaderWriter::~ShaderWriter() = default; + + void ShaderWriter::EnableCondition(const String& name, bool cond) + { + if (cond) + m_conditions.insert(name); + else + m_conditions.erase(name); + } + + bool ShaderWriter::IsConditionEnabled(const String & name) const + { + return m_conditions.count(name) != 0; + } +} diff --git a/src/Nazara/Utility/AlgorithmUtility.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp index d37d02f96..22bf4bb43 100644 --- a/src/Nazara/Utility/AlgorithmUtility.cpp +++ b/src/Nazara/Utility/AlgorithmUtility.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -26,11 +26,13 @@ */ #include -#include #include +#include #include #include #include +#include +#include namespace Nz { @@ -1162,6 +1164,6 @@ namespace Nz if (vertexPointers.tangentPtr) *vertexPointers.tangentPtr++ = matrix.Transform(*vertexPointers.tangentPtr, 0.f) / scale; - } + } } } diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index eb53424fe..f851a430b 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -88,8 +90,8 @@ namespace Nz { Joint* joint = targetSkeleton->GetJoint(i); - SequenceJoint& sequenceJointA = m_impl->sequenceJoints[frameA*m_impl->jointCount + i]; - SequenceJoint& sequenceJointB = m_impl->sequenceJoints[frameB*m_impl->jointCount + i]; + const SequenceJoint& sequenceJointA = m_impl->sequenceJoints[frameA*m_impl->jointCount + i]; + const SequenceJoint& sequenceJointB = m_impl->sequenceJoints[frameB*m_impl->jointCount + i]; joint->SetPosition(Vector3f::Lerp(sequenceJointA.position, sequenceJointB.position, interpolation)); joint->SetRotation(Quaternionf::Slerp(sequenceJointA.rotation, sequenceJointB.rotation, interpolation)); diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index e65488d28..c4f0acbb9 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -9,9 +9,7 @@ #include #include #include -#include #include -#include #include namespace Nz @@ -74,7 +72,7 @@ namespace Nz void Buffer::Destroy() { - if (!m_impl) + if (m_impl) { OnBufferDestroy(this); diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index ad2ff9969..dd24a1469 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -5,11 +5,9 @@ #include #include #include -#include #include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 76ee1c1ea..6758a2e1b 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -6,15 +6,13 @@ #include #include #include -#include #include -#include #include #include #include +#include #include -#include -#include +#include #include #include @@ -108,7 +106,7 @@ namespace Nz } } - IndexBufferRef indexBuffer = IndexBuffer::New(false, header.num_tris*3, parameters.storage, 0); + IndexBufferRef indexBuffer = IndexBuffer::New(false, header.num_tris*3, parameters.storage, parameters.indexBufferFlags); // Extract triangles data std::vector triangles(header.num_tris); @@ -159,7 +157,7 @@ namespace Nz } #endif - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), header.num_vertices, parameters.storage, 0); + VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, header.num_vertices, parameters.storage, parameters.vertexBufferFlags); StaticMeshRef subMesh = StaticMesh::New(mesh); if (!subMesh->Create(vertexBuffer)) { @@ -192,23 +190,26 @@ namespace Nz scale *= ScaleAdjust; translate *= ScaleAdjust; - BufferMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); - MeshVertex* vertex = static_cast(vertexMapper.GetPointer()); + VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); // Loading texture coordinates - const unsigned int indexFix[3] = {0, 2, 1}; - Vector2f invSkinSize(1.f / header.skinwidth, 1.f / header.skinheight); - for (unsigned int i = 0; i < header.num_tris; ++i) + if (auto uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord)) { - for (unsigned int j = 0; j < 3; ++j) + const unsigned int indexFix[3] = {0, 2, 1}; + + Vector2f invSkinSize(1.f / header.skinwidth, 1.f / header.skinheight); + for (unsigned int i = 0; i < header.num_tris; ++i) { - const unsigned int fixedIndex = indexFix[j]; //< Reverse winding order + for (unsigned int j = 0; j < 3; ++j) + { + const unsigned int fixedIndex = indexFix[j]; //< Reverse winding order - const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]]; - Vector2f uv(texC.u, texC.v); - uv *= invSkinSize; + const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]]; + Vector2f uv(texC.u, texC.v); + uv *= invSkinSize; - vertex[triangles[i].vertices[fixedIndex]].uv.Set(parameters.texCoordOffset + uv * parameters.texCoordScale); + uvPtr[triangles[i].vertices[fixedIndex]].Set(parameters.texCoordOffset + uv * parameters.texCoordScale); + } } } @@ -219,15 +220,27 @@ namespace Nz Nz::Matrix4f matrix = Matrix4f::Transform(translate, rotationQuat, scale); matrix *= parameters.matrix; + if (auto normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal)) + { + Nz::Matrix4f normalMatrix = Matrix4f::Rotate(rotationQuat); + normalMatrix *= parameters.matrix; + + for (unsigned int v = 0; v < header.num_vertices; ++v) + { + const MD2_Vertex& vert = vertices[v]; + + *normalPtr++ = normalMatrix.Transform(md2Normals[vert.n], 0.f); + } + } + + auto posPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + assert(posPtr); + for (unsigned int v = 0; v < header.num_vertices; ++v) { const MD2_Vertex& vert = vertices[v]; - Vector3f position = matrix * Vector3f(vert.x, vert.y, vert.z); - vertex->position = position; - vertex->normal = rotationQuat * md2Normals[vert.n]; - - vertex++; + *posPtr++ = matrix * Vector3f(vert.x, vert.y, vert.z); } vertexMapper.Unmap(); @@ -236,7 +249,9 @@ namespace Nz subMesh->SetMaterialIndex(0); subMesh->GenerateAABB(); - subMesh->GenerateTangents(); + + if (parameters.vertexDeclaration->HasComponentOfType(VertexComponent_Tangent)) + subMesh->GenerateTangents(); mesh->AddSubMesh(subMesh); diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp index 026c9e5d7..e67389409 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp @@ -3,7 +3,10 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include +#include +#include #include namespace Nz diff --git a/src/Nazara/Utility/Formats/MD5AnimParser.cpp b/src/Nazara/Utility/Formats/MD5AnimParser.cpp index 5930fe5a3..2d343f07c 100644 --- a/src/Nazara/Utility/Formats/MD5AnimParser.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimParser.cpp @@ -4,24 +4,19 @@ #include #include -#include #include -#include -#include #include -#include -#include #include namespace Nz { MD5AnimParser::MD5AnimParser(Stream& stream) : m_stream(stream), + m_streamFlags(stream.GetStreamOptions()), //< Saves stream flags m_keepLastLine(false), m_frameIndex(0), m_frameRate(0), - m_lineCount(0), - m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags + m_lineCount(0) { m_stream.EnableTextMode(true); } diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 5284d1d2c..d7104b9d0 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -5,9 +5,13 @@ #include #include #include +#include #include +#include #include +#include #include +#include #include #include #include @@ -91,8 +95,8 @@ namespace Nz bool largeIndices = (vertexCount > std::numeric_limits::max()); - IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, UInt32(indexCount), parameters.storage, 0); - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent_Skinning), UInt32(vertexCount), parameters.storage, 0); + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, UInt32(indexCount), parameters.storage, parameters.indexBufferFlags); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent_Skinning), UInt32(vertexCount), parameters.storage, parameters.vertexBufferFlags | BufferUsage_Dynamic); // Index buffer IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); @@ -125,6 +129,7 @@ namespace Nz BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); SkeletalMeshVertex* vertices = static_cast(vertexMapper.GetPointer()); + for (const MD5MeshParser::Vertex& vertex : md5Mesh.vertices) { // Skinning MD5 (Formule d'Id Tech) @@ -236,7 +241,7 @@ namespace Nz // Index buffer bool largeIndices = (vertexCount > std::numeric_limits::max()); - IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, UInt32(indexCount), parameters.storage, 0); + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, UInt32(indexCount), parameters.storage, parameters.indexBufferFlags); IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); IndexIterator index = indexMapper.begin(); @@ -251,13 +256,15 @@ namespace Nz indexMapper.Unmap(); // Vertex buffer - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), UInt32(vertexCount), parameters.storage, 0); - BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); + VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, UInt32(vertexCount), parameters.storage, parameters.vertexBufferFlags); + + VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); + + auto posPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); - MeshVertex* vertices = static_cast(vertexMapper.GetPointer()); for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) { - // Skinning MD5 (Formule d'Id Tech) + // Id Tech MD5 skinning Vector3f finalPos(Vector3f::Zero()); for (unsigned int j = 0; j < md5Vertex.weightCount; ++j) { @@ -268,9 +275,13 @@ namespace Nz } // On retourne le modèle dans le bon sens - vertices->position = matrix * finalPos; - vertices->uv.Set(parameters.texCoordOffset + md5Vertex.uv * parameters.texCoordScale); - vertices++; + *posPtr++ = matrix * finalPos; + } + + if (auto uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord)) + { + for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) + *uvPtr++ = parameters.texCoordOffset + md5Vertex.uv * parameters.texCoordScale; } vertexMapper.Unmap(); @@ -284,9 +295,16 @@ namespace Nz subMesh->SetIndexBuffer(indexBuffer); subMesh->GenerateAABB(); - subMesh->GenerateNormalsAndTangents(); subMesh->SetMaterialIndex(i); + if (parameters.vertexDeclaration->HasComponentOfType(VertexComponent_Normal)) + { + if (parameters.vertexDeclaration->HasComponentOfType(VertexComponent_Tangent)) + subMesh->GenerateNormalsAndTangents(); + else + subMesh->GenerateNormals(); + } + mesh->AddSubMesh(subMesh); // Material diff --git a/src/Nazara/Utility/Formats/MD5MeshParser.cpp b/src/Nazara/Utility/Formats/MD5MeshParser.cpp index 470e9a41a..0e719c90f 100644 --- a/src/Nazara/Utility/Formats/MD5MeshParser.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshParser.cpp @@ -4,18 +4,8 @@ #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include #include -#include -#include #include #include @@ -23,10 +13,10 @@ namespace Nz { MD5MeshParser::MD5MeshParser(Stream& stream) : m_stream(stream), + m_streamFlags(stream.GetStreamOptions()), //< Saves stream flags m_keepLastLine(false), m_lineCount(0), - m_meshIndex(0), - m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags + m_meshIndex(0) { m_stream.EnableTextMode(true); } diff --git a/src/Nazara/Utility/Formats/MTLParser.cpp b/src/Nazara/Utility/Formats/MTLParser.cpp index 894f20f02..d001588a4 100644 --- a/src/Nazara/Utility/Formats/MTLParser.cpp +++ b/src/Nazara/Utility/Formats/MTLParser.cpp @@ -4,11 +4,8 @@ #include #include -#include -#include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index d7dd15d14..da69bcac7 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -3,16 +3,14 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include -#include #include #include #include #include +#include #include #include -#include #include #include #include @@ -233,8 +231,8 @@ namespace Nz } // Création des buffers - IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), UInt32(indices.size()), parameters.storage, 0); - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), UInt32(vertexCount), parameters.storage, 0); + IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), UInt32(indices.size()), parameters.storage, parameters.indexBufferFlags); + VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, UInt32(vertexCount), parameters.storage, parameters.vertexBufferFlags); // Remplissage des indices IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); @@ -244,32 +242,53 @@ namespace Nz indexMapper.Unmap(); // Pour laisser les autres tâches affecter l'index buffer // Remplissage des vertices + + // Make sure the normal matrix won't rescale our normals + Nz::Matrix4f normalMatrix = parameters.matrix; + if (normalMatrix.HasScale()) + normalMatrix.ApplyScale(1.f / normalMatrix.GetScale()); + bool hasNormals = true; bool hasTexCoords = true; - BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); - MeshVertex* meshVertices = static_cast(vertexMapper.GetPointer()); + + VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); + + auto normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal); + auto posPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + auto uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord); + + if (!normalPtr) + hasNormals = false; + + if (!uvPtr) + hasTexCoords = false; + for (auto& vertexPair : vertices) { const OBJParser::FaceVertex& vertexIndices = vertexPair.first; unsigned int index = vertexPair.second; - MeshVertex& vertex = meshVertices[index]; - const Vector4f& vec = positions[vertexIndices.position-1]; - vertex.position = Vector3f(parameters.matrix * vec); + posPtr[index] = Vector3f(parameters.matrix * vec); - if (vertexIndices.normal > 0) - vertex.normal = normals[vertexIndices.normal-1]; - else - hasNormals = false; - - if (vertexIndices.texCoord > 0) + if (hasNormals) { - Vector2f uv = Vector2f(texCoords[vertexIndices.texCoord - 1]); - vertex.uv.Set(parameters.texCoordOffset + uv * parameters.texCoordScale); + if (vertexIndices.normal > 0) + normalPtr[index] = normalMatrix.Transform(normals[vertexIndices.normal - 1], 0.f); + else + hasNormals = false; + } + + if (hasTexCoords) + { + if (vertexIndices.texCoord > 0) + { + Vector2f uv = Vector2f(texCoords[vertexIndices.texCoord - 1]); + uvPtr[index] = Vector2f(parameters.texCoordOffset + uv * parameters.texCoordScale); + } + else + hasTexCoords = false; } - else - hasTexCoords = false; } vertexMapper.Unmap(); @@ -294,7 +313,7 @@ namespace Nz subMesh->GenerateTangents(); else if (hasTexCoords) subMesh->GenerateNormalsAndTangents(); - else + else if (normalPtr) subMesh->GenerateNormals(); mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh); diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index f85251f57..95d7fa6ce 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/src/Nazara/Utility/Formats/OBJSaver.cpp b/src/Nazara/Utility/Formats/OBJSaver.cpp index 7b3507730..74585971d 100644 --- a/src/Nazara/Utility/Formats/OBJSaver.cpp +++ b/src/Nazara/Utility/Formats/OBJSaver.cpp @@ -2,11 +2,7 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include -#include -#include -#include -#include +#include #include #include #include @@ -14,10 +10,7 @@ #include #include #include -#include -#include #include -#include #include #include diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index 83b9880dd..c7fcc7e8f 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/src/Nazara/Utility/Formats/STBSaver.cpp b/src/Nazara/Utility/Formats/STBSaver.cpp index 0e2f31e3f..4ec466c23 100644 --- a/src/Nazara/Utility/Formats/STBSaver.cpp +++ b/src/Nazara/Utility/Formats/STBSaver.cpp @@ -2,7 +2,6 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include #include #include #include diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 15d9133fe..54c47b5a3 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -7,9 +7,7 @@ #include #include #include -#include #include -#include #include ///TODO: Rajouter des warnings (Formats compressés avec les méthodes Copy/Update, tests taille dans Copy) diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 306fffb7f..4455a2f0c 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index b6985714e..66ee817ff 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -6,18 +6,14 @@ #include #include #include -#include #include -#include #include #include #include -#include #include #include #include #include -#include #include #include #include @@ -45,6 +41,18 @@ namespace Nz return false; } + if (!vertexDeclaration) + { + NazaraError("The vertex declaration can't be null"); + return false; + } + + if (!vertexDeclaration->HasComponent(VertexComponent_Position)) + { + NazaraError("Vertex declaration must contains a vertex position"); + return false; + } + return true; } @@ -52,7 +60,7 @@ namespace Nz { MeshImpl() { - materialData.resize(1); // Un matériau par défaut + materialData.resize(1); // One material by default } std::unordered_map subMeshMap; @@ -60,10 +68,10 @@ namespace Nz std::vector subMeshes; AnimationType animationType; Boxf aabb; - Skeleton skeleton; // Uniquement pour les meshs squelettiques + Skeleton skeleton; // Only used by skeletal meshes String animationPath; bool aabbUpdated = false; - UInt32 jointCount; // Uniquement pour les meshs squelettiques + UInt32 jointCount; // Only used by skeletal meshes }; Mesh::~Mesh() @@ -105,6 +113,7 @@ namespace Nz NazaraAssert(m_impl, "Mesh should be created first"); NazaraAssert(m_impl->animationType == AnimationType_Static, "Submesh building only works for static meshes"); NazaraAssert(params.IsValid(), "Invalid parameters"); + NazaraAssert(params.vertexDeclaration->HasComponentOfType(VertexComponent_Position), "The vertex declaration doesn't have a Vector3 position component"); Boxf aabb; IndexBufferRef indexBuffer; @@ -113,7 +122,7 @@ namespace Nz Matrix4f matrix(primitive.matrix); matrix *= params.matrix; - VertexDeclaration* declaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent); + VertexDeclaration* declaration = params.vertexDeclaration; switch (primitive.type) { @@ -123,8 +132,8 @@ namespace Nz unsigned int vertexCount; ComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, params.indexBufferFlags); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, params.vertexBufferFlags); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -145,8 +154,8 @@ namespace Nz unsigned int vertexCount; ComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, params.indexBufferFlags); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, params.vertexBufferFlags); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -167,8 +176,8 @@ namespace Nz unsigned int vertexCount; ComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, params.indexBufferFlags); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, params.vertexBufferFlags); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -193,8 +202,8 @@ namespace Nz unsigned int vertexCount; ComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, params.indexBufferFlags); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, params.vertexBufferFlags); VertexMapper vertexMapper(vertexBuffer, BufferAccess_ReadWrite); @@ -215,8 +224,8 @@ namespace Nz unsigned int vertexCount; ComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, params.indexBufferFlags); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, params.vertexBufferFlags); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -237,8 +246,8 @@ namespace Nz unsigned int vertexCount; ComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, params.indexBufferFlags); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, params.vertexBufferFlags); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 739af792e..6216a815b 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -377,6 +377,7 @@ namespace Nz m_drawPos.x = 0; m_drawPos.y += sizeInfo.lineHeight; + m_workingBounds.ExtendTo(m_lines.back().bounds); m_lines.emplace_back(Line{Rectf(0.f, float(sizeInfo.lineHeight * m_lines.size()), 0.f, float(sizeInfo.lineHeight)), m_glyphs.size() + 1}); break; } @@ -385,17 +386,16 @@ namespace Nz m_lines.back().bounds.ExtendTo(glyph.bounds); - if (!m_workingBounds.IsValid()) - m_workingBounds.Set(glyph.bounds); - else - m_workingBounds.ExtendTo(glyph.bounds); - m_drawPos.x += advance; m_glyphs.push_back(glyph); } m_lines.back().bounds.ExtendTo(m_glyphs.back().bounds); + m_workingBounds.ExtendTo(m_lines.back().bounds); m_bounds.Set(Rectf(std::floor(m_workingBounds.x), std::floor(m_workingBounds.y), std::ceil(m_workingBounds.width), std::ceil(m_workingBounds.height))); + + m_colorUpdated = true; + m_glyphUpdated = true; } void SimpleTextDrawer::OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer) diff --git a/src/Nazara/Utility/SkeletalMesh.cpp b/src/Nazara/Utility/SkeletalMesh.cpp index e866c0d33..02550a4d6 100644 --- a/src/Nazara/Utility/SkeletalMesh.cpp +++ b/src/Nazara/Utility/SkeletalMesh.cpp @@ -4,9 +4,6 @@ #include #include -#include -#include -#include #include namespace Nz diff --git a/src/Nazara/Utility/Skeleton.cpp b/src/Nazara/Utility/Skeleton.cpp index 480522b4e..45958980f 100644 --- a/src/Nazara/Utility/Skeleton.cpp +++ b/src/Nazara/Utility/Skeleton.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include diff --git a/src/Nazara/Utility/SoftwareBuffer.cpp b/src/Nazara/Utility/SoftwareBuffer.cpp index 6dce1fc6a..c76f20784 100644 --- a/src/Nazara/Utility/SoftwareBuffer.cpp +++ b/src/Nazara/Utility/SoftwareBuffer.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include namespace Nz diff --git a/src/Nazara/Utility/StaticMesh.cpp b/src/Nazara/Utility/StaticMesh.cpp index a1a25f3d7..7c7637481 100644 --- a/src/Nazara/Utility/StaticMesh.cpp +++ b/src/Nazara/Utility/StaticMesh.cpp @@ -5,10 +5,7 @@ #include #include #include -#include -#include #include -#include #include namespace Nz diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index 9607052fb..44e601d22 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -6,10 +6,8 @@ #include #include #include -#include #include #include -#include #include namespace Nz @@ -30,12 +28,14 @@ namespace Nz void SubMesh::GenerateNormals() { VertexMapper mapper(this); - unsigned int vertexCount = GetVertexCount(); + UInt32 vertexCount = mapper.GetVertexCount(); SparsePtr normals = mapper.GetComponentPtr(VertexComponent_Normal); SparsePtr positions = mapper.GetComponentPtr(VertexComponent_Position); + if (!normals || !positions) + return; - for (unsigned int i = 0; i < vertexCount; ++i) + for (UInt32 i = 0; i < vertexCount; ++i) normals[i].MakeZero(); TriangleIterator iterator(this); @@ -54,21 +54,23 @@ namespace Nz } while (iterator.Advance()); - for (unsigned int i = 0; i < vertexCount; ++i) + for (UInt32 i = 0; i < vertexCount; ++i) normals[i].Normalize(); } void SubMesh::GenerateNormalsAndTangents() { VertexMapper mapper(this); - unsigned int vertexCount = GetVertexCount(); + UInt32 vertexCount = mapper.GetVertexCount(); SparsePtr normals = mapper.GetComponentPtr(VertexComponent_Normal); SparsePtr positions = mapper.GetComponentPtr(VertexComponent_Position); SparsePtr tangents = mapper.GetComponentPtr(VertexComponent_Tangent); SparsePtr texCoords = mapper.GetComponentPtr(VertexComponent_TexCoord); + if (!normals || !positions || !tangents || !texCoords) + return; - for (unsigned int i = 0; i < vertexCount; ++i) + for (UInt32 i = 0; i < vertexCount; ++i) { normals[i].MakeZero(); tangents[i].MakeZero(); @@ -107,7 +109,7 @@ namespace Nz } while (iterator.Advance()); - for (unsigned int i = 0; i < vertexCount; ++i) + for (UInt32 i = 0; i < vertexCount; ++i) { normals[i].Normalize(); tangents[i].Normalize(); @@ -122,6 +124,8 @@ namespace Nz SparsePtr positions = mapper.GetComponentPtr(VertexComponent_Position); SparsePtr tangents = mapper.GetComponentPtr(VertexComponent_Tangent); SparsePtr texCoords = mapper.GetComponentPtr(VertexComponent_TexCoord); + if (!normals || !positions || !tangents || !texCoords) + return; TriangleIterator iterator(this); do diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index c6e87e0bb..4c8f1809e 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -6,21 +6,15 @@ #include #include #include -#include -#include -#include -#include #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -35,15 +29,29 @@ namespace Nz { + /*! + * \ingroup utility + * \class Nz::Utility + * \brief Utility class that represents the module initializer of Utility + */ + + /*! + * \brief Initializes the Utility module + * \return true if initialization is successful + * + * \remark Produces a NazaraNotice + * \remark Produces a NazaraError if one submodule failed + */ + bool Utility::Initialize() { if (s_moduleReferenceCounter > 0) { s_moduleReferenceCounter++; - return true; // Déjà initialisé + return true; // Already initialized } - // Initialisation des dépendances + // Initialisation of dependencies if (!Core::Initialize()) { NazaraError("Failed to initialize core module"); @@ -103,23 +111,6 @@ namespace Nz return false; } - bool bParam; - if (!s_initializationParameters.GetBooleanParameter("NoWindowSystem", &bParam) || !bParam) - { - if (!Window::Initialize()) - { - NazaraError("Failed to initialize window's system"); - return false; - } - - // Must be initialized after Window - if (!Cursor::Initialize()) - { - NazaraError("Failed to initialize cursors"); - return false; - } - } - // On enregistre les loaders pour les extensions // Il s'agit ici d'une liste LIFO, le dernier loader enregistré possède la priorité @@ -159,11 +150,6 @@ namespace Nz return s_moduleReferenceCounter != 0; } - void Utility::SetParameters(const ParameterList& parameters) - { - s_initializationParameters = parameters; - } - void Utility::Uninitialize() { if (s_moduleReferenceCounter != 1) @@ -188,9 +174,6 @@ namespace Nz Loaders::UnregisterSTBLoader(); Loaders::UnregisterSTBSaver(); - Cursor::Uninitialize(); //< Must be done before Window - Window::Uninitialize(); - VertexDeclaration::Uninitialize(); Skeleton::Uninitialize(); PixelFormat::Uninitialize(); @@ -246,6 +229,5 @@ namespace Nz static_assert(ComponentType_Max+1 == 14, "Component stride array is incomplete"); - ParameterList Utility::s_initializationParameters; unsigned int Utility::s_moduleReferenceCounter = 0; } diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index f06d46ed0..e072c4aa1 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include namespace Nz diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index 51160ab3f..7edbd3124 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Nz @@ -121,6 +120,15 @@ namespace Nz *offset = vertexComponent.offset; } + bool VertexDeclaration::HasComponent(VertexComponent component) const + { + bool enabled; + + GetComponent(component, &enabled, nullptr, nullptr); + + return enabled; + } + std::size_t VertexDeclaration::GetStride() const { return m_stride; diff --git a/tests/Engine/Core/AlgorithmCore.cpp b/tests/Engine/Core/AlgorithmCore.cpp index 8aff5cb24..39e06c566 100644 --- a/tests/Engine/Core/AlgorithmCore.cpp +++ b/tests/Engine/Core/AlgorithmCore.cpp @@ -3,8 +3,6 @@ #include -#include - TEST_CASE("Apply", "[CORE][ALGORITHM]") { SECTION("Apply lambda to two vector2") @@ -32,9 +30,63 @@ TEST_CASE("Apply", "[CORE][ALGORITHM]") TEST_CASE("ComputeHash", "[CORE][ALGORITHM]") { - SECTION("Compute hash of '0'") + /*SECTION("Compute CRC32 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_CRC32, "1234"); + REQUIRE(result.ToHex().ToUpper() == "596A3B55"); + } + + SECTION("Compute CRC64 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_CRC64, "1234"); + REQUIRE(result.ToHex().ToUpper() == "33302B9FC23855A8"); + } + + SECTION("Compute Fletcher16 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_Fletcher16, "1234"); + REQUIRE(result.ToHex().ToUpper() == "F5CA"); + }*/ + + SECTION("Compute MD5 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_MD5, "1234"); + REQUIRE(result.ToHex().ToUpper() == "81DC9BDB52D04DC20036DBD8313ED055"); + } + + SECTION("Compute SHA1 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA1, "1234"); + REQUIRE(result.ToHex().ToUpper() == "7110EDA4D09E062AA5E4A390B0A572AC0D2C0220"); + } + + SECTION("Compute SHA224 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA224, "1234"); + REQUIRE(result.ToHex().ToUpper() == "99FB2F48C6AF4761F904FC85F95EB56190E5D40B1F44EC3A9C1FA319"); + } + + SECTION("Compute SHA256 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA256, "1234"); + REQUIRE(result.ToHex().ToUpper() == "03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4"); + } + + SECTION("Compute SHA384 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA384, "1234"); + REQUIRE(result.ToHex().ToUpper() == "504F008C8FCF8B2ED5DFCDE752FC5464AB8BA064215D9C5B5FC486AF3D9AB8C81B14785180D2AD7CEE1AB792AD44798C"); + } + + SECTION("Compute SHA512 of '1234'") { auto result = Nz::ComputeHash(Nz::HashType_SHA512, "1234"); REQUIRE(result.ToHex().ToUpper() == "D404559F602EAB6FD602AC7680DACBFAADD13630335E951F097AF3900E9DE176B6DB28512F2E000B9D04FBA5133E8B1C6E8DF59DB3A8AB9D60BE4B97CC9E81DB"); } + + SECTION("Compute Whirlpool of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_Whirlpool, "1234"); + REQUIRE(result.ToHex().ToUpper() == "2F9959B230A44678DD2DC29F037BA1159F233AA9AB183CE3A0678EAAE002E5AA6F27F47144A1A4365116D3DB1B58EC47896623B92D85CB2F191705DAF11858B8"); + } } diff --git a/tests/Engine/Core/Bitset.cpp b/tests/Engine/Core/Bitset.cpp index b06a38aa8..9cbd605b3 100644 --- a/tests/Engine/Core/Bitset.cpp +++ b/tests/Engine/Core/Bitset.cpp @@ -8,6 +8,7 @@ template void Check(const char* title); template void CheckAppend(const char* title); template void CheckBitOps(const char* title); +template void CheckBitOpsMultipleBlocks(const char* title); template void CheckConstructor(const char* title); template void CheckCopyMoveSwap(const char* title); template void CheckRead(const char* title); @@ -28,6 +29,7 @@ void Check(const char* title) CheckCopyMoveSwap(title); CheckBitOps(title); + CheckBitOpsMultipleBlocks(title); CheckAppend(title); CheckRead(title); @@ -111,7 +113,68 @@ void CheckBitOps(const char* title) { CHECK(andBitset == Nz::Bitset("00001")); CHECK(orBitset == Nz::Bitset("11111")); + CHECK(orBitset.TestAll()); CHECK(xorBitset == Nz::Bitset("11110")); + CHECK(!xorBitset.TestAll()); + CHECK((~orBitset).TestNone()); + } + } + + WHEN("We perform bit shifts") + { + first.ShiftLeft(1); + second.ShiftRight(2); + + THEN("We should obtain these") + { + CHECK(first == Nz::Bitset("10010")); + CHECK(second == Nz::Bitset("101")); + } + } + } + } +} + +template +void CheckBitOpsMultipleBlocks(const char* title) +{ + SECTION(title) + { + GIVEN("Two bitsets") + { + Nz::Bitset first("01001011010010101001010011010101001"); + Nz::Bitset second("10111111101101110110111101101110110"); + + WHEN("We perform operators") + { + Nz::Bitset andBitset = first & second; + Nz::Bitset orBitset = first | second; + Nz::Bitset xorBitset = first ^ second; + + THEN("They should operate as logical operators") + { + CHECK(andBitset == Nz::Bitset("00001011000000100000010001000100000")); + CHECK(orBitset == Nz::Bitset("11111111111111111111111111111111111")); + CHECK(orBitset.TestAll()); + CHECK(xorBitset == Nz::Bitset("11110100111111011111101110111011111")); + CHECK(!xorBitset.TestAll()); + CHECK((~orBitset).TestNone()); + } + } + + WHEN("We perform bit shifts") + { + first.ShiftLeft(16); + second.ShiftRight(16); + + THEN("We should obtain these") + { + CHECK(first == Nz::Bitset("10010100110101010010000000000000000")); + first.ShiftLeft(1); + CHECK(first == Nz::Bitset("00101001101010100100000000000000000")); + CHECK(second == Nz::Bitset("1011111110110111011")); + second.ShiftRight(1); + CHECK(second == Nz::Bitset("101111111011011101")); } } } diff --git a/tests/Engine/Core/ByteArray.cpp b/tests/Engine/Core/ByteArray.cpp index d085585a5..d7bf4cf3c 100644 --- a/tests/Engine/Core/ByteArray.cpp +++ b/tests/Engine/Core/ByteArray.cpp @@ -102,7 +102,7 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") { Nz::ByteArray abc("abc", 3); Nz::ByteArray cba; - cba = std::move(Nz::ByteArray("cba", 3)); + cba = Nz::ByteArray("cba", 3); WHEN("We do some antagonists operations") { diff --git a/tests/Engine/Core/ByteStream.cpp b/tests/Engine/Core/ByteStream.cpp new file mode 100644 index 000000000..58c31020d --- /dev/null +++ b/tests/Engine/Core/ByteStream.cpp @@ -0,0 +1,73 @@ +#include +#include + +#include + +SCENARIO("ByteStream", "[CORE][BYTESTREAM]") +{ + GIVEN("A bytestream from a bunch of bytes") + { + const int numberOfBytes = 16; + std::array data; + + Nz::ByteStream byteStream(data.data(), numberOfBytes); + + WHEN("We write some data in it") + { + int value = 5; + byteStream << value; + Nz::String string = "string"; + byteStream << string; + + byteStream.FlushBits(); + + THEN("We can retrieve them") + { + const void* const ptrData = data.data(); + Nz::ByteStream readStream; + CHECK(readStream.GetSize() == 0); + readStream = Nz::ByteStream(ptrData, byteStream.GetSize()); + int retrievedValue = 0; + readStream >> retrievedValue; + Nz::String retrievedString; + readStream >> retrievedString; + + CHECK(value == retrievedValue); + CHECK(string == retrievedString); + } + } + } + + GIVEN("A bytestream with a byte array and a different endianness") + { + const int numberOfBytes = 16; + Nz::ByteArray byteArray(numberOfBytes); + Nz::ByteStream byteStream(&byteArray); + + byteStream.SetDataEndianness(Nz::GetPlatformEndianness() == Nz::Endianness_BigEndian ? Nz::Endianness_LittleEndian : Nz::Endianness_BigEndian); + + WHEN("We write an integer") + { + int value = 7; + byteStream.Write(&value, sizeof(int)); + bool boolean = true; + byteStream << boolean; + byteStream.FlushBits(); + + THEN("We can retrieve it properly") + { + Nz::ByteStream tmpStream(&byteArray); + tmpStream.SetDataEndianness(byteStream.GetDataEndianness()); + + int retrievedValue = 0; + tmpStream.Read(&retrievedValue, sizeof(int)); + CHECK(value == retrievedValue); + + Nz::ByteStream readStream(std::move(tmpStream)); + bool retrievedBoolean = false; + readStream >> retrievedBoolean; + CHECK(boolean == retrievedBoolean); + } + } + } +} \ No newline at end of file diff --git a/tests/Engine/Core/Clock.cpp b/tests/Engine/Core/Clock.cpp index 5b004f885..0bd579163 100644 --- a/tests/Engine/Core/Clock.cpp +++ b/tests/Engine/Core/Clock.cpp @@ -6,24 +6,43 @@ SCENARIO("Clock", "[CORE][CLOCK]") { GIVEN("A clock paused") { - Nz::UInt64 initialTime = 1; + Nz::UInt64 initialTime = 100; Nz::Clock clock(initialTime, true); - WHEN("We get time") + WHEN("We get time since it is paused") { THEN("Time must be the initialTime") { - REQUIRE(clock.GetMicroseconds() == initialTime); + CHECK(clock.GetMicroseconds() == initialTime); + CHECK(clock.IsPaused()); } + } - AND_WHEN("We unpause it") + WHEN("We unpause it") + { + clock.Unpause(); + REQUIRE(!clock.IsPaused()); + + THEN("Time must not be the initialTime") { - clock.Unpause(); - THEN("Time must not be the initialTime") - { - Nz::Thread::Sleep(1); - REQUIRE(clock.GetMicroseconds() != initialTime); - } + Nz::Thread::Sleep(1); + Nz::UInt64 microSeconds = clock.GetMicroseconds(); + CHECK(microSeconds != initialTime); + CHECK(microSeconds / 1000 <= clock.GetMilliseconds()); + CHECK(microSeconds / (1000.f * 1000.f) <= clock.GetSeconds()); + } + } + + WHEN("We restart it") + { + clock.Restart(); + + THEN("It is unpaused and we can pause it") + { + CHECK(!clock.IsPaused()); + clock.Pause(); + CHECK(clock.IsPaused()); + CHECK(clock.GetMicroseconds() != initialTime); } } } diff --git a/tests/Engine/Core/Color.cpp b/tests/Engine/Core/Color.cpp index 40ada67c2..ce9b50cfa 100644 --- a/tests/Engine/Core/Color.cpp +++ b/tests/Engine/Core/Color.cpp @@ -1,6 +1,63 @@ #include #include +const float epsilon = 0.01f; + +void CompareColor(const Nz::Color& lhs, const Nz::Color& rhs) +{ + Nz::UInt8 tolerance = 3; + REQUIRE(Nz::NumberEquals(lhs.r, rhs.r, tolerance)); + REQUIRE(Nz::NumberEquals(lhs.g, rhs.g, tolerance)); + REQUIRE(Nz::NumberEquals(lhs.b, rhs.b, tolerance)); + REQUIRE(Nz::NumberEquals(lhs.a, rhs.a, tolerance)); +} + +void CompareCMY(const Nz::Color& color, float cyan, float magenta, float yellow) +{ + float retrievedCyan = 0.f, retrievedMagenta = 0.f, retrievedYellow = 0.f; + Nz::Color::ToCMY(color, &retrievedCyan, &retrievedMagenta, &retrievedYellow); + CHECK(retrievedCyan == Approx(cyan).epsilon(epsilon)); + CHECK(retrievedMagenta == Approx(magenta).epsilon(epsilon)); + CHECK(retrievedYellow == Approx(yellow).epsilon(epsilon)); +} + +void CompareCMYK(const Nz::Color& color, float cyan, float magenta, float yellow, float black) +{ + float retrievedCyan = 0.f, retrievedMagenta = 0.f, retrievedYellow = 0.f, retrievedBlack = 0.f; + Nz::Color::ToCMYK(color, &retrievedCyan, &retrievedMagenta, &retrievedYellow, &retrievedBlack); + CHECK(retrievedCyan == Approx(cyan).epsilon(epsilon)); + CHECK(retrievedMagenta == Approx(magenta).epsilon(epsilon)); + CHECK(retrievedYellow == Approx(yellow).epsilon(epsilon)); + CHECK(retrievedBlack == Approx(black).epsilon(epsilon)); +} + +void CompareHSL(const Nz::Color& color, float hue, float saturation, float luminosity) +{ + float retrievedHue = 0.f, retrievedSaturation = 0.f, retrievedLuminosity = 0.f; + Nz::Color::ToHSL(color, &retrievedHue, &retrievedSaturation, &retrievedLuminosity); + CHECK(retrievedHue == Approx(hue).epsilon(epsilon)); + CHECK(retrievedSaturation == Approx(saturation).epsilon(epsilon)); + CHECK(retrievedLuminosity == Approx(luminosity).epsilon(epsilon)); +} + +void CompareHSV(const Nz::Color& color, float hue, float saturation, float value) +{ + float retrievedHue = 0.f, retrievedSaturation = 0.f, retrievedValue = 0.f; + Nz::Color::ToHSV(color, &retrievedHue, &retrievedSaturation, &retrievedValue); + CHECK(retrievedHue == Approx(hue).epsilon(epsilon)); + CHECK(retrievedSaturation == Approx(saturation).epsilon(epsilon)); + CHECK(retrievedValue == Approx(value).epsilon(epsilon)); +} + +void CompareXYZ(const Nz::Color& color, float x, float y, float z) +{ + Nz::Vector3f retrievedValues = Nz::Vector3f::Zero(); + Nz::Color::ToXYZ(color, &retrievedValues); + CHECK(retrievedValues.x == Approx(x).epsilon(epsilon)); + CHECK(retrievedValues.y == Approx(y).epsilon(epsilon)); + CHECK(retrievedValues.z == Approx(z).epsilon(epsilon)); +} + SCENARIO("Color", "[CORE][COLOR]") { GIVEN("Two colors, one red (255) and one gray (128)") @@ -19,4 +76,74 @@ SCENARIO("Color", "[CORE][COLOR]") } } } + + GIVEN("A special color in different formats") + { + struct ColorData + { + const char* name; + Nz::Color rgb; + float cyan, magenta, yellow; + float cyanK, magentaK, yellowK, black; + float hue, saturation, luminosity; + float hueV, saturationV, valueV; + float x, y, z; + }; + + std::vector colors; + + colors.push_back({ + "blue", + Nz::Color(0, 0, 255), + 1.f, 1.f, 0.f, // cmy + 1.f, 1.f, 0.f, 0.f, // cmyk + 240.f, 1.f, 0.5f, // hsl + 240.f, 1.f, 1.f, // hsv + 18.05f, 7.22f, 95.05f // xyz + }); + + colors.push_back({ + "white", + Nz::Color(255, 255, 255), + 0.f, 0.f, 0.f, // cmy + 0.f, 0.f, 0.f, 0.f, // cmyk + 0.f, 0.f, 1.f, // hsl + 0.f, 0.f, 1.f, // hsv + 95.05f, 100.f, 108.09f // xyz + }); + + colors.push_back({ + "greenish", + Nz::Color(5, 191, 25), + 0.980f, 0.251f, 0.902f, // cmy + 0.974f, 0.000f, 0.869f, 0.251f, // cmyk + 126.f, 0.95f, 0.38f, // hsl + 126.f, 0.97f, 0.75f, // hsv + 18.869f, 37.364f, 7.137f // xyz + }); + + for (const ColorData& color : colors) + { + WHEN("We perform conversion for: " + color.name) + { + THEN("From other color spaces") + { + CompareColor(color.rgb, Nz::Color::FromCMY(color.cyan, color.magenta, color.yellow)); + CompareColor(color.rgb, Nz::Color::FromCMYK(color.cyanK, color.magentaK, color.yellowK, color.black)); + CompareColor(color.rgb, Nz::Color::FromHSL(color.hue, color.saturation, color.luminosity)); + CompareColor(color.rgb, Nz::Color::FromHSV(color.hueV, color.saturationV, color.valueV)); + CompareColor(color.rgb, Nz::Color::FromXYZ(Nz::Vector3f(color.x, color.y, color.z))); + } + + THEN("To other color spaces") + { + CompareCMY(color.rgb, color.cyan, color.magenta, color.yellow); + CompareCMYK(color.rgb, color.cyanK, color.magentaK, color.yellowK, color.black); + CompareHSL(color.rgb, color.hue, color.saturation, color.luminosity); + CompareHSV(color.rgb, color.hueV, color.saturationV, color.valueV); + CompareXYZ(color.rgb, color.x, color.y, color.z); + } + } + } + } } diff --git a/tests/Engine/Core/File.cpp b/tests/Engine/Core/File.cpp index 1163a8aad..60b5bcc40 100644 --- a/tests/Engine/Core/File.cpp +++ b/tests/Engine/Core/File.cpp @@ -1,4 +1,5 @@ #include +#include #include SCENARIO("File", "[CORE][FILE]") diff --git a/tests/Engine/Core/MemoryPool.cpp b/tests/Engine/Core/MemoryPool.cpp index 6a3c230c4..2cd90a9dc 100644 --- a/tests/Engine/Core/MemoryPool.cpp +++ b/tests/Engine/Core/MemoryPool.cpp @@ -24,5 +24,21 @@ SCENARIO("MemoryPool", "[CORE][MEMORYPOOL]") memoryPool.Delete(vector2); } } + + WHEN("We construct three vectors") + { + Nz::Vector2* vector1 = memoryPool.New>(1, 2); + Nz::Vector2* vector2 = memoryPool.New>(3, 4); + Nz::Vector2* vector3 = memoryPool.New>(5, 6); + + THEN("Memory is available") + { + vector1->x = 3; + vector2->y = 5; + CHECK(*vector1 == Nz::Vector2(3, 2)); + CHECK(*vector2 == Nz::Vector2(3, 5)); + CHECK(vector3->GetSquaredLength() == Approx(61.f)); + } + } } } diff --git a/tests/Engine/Core/ParameterList.cpp b/tests/Engine/Core/ParameterList.cpp index 5d998f5b8..8ffca3097 100644 --- a/tests/Engine/Core/ParameterList.cpp +++ b/tests/Engine/Core/ParameterList.cpp @@ -3,35 +3,204 @@ #include +void nullAction(void*) +{ +} + SCENARIO("ParameterList", "[CORE][PARAMETERLIST]") { GIVEN("An empty ParameterList") { Nz::ParameterList parameterList; - WHEN("We add String 'string'") + WHEN("We add Bool 'true' and analogous") + { + bool boolean = true; + parameterList.SetParameter("bool", boolean); + + long long intTrue = 1; + parameterList.SetParameter("intTrue", intTrue); + long long intFalse = 0; + parameterList.SetParameter("intFalse", intFalse); + + Nz::String strTrue = "true"; + parameterList.SetParameter("strTrue", strTrue); + Nz::String strFalse = "false"; + parameterList.SetParameter("strFalse", strFalse); + + THEN("We can get it back") + { + bool retrievedValue = false; + CHECK(parameterList.GetBooleanParameter("bool", &retrievedValue)); + CHECK(retrievedValue == boolean); + } + + THEN("Conversion from int to bool should also work") + { + bool retrievedValue = false; + CHECK(parameterList.GetBooleanParameter("intTrue", &retrievedValue)); + CHECK(retrievedValue); + CHECK(parameterList.GetBooleanParameter("intFalse", &retrievedValue)); + CHECK(!retrievedValue); + } + + THEN("Conversion from str to bool should also work") + { + bool retrievedValue = false; + CHECK(parameterList.GetBooleanParameter("strTrue", &retrievedValue)); + CHECK(retrievedValue); + CHECK(parameterList.GetBooleanParameter("strFalse", &retrievedValue)); + CHECK(!retrievedValue); + } + } + + WHEN("We add Color 'rgb(1, 2, 3)'") + { + Nz::Color rgb(1, 2, 3); + parameterList.SetParameter("color", rgb); + + THEN("We can get it back") + { + Nz::Color retrievedColor; + CHECK(parameterList.GetColorParameter("color", &retrievedColor)); + CHECK(retrievedColor == rgb); + } + } + + WHEN("We add Double '3.0' and analogous") + { + double fl = 3.0; + parameterList.SetParameter("double", fl); + + long long intDouble = 3; + parameterList.SetParameter("intDouble", intDouble); + + Nz::String strDouble = "3.0"; + parameterList.SetParameter("strDouble", strDouble); + + THEN("We can get it back") + { + double retrievedValue; + CHECK(parameterList.GetDoubleParameter("double", &retrievedValue)); + CHECK(retrievedValue == fl); + } + + THEN("Conversion from int to double should also work") + { + double retrievedValue; + CHECK(parameterList.GetDoubleParameter("intDouble", &retrievedValue)); + CHECK(retrievedValue == fl); + } + + THEN("Conversion from string to double should also work") + { + double retrievedValue; + CHECK(parameterList.GetDoubleParameter("strDouble", &retrievedValue)); + CHECK(retrievedValue == fl); + } + } + + WHEN("We add Int '3' and analogous") + { + long long i = 3; + parameterList.SetParameter("int", i); + + bool trueInt = 1; + parameterList.SetParameter("trueInt", trueInt); + bool falseInt = 0; + parameterList.SetParameter("falseInt", falseInt); + + double doubleInt = 3; + parameterList.SetParameter("doubleInt", doubleInt); + + Nz::String strInt = "3"; + parameterList.SetParameter("strInt", strInt); + + THEN("We can get it back") + { + long long retrievedValue; + CHECK(parameterList.GetIntegerParameter("int", &retrievedValue)); + CHECK(retrievedValue == i); + } + + THEN("Conversion from bool to int should also work") + { + long long retrievedValue; + CHECK(parameterList.GetIntegerParameter("trueInt", &retrievedValue)); + CHECK(retrievedValue == trueInt); + CHECK(parameterList.GetIntegerParameter("falseInt", &retrievedValue)); + CHECK(retrievedValue == falseInt); + } + + THEN("Conversion from double to int should also work") + { + long long retrievedValue; + CHECK(parameterList.GetIntegerParameter("doubleInt", &retrievedValue)); + CHECK(retrievedValue == i); + } + + THEN("Conversion from string to int should also work") + { + long long retrievedValue; + CHECK(parameterList.GetIntegerParameter("strInt", &retrievedValue)); + CHECK(retrievedValue == i); + } + } + + WHEN("We add String 'string' and analogous") { Nz::String string("string"); parameterList.SetParameter("string", string); + bool trueString = 1; + parameterList.SetParameter("trueString", trueString); + bool falseString = 0; + parameterList.SetParameter("falseString", falseString); + + Nz::Color colorString(1, 2, 3); + parameterList.SetParameter("colorString", colorString); + + double doubleString = 3.0; + parameterList.SetParameter("doubleString", doubleString); + + long long intString = 3; + parameterList.SetParameter("intString", intString); + THEN("We can get it back") { Nz::String newString; - REQUIRE(parameterList.GetStringParameter("string", &newString)); - REQUIRE(newString == string); + CHECK(parameterList.GetStringParameter("string", &newString)); + CHECK(newString == string); } - } - WHEN("We add Float '3.f'") - { - double fl = 3.f; - parameterList.SetParameter("double", fl); - - THEN("We can get it back") + THEN("Conversion from bool to str should also work") { - double newFl; - REQUIRE(parameterList.GetDoubleParameter("double", &newFl)); - REQUIRE(newFl == fl); + Nz::String retrievedValue; + CHECK(parameterList.GetStringParameter("trueString", &retrievedValue)); + CHECK(retrievedValue == "true"); + CHECK(parameterList.GetStringParameter("falseString", &retrievedValue)); + CHECK(retrievedValue == "false"); + } + + THEN("Conversion from color to string should also work") + { + Nz::String retrievedValue; + CHECK(parameterList.GetStringParameter("colorString", &retrievedValue)); + CHECK(retrievedValue == colorString.ToString()); + } + + THEN("Conversion from string to double should also work") + { + Nz::String retrievedValue; + CHECK(parameterList.GetStringParameter("doubleString", &retrievedValue)); + CHECK(retrievedValue == "3"); + } + + THEN("Conversion from string to int should also work") + { + Nz::String retrievedValue; + CHECK(parameterList.GetStringParameter("intString", &retrievedValue)); + CHECK(retrievedValue == "3"); } } @@ -44,8 +213,71 @@ SCENARIO("ParameterList", "[CORE][PARAMETERLIST]") THEN("We can get it back") { void* newPtrToStackValue = nullptr; - REQUIRE(parameterList.GetPointerParameter("ptr", &newPtrToStackValue)); - REQUIRE(newPtrToStackValue == ptrToStackValue); + CHECK(parameterList.GetPointerParameter("ptr", &newPtrToStackValue)); + CHECK(newPtrToStackValue == ptrToStackValue); + } + } + + WHEN("We set our own data") + { + struct Data { + int i; + float f; + }; + + Data data{ 1, 3.f }; + parameterList.SetParameter("userData", &data, nullAction); + + THEN("We can get it back") + { + Data retrievedValue; + void* ptrToData = &retrievedValue; + + CHECK(parameterList.GetUserdataParameter("userData", &ptrToData)); + Data* dataPtr = reinterpret_cast(ptrToData); + CHECK(dataPtr->i == data.i); + CHECK(dataPtr->f == data.f); + } + } + } + + GIVEN("A parameter list with some values") + { + Nz::ParameterList parameterList; + + long long i = 3; + parameterList.SetParameter("i", i); + double d = 1.0; + parameterList.SetParameter("d", d); + + parameterList.SetParameter("toaster"); + parameterList.SetParameter("str", "ing"); + + WHEN("We remove two elements") + { + CHECK(parameterList.HasParameter("i")); + CHECK(parameterList.HasParameter("toaster")); + + parameterList.RemoveParameter("i"); + parameterList.RemoveParameter("toaster"); + + THEN("They do not exist anymore") + { + CHECK(!parameterList.HasParameter("i")); + CHECK(!parameterList.HasParameter("toaster")); + } + } + + WHEN("We copy this list") + { + Nz::ParameterList copy = parameterList; + + THEN("It has the same elements") + { + CHECK(parameterList.HasParameter("i")); + CHECK(parameterList.HasParameter("d")); + CHECK(parameterList.HasParameter("toaster")); + CHECK(parameterList.HasParameter("str")); } } } diff --git a/tests/Engine/Core/StringStream.cpp b/tests/Engine/Core/StringStream.cpp index 5efb9e926..ece0d352c 100644 --- a/tests/Engine/Core/StringStream.cpp +++ b/tests/Engine/Core/StringStream.cpp @@ -49,13 +49,22 @@ SCENARIO("StringStream", "[CORE][STRINGSTREAM]") REQUIRE(stringStream.ToString() == "default-33-33"); } - AND_WHEN("We add floating points") + AND_WHEN("We add round floating points") { stringStream << 3.f; stringStream << 3.0; stringStream << 3.0L; - REQUIRE(stringStream.ToString() == "default333"); + REQUIRE(stringStream.ToString() == "default3.0000003.0000003.000000"); + } + + AND_WHEN("We add floating points") + { + stringStream << 3.5f << ' '; + stringStream << 3.65 << ' '; + stringStream << 3.6478L; + + REQUIRE(stringStream.ToString() == "default3.500000 3.650000 3.647800"); } AND_WHEN("We add string and pointer") diff --git a/tests/Engine/Math/AlgorithmMath.cpp b/tests/Engine/Math/AlgorithmMath.cpp index e6dc2218b..de21817f4 100644 --- a/tests/Engine/Math/AlgorithmMath.cpp +++ b/tests/Engine/Math/AlgorithmMath.cpp @@ -204,6 +204,69 @@ TEST_CASE("MultiplyAdd", "[MATH][ALGORITHM]") } } +TEST_CASE("NormalizeAngle", "[MATH][ALGORITHM]") +{ + SECTION("-90 should be normalized to +270") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-90.f)) == Nz::FromDegrees(270.f)); + } + + SECTION("-540 should be normalized to +180") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-540.f)) == Nz::FromDegrees(180.f)); + } + + SECTION("0 should remain 0") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(0.f)) == Nz::FromDegrees(0.f)); + } + + SECTION("90 should remain 90") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(90.f)) == Nz::FromDegrees(90.f)); + } + + SECTION("360 should be normalized to 0") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(360.f)) == Nz::FromDegrees(0.f)); + } + + SECTION("450 should be normalized to 90") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(450.f)) == Nz::FromDegrees(90.f)); + } + + SECTION("-90 should be normalized to +270") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-90)) == Nz::FromDegrees(270)); + } + + SECTION("-540 should be normalized to +180") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-540)) == Nz::FromDegrees(180)); + } + + SECTION("0 should remain 0") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(0)) == Nz::FromDegrees(0)); + } + + SECTION("90 should remain 90") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(90)) == Nz::FromDegrees(90)); + } + + SECTION("360 should be normalized to 0") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(360)) == Nz::FromDegrees(0)); + } + + SECTION("450 should be normalized to 90") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(450)) == Nz::FromDegrees(90)); + } +} + TEST_CASE("NumberEquals", "[MATH][ALGORITHM]") { SECTION("2.35 and 2.351 should be the same at 0.01") @@ -211,11 +274,16 @@ TEST_CASE("NumberEquals", "[MATH][ALGORITHM]") CHECK(Nz::NumberEquals(2.35, 2.35, 0.01)); } - SECTION("0 and 4 unsigned should be the same at 1") + SECTION("0 and 4 unsigned should be the same at 4") { CHECK(Nz::NumberEquals(0U, 4U, 4U)); } + SECTION("1 and -1 signed should be the same at 2") + { + CHECK(Nz::NumberEquals(1, -1, 2)); + } + SECTION("Maximum integer and -1 should not be equal") { CHECK_FALSE(Nz::NumberEquals(std::numeric_limits::max(), -1)); @@ -229,6 +297,11 @@ TEST_CASE("NumberEquals", "[MATH][ALGORITHM]") TEST_CASE("NumberToString", "[MATH][ALGORITHM]") { + SECTION("0 to string") + { + REQUIRE(Nz::NumberToString(0) == "0"); + } + SECTION("235 to string") { REQUIRE(Nz::NumberToString(235) == "235"); @@ -265,8 +338,20 @@ TEST_CASE("StringToNumber", "[MATH][ALGORITHM]") REQUIRE(Nz::StringToNumber("-235") == -235); } + SECTION("235 157 in string") + { + REQUIRE(Nz::StringToNumber("235 157") == 235157); + } + SECTION("16 in base 16 in string") { REQUIRE(Nz::StringToNumber("10", 16) == 16); } + + SECTION("8 in base 4 in string should not be valid") + { + bool ok = true; + REQUIRE(Nz::StringToNumber("8", 4, &ok) == 0); + REQUIRE(!ok); + } } diff --git a/tests/Engine/Math/BoundingVolume.cpp b/tests/Engine/Math/BoundingVolume.cpp index 9fd552863..a8213b09e 100644 --- a/tests/Engine/Math/BoundingVolume.cpp +++ b/tests/Engine/Math/BoundingVolume.cpp @@ -114,5 +114,52 @@ SCENARIO("BoundingVolume", "[MATH][BOUNDINGVOLUME]") REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, centerAndUnit, 0.5f) == result); } } + + WHEN("We lerp with special cases") + { + Nz::OrientedBoxf centerAndUnitOBB(0.f, 0.f, 0.f, 1.f, 1.f, 1.f); + centerAndUnitOBB.Update(Nz::Matrix4f::Identity()); + + Nz::BoundingVolumef centerAndUnit(centerAndUnitOBB); + + Nz::BoundingVolumef nullBoundingVolume(Nz::Extend_Null); + Nz::BoundingVolumef infiniteBoundingVolume(Nz::Extend_Infinite); + + THEN("Normal to null should give a smaller volume") + { + Nz::BoundingVolumef result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f); + result.Update(Nz::Matrix4f::Identity()); + + REQUIRE(Nz::BoundingVolumef::Lerp(centerAndUnit, nullBoundingVolume, 0.5f) == result); + } + + THEN("Normal to infinite should give an infinite volume") + { + REQUIRE(Nz::BoundingVolumef::Lerp(centerAndUnit, infiniteBoundingVolume, 0.5f) == infiniteBoundingVolume); + } + + THEN("Null to normal should give a small volume") + { + Nz::BoundingVolumef result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f); + result.Update(Nz::Matrix4f::Identity()); + + REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, centerAndUnit, 0.5f) == result); + } + + THEN("Infinite to normal should give an infinite volume") + { + REQUIRE(Nz::BoundingVolumef::Lerp(infiniteBoundingVolume, centerAndUnit, 0.5f) == infiniteBoundingVolume); + } + + THEN("Infinite to null should give an infinite volume") + { + REQUIRE(Nz::BoundingVolumef::Lerp(infiniteBoundingVolume, nullBoundingVolume, 0.5f) == infiniteBoundingVolume); + } + + THEN("Null to null should give a null volume") + { + REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, nullBoundingVolume, 0.5f) == nullBoundingVolume); + } + } } } diff --git a/tests/Engine/Math/Box.cpp b/tests/Engine/Math/Box.cpp index 7d9b42a51..ade117515 100644 --- a/tests/Engine/Math/Box.cpp +++ b/tests/Engine/Math/Box.cpp @@ -56,6 +56,16 @@ SCENARIO("Box", "[MATH][BOX]") } } + WHEN("We ask for the intersection when there are none") + { + firstCenterAndUnit.Translate(Nz::Vector3f::UnitZ() * 5.f); + THEN("We should have a center and unit") + { + Nz::Boxf thirdCenterAndUnit; + CHECK(!firstCenterAndUnit.Intersect(secondCenterAndUnit, &thirdCenterAndUnit)); + } + } + WHEN("We use the constructor of conversion") { THEN("Shouldn't be a problem") diff --git a/tests/Engine/Math/Matrix4.cpp b/tests/Engine/Math/Matrix4.cpp index eec10aacd..d649cbf72 100644 --- a/tests/Engine/Math/Matrix4.cpp +++ b/tests/Engine/Math/Matrix4.cpp @@ -1,7 +1,9 @@ #include #include -SCENARIO("Matrix4", "[MATH][Matrix4]") +#include + +SCENARIO("Matrix4", "[MATH][MATRIX4]") { GIVEN("Two identity matrix") { @@ -20,9 +22,9 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { THEN("Nz::Vector stay the same") { - REQUIRE(firstIdentity.Transform(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit()); - REQUIRE(firstIdentity.Transform(Nz::Vector3f::Unit()) == Nz::Vector3f::Unit()); - REQUIRE(firstIdentity.Transform(Nz::Vector4f(1.f, 1.f, 1.f, 1.f)) == Nz::Vector4f(1.f, 1.f, 1.f, 1.f)); + CHECK(firstIdentity * Nz::Vector2f::Unit() == Nz::Vector2f::Unit()); + CHECK(firstIdentity * Nz::Vector3f::Unit() == Nz::Vector3f::Unit()); + CHECK(firstIdentity * Nz::Vector4f(1.f, 1.f, 1.f, 1.f) == Nz::Vector4f(1.f, 1.f, 1.f, 1.f)); } } @@ -30,11 +32,11 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { THEN("It keeps being a identity") { - REQUIRE(firstIdentity.Concatenate(secondIdentity) == firstIdentity); - REQUIRE(firstIdentity.ConcatenateAffine(secondIdentity) == firstIdentity); - REQUIRE((firstIdentity * secondIdentity) == firstIdentity); - REQUIRE((1.f * firstIdentity) == firstIdentity); - REQUIRE(firstIdentity.Inverse() == secondIdentity.InverseAffine()); + CHECK(firstIdentity.Concatenate(secondIdentity) == firstIdentity); + CHECK(firstIdentity.ConcatenateAffine(secondIdentity) == firstIdentity); + CHECK((firstIdentity * secondIdentity) == firstIdentity); + CHECK((1.f * firstIdentity) == firstIdentity); + CHECK(firstIdentity.Inverse() == secondIdentity.InverseAffine()); } } @@ -65,8 +67,8 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { THEN("These results are expected") { - REQUIRE(matrix1.GetDeterminant() == Approx(24.f)); - REQUIRE(matrix2.GetDeterminant() == Approx(-1.f)); + CHECK(matrix1.GetDeterminant() == Approx(24.f)); + CHECK(matrix2.GetDeterminant() == Approx(-1.f)); } } @@ -81,12 +83,12 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") THEN("We get the identity") { Nz::Matrix4f tmp = matrix1 * invMatrix1; - REQUIRE(tmp.m32 == Approx(0.f)); - REQUIRE(tmp.m42 == Approx(0.f)); + CHECK(tmp.m32 == Approx(0.f)); + CHECK(tmp.m42 == Approx(0.f)); tmp.m32 = 0.f; tmp.m42 = 0.f; - REQUIRE(tmp == Nz::Matrix4f::Identity()); - REQUIRE((matrix2 * invMatrix2) == Nz::Matrix4f::Identity()); + CHECK(tmp == Nz::Matrix4f::Identity()); + CHECK((matrix2 * invMatrix2) == Nz::Matrix4f::Identity()); } } } @@ -106,10 +108,10 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") 0.f, -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, 0.f, 0.f, 1.f); - REQUIRE(transformedMatrix == rotation45X); + CHECK(transformedMatrix == rotation45X); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::FromDegrees(45.f), 0.f, 0.f).ToQuaternion()); rotation45X.ApplyTranslation(Nz::Vector3f::Unit()); - REQUIRE(transformedMatrix == rotation45X); + CHECK(transformedMatrix == rotation45X); } THEN("Rotation around Y") @@ -120,10 +122,10 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") std::sqrt(2.f) / 2.f, 0.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, 0.f, 0.f, 1.f); - REQUIRE(transformedMatrix == rotation45Y); + CHECK(transformedMatrix == rotation45Y); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(0.f, Nz::FromDegrees(45.f), 0.f).ToQuaternion()); rotation45Y.ApplyTranslation(Nz::Vector3f::Unit()); - REQUIRE(transformedMatrix == rotation45Y); + CHECK(transformedMatrix == rotation45Y); } THEN("Rotation around Z") @@ -134,10 +136,172 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f); - REQUIRE(transformedMatrix == rotation45Z); + CHECK(transformedMatrix == rotation45Z); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(45.f)).ToQuaternion())); rotation45Z.ApplyTranslation(Nz::Vector3f::Unit()); - REQUIRE(transformedMatrix == rotation45Z); + CHECK(transformedMatrix == rotation45Z); + } + } + } + + GIVEN("An identity matrix") + { + std::array content{{ 1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f + }}; + + Nz::Matrix4f identity(content.data()); + REQUIRE(identity.IsIdentity()); + + WHEN("We rotate it from pitch 30") + { + Nz::Quaternionf rotation(Nz::EulerAnglesf(Nz::FromDegrees(30.f), 0.f, 0.f)); + identity.ApplyRotation(rotation); + + THEN("We should retrieve it") + { + REQUIRE(identity.GetRotation() == rotation); + } + } + + WHEN("We rotate it from yaw 30") + { + Nz::Quaternionf rotation(Nz::EulerAnglesf(0.f, Nz::FromDegrees(30.f), 0.f)); + identity.ApplyRotation(rotation); + + THEN("We should retrieve it") + { + REQUIRE(identity.GetRotation() == rotation); + } + } + + WHEN("We rotate it from roll 30") + { + Nz::Quaternionf rotation(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(30.f))); + identity.ApplyRotation(rotation); + + THEN("We should retrieve it") + { + REQUIRE(identity.GetRotation() == rotation); + } + } + + WHEN("We rotate it from a strange rotation") + { + Nz::Quaternionf rotation(Nz::EulerAnglesf(Nz::FromDegrees(10.f), Nz::FromDegrees(20.f), Nz::FromDegrees(30.f))); + identity.ApplyRotation(rotation); + + THEN("We should retrieve it") + { + REQUIRE(identity.GetRotation() == rotation); + } + } + + WHEN("We scale it") + { + Nz::Vector3f scale(1.f, 2.f, 3.f); + Nz::Vector3f squaredScale(scale.x * scale.x, scale.y * scale.y, scale.z * scale.z); + identity.ApplyScale(scale); + + THEN("We should retrieve it") + { + CHECK(identity.GetScale() == scale); + CHECK(identity.GetSquaredScale() == squaredScale); + } + + AND_THEN("With a rotation") + { + identity.ApplyRotation(Nz::EulerAnglesf(Nz::FromDegrees(10.f), Nz::FromDegrees(20.f), Nz::FromDegrees(30.f))); + Nz::Vector3f retrievedScale = identity.GetScale(); + CHECK(retrievedScale.x == Approx(scale.x)); + CHECK(retrievedScale.y == Approx(scale.y)); + CHECK(retrievedScale.z == Approx(scale.z)); + } + } + } + + GIVEN("A matrix with a negative determinant") + { + Nz::Matrix4f negativeDeterminant( -1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f); + + WHEN("We ask information about determinant") + { + THEN("We expect those to be true") + { + CHECK(negativeDeterminant.GetDeterminant() == Approx(-1.f)); + CHECK(!negativeDeterminant.HasScale()); + CHECK(negativeDeterminant.HasNegativeScale()); + } + } + } + + GIVEN("Some transformed matrices") + { + Nz::Vector3f simpleTranslation = Nz::Vector3f::Zero(); + Nz::Quaternionf simpleRotation = Nz::Quaternionf::Identity(); + Nz::Vector3f simpleScale = Nz::Vector3f::Unit(); + Nz::Matrix4f simple = Nz::Matrix4f::Transform(simpleTranslation, simpleRotation, simpleScale); + + Nz::Vector3f complexTranslation = Nz::Vector3f(-5.f, 7.f, 3.5f); + Nz::Quaternionf complexRotation = Nz::EulerAnglesf(Nz::FromDegrees(-22.5f), Nz::FromDegrees(30.f), Nz::FromDegrees(15.f)); + Nz::Vector3f complexScale = Nz::Vector3f(1.f, 2.f, 0.5f); + Nz::Matrix4f complex = Nz::Matrix4f::Transform(complexTranslation, complexRotation, complexScale); + + Nz::Vector3f oppositeTranslation = Nz::Vector3f(-5.f, 7.f, 3.5f); + Nz::Quaternionf oppositeRotation = Nz::EulerAnglesf(Nz::FromDegrees(-90.f), Nz::FromDegrees(0.f), Nz::FromDegrees(0.f)); + Nz::Vector3f oppositeScale = Nz::Vector3f(1.f, 2.f, 0.5f); + Nz::Matrix4f opposite = Nz::Matrix4f::Transform(oppositeTranslation, oppositeRotation, oppositeScale); + + WHEN("We retrieve the different components") + { + THEN("It should be the original ones") + { + CHECK(simple.GetTranslation() == simpleTranslation); + CHECK(simple.GetRotation() == simpleRotation); + CHECK(simple.GetScale() == simpleScale); + + /*CHECK(complex.GetTranslation() == complexTranslation); + CHECK(complex.GetRotation() == complexRotation); + CHECK(complex.GetScale() == complexScale); + + CHECK(opposite.GetTranslation() == oppositeTranslation); + CHECK(opposite.GetRotation() == oppositeRotation); + CHECK(opposite.GetScale() == oppositeScale);*/ + } + } + } + + GIVEN("Some defined matrix and its opposite") + { + Nz::Vector3f translation(-5.f, 3.f, 0.5); + Nz::Matrix4f initial = Nz::Matrix4f::Translate(translation); + Nz::Quaternionf rotation = Nz::EulerAnglesf(Nz::FromDegrees(30.f), Nz::FromDegrees(-90.f), 0.f); + initial.ApplyRotation(rotation); + + Nz::Matrix4f simple = Nz::Matrix4f::Transform(-translation, rotation.GetInverse(), Nz::Vector3f::Unit()); + + WHEN("We multiply them together") + { + Nz::Matrix4f result = Nz::Matrix4f::Concatenate(simple, initial); + + THEN("We should get the identity") + { + Nz::Matrix4f identity = Nz::Matrix4f::Identity(); + for (int i = 0; i != 4; ++i) + { + Nz::Vector4f row = result.GetRow(i); + Nz::Vector4f column = result.GetColumn(i); + for (int j = 0; j != 4; ++j) + { + CHECK(Nz::NumberEquals(row[j], identity(i, j), 0.00001f)); + CHECK(Nz::NumberEquals(column[j], identity(i, j), 0.00001f)); + } + } } } } diff --git a/tests/Engine/Math/Quaternion.cpp b/tests/Engine/Math/Quaternion.cpp index 7ebf6ede5..3cae63386 100644 --- a/tests/Engine/Math/Quaternion.cpp +++ b/tests/Engine/Math/Quaternion.cpp @@ -173,15 +173,73 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") WHEN("We get the rotation between two vectors") { - /*TODO - * Nz::Quaternionf rotationBetweenXY = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY()); - - THEN("The rotation in left-handed is 270 degree on z") + THEN("The rotation in right-handed is 90 degree on z") { - Nz::Quaternionf rotation270Z(Nz::FromDegrees(270.f), Nz::Vector3f::UnitZ()); + Nz::Quaternionf rotationBetweenXY = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY()); Nz::Quaternionf rotation90Z(Nz::FromDegrees(90.f), Nz::Vector3f::UnitZ()); REQUIRE(rotation90Z == rotationBetweenXY); - }*/ + } + + THEN("The rotation in right-handed is 90 degree on y") + { + Nz::Quaternionf rotationBetweenXZ = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitZ()); + Nz::Quaternionf rotation90Y(Nz::FromDegrees(-90.f), Nz::Vector3f::UnitY()); + REQUIRE(rotation90Y == rotationBetweenXZ); + } + + THEN("The rotation in right-handed is 90 degree on x") + { + Nz::Quaternionf rotationBetweenYZ = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitY(), Nz::Vector3f::UnitZ()); + Nz::Quaternionf rotation90X(Nz::FromDegrees(90.f), Nz::Vector3f::UnitX()); + REQUIRE(rotation90X == rotationBetweenYZ); + } + + THEN("The rotation in right-handed is 90 degree on y with non-unit vectors") + { + Nz::Vector3f origin(1.f, 0.f, 1.f); + Nz::Vector3f extremity(-1.f, 0.f, 1.f); + Nz::Quaternionf rotation = Nz::Quaternionf::RotationBetween(origin, extremity); + REQUIRE(rotation * origin == extremity); + } + } + } + + GIVEN("Different angles") + { + Nz::Quaternionf rotation90X(0.707f, 0.707f, 0.f, 0.f); + Nz::Quaternionf rotation90Y(0.707f, 0.f, 0.707f, 0.f); + Nz::Quaternionf rotation90Z(0.707f, 0.f, 0.f, 0.707f); + + Nz::Quaternionf rotation180X(0.f, 1.f, 0.f, 0.f); + Nz::Quaternionf rotation180Y(0.f, 0.f, 1.f, 0.f); + Nz::Quaternionf rotation180Z(0.f, 0.f, 0.f, 1.f); + + Nz::Quaternionf rotation270X(-0.707f, 0.707f, 0.f, 0.f); + Nz::Quaternionf rotation270Y(-0.707f, 0.f, 0.707f, 0.f); + Nz::Quaternionf rotation270Z(-0.707f, 0.f, 0.f, 0.707f); + + Nz::Quaternionf special(0.707f, 0.006f, 0.006f, 0.707f); + + WHEN("We convert them to euler angles") + { + THEN("Those are equal to") + { + CHECK(Nz::NumberEquals(rotation90X.ToEulerAngles().pitch, Nz::FromDegrees(90.f), 0.1f)); + CHECK(Nz::NumberEquals(rotation90Y.ToEulerAngles().yaw, Nz::FromDegrees(90.f), 0.1f)); + CHECK(Nz::NumberEquals(rotation90Z.ToEulerAngles().roll, Nz::FromDegrees(90.f), 0.1f)); + + CHECK(rotation180X == Nz::EulerAnglesf(180.f, 0.f, 0.f)); + CHECK(rotation180Y == Nz::EulerAnglesf(0.f, 180.f, 0.f)); + CHECK(rotation180Z == Nz::EulerAnglesf(0.f, 0.f, 180.f)); + + CHECK(Nz::NumberEquals(rotation270X.ToEulerAngles().pitch, Nz::FromDegrees(-90.f), 0.1f)); + CHECK(Nz::NumberEquals(rotation270Y.ToEulerAngles().yaw, Nz::FromDegrees(-90.f), 0.1f)); + CHECK(Nz::NumberEquals(rotation270Z.ToEulerAngles().roll, Nz::FromDegrees(-90.f), 0.1f)); + + CHECK(Nz::NumberEquals(special.ToEulerAngles().pitch, Nz::FromDegrees(0.f), 0.1f)); + CHECK(Nz::NumberEquals(special.ToEulerAngles().yaw, Nz::FromDegrees(1.f), 0.1f)); + CHECK(Nz::NumberEquals(special.ToEulerAngles().roll, Nz::FromDegrees(90.f), 0.1f)); + } } } } diff --git a/tests/Engine/Math/Rect.cpp b/tests/Engine/Math/Rect.cpp index b119d76c9..7fe9d30fb 100644 --- a/tests/Engine/Math/Rect.cpp +++ b/tests/Engine/Math/Rect.cpp @@ -12,9 +12,9 @@ SCENARIO("Rect", "[MATH][RECT]") { THEN("They should be") { - REQUIRE(firstCenterAndUnit == secondCenterAndUnit); - REQUIRE(firstCenterAndUnit.GetCenter() == secondCenterAndUnit.GetCenter()); - REQUIRE(firstCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom) == secondCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom)); + CHECK(firstCenterAndUnit == secondCenterAndUnit); + CHECK(firstCenterAndUnit.GetCenter() == secondCenterAndUnit.GetCenter()); + CHECK(firstCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom) == secondCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom)); CHECK(firstCenterAndUnit.IsValid()); } } @@ -43,16 +43,24 @@ SCENARIO("Rect", "[MATH][RECT]") { THEN("These results are expected") { - REQUIRE(firstCenterAndUnit.GetLengths() == Nz::Vector2f::Unit()); - REQUIRE(firstCenterAndUnit.GetMaximum() == Nz::Vector2f::Unit()); - REQUIRE(firstCenterAndUnit.GetMinimum() == Nz::Vector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetNegativeVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetPosition() == Nz::Vector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetPositiveVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit()); + CHECK(firstCenterAndUnit.GetLengths() == Nz::Vector2f::Unit()); + CHECK(firstCenterAndUnit.GetMaximum() == Nz::Vector2f::Unit()); + CHECK(firstCenterAndUnit.GetMinimum() == Nz::Vector2f::Zero()); + CHECK(firstCenterAndUnit.GetNegativeVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Zero()); + CHECK(firstCenterAndUnit.GetPosition() == Nz::Vector2f::Zero()); + CHECK(firstCenterAndUnit.GetPositiveVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit()); } } + WHEN("We ask for intersection") + { + Nz::Rectf intersection; + CHECK(firstCenterAndUnit.Intersect(secondCenterAndUnit, &intersection)); + CHECK(intersection == Nz::Rectf(1.f, 1.f)); + CHECK(intersection == Nz::Rectf(Nz::Vector2f(1.f, 1.f))); + } + WHEN("We try to lerp") { THEN("Compilation should be fine") diff --git a/tests/Engine/Math/Vector3.cpp b/tests/Engine/Math/Vector3.cpp index 84c6a01ae..2bcfbd361 100644 --- a/tests/Engine/Math/Vector3.cpp +++ b/tests/Engine/Math/Vector3.cpp @@ -1,6 +1,7 @@ #include #include +#include #include SCENARIO("Vector3", "[MATH][VECTOR3]") @@ -97,4 +98,24 @@ SCENARIO("Vector3", "[MATH][VECTOR3]") } } } + + GIVEN("Two vectors") + { + Nz::Vector2f unit = Nz::Vector2f::Unit(); + Nz::Vector3f smaller(-1.f, unit); + + float data[3] = { 1.f, unit.x, unit.y }; + Nz::Vector3f bigger(data); + + WHEN("We combine divisions and multiplications") + { + Nz::Vector3f result = smaller / bigger; + result *= bigger; + + THEN("We should get the identity") + { + REQUIRE(result == smaller); + } + } + } } diff --git a/tests/Engine/Physics2D/Collider2D.cpp b/tests/Engine/Physics2D/Collider2D.cpp new file mode 100644 index 000000000..dee2b85c8 --- /dev/null +++ b/tests/Engine/Physics2D/Collider2D.cpp @@ -0,0 +1,133 @@ +#include +#include + +SCENARIO("Collider2D", "[PHYSICS2D][COLLIDER2D]") +{ + GIVEN("No particular elements") + { + WHEN("We construct a box with Rect") + { + Nz::Rectf aabb(5.f, 3.f, 10.f, 6.f); + Nz::BoxCollider2D box(aabb); + + THEN("We expect those to be true") + { + CHECK(box.GetRect() == aabb); + CHECK(box.GetSize() == aabb.GetLengths()); + CHECK(box.GetType() == Nz::ColliderType2D_Box); + } + } + + WHEN("We construct a box with Vector2D") + { + Nz::Vector2f vec(5.f, 3.f); + Nz::Rectf aabb(-2.5f, -1.5f, 5.f, 3.f); + Nz::BoxCollider2D box(vec); + + THEN("We expect those to be true") + { + CHECK(box.GetRect() == aabb); + CHECK(box.GetSize() == vec); + CHECK(box.GetType() == Nz::ColliderType2D_Box); + } + } + + WHEN("We construct a circle") + { + Nz::Vector2f position(5.f, 3.f); + float radius = 7.f; + Nz::CircleCollider2D circle(radius, position); + + THEN("We expect those to be true") + { + CHECK(circle.GetRadius() == Approx(radius)); + CHECK(circle.GetType() == Nz::ColliderType2D_Circle); + } + } + + WHEN("We construct a compound") + { + Nz::Rectf aabb(0.f, 0.f, 1.f, 1.f); + Nz::BoxCollider2DRef box1 = Nz::BoxCollider2D::New(aabb); + aabb.Translate(Nz::Vector2f::Unit()); + Nz::BoxCollider2DRef box2 = Nz::BoxCollider2D::New(aabb); + + std::vector colliders; + colliders.push_back(box1); + colliders.push_back(box2); + Nz::CompoundCollider2D compound(colliders); + + THEN("We expect those to be true") + { + CHECK(compound.GetType() == Nz::ColliderType2D_Compound); + } + } + + WHEN("We construct a convex") + { + std::vector vertices; + vertices.push_back(Nz::Vector2f(0.f, 0.f)); + vertices.push_back(Nz::Vector2f(0.f, 1.f)); + vertices.push_back(Nz::Vector2f(1.f, 1.f)); + vertices.push_back(Nz::Vector2f(1.f, 0.f)); + + Nz::ConvexCollider2D convex(Nz::SparsePtr(vertices.data()), vertices.size()); + + THEN("We expect those to be true") + { + CHECK(convex.GetType() == Nz::ColliderType2D_Convex); + } + } + + WHEN("We construct a null") + { + Nz::NullCollider2D null; + + THEN("We expect those to be true") + { + CHECK(null.GetType() == Nz::ColliderType2D_Null); + } + } + + WHEN("We construct a segment") + { + Nz::Vector2f firstPoint(2.f, 1.f); + Nz::Vector2f secondPoint(-4.f, -3.f); + Nz::SegmentCollider2D segment(firstPoint, secondPoint); + + THEN("We expect those to be true") + { + CHECK(segment.GetFirstPoint() == firstPoint); + CHECK(segment.GetLength() == firstPoint.Distance(secondPoint)); + CHECK(segment.GetSecondPoint() == secondPoint); + CHECK(segment.GetType() == Nz::ColliderType2D_Segment); + } + } + + WHEN("We verify general purpose methods") + { + Nz::Rectf aabb(5.f, 3.f, 10.f, 6.f); + Nz::BoxCollider2D box(aabb); + + Nz::UInt32 categoryMask = 1; + Nz::UInt32 groupId = 2; + Nz::UInt32 typeId = 3; + Nz::UInt32 mask = 4; + bool trigger = true; + box.SetCategoryMask(categoryMask); + box.SetCollisionGroup(groupId); + box.SetCollisionId(typeId); + box.SetCollisionMask(mask); + box.SetTrigger(trigger); + + THEN("We expect those to be true") + { + CHECK(box.GetCategoryMask() == categoryMask); + CHECK(box.GetCollisionGroup() == groupId); + CHECK(box.GetCollisionId() == typeId); + CHECK(box.GetCollisionMask() == mask); + CHECK(box.IsTrigger() == trigger); + } + } + } +} diff --git a/tests/Engine/Physics2D/PhysWorld2D.cpp b/tests/Engine/Physics2D/PhysWorld2D.cpp new file mode 100644 index 000000000..3c19ba653 --- /dev/null +++ b/tests/Engine/Physics2D/PhysWorld2D.cpp @@ -0,0 +1,202 @@ +#include +#include + +Nz::RigidBody2D CreateBody(Nz::PhysWorld2D& world, const Nz::Vector2f& position, bool isMoving = true, const Nz::Vector2f& lengths = Nz::Vector2f::Unit()); + +Nz::UInt32 collisionGroup = 1; +Nz::UInt32 categoryMask = 2; +Nz::UInt32 collisionMask = 3; + +SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]") +{ + GIVEN("A physic world and a bunch of entities on a grid") + { + Nz::PhysWorld2D world; + + std::vector bodies; + const int numberOfBodiesPerLign = 3; + for (int i = 0; i != numberOfBodiesPerLign; ++i) + { + for (int j = 0; j != numberOfBodiesPerLign; ++j) + { + bodies.push_back(CreateBody(world, Nz::Vector2f(10.f * i, 10.f * j))); + } + } + + world.Step(1.f); + + WHEN("We ask for the nearest body") + { + Nz::PhysWorld2D::NearestQueryResult result; + REQUIRE(world.NearestBodyQuery(-Nz::Vector2f::UnitY() * 1.f, 2.f, collisionGroup, categoryMask, collisionMask, &result)); + + THEN("It should be the one on the origin") + { + CHECK(result.nearestBody == &bodies[0]); + CHECK(result.closestPoint == Nz::Vector2f::Zero()); + CHECK(result.fraction == -Nz::Vector2f::UnitY()); + CHECK(result.distance == Approx(1.f)); + } + + REQUIRE(world.NearestBodyQuery(Nz::Vector2f::UnitY() * 2.f, 2.f, collisionGroup, categoryMask, collisionMask, &result)); + + THEN("It should be the one on the origin") + { + CHECK(result.nearestBody == &bodies[0]); + CHECK(result.closestPoint == Nz::Vector2f::UnitY()); + CHECK(result.fraction == Nz::Vector2f::UnitY()); + CHECK(result.distance == Approx(1.f)); + } + } + + WHEN("We ask for the first ray collision") + { + Nz::Vector2f origin = -Nz::Vector2f::UnitY() * 2.f; + Nz::Vector2f end = (numberOfBodiesPerLign + 1) * 10.f * Nz::Vector2f::UnitY(); + Nz::PhysWorld2D::RaycastHit result; + REQUIRE(world.RaycastQueryFirst(origin, end, 1.f, collisionGroup, categoryMask, collisionMask, &result)); + + THEN("It should be the one on the origin") + { + CHECK(result.nearestBody == &bodies[0]); + CHECK(result.fraction == Approx(1.f / 42.f)); + CHECK(result.hitPos == Nz::Vector2f::Zero()); + CHECK(result.hitNormal == -Nz::Vector2f::UnitY()); + } + } + + WHEN("We ask for the ray collisions") + { + Nz::Vector2f origin = -Nz::Vector2f::UnitY() * 2.f; + Nz::Vector2f end = (numberOfBodiesPerLign + 1) * 10.f * Nz::Vector2f::UnitY(); + std::vector results; + REQUIRE(world.RaycastQuery(origin, end, 1.f, collisionGroup, categoryMask, collisionMask, &results)); + + THEN("It should be the first lign") + { + REQUIRE(results.size() == numberOfBodiesPerLign); + + for (int i = 0; i != numberOfBodiesPerLign; ++i) + { + const Nz::PhysWorld2D::RaycastHit& result = results[i]; + CHECK(result.nearestBody == &bodies[i]); + CHECK(result.fraction == Approx(i / 4.f).epsilon(0.1f)); + CHECK(result.hitPos == Nz::Vector2f(0.f, i * 10.f)); + CHECK(result.hitNormal == -Nz::Vector2f::UnitY()); + } + } + } + + WHEN("We ask for a region") + { + std::vector results; + world.RegionQuery(Nz::Rectf(-5.f, -5.f, 5.f, 5.f), collisionGroup, categoryMask, collisionMask, &results); + + THEN("It should be the one on the origin") + { + REQUIRE(results.size() == 1); + CHECK(results[0] == &bodies[0]); + } + } + } + + GIVEN("Three entities, a character, a wall and a trigger zone") + { + unsigned int CHARACTER_COLLISION_ID = 1; + unsigned int WALL_COLLISION_ID = 2; + unsigned int TRIGGER_COLLISION_ID = 3; + + Nz::PhysWorld2D world; + + Nz::Rectf characterAABB(0.f, 0.f, 1.f, 1.f); + Nz::Collider2DRef characterBox = Nz::BoxCollider2D::New(characterAABB); + characterBox->SetCollisionId(CHARACTER_COLLISION_ID); + Nz::RigidBody2D character(&world, 1.f, characterBox); + character.SetPosition(Nz::Vector2f::Zero()); + + Nz::Rectf wallAABB(0.f, 0.f, 1.f, 2.f); + Nz::Collider2DRef wallBox = Nz::BoxCollider2D::New(wallAABB); + wallBox->SetCollisionId(WALL_COLLISION_ID); + Nz::RigidBody2D wall(&world, 0.f, wallBox); + wall.SetPosition(Nz::Vector2f(5.f, 0.f)); + + Nz::Rectf triggerAABB(0.f, 0.f, 1.f, 1.f); + Nz::Collider2DRef triggerBox = Nz::BoxCollider2D::New(triggerAABB); + triggerBox->SetTrigger(true); + triggerBox->SetCollisionId(TRIGGER_COLLISION_ID); + Nz::RigidBody2D trigger(&world, 0.f, triggerBox); + trigger.SetPosition(Nz::Vector2f(2.f, 0.f)); + + world.Step(0.f); + + int statusTriggerCollision = 0; + Nz::PhysWorld2D::Callback characterTriggerCallback; + characterTriggerCallback.startCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool { + statusTriggerCollision = statusTriggerCollision | 1 << 0; + return true; + }; + characterTriggerCallback.preSolveCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool { + statusTriggerCollision = statusTriggerCollision | 1 << 1; + return true; + }; + characterTriggerCallback.postSolveCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) { + statusTriggerCollision = statusTriggerCollision | 1 << 2; + }; + characterTriggerCallback.endCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) { + statusTriggerCollision = statusTriggerCollision | 1 << 3; + }; + world.RegisterCallbacks(CHARACTER_COLLISION_ID, TRIGGER_COLLISION_ID, characterTriggerCallback); + + int statusWallCollision = 0; + Nz::PhysWorld2D::Callback characterWallCallback; + characterWallCallback.startCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool { + statusWallCollision = statusWallCollision | 1 << 0; + return true; + }; + characterWallCallback.endCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) { + statusWallCollision = statusWallCollision | 1 << 1; + }; + world.RegisterCallbacks(CHARACTER_COLLISION_ID, WALL_COLLISION_ID, characterWallCallback); + + WHEN("We make our character go towards the wall") + { + character.SetVelocity(Nz::Vector2f(1.f, 0.f)); + for (int i = 0; i != 11; ++i) + world.Step(0.1f); + + THEN("It should trigger several collisions") + { + CHECK(statusTriggerCollision == 3); + for (int i = 0; i != 20; ++i) + world.Step(0.1f); + CHECK(statusTriggerCollision == 11); + + CHECK(character.GetPosition().x == Approx(3.1f).epsilon(0.01f)); + + for (int i = 0; i != 9; ++i) + world.Step(0.1f); + CHECK(character.GetPosition().x == Approx(4.f).epsilon(0.01f)); + world.Step(0.1f); + CHECK(character.GetPosition().x == Approx(4.f).epsilon(0.01f)); + CHECK(statusWallCollision == 1); // It should be close to the wall + + character.SetVelocity(Nz::Vector2f(-2.f, 0.f)); + for (int i = 0; i != 10; ++i) + world.Step(0.1f); + CHECK(statusWallCollision == 3); + } + } + } +} + +Nz::RigidBody2D CreateBody(Nz::PhysWorld2D& world, const Nz::Vector2f& position, bool isMoving, const Nz::Vector2f& lengths) +{ + Nz::Rectf aabb(0.f, 0.f, lengths.x, lengths.y); + Nz::Collider2DRef box = Nz::BoxCollider2D::New(aabb); + box->SetCategoryMask(categoryMask); + box->SetCollisionMask(collisionMask); + float mass = isMoving ? 1.f : 0.f; + Nz::RigidBody2D rigidBody(&world, mass, box); + rigidBody.SetPosition(position); + return rigidBody; +} diff --git a/tests/Engine/Physics2D/RigidBody2D.cpp b/tests/Engine/Physics2D/RigidBody2D.cpp new file mode 100644 index 000000000..98a7fc35a --- /dev/null +++ b/tests/Engine/Physics2D/RigidBody2D.cpp @@ -0,0 +1,318 @@ +#include +#include +#include + +Nz::RigidBody2D CreateBody(Nz::PhysWorld2D& world); +void EQUALITY(const Nz::RigidBody2D& left, const Nz::RigidBody2D& right); + +SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]") +{ + GIVEN("A physic world and a rigid body") + { + Nz::PhysWorld2D world; + + Nz::Vector2f positionAABB(3.f, 4.f); + Nz::Rectf aabb(positionAABB.x, positionAABB.y, 1.f, 2.f); + Nz::Collider2DRef box = Nz::BoxCollider2D::New(aabb); + float mass = 1.f; + Nz::RigidBody2D body(&world, mass, box); + float angularVelocity = 0.2f; + body.SetAngularVelocity(angularVelocity); + Nz::Vector2f massCenter(5.f, 7.f); + body.SetMassCenter(massCenter); + Nz::Vector2f position(9.f, 1.f); + body.SetPosition(position); + float rotation = 0.1f; + body.SetRotation(rotation); + Nz::Vector2f velocity(-4.f, -2.f); + body.SetVelocity(velocity); + bool userdata = false; + body.SetUserdata(&userdata); + + world.Step(1.f); + + WHEN("We copy construct the body") + { + body.AddForce(Nz::Vector2f(3.f, 5.f)); + Nz::RigidBody2D copiedBody(body); + EQUALITY(copiedBody, body); + world.Step(1.f); + EQUALITY(copiedBody, body); + } + + WHEN("We move construct the body") + { + Nz::RigidBody2D copiedBody(body); + Nz::RigidBody2D movedBody(std::move(body)); + EQUALITY(movedBody, copiedBody); + } + + WHEN("We copy assign the body") + { + Nz::RigidBody2D copiedBody(&world, 0.f); + copiedBody = body; + EQUALITY(copiedBody, body); + } + + WHEN("We move assign the body") + { + Nz::RigidBody2D copiedBody(body); + Nz::RigidBody2D movedBody(&world, 0.f); + movedBody = std::move(body); + EQUALITY(movedBody, copiedBody); + } + + WHEN("We set a new geometry") + { + float radius = 5.f; + Nz::Vector2f positionCircle(0.f, 0.f); + Nz::Collider2DRef circle = Nz::CircleCollider2D::New(radius, position); + body.SetGeom(circle); + + world.Step(1.f); + + THEN("The aabb should be updated") + { + Nz::Rectf circleAABB(position.x - radius, position.y - radius, 2.f * radius, 2.f* radius); + REQUIRE(body.GetAABB() == circleAABB); + } + } + } + + GIVEN("A physic world") + { + Nz::PhysWorld2D world; + Nz::Rectf aabb(3.f, 4.f, 1.f, 2.f); + + WHEN("We get a rigid body from a function") + { + std::vector tmp; + tmp.push_back(CreateBody(world)); + tmp.push_back(CreateBody(world)); + world.Step(1.f); + + THEN("They should be valid") + { + CHECK(tmp[0].GetAABB() == aabb); + CHECK(tmp[1].GetAABB() == aabb); + } + } + } + + GIVEN("A physic world and a rigid body") + { + Nz::PhysWorld2D world; + Nz::Vector2f positionAABB(3.f, 4.f); + Nz::Rectf aabb(positionAABB.x, positionAABB.y, 1.f, 2.f); + Nz::Collider2DRef box = Nz::BoxCollider2D::New(aabb); + float mass = 1.f; + Nz::RigidBody2D body(&world, mass, box); + bool userData = false; + body.SetUserdata(&userData); + + Nz::Vector2f position = Nz::Vector2f::Zero(); + + world.Step(1.f); + + WHEN("We retrieve standard information") + { + THEN("We expect those to be true") + { + CHECK(body.GetAABB() == aabb); + CHECK(body.GetAngularVelocity() == Approx(0.f)); + CHECK(body.GetCenterOfGravity() == Nz::Vector2f::Zero()); + CHECK(body.GetGeom() == box); + CHECK(body.GetMass() == Approx(mass)); + CHECK(body.GetPosition() == position); + CHECK(body.GetRotation() == Approx(0.f)); + CHECK(body.GetUserdata() == &userData); + CHECK(body.GetVelocity() == Nz::Vector2f::Zero()); + + CHECK(body.IsKinematic() == false); + CHECK(body.IsSleeping() == false); + } + } + + WHEN("We set a velocity") + { + Nz::Vector2f velocity(Nz::Vector2f::Unit()); + body.SetVelocity(velocity); + position += velocity; + world.Step(1.f); + + THEN("We expect those to be true") + { + aabb.Translate(velocity); + CHECK(body.GetAABB() == aabb); + CHECK(body.GetCenterOfGravity() == Nz::Vector2f::Zero()); + CHECK(body.GetPosition() == position); + CHECK(body.GetVelocity() == velocity); + } + + AND_THEN("We apply an impulse in the opposite direction") + { + body.AddImpulse(-velocity); + world.Step(1.f); + + REQUIRE(body.GetVelocity() == Nz::Vector2f::Zero()); + } + } + + WHEN("We set an angular velocity") + { + float angularSpeed = Nz::FromDegrees(90.f); + body.SetAngularVelocity(angularSpeed); + world.Step(1.f); + + THEN("We expect those to be true") + { + CHECK(body.GetAngularVelocity() == Approx(angularSpeed)); + CHECK(body.GetRotation() == Approx(angularSpeed)); + CHECK(body.GetAABB() == Nz::Rectf(-6.f, 3.f, 2.f, 1.f)); + + world.Step(1.f); + CHECK(body.GetRotation() == Approx(2.f * angularSpeed)); + CHECK(body.GetAABB() == Nz::Rectf(-4.f, -6.f, 1.f, 2.f)); + + world.Step(1.f); + CHECK(body.GetRotation() == Approx(3.f * angularSpeed)); + CHECK(body.GetAABB() == Nz::Rectf(4.f, -4.f, 2.f, 1.f)); + + world.Step(1.f); + CHECK(body.GetRotation() == Approx(4.f * angularSpeed)); + } + } + + WHEN("We apply a torque") + { + float angularSpeed = Nz::DegreeToRadian(90.f); + body.AddTorque(angularSpeed); + world.Step(1.f); + + THEN("It is also counter-clockwise") + { + CHECK(body.GetAngularVelocity() >= 0.f); + CHECK(body.GetRotation() >= 0.f); + } + } + } + + GIVEN("A physic world and a rigid body of circle") + { + Nz::PhysWorld2D world; + + Nz::Vector2f position(3.f, 4.f); + float radius = 5.f; + Nz::Collider2DRef circle = Nz::CircleCollider2D::New(radius, position); + float mass = 1.f; + Nz::RigidBody2D body(&world, mass, circle); + world.Step(1.f); + + WHEN("We ask for the aabb of the circle") + { + THEN("We expect this to be true") + { + Nz::Rectf circleAABB(position.x - radius, position.y - radius, 2.f * radius, 2.f* radius); + REQUIRE(body.GetAABB() == circleAABB); + } + } + } + + GIVEN("A physic world and a rigid body of compound") + { + Nz::PhysWorld2D world; + + Nz::Rectf aabb(0.f, 0.f, 1.f, 1.f); + Nz::BoxCollider2DRef box1 = Nz::BoxCollider2D::New(aabb); + aabb.Translate(Nz::Vector2f::Unit()); + Nz::BoxCollider2DRef box2 = Nz::BoxCollider2D::New(aabb); + + std::vector colliders; + colliders.push_back(box1); + colliders.push_back(box2); + Nz::CompoundCollider2DRef compound = Nz::CompoundCollider2D::New(colliders); + + float mass = 1.f; + Nz::RigidBody2D body(&world, mass, compound); + world.Step(1.f); + + WHEN("We ask for the aabb of the compound") + { + THEN("We expect this to be true") + { + Nz::Rectf compoundAABB(0.f, 0.f, 2.f, 2.f); + REQUIRE(body.GetAABB() == compoundAABB); + } + } + } + + GIVEN("A physic world and a rigid body of circle") + { + Nz::PhysWorld2D world; + + std::vector vertices; + vertices.push_back(Nz::Vector2f(0.f, 0.f)); + vertices.push_back(Nz::Vector2f(0.f, 1.f)); + vertices.push_back(Nz::Vector2f(1.f, 1.f)); + vertices.push_back(Nz::Vector2f(1.f, 0.f)); + + Nz::SparsePtr sparsePtr(vertices.data()); + Nz::ConvexCollider2DRef convex = Nz::ConvexCollider2D::New(sparsePtr, vertices.size()); + float mass = 1.f; + Nz::RigidBody2D body(&world, mass, convex); + world.Step(1.f); + + WHEN("We ask for the aabb of the convex") + { + THEN("We expect this to be true") + { + Nz::Rectf convexAABB(0.f, 0.f, 1.f, 1.f); + REQUIRE(body.GetAABB() == convexAABB); + } + } + } + + GIVEN("A physic world and a rigid body of segment") + { + Nz::PhysWorld2D world; + + Nz::Vector2f positionA(3.f, 4.f); + Nz::Vector2f positionB(1.f, -4.f); + Nz::Collider2DRef segment = Nz::SegmentCollider2D::New(positionA, positionB, 0.f); + float mass = 1.f; + Nz::RigidBody2D body(&world, mass, segment); + world.Step(1.f); + + WHEN("We ask for the aabb of the segment") + { + THEN("We expect this to be true") + { + Nz::Rectf segmentAABB(positionA, positionB); + REQUIRE(body.GetAABB() == segmentAABB); + } + } + } +} + +Nz::RigidBody2D CreateBody(Nz::PhysWorld2D& world) +{ + Nz::Vector2f positionAABB(3.f, 4.f); + Nz::Rectf aabb(positionAABB.x, positionAABB.y, 1.f, 2.f); + Nz::Collider2DRef box = Nz::BoxCollider2D::New(aabb); + float mass = 1.f; + return Nz::RigidBody2D(&world, mass, box); +} + +void EQUALITY(const Nz::RigidBody2D& left, const Nz::RigidBody2D& right) +{ + CHECK(left.GetAABB() == right.GetAABB()); + CHECK(left.GetAngularVelocity() == right.GetAngularVelocity()); + CHECK(left.GetCenterOfGravity() == right.GetCenterOfGravity()); + CHECK(left.GetGeom() == right.GetGeom()); + CHECK(left.GetHandle() != right.GetHandle()); + CHECK(left.GetMass() == right.GetMass()); + CHECK(left.GetPosition() == right.GetPosition()); + CHECK(left.GetRotation() == right.GetRotation()); + CHECK(left.GetUserdata() == right.GetUserdata()); + CHECK(left.GetVelocity() == right.GetVelocity()); +} diff --git a/tests/Engine/Utility/EventHandler.cpp b/tests/Engine/Platform/EventHandler.cpp similarity index 97% rename from tests/Engine/Utility/EventHandler.cpp rename to tests/Engine/Platform/EventHandler.cpp index dedf3fc31..b143b949a 100644 --- a/tests/Engine/Utility/EventHandler.cpp +++ b/tests/Engine/Platform/EventHandler.cpp @@ -25,7 +25,7 @@ Ndk::EntityHandle AddCamera(Ndk::World& world, Nz::RenderWindow& window); - Text entered is never repeated */ -SCENARIO("EventHandler", "[UTILITY][EVENTHANDLER][INTERACTIVE][.]") +SCENARIO("EventHandler", "[PLATFORM][EVENTHANDLER][INTERACTIVE][.]") { GIVEN("An application") { diff --git a/tests/Engine/Platform/EventHandler/BaseState.cpp b/tests/Engine/Platform/EventHandler/BaseState.cpp new file mode 100644 index 000000000..8cb229445 --- /dev/null +++ b/tests/Engine/Platform/EventHandler/BaseState.cpp @@ -0,0 +1,39 @@ +#include "BaseState.hpp" + +#include "StateContext.hpp" +#include "StateFactory.hpp" + +#include +#include + +BaseState::BaseState(StateContext& context) : +State(), +m_context(context), +m_text(context) +{ +} + +BaseState::~BaseState() +{ +} + +void BaseState::Enter(Ndk::StateMachine& /*fsm*/) +{ + m_text.SetVisible(true); + DrawMenu(); +} + +void BaseState::Leave(Ndk::StateMachine& /*fsm*/) +{ + m_text.SetVisible(false); +} + +bool BaseState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) +{ + return true; +} + +void BaseState::DrawMenu() +{ + m_text.SetContent("This shouldn't be visible\nM for Menu"); +} \ No newline at end of file diff --git a/tests/Engine/Platform/EventHandler/BaseState.hpp b/tests/Engine/Platform/EventHandler/BaseState.hpp new file mode 100644 index 000000000..2356e39cd --- /dev/null +++ b/tests/Engine/Platform/EventHandler/BaseState.hpp @@ -0,0 +1,31 @@ +#ifndef BASESTATE_HPP +#define BASESTATE_HPP + +#include "Text.hpp" + +#include + +#include + +class StateContext; + +class BaseState : public Ndk::State +{ + public: + BaseState(StateContext& stateContext); + virtual ~BaseState(); + + virtual void Enter(Ndk::StateMachine& fsm) override; + + virtual void Leave(Ndk::StateMachine& fsm) override; + + virtual bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; + + protected: + virtual void DrawMenu(); + + StateContext& m_context; + Text m_text; +}; + +#endif // BASESTATE_HPP \ No newline at end of file diff --git a/tests/Engine/Utility/EventHandler/EventState.cpp b/tests/Engine/Platform/EventHandler/EventState.cpp similarity index 90% rename from tests/Engine/Utility/EventHandler/EventState.cpp rename to tests/Engine/Platform/EventHandler/EventState.cpp index 9fa5ea244..1d6a6784a 100644 --- a/tests/Engine/Utility/EventHandler/EventState.cpp +++ b/tests/Engine/Platform/EventHandler/EventState.cpp @@ -7,17 +7,14 @@ #include EventState::EventState(StateContext& context) : -State(), -m_context(context), -m_text(context), +BaseState(context), m_count(0) { } void EventState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -35,16 +32,6 @@ void EventState::Enter(Ndk::StateMachine& fsm) }); } -void EventState::Leave(Ndk::StateMachine& /*fsm*/) -{ - m_text.SetVisible(false); -} - -bool EventState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) -{ - return true; -} - void EventState::AddEvent(const Nz::WindowEvent& event) { if (m_events.size() > 9) diff --git a/tests/Engine/Utility/EventHandler/EventState.hpp b/tests/Engine/Platform/EventHandler/EventState.hpp similarity index 59% rename from tests/Engine/Utility/EventHandler/EventState.hpp rename to tests/Engine/Platform/EventHandler/EventState.hpp index 7b1cc63d7..d22ebd4c4 100644 --- a/tests/Engine/Utility/EventHandler/EventState.hpp +++ b/tests/Engine/Platform/EventHandler/EventState.hpp @@ -1,32 +1,26 @@ #ifndef __EVENTSTATE_HPP__ #define __EVENTSTATE_HPP__ -#include "Text.hpp" - -#include - -#include +#include "BaseState.hpp" #include class StateContext; -class EventState : public Ndk::State +class EventState : public BaseState { public: EventState(StateContext& stateContext); void Enter(Ndk::StateMachine& fsm) override; - void Leave(Ndk::StateMachine& fsm) override; - bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; private: void AddEvent(const Nz::WindowEvent& event); - void DrawMenu(); + + void DrawMenu() override; + Nz::String ToString(const Nz::WindowEvent& event) const; - StateContext& m_context; - Text m_text; std::deque m_events; int m_count; NazaraSlot(Nz::EventHandler, OnEvent, m_eventSlot); diff --git a/tests/Engine/Utility/EventHandler/FocusState.cpp b/tests/Engine/Platform/EventHandler/FocusState.cpp similarity index 78% rename from tests/Engine/Utility/EventHandler/FocusState.cpp rename to tests/Engine/Platform/EventHandler/FocusState.cpp index bc9c77ab5..ee5fd5f7e 100644 --- a/tests/Engine/Utility/EventHandler/FocusState.cpp +++ b/tests/Engine/Platform/EventHandler/FocusState.cpp @@ -7,16 +7,13 @@ #include FocusState::FocusState(StateContext& context) : -State(), -m_context(context), -m_text(context) +BaseState(context) { } void FocusState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -38,16 +35,6 @@ void FocusState::Enter(Ndk::StateMachine& fsm) }); } -void FocusState::Leave(Ndk::StateMachine& /*fsm*/) -{ - m_text.SetVisible(false); -} - -bool FocusState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) -{ - return true; -} - void FocusState::DrawMenu() { m_text.SetContent("Click outside the windows, this text should change !\nM for Menu"); diff --git a/tests/Engine/Utility/EventHandler/FocusState.hpp b/tests/Engine/Platform/EventHandler/FocusState.hpp similarity index 53% rename from tests/Engine/Utility/EventHandler/FocusState.hpp rename to tests/Engine/Platform/EventHandler/FocusState.hpp index 9287722ab..359dceaa1 100644 --- a/tests/Engine/Utility/EventHandler/FocusState.hpp +++ b/tests/Engine/Platform/EventHandler/FocusState.hpp @@ -1,28 +1,20 @@ #ifndef __FOCUSSTATE_HPP__ #define __FOCUSSTATE_HPP__ -#include "Text.hpp" - -#include - -#include +#include "BaseState.hpp" class StateContext; -class FocusState : public Ndk::State +class FocusState : public BaseState { public: FocusState(StateContext& stateContext); void Enter(Ndk::StateMachine& fsm) override; - void Leave(Ndk::StateMachine& fsm) override; - bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; private: - void DrawMenu(); + void DrawMenu() override; - StateContext& m_context; - Text m_text; NazaraSlot(Nz::EventHandler, OnGainedFocus, m_gainedFocusSlot); NazaraSlot(Nz::EventHandler, OnLostFocus, m_lostFocusSlot); NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); diff --git a/tests/Engine/Utility/EventHandler/KeyState.cpp b/tests/Engine/Platform/EventHandler/KeyState.cpp similarity index 87% rename from tests/Engine/Utility/EventHandler/KeyState.cpp rename to tests/Engine/Platform/EventHandler/KeyState.cpp index 6244e8ed6..40bd785f1 100644 --- a/tests/Engine/Utility/EventHandler/KeyState.cpp +++ b/tests/Engine/Platform/EventHandler/KeyState.cpp @@ -7,17 +7,14 @@ #include KeyState::KeyState(StateContext& context) : -State(), -m_context(context), -m_text(context), +BaseState(context), m_keyStatus(KeyStatus::Pressed) { } void KeyState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -31,16 +28,6 @@ void KeyState::Enter(Ndk::StateMachine& fsm) }); } -void KeyState::Leave(Ndk::StateMachine& /*fsm*/) -{ - m_text.SetVisible(false); -} - -bool KeyState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) -{ - return true; -} - void KeyState::DrawMenu() { m_text.SetContent("Clic on a key, this text should change !\nN for alternating event\nM for Menu"); diff --git a/tests/Engine/Utility/EventHandler/KeyState.hpp b/tests/Engine/Platform/EventHandler/KeyState.hpp similarity index 60% rename from tests/Engine/Utility/EventHandler/KeyState.hpp rename to tests/Engine/Platform/EventHandler/KeyState.hpp index 9b0fb1fcd..8e16c85f2 100644 --- a/tests/Engine/Utility/EventHandler/KeyState.hpp +++ b/tests/Engine/Platform/EventHandler/KeyState.hpp @@ -1,11 +1,7 @@ #ifndef __KEYSTATE_HPP__ #define __KEYSTATE_HPP__ -#include "Text.hpp" - -#include - -#include +#include "BaseState.hpp" class StateContext; @@ -15,21 +11,18 @@ enum class KeyStatus Released }; -class KeyState : public Ndk::State +class KeyState : public BaseState { public: KeyState(StateContext& stateContext); void Enter(Ndk::StateMachine& fsm) override; - void Leave(Ndk::StateMachine& fsm) override; - bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; private: - void DrawMenu(); + void DrawMenu() override; + void ManageInput(KeyStatus isKeyPressed, const Nz::WindowEvent::KeyEvent& key, Ndk::StateMachine& fsm); - StateContext& m_context; - Text m_text; KeyStatus m_keyStatus; NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); NazaraSlot(Nz::EventHandler, OnKeyReleased, m_keyReleasedSlot); diff --git a/tests/Engine/Utility/EventHandler/MenuState.cpp b/tests/Engine/Platform/EventHandler/MenuState.cpp similarity index 82% rename from tests/Engine/Utility/EventHandler/MenuState.cpp rename to tests/Engine/Platform/EventHandler/MenuState.cpp index b659f51b2..d1a244369 100644 --- a/tests/Engine/Utility/EventHandler/MenuState.cpp +++ b/tests/Engine/Platform/EventHandler/MenuState.cpp @@ -7,17 +7,14 @@ #include MenuState::MenuState(StateContext& context) : -State(), -m_context(context), -m_text(context), +BaseState(context), m_selectedNextState(-1) { } -void MenuState::Enter(Ndk::StateMachine& /*fsm*/) +void MenuState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [this] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -29,9 +26,9 @@ void MenuState::Enter(Ndk::StateMachine& /*fsm*/) }); } -void MenuState::Leave(Ndk::StateMachine& /*fsm*/) +void MenuState::Leave(Ndk::StateMachine& fsm) { - m_text.SetVisible(false); + BaseState::Leave(fsm); m_selectedNextState = -1; } diff --git a/tests/Engine/Utility/EventHandler/MenuState.hpp b/tests/Engine/Platform/EventHandler/MenuState.hpp similarity index 69% rename from tests/Engine/Utility/EventHandler/MenuState.hpp rename to tests/Engine/Platform/EventHandler/MenuState.hpp index 356a12a72..56c7d594c 100644 --- a/tests/Engine/Utility/EventHandler/MenuState.hpp +++ b/tests/Engine/Platform/EventHandler/MenuState.hpp @@ -1,28 +1,24 @@ #ifndef __MENUSTATE_HPP__ #define __MENUSTATE_HPP__ -#include "Text.hpp" - -#include - -#include +#include "BaseState.hpp" class StateContext; -class MenuState : public Ndk::State +class MenuState : public BaseState { public: MenuState(StateContext& stateContext); void Enter(Ndk::StateMachine& fsm) override; + void Leave(Ndk::StateMachine& fsm) override; + bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; private: - void DrawMenu(); + void DrawMenu() override; - StateContext& m_context; - Text m_text; NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); int m_selectedNextState; }; diff --git a/tests/Engine/Utility/EventHandler/MouseClickState.cpp b/tests/Engine/Platform/EventHandler/MouseClickState.cpp similarity index 88% rename from tests/Engine/Utility/EventHandler/MouseClickState.cpp rename to tests/Engine/Platform/EventHandler/MouseClickState.cpp index bc2627195..74cb8ef79 100644 --- a/tests/Engine/Utility/EventHandler/MouseClickState.cpp +++ b/tests/Engine/Platform/EventHandler/MouseClickState.cpp @@ -7,16 +7,13 @@ #include MouseClickState::MouseClickState(StateContext& context) : -State(), -m_context(context), -m_text(context) +BaseState(context) { } void MouseClickState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -43,16 +40,6 @@ void MouseClickState::Enter(Ndk::StateMachine& fsm) }); } -void MouseClickState::Leave(Ndk::StateMachine& /*fsm*/) -{ - m_text.SetVisible(false); -} - -bool MouseClickState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) -{ - return true; -} - void MouseClickState::DrawMenu() { m_text.SetContent("Click in the windows, this text should change !\nM for Menu"); diff --git a/tests/Engine/Utility/EventHandler/MouseClickState.hpp b/tests/Engine/Platform/EventHandler/MouseClickState.hpp similarity index 67% rename from tests/Engine/Utility/EventHandler/MouseClickState.hpp rename to tests/Engine/Platform/EventHandler/MouseClickState.hpp index 28c4203a9..9a0e38077 100644 --- a/tests/Engine/Utility/EventHandler/MouseClickState.hpp +++ b/tests/Engine/Platform/EventHandler/MouseClickState.hpp @@ -1,11 +1,7 @@ #ifndef __MOUSECLICKSTATE_HPP__ #define __MOUSECLICKSTATE_HPP__ -#include "Text.hpp" - -#include - -#include +#include "BaseState.hpp" class StateContext; @@ -16,21 +12,18 @@ enum class MouseStatus Released }; -class MouseClickState : public Ndk::State +class MouseClickState : public BaseState { public: MouseClickState(StateContext& stateContext); void Enter(Ndk::StateMachine& fsm) override; - void Leave(Ndk::StateMachine& fsm) override; - bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; private: - void DrawMenu(); + void DrawMenu() override; + void ManageInput(MouseStatus mouseStatus, const Nz::WindowEvent::MouseButtonEvent& mouse, Ndk::StateMachine& fsm); - StateContext& m_context; - Text m_text; NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); NazaraSlot(Nz::EventHandler, OnMouseButtonDoubleClicked, m_mouseButtonDoubleClickedSlot); NazaraSlot(Nz::EventHandler, OnMouseButtonPressed, m_mouseButtonPressedSlot); diff --git a/tests/Engine/Utility/EventHandler/MouseEnterState.cpp b/tests/Engine/Platform/EventHandler/MouseEnterState.cpp similarity index 78% rename from tests/Engine/Utility/EventHandler/MouseEnterState.cpp rename to tests/Engine/Platform/EventHandler/MouseEnterState.cpp index 2a13f1c1e..1eb2ca9e2 100644 --- a/tests/Engine/Utility/EventHandler/MouseEnterState.cpp +++ b/tests/Engine/Platform/EventHandler/MouseEnterState.cpp @@ -7,16 +7,13 @@ #include MouseEnterState::MouseEnterState(StateContext& context) : -State(), -m_context(context), -m_text(context) +BaseState(context) { } void MouseEnterState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -38,16 +35,6 @@ void MouseEnterState::Enter(Ndk::StateMachine& fsm) }); } -void MouseEnterState::Leave(Ndk::StateMachine& /*fsm*/) -{ - m_text.SetVisible(false); -} - -bool MouseEnterState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) -{ - return true; -} - void MouseEnterState::DrawMenu() { m_text.SetContent("Move your mouse outside the windows, this text should change !\nM for Menu"); diff --git a/tests/Engine/Utility/EventHandler/MouseEnterState.hpp b/tests/Engine/Platform/EventHandler/MouseEnterState.hpp similarity index 54% rename from tests/Engine/Utility/EventHandler/MouseEnterState.hpp rename to tests/Engine/Platform/EventHandler/MouseEnterState.hpp index b5c7a72be..2328149ea 100644 --- a/tests/Engine/Utility/EventHandler/MouseEnterState.hpp +++ b/tests/Engine/Platform/EventHandler/MouseEnterState.hpp @@ -1,28 +1,20 @@ #ifndef __MOUSEENTERSTATE_HPP__ #define __MOUSEENTERSTATE_HPP__ -#include "Text.hpp" - -#include - -#include +#include "BaseState.hpp" class StateContext; -class MouseEnterState : public Ndk::State +class MouseEnterState : public BaseState { public: MouseEnterState(StateContext& stateContext); void Enter(Ndk::StateMachine& fsm) override; - void Leave(Ndk::StateMachine& fsm) override; - bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; private: - void DrawMenu(); + void DrawMenu() override; - StateContext& m_context; - Text m_text; NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); NazaraSlot(Nz::EventHandler, OnMouseEntered, m_mouseEnteredSlot); NazaraSlot(Nz::EventHandler, OnMouseLeft, m_mouseLeftSlot); diff --git a/tests/Engine/Utility/EventHandler/MouseMoveState.cpp b/tests/Engine/Platform/EventHandler/MouseMoveState.cpp similarity index 82% rename from tests/Engine/Utility/EventHandler/MouseMoveState.cpp rename to tests/Engine/Platform/EventHandler/MouseMoveState.cpp index 6a2cbd947..f0fcb3659 100644 --- a/tests/Engine/Utility/EventHandler/MouseMoveState.cpp +++ b/tests/Engine/Platform/EventHandler/MouseMoveState.cpp @@ -7,16 +7,13 @@ #include MouseMoveState::MouseMoveState(StateContext& context) : -State(), -m_context(context), -m_text(context) +BaseState(context) { } void MouseMoveState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -38,16 +35,6 @@ void MouseMoveState::Enter(Ndk::StateMachine& fsm) }); } -void MouseMoveState::Leave(Ndk::StateMachine& /*fsm*/) -{ - m_text.SetVisible(false); -} - -bool MouseMoveState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) -{ - return true; -} - void MouseMoveState::DrawMenu() { m_text.SetContent("Move your mouse or your wheel, this text should change !\nM for Menu"); diff --git a/tests/Engine/Utility/EventHandler/MouseMoveState.hpp b/tests/Engine/Platform/EventHandler/MouseMoveState.hpp similarity index 54% rename from tests/Engine/Utility/EventHandler/MouseMoveState.hpp rename to tests/Engine/Platform/EventHandler/MouseMoveState.hpp index f94dc0998..9aade79f8 100644 --- a/tests/Engine/Utility/EventHandler/MouseMoveState.hpp +++ b/tests/Engine/Platform/EventHandler/MouseMoveState.hpp @@ -1,28 +1,20 @@ #ifndef __MOUSEMOVESTATE_HPP__ #define __MOUSEMOVESTATE_HPP__ -#include "Text.hpp" - -#include - -#include +#include "BaseState.hpp" class StateContext; -class MouseMoveState : public Ndk::State +class MouseMoveState : public BaseState { public: MouseMoveState(StateContext& stateContext); void Enter(Ndk::StateMachine& fsm) override; - void Leave(Ndk::StateMachine& fsm) override; - bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; private: - void DrawMenu(); + void DrawMenu() override; - StateContext& m_context; - Text m_text; NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); NazaraSlot(Nz::EventHandler, OnMouseMoved, m_mouseMovedSlot); NazaraSlot(Nz::EventHandler, OnMouseWheelMoved, m_mouseWheelMovedSlot); diff --git a/tests/Engine/Utility/EventHandler/StateContext.cpp b/tests/Engine/Platform/EventHandler/StateContext.cpp similarity index 100% rename from tests/Engine/Utility/EventHandler/StateContext.cpp rename to tests/Engine/Platform/EventHandler/StateContext.cpp diff --git a/tests/Engine/Utility/EventHandler/StateContext.hpp b/tests/Engine/Platform/EventHandler/StateContext.hpp similarity index 100% rename from tests/Engine/Utility/EventHandler/StateContext.hpp rename to tests/Engine/Platform/EventHandler/StateContext.hpp diff --git a/tests/Engine/Utility/EventHandler/StateFactory.cpp b/tests/Engine/Platform/EventHandler/StateFactory.cpp similarity index 100% rename from tests/Engine/Utility/EventHandler/StateFactory.cpp rename to tests/Engine/Platform/EventHandler/StateFactory.cpp diff --git a/tests/Engine/Utility/EventHandler/StateFactory.hpp b/tests/Engine/Platform/EventHandler/StateFactory.hpp similarity index 100% rename from tests/Engine/Utility/EventHandler/StateFactory.hpp rename to tests/Engine/Platform/EventHandler/StateFactory.hpp diff --git a/tests/Engine/Utility/EventHandler/Text.cpp b/tests/Engine/Platform/EventHandler/Text.cpp similarity index 100% rename from tests/Engine/Utility/EventHandler/Text.cpp rename to tests/Engine/Platform/EventHandler/Text.cpp diff --git a/tests/Engine/Utility/EventHandler/Text.hpp b/tests/Engine/Platform/EventHandler/Text.hpp similarity index 100% rename from tests/Engine/Utility/EventHandler/Text.hpp rename to tests/Engine/Platform/EventHandler/Text.hpp diff --git a/tests/Engine/Utility/EventHandler/TextEnterState.cpp b/tests/Engine/Platform/EventHandler/TextEnterState.cpp similarity index 79% rename from tests/Engine/Utility/EventHandler/TextEnterState.cpp rename to tests/Engine/Platform/EventHandler/TextEnterState.cpp index 1a0516f29..2aa58da69 100644 --- a/tests/Engine/Utility/EventHandler/TextEnterState.cpp +++ b/tests/Engine/Platform/EventHandler/TextEnterState.cpp @@ -7,16 +7,13 @@ #include TextEnterState::TextEnterState(StateContext& context) : -State(), -m_context(context), -m_text(context) +BaseState(context) { } void TextEnterState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -36,16 +33,6 @@ void TextEnterState::Enter(Ndk::StateMachine& fsm) }); } -void TextEnterState::Leave(Ndk::StateMachine& /*fsm*/) -{ - m_text.SetVisible(false); -} - -bool TextEnterState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) -{ - return true; -} - void TextEnterState::DrawMenu() { m_text.SetContent("Enter some text, this text should change !\nM for Menu"); diff --git a/tests/Engine/Platform/EventHandler/TextEnterState.hpp b/tests/Engine/Platform/EventHandler/TextEnterState.hpp new file mode 100644 index 000000000..ed193d204 --- /dev/null +++ b/tests/Engine/Platform/EventHandler/TextEnterState.hpp @@ -0,0 +1,22 @@ +#ifndef __TEXTENTERSTATE_HPP__ +#define __TEXTENTERSTATE_HPP__ + +#include "BaseState.hpp" + +class StateContext; + +class TextEnterState : public BaseState +{ + public: + TextEnterState(StateContext& stateContext); + + void Enter(Ndk::StateMachine& fsm) override; + + private: + void DrawMenu() override; + + NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); + NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot); +}; + +#endif // __TEXTENTERSTATE_HPP__ \ No newline at end of file diff --git a/tests/Engine/Utility/EventHandler/WindowModificationState.cpp b/tests/Engine/Platform/EventHandler/WindowModificationState.cpp similarity index 81% rename from tests/Engine/Utility/EventHandler/WindowModificationState.cpp rename to tests/Engine/Platform/EventHandler/WindowModificationState.cpp index e50d94f51..027185fe6 100644 --- a/tests/Engine/Utility/EventHandler/WindowModificationState.cpp +++ b/tests/Engine/Platform/EventHandler/WindowModificationState.cpp @@ -7,16 +7,13 @@ #include WindowModificationState::WindowModificationState(StateContext& context) : -State(), -m_context(context), -m_text(context) +BaseState(context) { } void WindowModificationState::Enter(Ndk::StateMachine& fsm) { - m_text.SetVisible(true); - DrawMenu(); + BaseState::Enter(fsm); Nz::EventHandler& eventHandler = m_context.window.GetEventHandler(); m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key) @@ -38,16 +35,6 @@ void WindowModificationState::Enter(Ndk::StateMachine& fsm) }); } -void WindowModificationState::Leave(Ndk::StateMachine& /*fsm*/) -{ - m_text.SetVisible(false); -} - -bool WindowModificationState::Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) -{ - return true; -} - void WindowModificationState::DrawMenu() { m_text.SetContent("Move the window or resize it, this text should change !\nM for Menu"); diff --git a/tests/Engine/Utility/EventHandler/WindowModificationState.hpp b/tests/Engine/Platform/EventHandler/WindowModificationState.hpp similarity index 53% rename from tests/Engine/Utility/EventHandler/WindowModificationState.hpp rename to tests/Engine/Platform/EventHandler/WindowModificationState.hpp index 4fb84188d..fce207039 100644 --- a/tests/Engine/Utility/EventHandler/WindowModificationState.hpp +++ b/tests/Engine/Platform/EventHandler/WindowModificationState.hpp @@ -1,28 +1,20 @@ #ifndef __WINDOWMODIFICATIONSTATE_HPP__ #define __WINDOWMODIFICATIONSTATE_HPP__ -#include "Text.hpp" - -#include - -#include +#include "BaseState.hpp" class StateContext; -class WindowModificationState : public Ndk::State +class WindowModificationState : public BaseState { public: WindowModificationState(StateContext& stateContext); void Enter(Ndk::StateMachine& fsm) override; - void Leave(Ndk::StateMachine& fsm) override; - bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; private: - void DrawMenu(); + void DrawMenu() override; - StateContext& m_context; - Text m_text; NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); NazaraSlot(Nz::EventHandler, OnMoved, m_movedSlot); NazaraSlot(Nz::EventHandler, OnResized, m_resizedSlot); diff --git a/tests/Engine/Utility/EventHandler/TextEnterState.hpp b/tests/Engine/Utility/EventHandler/TextEnterState.hpp deleted file mode 100644 index c9137c51d..000000000 --- a/tests/Engine/Utility/EventHandler/TextEnterState.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __TEXTENTERSTATE_HPP__ -#define __TEXTENTERSTATE_HPP__ - -#include "Text.hpp" - -#include - -#include - -class StateContext; - -class TextEnterState : public Ndk::State -{ - public: - TextEnterState(StateContext& stateContext); - - void Enter(Ndk::StateMachine& fsm) override; - void Leave(Ndk::StateMachine& fsm) override; - bool Update(Ndk::StateMachine& fsm, float elapsedTime) override; - - private: - void DrawMenu(); - - StateContext& m_context; - Text m_text; - NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); - NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot); -}; - -#endif // __TEXTENTERSTATE_HPP__ \ No newline at end of file diff --git a/tests/SDK/NDK/BaseSystem.cpp b/tests/SDK/NDK/BaseSystem.cpp index 3bb0fa9e4..84649df22 100644 --- a/tests/SDK/NDK/BaseSystem.cpp +++ b/tests/SDK/NDK/BaseSystem.cpp @@ -32,7 +32,8 @@ SCENARIO("BaseSystem", "[NDK][BASESYSTEM]") { GIVEN("Our TestSystem") { - Ndk::World world; + Ndk::World world(false); + Ndk::BaseSystem& system = world.AddSystem(); REQUIRE(&system.GetWorld() == &world); diff --git a/tests/SDK/NDK/Entity.cpp b/tests/SDK/NDK/Entity.cpp index dd3216fb0..7d59cfc20 100644 --- a/tests/SDK/NDK/Entity.cpp +++ b/tests/SDK/NDK/Entity.cpp @@ -55,7 +55,8 @@ SCENARIO("Entity", "[NDK][ENTITY]") { GIVEN("A world & an entity") { - Ndk::World world; + Ndk::World world(false); + Ndk::BaseSystem& system = world.AddSystem(); Ndk::EntityHandle entity = world.CreateEntity(); diff --git a/tests/SDK/NDK/EntityList.cpp b/tests/SDK/NDK/EntityList.cpp index 30a57573d..0642b50b7 100644 --- a/tests/SDK/NDK/EntityList.cpp +++ b/tests/SDK/NDK/EntityList.cpp @@ -6,7 +6,8 @@ SCENARIO("EntityList", "[NDK][ENTITYLIST]") { GIVEN("A world & a set of entities") { - Ndk::World world; + Ndk::World world(false); + const Ndk::EntityHandle& entity = world.CreateEntity(); Ndk::EntityList entityList; entityList.Insert(entity); diff --git a/tests/SDK/NDK/EntityOwner.cpp b/tests/SDK/NDK/EntityOwner.cpp index f2fd76d58..c28ed7d91 100644 --- a/tests/SDK/NDK/EntityOwner.cpp +++ b/tests/SDK/NDK/EntityOwner.cpp @@ -6,7 +6,7 @@ SCENARIO("EntityOwner", "[NDK][ENTITYOWNER]") { GIVEN("A world & an entity") { - Ndk::World world; + Ndk::World world(false); Ndk::EntityHandle entity = world.CreateEntity(); WHEN("We set the ownership of the entity to our owner") diff --git a/tests/SDK/NDK/StateMachine.cpp b/tests/SDK/NDK/StateMachine.cpp index 066a150d7..15502c5cf 100644 --- a/tests/SDK/NDK/StateMachine.cpp +++ b/tests/SDK/NDK/StateMachine.cpp @@ -64,8 +64,8 @@ SCENARIO("State & StateMachine", "[NDK][STATE]") std::shared_ptr secondTestState = std::make_shared(); Ndk::StateMachine stateMachine(secondTestState); stateMachine.PushState(testState); - REQUIRE(!testState->IsUpdated()); - REQUIRE(!secondTestState->IsUpdated()); + CHECK(!testState->IsUpdated()); + CHECK(!secondTestState->IsUpdated()); WHEN("We update our machine") { @@ -73,34 +73,32 @@ SCENARIO("State & StateMachine", "[NDK][STATE]") THEN("Our state on the top has been updated but not the bottom one") { - REQUIRE(stateMachine.IsTopState(testState.get())); - REQUIRE(!stateMachine.IsTopState(secondTestState.get())); + CHECK(stateMachine.IsTopState(testState.get())); + CHECK(!stateMachine.IsTopState(secondTestState.get())); - REQUIRE(testState->IsUpdated()); - REQUIRE(!secondTestState->IsUpdated()); + CHECK(testState->IsUpdated()); + CHECK(!secondTestState->IsUpdated()); } } WHEN("We exchange the states' positions while emptying the stack") { - REQUIRE(stateMachine.PopStatesUntil(secondTestState)); - REQUIRE(stateMachine.IsTopState(secondTestState.get())); + stateMachine.PopStatesUntil(secondTestState); + stateMachine.Update(1.f); + CHECK(stateMachine.IsTopState(secondTestState.get())); - std::shared_ptr oldState = stateMachine.PopState(); - REQUIRE(stateMachine.PopState() == nullptr); - - stateMachine.SetState(testState); - stateMachine.PushState(oldState); + stateMachine.ResetState(testState); + stateMachine.PushState(secondTestState); stateMachine.Update(1.f); THEN("Both states should be updated") { - REQUIRE(!stateMachine.IsTopState(testState.get())); - REQUIRE(stateMachine.IsTopState(secondTestState.get())); + CHECK(!stateMachine.IsTopState(testState.get())); + CHECK(stateMachine.IsTopState(secondTestState.get())); - REQUIRE(testState->IsUpdated()); - REQUIRE(secondTestState->IsUpdated()); + CHECK(testState->IsUpdated()); + CHECK(secondTestState->IsUpdated()); } } } diff --git a/tests/SDK/NDK/System.cpp b/tests/SDK/NDK/System.cpp index d965e37f3..ba7e9f4aa 100644 --- a/tests/SDK/NDK/System.cpp +++ b/tests/SDK/NDK/System.cpp @@ -1,6 +1,6 @@ #include #include - +/* namespace { class TestSystem : public Ndk::System @@ -23,7 +23,7 @@ namespace private: int m_value; - void OnUpdate(float /*elapsedTime*/) override + void OnUpdate(float elapsedTime) override { } }; @@ -47,4 +47,4 @@ SCENARIO("System", "[NDK][SYSTEM]") } } } -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/tests/SDK/NDK/Systems/PhysicsSystem2D.cpp b/tests/SDK/NDK/Systems/PhysicsSystem2D.cpp index 4bdb1e039..9173ab167 100644 --- a/tests/SDK/NDK/Systems/PhysicsSystem2D.cpp +++ b/tests/SDK/NDK/Systems/PhysicsSystem2D.cpp @@ -5,19 +5,21 @@ #include #include +Ndk::EntityHandle CreateBaseEntity(Ndk::World& world, const Nz::Vector2f& position, const Nz::Rectf AABB); + SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]") { GIVEN("A world and an entity") { Ndk::World world; - const Ndk::EntityHandle& entity = world.CreateEntity(); - Ndk::NodeComponent& nodeComponent = entity->AddComponent(); + Nz::Vector2f position(2.f, 3.f); - nodeComponent.SetPosition(position); - Nz::Rectf aabb(0.f, 0.f, 16.f, 18.f); - Nz::BoxCollider2DRef collisionBox = Nz::BoxCollider2D::New(aabb); - Ndk::CollisionComponent2D& collisionComponent = entity->AddComponent(collisionBox); - Ndk::PhysicsComponent2D& physicsComponent = entity->AddComponent(); + Nz::Rectf movingAABB(0.f, 0.f, 16.f, 18.f); + Ndk::EntityHandle movingEntity = CreateBaseEntity(world, position, movingAABB); + Ndk::NodeComponent& nodeComponent = movingEntity->GetComponent(); + Ndk::PhysicsComponent2D& physicsComponent2D = movingEntity->AddComponent(); + + world.GetSystem().SetFixedUpdateRate(30.f); WHEN("We update the world") { @@ -26,9 +28,127 @@ SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]") THEN("Entity should have correct bounding box") { REQUIRE(nodeComponent.GetPosition() == position); - aabb.Translate(position); - REQUIRE(physicsComponent.GetAABB() == aabb); + movingAABB.Translate(position); + REQUIRE(physicsComponent2D.GetAABB() == movingAABB); + } + } + + WHEN("We make it collide with a wall") + { + int rawDistance = 3; + Nz::Vector2f distance(rawDistance, 0.f); + Nz::Vector2f wallPosition = position + Nz::Vector2f(movingAABB.width, 0.f) + distance; + Nz::Rectf wallAABB(0.f, 0.f, 100.f, 100.f); + Ndk::EntityHandle wallEntity = CreateBaseEntity(world, wallPosition, wallAABB); + + world.Update(1.f); + + THEN("It should moved freely") + { + REQUIRE(nodeComponent.GetPosition() == position); + movingAABB.Translate(position); + REQUIRE(physicsComponent2D.GetAABB() == movingAABB); + + physicsComponent2D.SetVelocity(Nz::Vector2f::UnitX()); + + for (int i = 0; i < rawDistance; ++i) + { + world.Update(1.f); + position += Nz::Vector2f::UnitX(); + REQUIRE(nodeComponent.GetPosition() == position); + movingAABB.Translate(Nz::Vector2f::UnitX()); + REQUIRE(physicsComponent2D.GetAABB() == movingAABB); + } + } + + AND_THEN("It should be stopped by it") + { + world.Update(1.f); + REQUIRE(nodeComponent.GetPosition().SquaredDistance(position) < 0.1f); } } } -} \ No newline at end of file + + GIVEN("A world and a simple entity") + { + Ndk::World world; + + Nz::Vector2f position(0.f, 0.f); + Nz::Rectf movingAABB(0.f, 0.f, 1.f, 2.f); + Ndk::EntityHandle movingEntity = CreateBaseEntity(world, position, movingAABB); + Ndk::NodeComponent& nodeComponent = movingEntity->GetComponent(); + Ndk::PhysicsComponent2D& physicsComponent2D = movingEntity->AddComponent(); + + world.GetSystem().SetFixedUpdateRate(30.f); + + WHEN("We make rotate our entity") + { + float angularSpeed = Nz::FromDegrees(45.f); + physicsComponent2D.SetAngularVelocity(angularSpeed); + world.Update(2.f); + + THEN("It should have been rotated") + { + CHECK(physicsComponent2D.GetAngularVelocity() == angularSpeed); + CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(-2.f, 0.f, 2.f, 1.f)); + CHECK(physicsComponent2D.GetRotation() == Approx(Nz::FromDegrees(90.f))); + CHECK(nodeComponent.GetRotation().ToEulerAngles().roll == Approx(Nz::FromDegrees(90.f))); + } + } + + WHEN("We put a force on it") + { + float stepSize = world.GetSystem().GetWorld().GetStepSize(); + Nz::Vector2f velocity = Nz::Vector2f::UnitX(); + physicsComponent2D.AddForce(velocity / stepSize); + world.Update(1.f); + + THEN("Velocity should be the one targetted") + { + REQUIRE(physicsComponent2D.GetVelocity() == velocity); + world.Update(99.f); + REQUIRE(physicsComponent2D.GetPosition().Distance(Nz::Vector2f::UnitX() * 100.f) < 1.f); + REQUIRE(nodeComponent.GetPosition().Distance(Nz::Vector2f::UnitX() * 100.f) < 1.f); + } + } + } + + GIVEN("A world and a simple entity not at the origin") + { + Ndk::World world; + + Nz::Vector2f position(3.f, 4.f); + Nz::Rectf movingAABB(0.f, 0.f, 1.f, 2.f); + Ndk::EntityHandle movingEntity = CreateBaseEntity(world, position, movingAABB); + Ndk::NodeComponent& nodeComponent = movingEntity->GetComponent(); + Ndk::PhysicsComponent2D& physicsComponent2D = movingEntity->AddComponent(); + + world.GetSystem().SetFixedUpdateRate(30.f); + + WHEN("We make rotate our entity") + { + float angularSpeed = Nz::FromDegrees(45.f); + physicsComponent2D.SetAngularVelocity(angularSpeed); + world.Update(2.f); + + THEN("It should have been rotated") + { + CHECK(physicsComponent2D.GetAngularVelocity() == angularSpeed); + CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(1.f, 4.f, 2.f, 1.f)); + CHECK(physicsComponent2D.GetRotation() == Approx(Nz::FromDegrees(90.f))); + CHECK(nodeComponent.GetPosition() == position); + CHECK(nodeComponent.GetRotation().ToEulerAngles().roll == Approx(Nz::FromDegrees(90.f))); + } + } + } +} + +Ndk::EntityHandle CreateBaseEntity(Ndk::World& world, const Nz::Vector2f& position, const Nz::Rectf AABB) +{ + Ndk::EntityHandle entity = world.CreateEntity(); + Ndk::NodeComponent& nodeComponent = entity->AddComponent(); + nodeComponent.SetPosition(position); + Nz::BoxCollider2DRef collisionBox = Nz::BoxCollider2D::New(AABB); + entity->AddComponent(collisionBox); + return entity; +} diff --git a/tests/SDK/NDK/Systems/RenderSystem.cpp b/tests/SDK/NDK/Systems/RenderSystem.cpp index f106b3aae..ec22d6e57 100644 --- a/tests/SDK/NDK/Systems/RenderSystem.cpp +++ b/tests/SDK/NDK/Systems/RenderSystem.cpp @@ -1,13 +1,13 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include #include #include +void CompareAABB(const Nz::Rectf& aabb, const Nz::BoundingVolumef& boundingVolume); + SCENARIO("RenderSystem", "[NDK][RenderSystem]") { GIVEN("A world with a camera, a drawable, a light and some particles") @@ -41,4 +41,80 @@ SCENARIO("RenderSystem", "[NDK][RenderSystem]") } } } + + GIVEN("A world with 2D coordinates (upper-left) and an entity with graphics and physics") + { + Ndk::World world; + world.GetSystem().SetGlobalUp(Nz::Vector3f::Down()); + const Ndk::EntityHandle& entity = world.CreateEntity(); + + Nz::Vector2f position(3.f, 4.f); + Ndk::NodeComponent& nodeComponent = entity->AddComponent(); + nodeComponent.SetPosition(position); + + Nz::Vector2f dimensions(1.f, 2.f); + Ndk::GraphicsComponent& graphicsComponent = entity->AddComponent(); + Nz::SpriteRef sprite = Nz::Sprite::New(); + sprite->SetSize(dimensions); + graphicsComponent.Attach(sprite); + + Nz::Rectf aabb(Nz::Vector2f::Zero(), dimensions); + Nz::BoxCollider2DRef boxCollider2D = Nz::BoxCollider2D::New(aabb); + entity->AddComponent(boxCollider2D); + Ndk::PhysicsComponent2D& physicsComponent2D = entity->AddComponent(); + + world.GetSystem().SetFixedUpdateRate(30.f); + world.Update(1.f); + + WHEN("We move it") + { + Nz::Vector2f velocity = Nz::Vector2f::UnitY(); + physicsComponent2D.SetVelocity(velocity); + world.Update(1.f); + + THEN("Graphics and physics should be synchronised") + { + CHECK(nodeComponent.GetPosition() == position + velocity); + CHECK(physicsComponent2D.GetAABB() == aabb.Translate(position + velocity)); + CompareAABB(physicsComponent2D.GetAABB(), graphicsComponent.GetBoundingVolume()); + } + } + + WHEN("We set an angular velocity") + { + float angularSpeed = Nz::FromDegrees(90.f); + physicsComponent2D.SetAngularVelocity(angularSpeed); + world.Update(1.f); + + THEN("We expect those to be true") + { + CHECK(physicsComponent2D.GetAngularVelocity() == Approx(angularSpeed)); + CHECK(physicsComponent2D.GetRotation() == Approx(angularSpeed)); + CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(1.f, 4.f, 2.f, 1.f)); + CompareAABB(physicsComponent2D.GetAABB(), graphicsComponent.GetBoundingVolume()); + + world.Update(1.f); + CHECK(physicsComponent2D.GetRotation() == Approx(2.f * angularSpeed)); + CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(2.f, 2.f, 1.f, 2.f)); + CompareAABB(physicsComponent2D.GetAABB(), graphicsComponent.GetBoundingVolume()); + + world.Update(1.f); + CHECK(physicsComponent2D.GetRotation() == Approx(3.f * angularSpeed)); + CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(3.f, 3.f, 2.f, 1.f)); + CompareAABB(physicsComponent2D.GetAABB(), graphicsComponent.GetBoundingVolume()); + + world.Update(1.f); + CHECK(physicsComponent2D.GetRotation() == Approx(4.f * angularSpeed)); + } + } + } +} + +void CompareAABB(const Nz::Rectf& aabb, const Nz::BoundingVolumef& boundingVolume) +{ + Nz::Boxf box = boundingVolume.aabb; + CHECK(aabb.x == Approx(box.x)); + CHECK(aabb.y == Approx(box.y)); + CHECK(aabb.width == Approx(box.width)); + CHECK(aabb.height == Approx(box.height)); } \ No newline at end of file diff --git a/tests/SDK/NDK/Systems/VelocitySystem.cpp b/tests/SDK/NDK/Systems/VelocitySystem.cpp index bfde34896..aff645106 100644 --- a/tests/SDK/NDK/Systems/VelocitySystem.cpp +++ b/tests/SDK/NDK/Systems/VelocitySystem.cpp @@ -13,6 +13,8 @@ SCENARIO("VelocitySystem", "[NDK][VELOCITYSYSTEM]") Ndk::VelocityComponent& velocityComponent = entity->AddComponent(); Ndk::NodeComponent& nodeComponent = entity->AddComponent(); + world.GetSystem().SetFixedUpdateRate(30.f); + WHEN("We give a speed to our entity") { Nz::Vector3f velocity = Nz::Vector3f::Unit() * 2.f; diff --git a/tests/SDK/NDK/World.cpp b/tests/SDK/NDK/World.cpp index d46b6621b..4d25db5f6 100644 --- a/tests/SDK/NDK/World.cpp +++ b/tests/SDK/NDK/World.cpp @@ -55,7 +55,7 @@ SCENARIO("World", "[NDK][WORLD]") { GIVEN("A brave new world and the update system") { - Ndk::World world; + Ndk::World world(false); Ndk::BaseSystem& system = world.AddSystem(); WHEN("We had a new entity with an updatable component and a system") diff --git a/tests/main.cpp b/tests/main.cpp index 112b7498c..34bb79e5f 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include