diff --git a/trinity/CMakeLists.txt b/trinity/CMakeLists.txt index ba40ebe53..570d3d4a3 100644 --- a/trinity/CMakeLists.txt +++ b/trinity/CMakeLists.txt @@ -484,6 +484,12 @@ set(_SOURCES Eve/SpaceObject/Children/TransformModifiers/EveChildModifierHaloInverted.cpp Eve/SpaceObject/Children/TransformModifiers/EveChildModifierHaloInverted.h Eve/SpaceObject/Children/TransformModifiers/EveChildModifierHaloInverted_Blue.cpp + Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate.cpp + Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate.h + Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate_Blue.cpp + Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake.cpp + Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake.h + Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake_Blue.cpp Eve/SpaceObject/Children/TransformModifiers/EveChildModifierSRT.cpp Eve/SpaceObject/Children/TransformModifiers/EveChildModifierSRT.h Eve/SpaceObject/Children/TransformModifiers/EveChildModifierSRT_Blue.cpp diff --git a/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate.cpp b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate.cpp new file mode 100644 index 000000000..3a004d0f9 --- /dev/null +++ b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate.cpp @@ -0,0 +1,32 @@ +// Copyright © 2026 CCP ehf. + +#include "StdAfx.h" +#include "EveChildModifierRotate.h" +#include "Include/TriMath.h" + +EveChildModifierRotate::EveChildModifierRotate( IRoot* lockobj ) : + m_rotationSpeed( 0.f, 0.f, 0.f ), + m_timeOffset( 0.f ) +{ +} + +EveChildModifierRotate::~EveChildModifierRotate() +{ +} + +Matrix EveChildModifierRotate::ApplyTransform( const Matrix& transform, size_t, const Float4x3* ) const +{ + // Absolute time — never accumulated — so rotation stays stable across frame-time variation. + const double time = TimeAsDouble( BeOS->GetCurrentFrameTime() ) + double( m_timeOffset ); + + // Wrap in double degrees before narrowing so the angle keeps float precision on long-running clients. + auto angle = [time]( float degreesPerSecond ) -> float { + return float( fmod( time * double( degreesPerSecond ), 360.0 ) ) * ( TRI_PI / 180.f ); + }; + + // Same Euler composition as Tr2CurveEulerRotation: yaw about local Y, pitch about X, roll about Z. + const Quaternion rotation = RotationQuaternion( angle( m_rotationSpeed.y ), angle( m_rotationSpeed.x ), angle( m_rotationSpeed.z ) ); + + // Left-multiply so the spin happens in the object's local space, before its world transform. + return RotationMatrix( rotation ) * transform; +} diff --git a/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate.h b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate.h new file mode 100644 index 000000000..90e59c51c --- /dev/null +++ b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate.h @@ -0,0 +1,27 @@ +// Copyright © 2026 CCP ehf. + +#pragma once +#ifndef EveChildModifierRotate_H +#define EveChildModifierRotate_H + +#include "IEveChildTransformModifier.h" + +BLUE_CLASS( EveChildModifierRotate ) : + public IEveChildTransformModifier +{ +public: + EXPOSE_TO_BLUE(); + + EveChildModifierRotate( IRoot* lockobj = NULL ); + ~EveChildModifierRotate(); + + Matrix ApplyTransform( const Matrix& transform, size_t boneCount, const Float4x3* bones ) const; + +private: + Vector3 m_rotationSpeed; + float m_timeOffset; +}; + +TYPEDEF_BLUECLASS( EveChildModifierRotate ); + +#endif diff --git a/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate_Blue.cpp b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate_Blue.cpp new file mode 100644 index 000000000..c0dd7155e --- /dev/null +++ b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierRotate_Blue.cpp @@ -0,0 +1,18 @@ +// Copyright © 2026 CCP ehf. + +#include "StdAfx.h" +#include "EveChildModifierRotate.h" + +BLUE_DEFINE( EveChildModifierRotate ); + +const Be::ClassInfo* EveChildModifierRotate::ExposeToBlue() +{ + EXPOSURE_BEGIN( EveChildModifierRotate, "Spins an object continuously around its local axes." ) + MAP_INTERFACE( EveChildModifierRotate ) + MAP_INTERFACE( IEveChildTransformModifier ) + + MAP_ATTRIBUTE( "rotationSpeed", m_rotationSpeed, "Euler rotation speed in degrees per second around the local axes: x is pitch, y is yaw, z is roll.", Be::READWRITE | Be::PERSIST ); + MAP_ATTRIBUTE( "timeOffset", m_timeOffset, "Seconds added to the clock. Objects with the same rotation speed spin in sync unless given different offsets.", Be::READWRITE | Be::PERSIST ); + + EXPOSURE_END() +} diff --git a/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake.cpp b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake.cpp new file mode 100644 index 000000000..fc5205e8b --- /dev/null +++ b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake.cpp @@ -0,0 +1,34 @@ +// Copyright © 2026 CCP ehf. + +#include "StdAfx.h" +#include "EveChildModifierShake.h" +#include "Include/TriMath.h" + +EveChildModifierShake::EveChildModifierShake( IRoot* lockobj ) : + m_frequency( 1.f ), + m_amplitude( 1.f ), + m_timeOffset( 0.f ) +{ +} + +EveChildModifierShake::~EveChildModifierShake() +{ +} + +Matrix EveChildModifierShake::ApplyTransform( const Matrix& transform, size_t, const Float4x3* ) const +{ + // Absolute time only — never accumulated — so the object cannot drift. + const double time = TimeAsDouble( BeOS->GetCurrentFrameTime() ) + double( m_timeOffset ); + const int octaves = 8; + + // One independent noise channel per axis, each within (-amplitude, +amplitude). + // Channels are offset after the frequency scale so they stay decorrelated at any frequency, + // and the offsets differ in their fractional part so the axes never cross zero together. + auto noise = [&]( double channelOffset ) -> float { + return m_amplitude * float( PerlinNoise1D( time * double( m_frequency ) + channelOffset, 2.0, 2.0, octaves ) ); + }; + + Matrix result = transform; + result.GetTranslation() += Vector3( noise( 17.31 ), noise( 53.77 ), noise( 89.13 ) ); + return result; +} diff --git a/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake.h b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake.h new file mode 100644 index 000000000..f0d622ff4 --- /dev/null +++ b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake.h @@ -0,0 +1,28 @@ +// Copyright © 2026 CCP ehf. + +#pragma once +#ifndef EveChildModifierShake_H +#define EveChildModifierShake_H + +#include "IEveChildTransformModifier.h" + +BLUE_CLASS( EveChildModifierShake ) : + public IEveChildTransformModifier +{ +public: + EXPOSE_TO_BLUE(); + + EveChildModifierShake( IRoot* lockobj = NULL ); + ~EveChildModifierShake(); + + Matrix ApplyTransform( const Matrix& transform, size_t boneCount, const Float4x3* bones ) const; + +private: + float m_frequency; + float m_amplitude; + float m_timeOffset; +}; + +TYPEDEF_BLUECLASS( EveChildModifierShake ); + +#endif diff --git a/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake_Blue.cpp b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake_Blue.cpp new file mode 100644 index 000000000..b9814ee37 --- /dev/null +++ b/trinity/Eve/SpaceObject/Children/TransformModifiers/EveChildModifierShake_Blue.cpp @@ -0,0 +1,19 @@ +// Copyright © 2026 CCP ehf. + +#include "StdAfx.h" +#include "EveChildModifierShake.h" + +BLUE_DEFINE( EveChildModifierShake ); + +const Be::ClassInfo* EveChildModifierShake::ExposeToBlue() +{ + EXPOSURE_BEGIN( EveChildModifierShake, "Shakes an object in place with smooth 3D noise around its original position." ) + MAP_INTERFACE( EveChildModifierShake ) + MAP_INTERFACE( IEveChildTransformModifier ) + + MAP_ATTRIBUTE( "frequency", m_frequency, "Noise frequency. Higher values produce faster, more turbulent motion.", Be::READWRITE | Be::PERSIST ); + MAP_ATTRIBUTE( "amplitude", m_amplitude, "Upper bound on the displacement along each axis, in either direction.", Be::READWRITE | Be::PERSIST ); + MAP_ATTRIBUTE( "timeOffset", m_timeOffset, "Seconds added to the clock. Objects with the same settings shake in sync unless given different offsets.", Be::READWRITE | Be::PERSIST ); + + EXPOSURE_END() +}