MODEL LOADING BABY WORKS

This commit is contained in:
2026-01-20 00:13:54 +01:00
parent 87dcbb50ec
commit b9878f2a06
31 changed files with 755 additions and 252 deletions

View 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));
}

View File

@@ -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);
}

View 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 Ill 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);
}