MODEL LOADING BABY WORKS
This commit is contained in:
69
destrum/src/Components/OrbitAndSpin.cpp
Normal file
69
destrum/src/Components/OrbitAndSpin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <destrum/Components/OrbitAndSpin.h>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtx/norm.hpp>
|
||||
#include <random>
|
||||
#include <cmath>
|
||||
|
||||
#include "destrum/ObjectModel/Transform.h"
|
||||
|
||||
static glm::vec3 RandomUnitVector(std::mt19937& rng)
|
||||
{
|
||||
// uniform on sphere
|
||||
std::uniform_real_distribution<float> dist(0.0f, 1.0f);
|
||||
float z = dist(rng) * 2.0f - 1.0f; // -1..1
|
||||
float a = dist(rng) * 6.28318530718f; // 0..2pi
|
||||
float r = std::sqrt(std::max(0.0f, 1.0f - z*z));
|
||||
return glm::normalize(glm::vec3(r*std::cos(a), z, r*std::sin(a)));
|
||||
}
|
||||
|
||||
void OrbitAndSpin::Randomize(uint32_t seed)
|
||||
{
|
||||
std::mt19937 rng(seed);
|
||||
|
||||
// speeds + phase
|
||||
std::uniform_real_distribution<float> orbitSpeedDist(0.2f, 1.5f);
|
||||
std::uniform_real_distribution<float> spinSpeedDist(0.5f, 6.0f);
|
||||
std::uniform_real_distribution<float> phaseDist(0.0f, 6.28318530718f);
|
||||
|
||||
m_OrbitAxis = RandomUnitVector(rng);
|
||||
m_SpinAxis = RandomUnitVector(rng);
|
||||
|
||||
m_OrbitSpeed = orbitSpeedDist(rng);
|
||||
m_SpinSpeed = spinSpeedDist(rng);
|
||||
m_OrbitPhase = phaseDist(rng);
|
||||
|
||||
BuildOrbitBasis();
|
||||
}
|
||||
|
||||
void OrbitAndSpin::BuildOrbitBasis()
|
||||
{
|
||||
m_OrbitAxis = glm::normalize(m_OrbitAxis);
|
||||
|
||||
// pick any vector not parallel to axis
|
||||
glm::vec3 any = (std::abs(m_OrbitAxis.y) < 0.99f) ? glm::vec3(0,1,0) : glm::vec3(1,0,0);
|
||||
|
||||
m_U = glm::normalize(glm::cross(any, m_OrbitAxis));
|
||||
m_V = glm::normalize(glm::cross(m_OrbitAxis, m_U));
|
||||
}
|
||||
|
||||
void OrbitAndSpin::Update()
|
||||
{
|
||||
// If your engine provides dt via a global/time service, use that instead.
|
||||
// Since your Spinner takes dt indirectly, I'm assuming Component::Update()
|
||||
// is called once per frame and you can access dt somewhere globally.
|
||||
//
|
||||
// If you CAN pass dt into Update, change signature to Update(float dt).
|
||||
float dt = 1.0f / 60.0f;
|
||||
|
||||
// orbit
|
||||
m_OrbitAngle += m_OrbitSpeed * dt;
|
||||
float a = m_OrbitAngle + m_OrbitPhase;
|
||||
|
||||
glm::vec3 offset = (m_U * std::cos(a) + m_V * std::sin(a)) * m_Radius;
|
||||
GetTransform().SetWorldPosition(m_Center + offset);
|
||||
|
||||
// self spin (local rotation)
|
||||
glm::quat dq = glm::angleAxis(m_SpinSpeed * dt, glm::normalize(m_SpinAxis));
|
||||
auto current = GetTransform().GetLocalRotation(); // adapt to your API
|
||||
GetTransform().SetLocalRotation(glm::normalize(dq * current));
|
||||
}
|
||||
@@ -1,17 +1,95 @@
|
||||
#include <destrum/Components/Rotator.h>
|
||||
|
||||
Rotator::Rotator(GameObject& parent, float distance, float speed):
|
||||
Component(parent, "Rotator"),
|
||||
m_Distance(distance),
|
||||
m_Speed(speed),
|
||||
m_CurrentAngle(0),
|
||||
m_OriginalPosition(GetTransform().GetWorldPosition())
|
||||
{}
|
||||
#include <glm/gtx/rotate_vector.hpp> // glm::rotate(vec3, angle, axis)
|
||||
#include <glm/gtc/epsilon.hpp>
|
||||
#include <cmath>
|
||||
#include <glm/gtc/quaternion.hpp> // glm::quat, glm::angleAxis
|
||||
#include <glm/gtx/quaternion.hpp> // operator*(quat, vec3)
|
||||
|
||||
void Rotator::Update() {
|
||||
m_CurrentAngle += m_Speed * static_cast<float>(0.001);
|
||||
const float x = cos(m_CurrentAngle) * m_Distance;
|
||||
const float y = sin(m_CurrentAngle) * m_Distance;
|
||||
GetTransform().SetLocalPosition(m_OriginalPosition + glm::vec3(x, y, 0));
|
||||
glm::vec3 Rotator::MakePerpendicularUnitVector(const glm::vec3& axis)
|
||||
{
|
||||
// Pick any vector that is not parallel to axis, then cross to get perpendicular.
|
||||
const glm::vec3 a = glm::normalize(axis);
|
||||
const glm::vec3 ref = (std::abs(a.y) < 0.99f) ? glm::vec3(0, 1, 0) : glm::vec3(1, 0, 0);
|
||||
glm::vec3 perp = glm::cross(a, ref);
|
||||
|
||||
const float len2 = glm::dot(perp, perp);
|
||||
if (len2 < 1e-8f)
|
||||
return glm::vec3(1, 0, 0); // fallback
|
||||
|
||||
return perp / std::sqrt(len2);
|
||||
}
|
||||
|
||||
Rotator::Rotator(GameObject& parent, float distance, float speed)
|
||||
: Component(parent, "Rotator")
|
||||
, m_Distance(distance)
|
||||
, m_Speed(speed)
|
||||
, m_CurrentAngle(0.0f)
|
||||
{
|
||||
// Orbit around where we started (LOCAL), similar to your old behavior.
|
||||
m_Pivot = GetTransform().GetLocalPosition();
|
||||
|
||||
// Default axis is Z (so this behaves like your old XY circle by default).
|
||||
m_Axis = glm::vec3(0, 0, 1);
|
||||
|
||||
// Choose an initial offset that is perpendicular to the axis, with the requested radius.
|
||||
const glm::vec3 perp = MakePerpendicularUnitVector(m_Axis);
|
||||
m_InitialOffset = perp * m_Distance;
|
||||
|
||||
// Optional: if you'd rather keep the *current* position as the starting point on the orbit:
|
||||
// m_InitialOffset = GetTransform().GetLocalPosition() - m_Pivot;
|
||||
// m_Distance = glm::length(m_InitialOffset);
|
||||
}
|
||||
|
||||
void Rotator::SetPivotPosition(const glm::vec3& pivot)
|
||||
{
|
||||
m_Pivot = pivot;
|
||||
|
||||
// Recompute offset based on current position so it doesn't “jump”.
|
||||
m_InitialOffset = GetTransform().GetLocalPosition() - m_Pivot;
|
||||
const float len = glm::length(m_InitialOffset);
|
||||
|
||||
if (len > 1e-6f)
|
||||
m_Distance = len;
|
||||
else
|
||||
m_InitialOffset = MakePerpendicularUnitVector(m_Axis) * m_Distance;
|
||||
}
|
||||
|
||||
void Rotator::SetAxis(const glm::vec3& axis)
|
||||
{
|
||||
const float len2 = glm::dot(axis, axis);
|
||||
if (len2 < 1e-8f)
|
||||
return; // ignore invalid axis
|
||||
|
||||
m_Axis = glm::normalize(axis);
|
||||
|
||||
// Ensure the offset is perpendicular to the axis (remove any parallel component).
|
||||
m_InitialOffset -= m_Axis * glm::dot(m_Axis, m_InitialOffset);
|
||||
|
||||
const float offLen = glm::length(m_InitialOffset);
|
||||
if (offLen > 1e-6f)
|
||||
m_InitialOffset = (m_InitialOffset / offLen) * m_Distance;
|
||||
else
|
||||
m_InitialOffset = MakePerpendicularUnitVector(m_Axis) * m_Distance;
|
||||
}
|
||||
|
||||
void Rotator::SetDistance(float distance)
|
||||
{
|
||||
m_Distance = distance;
|
||||
|
||||
const float offLen = glm::length(m_InitialOffset);
|
||||
if (offLen > 1e-6f)
|
||||
m_InitialOffset = (m_InitialOffset / offLen) * m_Distance;
|
||||
else
|
||||
m_InitialOffset = MakePerpendicularUnitVector(m_Axis) * m_Distance;
|
||||
}
|
||||
|
||||
void Rotator::Update()
|
||||
{
|
||||
// Replace 0.001f with your engine delta time if you have one.
|
||||
m_CurrentAngle += m_Speed * 0.001f;
|
||||
|
||||
const glm::quat q = glm::angleAxis(m_CurrentAngle, glm::normalize(m_Axis));
|
||||
const glm::vec3 rotatedOffset = q * m_InitialOffset;
|
||||
GetTransform().SetLocalPosition(m_Pivot + rotatedOffset);
|
||||
}
|
||||
|
||||
26
destrum/src/Components/Spinner.cpp
Normal file
26
destrum/src/Components/Spinner.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <destrum/Components/Spinner.h>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include "destrum/ObjectModel/Transform.h"
|
||||
|
||||
void Spinner::Update()
|
||||
{
|
||||
// Replace with your engine dt if you have it available in Component.
|
||||
const float dt = 1.0f / 60.0f;
|
||||
|
||||
|
||||
m_Angle += m_Speed * dt;
|
||||
|
||||
// If you already have SetLocalRotation / SetWorldRotation, use that.
|
||||
// Here I'm assuming you can set rotation as a quaternion or Euler somewhere.
|
||||
// If not, tell me your Transform rotation API and I’ll adjust.
|
||||
|
||||
const glm::quat q = glm::angleAxis(m_Angle, m_Axis);
|
||||
|
||||
// Example APIs you might have:
|
||||
// GetTransform().SetLocalRotation(q);
|
||||
// or GetTransform().SetWorldRotation(q);
|
||||
|
||||
GetTransform().SetLocalRotation(q);
|
||||
}
|
||||
Reference in New Issue
Block a user