From 1ab70b2d2283d1537d50d9cef324a3c33bb82bcd Mon Sep 17 00:00:00 2001 From: Death Killer <884052+deathkiller@users.noreply.github.com> Date: Mon, 8 Jan 2024 01:02:16 +0100 Subject: [PATCH] Rewritten camera smoothing, refactoring, reverted previous changes --- Sources/Jazz2/LevelHandler.cpp | 68 ++++++++++++------ Sources/Jazz2/LevelHandler.h | 1 + Sources/Jazz2/PreferencesCache.cpp | 3 - Sources/Jazz2/PreferencesCache.h | 2 - Sources/Jazz2/Tiles/TileMap.cpp | 16 ++--- .../Jazz2/UI/Menu/GraphicsOptionsSection.cpp | 11 +-- Sources/nCine/Application.cpp | 3 +- Sources/nCine/Primitives/AABB.h | 9 ++- Sources/nCine/Primitives/Quaternion.h | 72 +++++++++---------- Sources/nCine/Primitives/Rect.h | 21 +++--- Sources/nCine/Primitives/Vector2.h | 17 +++-- Sources/nCine/Primitives/Vector3.h | 23 ++++-- Sources/nCine/Primitives/Vector4.h | 25 ++++--- 13 files changed, 154 insertions(+), 117 deletions(-) diff --git a/Sources/Jazz2/LevelHandler.cpp b/Sources/Jazz2/LevelHandler.cpp index 9d3597f1..6acc7218 100644 --- a/Sources/Jazz2/LevelHandler.cpp +++ b/Sources/Jazz2/LevelHandler.cpp @@ -50,7 +50,7 @@ namespace Jazz2 LevelHandler::LevelHandler(IRootController* root) : _root(root), _eventSpawner(this), _difficulty(GameDifficulty::Default), _isReforged(false), _cheatsUsed(false), _checkpointCreated(false), _cheatsBufferLength(0), _nextLevelType(ExitType::None), _nextLevelTime(0.0f), _elapsedFrames(0.0f), _checkpointFrames(0.0f), - _shakeDuration(0.0f), _waterLevel(FLT_MAX), _ambientLightTarget(1.0f), _weatherType(WeatherType::None), + _cameraResponsiveness(1.0f, 1.0f), _shakeDuration(0.0f), _waterLevel(FLT_MAX), _ambientLightTarget(1.0f), _weatherType(WeatherType::None), _downsamplePass(this), _blurPass1(this), _blurPass2(this), _blurPass3(this), _blurPass4(this), _pressedKeys((uint32_t)KeySym::COUNT), _pressedActions(0), _overrideActions(0), _playerFrozenEnabled(false), _lastPressedNumericKey(UINT32_MAX) @@ -250,7 +250,7 @@ namespace Jazz2 Vector2i levelBounds = _tileMap->GetLevelBounds(); _levelBounds = Recti(0, 0, levelBounds.X, levelBounds.Y); - _viewBounds = Rectf((float)_levelBounds.X, (float)_levelBounds.Y, (float)_levelBounds.W, (float)_levelBounds.H); + _viewBounds = _levelBounds.As(); _viewBoundsTarget = _viewBounds; _ambientColor = descriptor.AmbientColor; @@ -399,7 +399,7 @@ namespace Jazz2 TileMap::DestructibleDebris debris = { }; debris.Pos = debrisPos; debris.Depth = MainPlaneZ - 100 + (uint16_t)(200 * scale); - debris.Size = Vector2f((float)resBase->FrameDimensions.X, (float)resBase->FrameDimensions.Y); + debris.Size = resBase->FrameDimensions.As(); debris.Speed = Vector2f(speedX, speedY); debris.Acceleration = Vector2f(0.0f, 0.0f); @@ -438,15 +438,15 @@ namespace Jazz2 TileMap::DestructibleDebris debris = { }; debris.Pos = debrisPos; debris.Depth = MainPlaneZ - 100 + (uint16_t)(200 * scale); - debris.Size = Vector2f((float)resBase->FrameDimensions.X, (float)resBase->FrameDimensions.Y); + debris.Size = resBase->FrameDimensions.As(); debris.Speed = Vector2f(speedX, speedY); debris.Acceleration = Vector2f(accel, -std::abs(accel)); debris.Scale = scale; debris.ScaleSpeed = 0.0f; debris.Angle = Random().FastFloat(0.0f, fTwoPi); - debris.AngleSpeed = speedX * 0.02f, - debris.Alpha = 1.0f; + debris.AngleSpeed = speedX * 0.02f; + debris.Alpha = 1.0f; debris.AlphaSpeed = 0.0f; debris.Time = 180.0f; @@ -802,15 +802,13 @@ namespace Jazz2 Vector2f focusPos = actor->_pos; if (!fast) { - _cameraPos.X = focusPos.X; - _cameraPos.Y = focusPos.Y; + _cameraPos = focusPos; _cameraLastPos = _cameraPos; - _cameraDistanceFactor.X = 0.0f; - _cameraDistanceFactor.Y = 0.0f; + _cameraDistanceFactor = Vector2f(0.0f, 0.0f); + _cameraResponsiveness = Vector2f(1.0f, 1.0f); } else { Vector2f diff = _cameraLastPos - _cameraPos; - _cameraPos.X = focusPos.X; - _cameraPos.Y = focusPos.Y; + _cameraPos = focusPos; _cameraLastPos = _cameraPos + diff; } } @@ -1066,7 +1064,7 @@ namespace Jazz2 WarpCameraToTarget(player, true); } else { Vector2f pos = player->GetPos(); - if (Vector2f(prevPos.X - pos.X, prevPos.Y - pos.Y).Length() > 250.0f) { + if ((prevPos - pos).Length() > 250.0f) { WarpCameraToTarget(player); } } @@ -1518,7 +1516,7 @@ namespace Jazz2 return; } - auto targetObj = _players[0]; + auto* targetObj = _players[0]; // The position to focus on Vector2f focusPos = targetObj->_pos; @@ -1544,6 +1542,8 @@ namespace Jazz2 { ZoneScopedC(0x4876AF); + constexpr float ResponsivenessChange = 0.04f; + constexpr float ResponsivenessMin = 0.3f; constexpr float SlowRatioX = 0.3f; constexpr float SlowRatioY = 0.3f; constexpr float FastRatioX = 0.2f; @@ -1571,11 +1571,33 @@ namespace Jazz2 Vector2i halfView = _view->size() / 2; Vector2f focusPos = targetObj->_pos; Vector2f focusSpeed = targetObj->_speed; + Vector2f focusVelocity = Vector2f(std::abs(focusSpeed.X), std::abs(focusSpeed.Y)); + + // Camera responsiveness (smoothing unexpected movements) + if (focusVelocity.X < 1.0f) { + if (_cameraResponsiveness.X > ResponsivenessMin) { + _cameraResponsiveness.X = std::max(_cameraResponsiveness.X - ResponsivenessChange * timeMult, ResponsivenessMin); + } + } else { + if (_cameraResponsiveness.X < 1.0f) { + _cameraResponsiveness.X = std::min(_cameraResponsiveness.X + ResponsivenessChange * timeMult, 1.0f); + } + } + if (focusVelocity.Y < 1.0f) { + if (_cameraResponsiveness.Y > ResponsivenessMin) { + _cameraResponsiveness.Y = std::max(_cameraResponsiveness.Y - ResponsivenessChange * timeMult, ResponsivenessMin); + } + } else { + if (_cameraResponsiveness.Y < 1.0f) { + _cameraResponsiveness.Y = std::min(_cameraResponsiveness.Y + ResponsivenessChange * timeMult, 1.0f); + } + } - _cameraLastPos = focusPos; + _cameraLastPos.X = lerpByTime(_cameraLastPos.X, focusPos.X, _cameraResponsiveness.X, timeMult); + _cameraLastPos.Y = lerpByTime(_cameraLastPos.Y, focusPos.Y, _cameraResponsiveness.Y, timeMult); - _cameraDistanceFactor.X = lerpByTime(_cameraDistanceFactor.X, focusSpeed.X * 8.0f, (std::abs(focusSpeed.X) < 2.0f ? SlowRatioX : FastRatioX), timeMult); - _cameraDistanceFactor.Y = lerpByTime(_cameraDistanceFactor.Y, focusSpeed.Y * 5.0f, (std::abs(focusSpeed.Y) < 2.0f ? SlowRatioY : FastRatioY), timeMult); + _cameraDistanceFactor.X = lerpByTime(_cameraDistanceFactor.X, focusSpeed.X * 8.0f, (focusVelocity.X < 2.0f ? SlowRatioX : FastRatioX), timeMult); + _cameraDistanceFactor.Y = lerpByTime(_cameraDistanceFactor.Y, focusSpeed.Y * 5.0f, (focusVelocity.Y < 2.0f ? SlowRatioY : FastRatioY), timeMult); if (_shakeDuration > 0.0f) { _shakeDuration -= timeMult; @@ -1607,11 +1629,11 @@ namespace Jazz2 _cameraPos.Y = std::floor(_viewBounds.Y + _viewBounds.H * 0.5f + _shakeOffset.Y); } - _camera->setView(_cameraPos - Vector2f(halfView.X, halfView.Y), 0.0f, 1.0f); + _camera->setView(_cameraPos - halfView.As(), 0.0f, 1.0f); // Update audio listener position IAudioDevice& device = theServiceLocator().audioDevice(); - device.updateListener(Vector3f(_cameraPos.X, _cameraPos.Y, 0.0f), Vector3f(focusSpeed.X, focusSpeed.Y, 0.0f)); + device.updateListener(Vector3f(_cameraPos, 0.0f), Vector3f(focusSpeed, 0.0f)); } void LevelHandler::LimitCameraView(int left, int width) @@ -1624,10 +1646,10 @@ namespace Jazz2 } if (left == 0 && width == 0) { - _viewBounds = Rectf((float)_levelBounds.X, (float)_levelBounds.Y, (float)_levelBounds.W, (float)_levelBounds.H); + _viewBounds = _levelBounds.As(); _viewBoundsTarget = _viewBounds; } else { - Rectf bounds = Rectf((float)_levelBounds.X, (float)_levelBounds.Y, (float)_levelBounds.W, (float)_levelBounds.H); + Rectf bounds = _levelBounds.As(); float viewWidth = (float)_view->size().X; if (bounds.W < viewWidth) { bounds.X -= (viewWidth - bounds.W); @@ -2077,7 +2099,7 @@ namespace Jazz2 { Vector2i size = _target->size(); - auto instanceBlock = _renderCommand.material().uniformBlock(Material::InstanceBlockName); + auto* instanceBlock = _renderCommand.material().uniformBlock(Material::InstanceBlockName); instanceBlock->uniform(Material::TexRectUniformName)->setFloatValue(1.0f, 0.0f, 1.0f, 0.0f); instanceBlock->uniform(Material::SpriteSizeUniformName)->setFloatValue(static_cast(size.X), static_cast(size.Y)); instanceBlock->uniform(Material::ColorUniformName)->setFloatVector(Colorf::White.Data()); @@ -2164,7 +2186,7 @@ namespace Jazz2 command.material().setTexture(4, *_owner->_noiseTexture); } - auto instanceBlock = command.material().uniformBlock(Material::InstanceBlockName); + auto* instanceBlock = command.material().uniformBlock(Material::InstanceBlockName); instanceBlock->uniform(Material::TexRectUniformName)->setFloatValue(1.0f, 0.0f, 1.0f, 0.0f); instanceBlock->uniform(Material::SpriteSizeUniformName)->setFloatValue(_size.X, _size.Y); instanceBlock->uniform(Material::ColorUniformName)->setFloatVector(Colorf::White.Data()); diff --git a/Sources/Jazz2/LevelHandler.h b/Sources/Jazz2/LevelHandler.h index c2492578..8dafd543 100644 --- a/Sources/Jazz2/LevelHandler.h +++ b/Sources/Jazz2/LevelHandler.h @@ -297,6 +297,7 @@ namespace Jazz2 Vector2f _cameraPos; Vector2f _cameraLastPos; Vector2f _cameraDistanceFactor; + Vector2f _cameraResponsiveness; float _shakeDuration; Vector2f _shakeOffset; float _waterLevel; diff --git a/Sources/Jazz2/PreferencesCache.cpp b/Sources/Jazz2/PreferencesCache.cpp index 7e51aa65..ca595f29 100644 --- a/Sources/Jazz2/PreferencesCache.cpp +++ b/Sources/Jazz2/PreferencesCache.cpp @@ -25,7 +25,6 @@ namespace Jazz2 bool PreferencesCache::ShowPlayerTrails = true; bool PreferencesCache::LowGraphicsQuality = false; bool PreferencesCache::UnalignedViewport = false; - bool PreferencesCache::UnalignedParallaxLayers = false; bool PreferencesCache::EnableReforgedGameplay = true; bool PreferencesCache::EnableReforgedHUD = true; bool PreferencesCache::EnableReforgedMainMenu = true; @@ -155,7 +154,6 @@ namespace Jazz2 ShowPlayerTrails = ((boolOptions & BoolOptions::ShowPlayerTrails) == BoolOptions::ShowPlayerTrails); LowGraphicsQuality = ((boolOptions & BoolOptions::LowGraphicsQuality) == BoolOptions::LowGraphicsQuality); UnalignedViewport = ((boolOptions & BoolOptions::UnalignedViewport) == BoolOptions::UnalignedViewport); - UnalignedParallaxLayers = ((boolOptions & BoolOptions::UnalignedParallaxLayers) == BoolOptions::UnalignedParallaxLayers); EnableReforgedGameplay = ((boolOptions & BoolOptions::EnableReforgedGameplay) == BoolOptions::EnableReforgedGameplay); EnableLedgeClimb = ((boolOptions & BoolOptions::EnableLedgeClimb) == BoolOptions::EnableLedgeClimb); WeaponWheel = ((boolOptions & BoolOptions::EnableWeaponWheel) == BoolOptions::EnableWeaponWheel ? WeaponWheelStyle::Enabled : WeaponWheelStyle::Disabled); @@ -343,7 +341,6 @@ namespace Jazz2 if (ShowPlayerTrails) boolOptions |= BoolOptions::ShowPlayerTrails; if (LowGraphicsQuality) boolOptions |= BoolOptions::LowGraphicsQuality; if (UnalignedViewport) boolOptions |= BoolOptions::UnalignedViewport; - if (UnalignedParallaxLayers) boolOptions |= BoolOptions::UnalignedParallaxLayers; if (EnableReforgedGameplay) boolOptions |= BoolOptions::EnableReforgedGameplay; if (EnableLedgeClimb) boolOptions |= BoolOptions::EnableLedgeClimb; if (WeaponWheel != WeaponWheelStyle::Disabled) boolOptions |= BoolOptions::EnableWeaponWheel; diff --git a/Sources/Jazz2/PreferencesCache.h b/Sources/Jazz2/PreferencesCache.h index 48d70170..fe576069 100644 --- a/Sources/Jazz2/PreferencesCache.h +++ b/Sources/Jazz2/PreferencesCache.h @@ -93,7 +93,6 @@ namespace Jazz2 static bool ShowPlayerTrails; static bool LowGraphicsQuality; static bool UnalignedViewport; - static bool UnalignedParallaxLayers; // Gameplay static bool EnableReforgedGameplay; @@ -138,7 +137,6 @@ namespace Jazz2 ShowPlayerTrails = 0x08, LowGraphicsQuality = 0x10, UnalignedViewport = 0x20, - UnalignedParallaxLayers = 0x40, EnableReforgedGameplay = 0x100, EnableLedgeClimb = 0x200, diff --git a/Sources/Jazz2/Tiles/TileMap.cpp b/Sources/Jazz2/Tiles/TileMap.cpp index 9c3fa49d..79bc2180 100644 --- a/Sources/Jazz2/Tiles/TileMap.cpp +++ b/Sources/Jazz2/Tiles/TileMap.cpp @@ -602,7 +602,6 @@ namespace Jazz2::Tiles Vector2f viewCenter = _owner->GetCameraPos(); Vector2i tileCount = layer.LayoutSize; - Vector2i tileSize = Vector2i(TileSet::DefaultTileSize, TileSet::DefaultTileSize); // Get current layer offsets and speeds float loX = layer.Description.OffsetX; @@ -617,18 +616,16 @@ namespace Jazz2::Tiles constexpr float PerspectiveSpeedY = 0.16f; RenderTexturedBackground(renderQueue, layer, x1 * PerspectiveSpeedX + loX, y1 * PerspectiveSpeedY + loY); } else { - float xt, yt; bool xAlign, yAlign; + float xt, yt; switch (layer.Description.SpeedModelX) { case LayerSpeedModel::AlwaysOnTop: xt = -HardcodedOffset; - xAlign = false; break; case LayerSpeedModel::FitLevel: { float progress = (float)viewCenter.X / (_layers[_sprLayerIndex].LayoutSize.X * TileSet::DefaultTileSize); xt = std::clamp(progress, 0.0f, 1.0f) * ((layer.LayoutSize.X * TileSet::DefaultTileSize) - viewSize.X + HardcodedOffset) + loX; - xAlign = !PreferencesCache::UnalignedViewport && !PreferencesCache::UnalignedParallaxLayers; break; } case LayerSpeedModel::SpeedMultipliers: { @@ -639,25 +636,21 @@ namespace Jazz2::Tiles xt = progress * ((layer.LayoutSize.X * TileSet::DefaultTileSize) - HardcodedOffset) + loX; - xAlign = !PreferencesCache::UnalignedViewport && !PreferencesCache::UnalignedParallaxLayers; break; } default: xt = TranslateCoordinate(x1, layer.Description.SpeedX, loX, viewSize.X, false); - xAlign = !PreferencesCache::UnalignedViewport && (!PreferencesCache::UnalignedParallaxLayers || layer.Description.SpeedX == 1.0f); break; } switch (layer.Description.SpeedModelY) { case LayerSpeedModel::AlwaysOnTop: yt = -HardcodedOffset; - yAlign = false; break; case LayerSpeedModel::FitLevel: { float progress = (float)viewCenter.Y / (_layers[_sprLayerIndex].LayoutSize.Y * TileSet::DefaultTileSize); yt = std::clamp(progress, 0.0f, 1.0f) * ((layer.LayoutSize.Y * TileSet::DefaultTileSize) - viewSize.Y + HardcodedOffset) + loY; - yAlign = !PreferencesCache::UnalignedViewport && !PreferencesCache::UnalignedParallaxLayers; break; } case LayerSpeedModel::SpeedMultipliers: { @@ -668,7 +661,6 @@ namespace Jazz2::Tiles yt = progress * ((layer.LayoutSize.Y * TileSet::DefaultTileSize) - HardcodedOffset) + loY; - yAlign = !PreferencesCache::UnalignedViewport && !PreferencesCache::UnalignedParallaxLayers; break; } default: @@ -680,7 +672,6 @@ namespace Jazz2::Tiles }*/ yt = TranslateCoordinate(y1, layer.Description.SpeedY, loY, viewSize.Y, true); - yAlign = !PreferencesCache::UnalignedViewport && (!PreferencesCache::UnalignedParallaxLayers || layer.Description.SpeedY == 1.0f); break; } @@ -787,8 +778,9 @@ namespace Jazz2::Tiles instanceBlock->uniform(Material::ColorUniformName)->setFloatVector(color.Data()); float x2r = x2, y2r = y2; - if (xAlign) x2r = std::floor(x2r); - if (yAlign) y2r = std::floor(y2r); + if (!PreferencesCache::UnalignedViewport) { + x2r = std::floor(x2r); y2r = std::floor(y2r); + } command->setTransformation(Matrix4x4f::Translation(x2r, y2r, 0.0f)); command->setLayer(layer.Description.Depth); diff --git a/Sources/Jazz2/UI/Menu/GraphicsOptionsSection.cpp b/Sources/Jazz2/UI/Menu/GraphicsOptionsSection.cpp index 789b711c..544ca837 100644 --- a/Sources/Jazz2/UI/Menu/GraphicsOptionsSection.cpp +++ b/Sources/Jazz2/UI/Menu/GraphicsOptionsSection.cpp @@ -111,7 +111,7 @@ namespace Jazz2::UI::Menu case GraphicsOptionsItemType::Antialiasing: enabled = (PreferencesCache::ActiveRescaleMode & RescaleMode::UseAntialiasing) == RescaleMode::UseAntialiasing; break; case GraphicsOptionsItemType::LowGraphicsQuality: customText = (enabled ? _("Low") : _("High")); break; case GraphicsOptionsItemType::ShowPlayerTrails: enabled = PreferencesCache::ShowPlayerTrails; break; - case GraphicsOptionsItemType::UnalignedViewport: customText = (PreferencesCache::UnalignedViewport ? _("Enabled") : (PreferencesCache::UnalignedParallaxLayers ? _("Parallax Layers Only") : _("Disabled"))); break; + case GraphicsOptionsItemType::UnalignedViewport: enabled = PreferencesCache::UnalignedViewport; break; case GraphicsOptionsItemType::KeepAspectRatioInCinematics: enabled = PreferencesCache::KeepAspectRatioInCinematics; break; case GraphicsOptionsItemType::ShowPerformanceMetrics: enabled = PreferencesCache::ShowPerformanceMetrics; break; } @@ -175,14 +175,7 @@ namespace Jazz2::UI::Menu _root->PlaySfx("MenuSelect"_s, 0.6f); break; case GraphicsOptionsItemType::UnalignedViewport: - if (PreferencesCache::UnalignedViewport) { - PreferencesCache::UnalignedViewport = false; - PreferencesCache::UnalignedParallaxLayers = true; - } else if (PreferencesCache::UnalignedParallaxLayers) { - PreferencesCache::UnalignedParallaxLayers = false; - } else { - PreferencesCache::UnalignedViewport = true; - } + PreferencesCache::UnalignedViewport = !PreferencesCache::UnalignedViewport; _isDirty = true; _animation = 0.0f; _root->PlaySfx("MenuSelect"_s, 0.6f); diff --git a/Sources/nCine/Application.cpp b/Sources/nCine/Application.cpp index a0a1f530..bd9bdce2 100644 --- a/Sources/nCine/Application.cpp +++ b/Sources/nCine/Application.cpp @@ -676,7 +676,8 @@ namespace nCine if (appCfg_.frameLimit > 0) { FrameMarkStart("Frame limiting"); -#if defined(DEATH_TARGET_WINDOWS) +#if 0 //defined(DEATH_TARGET_WINDOWS) + // TODO: This code sometimes doesn't work properly const std::uint64_t clockFreq = static_cast(clock().frequency()); const std::uint64_t frameTimeDuration = (clockFreq / static_cast(appCfg_.frameLimit)); const std::int64_t remainingTime = (std::int64_t)frameTimeDuration - (std::int64_t)frameTimer_->frameDurationAsTicks(); diff --git a/Sources/nCine/Primitives/AABB.h b/Sources/nCine/Primitives/AABB.h index 1b159bfa..11e76f4f 100644 --- a/Sources/nCine/Primitives/AABB.h +++ b/Sources/nCine/Primitives/AABB.h @@ -23,12 +23,17 @@ namespace nCine AABB() : L(0), T(0), R(0), B(0) { } - AABB(S ll, S tt, S rr, S bb) - : L(ll), T(tt), R(rr), B(bb) { } + AABB(S l, S t, S r, S b) + : L(l), T(t), R(r), B(b) { } AABB(const Vector2& min, const Vector2& max) : L(std::min(min.X, max.X)), T(std::min(min.Y, max.Y)), R(std::max(min.X, max.X)), B(std::max(min.Y, max.Y)) { } + template + AABB As() { + return AABB(static_cast(L), static_cast(T), static_cast(R), static_cast(B)); + } + S GetWidth() const { return R - L; } diff --git a/Sources/nCine/Primitives/Quaternion.h b/Sources/nCine/Primitives/Quaternion.h index b6e466c2..00e69cff 100644 --- a/Sources/nCine/Primitives/Quaternion.h +++ b/Sources/nCine/Primitives/Quaternion.h @@ -14,18 +14,18 @@ namespace nCine Quaternion() : X(0), Y(0), Z(0), W(1) {} - Quaternion(T xx, T yy, T zz, T ww) - : X(xx), Y(yy), Z(zz), W(ww) {} + Quaternion(T x, T y, T z, T w) + : X(x), Y(y), Z(z), W(w) {} explicit Quaternion(const Vector4& v) : X(v.X), Y(v.Y), Z(v.Z), W(v.W) {} Quaternion(const Quaternion& other) : X(other.X), Y(other.Y), Z(other.Z), W(other.W) {} Quaternion& operator=(const Quaternion& other); - void set(T xx, T yy, T zz, T ww); + void Set(T x, T y, T z, T w); - T* data(); - const T* data() const; + T* Data(); + const T* Data() const; T& operator[](unsigned int index); const T& operator[](unsigned int index) const; @@ -48,19 +48,19 @@ namespace nCine Quaternion operator*(T s) const; Quaternion operator/(T s) const; - T magnitude() const; - T sqrMagnitude() const; - Quaternion normalized() const; - Quaternion& normalize(); - Quaternion conjugated() const; - Quaternion& conjugate(); + T Magnitude() const; + T SqrMagnitude() const; + Quaternion Normalized() const; + Quaternion& Normalize(); + Quaternion Conjugated() const; + Quaternion& Conjugate(); - Matrix4x4 toMatrix4x4() const; - static Quaternion fromAxisAngle(T xx, T yy, T zz, T degrees); - static Quaternion fromAxisAngle(const Vector3& axis, T degrees); - static Quaternion fromXAxisAngle(T degrees); - static Quaternion fromYAxisAngle(T degrees); - static Quaternion fromZAxisAngle(T degrees); + Matrix4x4 ToMatrix4x4() const; + static Quaternion FromAxisAngle(T xx, T yy, T zz, T degrees); + static Quaternion FromAxisAngle(const Vector3& axis, T degrees); + static Quaternion FromXAxisAngle(T degrees); + static Quaternion FromYAxisAngle(T degrees); + static Quaternion FromZAxisAngle(T degrees); /// A quaternion with all zero elements static const Quaternion Zero; @@ -82,22 +82,22 @@ namespace nCine } template - inline void Quaternion::set(T xx, T yy, T zz, T ww) + inline void Quaternion::Set(T x, T y, T z, T w) { - X = xx; - Y = yy; - Z = zz; - W = ww; + X = x; + Y = y; + Z = z; + W = w; } template - inline T* Quaternion::data() + inline T* Quaternion::Data() { return &X; } template - inline const T* Quaternion::data() const + inline const T* Quaternion::Data() const { return &X; } @@ -237,26 +237,26 @@ namespace nCine } template - inline T Quaternion::magnitude() const + inline T Quaternion::Magnitude() const { return sqrt(X * X + Y * Y + Z * Z + W * W); } template - inline T Quaternion::sqrMagnitude() const + inline T Quaternion::SqrMagnitude() const { return X * X + Y * Y + Z * Z + W * W; } template - inline Quaternion Quaternion::normalized() const + inline Quaternion Quaternion::Normalized() const { const T mag = magnitude(); return Quaternion(X / mag, Y / mag, Z / mag, W / mag); } template - inline Quaternion& Quaternion::normalize() + inline Quaternion& Quaternion::Normalize() { const T mag = magnitude(); @@ -269,13 +269,13 @@ namespace nCine } template - inline Quaternion Quaternion::conjugated() const + inline Quaternion Quaternion::Conjugated() const { return Quaternion(-X, -Y, -Z, W); } template - inline Quaternion& Quaternion::conjugate() + inline Quaternion& Quaternion::Conjugate() { X = -X; Y = -Y; @@ -285,7 +285,7 @@ namespace nCine } template - inline Matrix4x4 Quaternion::toMatrix4x4() const + inline Matrix4x4 Quaternion::ToMatrix4x4() const { const T x2 = X * 2; const T y2 = Y * 2; @@ -309,7 +309,7 @@ namespace nCine } template - inline Quaternion Quaternion::fromAxisAngle(T xx, T yy, T zz, T degrees) + inline Quaternion Quaternion::FromAxisAngle(T xx, T yy, T zz, T degrees) { const T halfRadians = static_cast(degrees * 0.5f) * (static_cast(Pi) / 180); const T sinus = sin(halfRadians); @@ -321,27 +321,27 @@ namespace nCine } template - inline Quaternion Quaternion::fromAxisAngle(const Vector3& axis, T degrees) + inline Quaternion Quaternion::FromAxisAngle(const Vector3& axis, T degrees) { return fromAxisAngle(axis.X, axis.Y, axis.Z, degrees); } template - inline Quaternion Quaternion::fromXAxisAngle(T degrees) + inline Quaternion Quaternion::FromXAxisAngle(T degrees) { const T halfRadians = static_cast(degrees * 0.5f) * (static_cast(Pi) / 180); return Quaternion(sin(halfRadians), 0, 0, cos(halfRadians)); } template - inline Quaternion Quaternion::fromYAxisAngle(T degrees) + inline Quaternion Quaternion::FromYAxisAngle(T degrees) { const T halfRadians = static_cast(degrees * 0.5f) * (static_cast(Pi) / 180); return Quaternion(0, sin(halfRadians), 0, cos(halfRadians)); } template - inline Quaternion Quaternion::fromZAxisAngle(T degrees) + inline Quaternion Quaternion::FromZAxisAngle(T degrees) { const T halfRadians = static_cast(degrees * 0.5f) * (static_cast(Pi) / 180); return Quaternion(0, 0, sin(halfRadians), cos(halfRadians)); diff --git a/Sources/nCine/Primitives/Rect.h b/Sources/nCine/Primitives/Rect.h index 3d5c40e6..ce8aa0e7 100644 --- a/Sources/nCine/Primitives/Rect.h +++ b/Sources/nCine/Primitives/Rect.h @@ -24,8 +24,8 @@ namespace nCine Rect() : X(0), Y(0), W(0), H(0) { } /// Constructs a rectangle from top-left point and size - Rect(T xx, T yy, T ww, T hh) - : X(xx), Y(yy), W(ww), H(hh) { } + Rect(T x, T y, T w, T h) + : X(x), Y(y), W(w), H(h) { } /// Constructs a rectangle from top-left point and size as two `Vector2` Rect(const Vector2& point, const Vector2& size) : X(point.X), Y(point.Y), W(size.X), H(size.Y) { } @@ -48,7 +48,7 @@ namespace nCine Vector2 Max() const; /// Sets rectangle top-left point and size - void Set(T xx, T yy, T ww, T hh); + void Set(T x, T y, T w, T h); /// Sets rectangle top-left point and size as two `Vector2` void Set(const Vector2& point, const Vector2& size); /// Retains rectangle size but moves its center to another position @@ -70,6 +70,11 @@ namespace nCine /// Sets rectangle minimum and maximum coordinates as two `Vector2` void SetMinMax(const Vector2& min, const Vector2& max); + template + Rect As() { + return Rect(static_cast(X), static_cast(Y), static_cast(W), static_cast(H)); + } + /// Inverts rectangle size and moves (x, y) to a different angle void InvertSize(); @@ -141,12 +146,12 @@ namespace nCine } template - inline void Rect::Set(T xx, T yy, T ww, T hh) + inline void Rect::Set(T x, T y, T w, T h) { - X = xx; - Y = yy; - W = ww; - H = hh; + X = x; + Y = y; + W = w; + H = h; } template diff --git a/Sources/nCine/Primitives/Vector2.h b/Sources/nCine/Primitives/Vector2.h index 547b7d43..f55d4aa6 100644 --- a/Sources/nCine/Primitives/Vector2.h +++ b/Sources/nCine/Primitives/Vector2.h @@ -17,8 +17,8 @@ namespace nCine : X(0), Y(0) {} explicit Vector2(T s) noexcept : X(s), Y(s) {} - Vector2(T xx, T yy) noexcept - : X(xx), Y(yy) {} + Vector2(T x, T y) noexcept + : X(x), Y(y) {} Vector2(const Vector2& other) noexcept : X(other.X), Y(other.Y) {} Vector2(Vector2&& other) noexcept @@ -26,7 +26,7 @@ namespace nCine Vector2& operator=(const Vector2& other) noexcept; Vector2& operator=(Vector2&& other) noexcept; - void Set(T xx, T yy); + void Set(T x, T y); T* Data(); const T* Data() const; @@ -66,6 +66,11 @@ namespace nCine Vector2 Normalized() const; Vector2& Normalize(); + template + Vector2 As() { + return Vector2(static_cast(X), static_cast(Y)); + } + static T Dot(const Vector2& v1, const Vector2& v2); static Vector2 Lerp(const Vector2& a, const Vector2& b, float t); @@ -99,10 +104,10 @@ namespace nCine } template - inline void Vector2::Set(T xx, T yy) + inline void Vector2::Set(T x, T y) { - X = xx; - Y = yy; + X = x; + Y = y; } template diff --git a/Sources/nCine/Primitives/Vector3.h b/Sources/nCine/Primitives/Vector3.h index c2c17189..6f735652 100644 --- a/Sources/nCine/Primitives/Vector3.h +++ b/Sources/nCine/Primitives/Vector3.h @@ -18,8 +18,12 @@ namespace nCine : X(0), Y(0), Z(0) {} explicit Vector3(T s) noexcept : X(s), Y(s), Z(s) {} - Vector3(T xx, T yy, T zz) noexcept - : X(xx), Y(yy), Z(zz) {} + Vector3(T x, T y, T z) noexcept + : X(x), Y(y), Z(z) {} + Vector3(const Vector2& other, T z) noexcept + : X(other.X), Y(other.Y), Z(z) {} + Vector3(Vector2&& other, T zz) noexcept + : X(other.X), Y(other.Y), Z(z) {} Vector3(const Vector3& other) noexcept : X(other.X), Y(other.Y), Z(other.Z) {} Vector3(Vector3&& other) noexcept @@ -27,7 +31,7 @@ namespace nCine Vector3& operator=(const Vector3& other) noexcept; Vector3& operator=(Vector3&& other) noexcept; - void Set(T xx, T yy, T zz); + void Set(T x, T y, T z); T* Data(); const T* Data() const; @@ -67,6 +71,11 @@ namespace nCine Vector3 Normalized() const; Vector3& Normalize(); + template + Vector3 As() { + return Vector3(static_cast(X), static_cast(Y), static_cast(Z)); + } + Vector2 ToVector2() const; static T Dot(const Vector3& v1, const Vector3& v2); @@ -107,11 +116,11 @@ namespace nCine } template - inline void Vector3::Set(T xx, T yy, T zz) + inline void Vector3::Set(T x, T y, T z) { - X = xx; - Y = yy; - Z = zz; + X = x; + Y = y; + Z = z; } template diff --git a/Sources/nCine/Primitives/Vector4.h b/Sources/nCine/Primitives/Vector4.h index 92a59caa..94b1a167 100644 --- a/Sources/nCine/Primitives/Vector4.h +++ b/Sources/nCine/Primitives/Vector4.h @@ -19,8 +19,12 @@ namespace nCine : X(0), Y(0), Z(0), W(0) {} explicit Vector4(T s) noexcept : X(s), Y(s), Z(s), W(s) {} - Vector4(T xx, T yy, T zz, T ww) noexcept - : X(xx), Y(yy), Z(zz), W(ww) {} + Vector4(T x, T y, T z, T w) noexcept + : X(x), Y(y), Z(z), W(w) {} + Vector4(const Vector3& other, T w) noexcept + : X(other.X), Y(other.Y), Z(other.Z), W(w) {} + Vector4(Vector3&& other, T w) noexcept + : X(other.X), Y(other.Y), Z(other.Z), W(w) {} Vector4(const Vector4& other) noexcept : X(other.X), Y(other.Y), Z(other.Z), W(other.W) {} Vector4(Vector4&& other) noexcept @@ -28,7 +32,7 @@ namespace nCine Vector4& operator=(const Vector4& other) noexcept; Vector4& operator=(Vector4&& other) noexcept; - void Set(T xx, T yy, T zz, T ww); + void Set(T x, T y, T z, T w); T* Data(); const T* Data() const; @@ -68,6 +72,11 @@ namespace nCine Vector4 Normalized() const; Vector4& Normalize(); + template + Vector4 As() { + return Vector4(static_cast(X), static_cast(Y), static_cast(Z), static_cast(W)); + } + Vector2 ToVector2() const; Vector3 ToVector3() const; @@ -112,12 +121,12 @@ namespace nCine } template - inline void Vector4::Set(T xx, T yy, T zz, T ww) + inline void Vector4::Set(T x, T y, T z, T w) { - X = xx; - Y = yy; - Z = zz; - W = ww; + X = x; + Y = y; + Z = z; + W = w; } template