#include "../engine/Shared.h" #include "Global.h" #include "Instance.h" #include "bx/bx.h" #include "bx/math.h" #include #include #include namespace { SharedData* SharedInstance = nullptr; Game::GameInstance* GameInst = nullptr; } // namespace void Transform::CreateTransform(float* out, bx::Vec3 pos, bx::Quaternion rot, bx::Vec3 scale) { if (out == nullptr) return; float rMat[16]{0}; float tMat[16]{0}; float sMat[16]{0}; bx::mtxFromQuaternion(rMat, bx::Quaternion{rot.x, rot.y, rot.z, rot.w}); bx::mtxTranslate(tMat, pos.x, pos.y, pos.z); bx::mtxScale(sMat, scale.x, scale.y, scale.z); float buf[16]{0}; bx::mtxMul(buf, rMat, sMat); bx::mtxMul(out, buf, tMat); } void Transform::Translate(Vec3 offset) { Position = bx::add(Position, {offset.x, offset.y, offset.z}); } void Transform::TranslateLocal(Vec3 offset) { Vec3 localOffset = GlobalToLocalDirection(offset); Position = bx::add(Position, {localOffset.x, localOffset.y, localOffset.z}); } void Transform::Rotate(bx::Vec3 rotation) { float rot[16]{0}; bx::mtxRotateXYZ(rot, rotation.x, rotation.y, rotation.z); float temp[16]{0}; bx::mtxMul(temp, rot, Rotation.M); bx::memCopy(Rotation.M, temp, sizeof(temp)); } void Transform::RotateLocal(bx::Vec3 rotation) { float rot[16]{0}; bx::mtxRotateXYZ(rot, rotation.x, rotation.y, rotation.z); float temp[16]{0}; bx::mtxMul(temp, Rotation.M, rot); bx::memCopy(Rotation.M, temp, sizeof(temp)); } Vec3 Transform::Right() const { return {M.M[0], M.M[1], M.M[2]}; } Vec3 Transform::Up() const { return {M.M[4], M.M[5], M.M[6]}; } Vec3 Transform::Forward() const { return {M.M[8], M.M[9], M.M[10]}; } void Transform::UpdateMatrix() { Mat4 pos; Mat4 scale; bx::mtxTranslate(pos.M, Position.x, Position.y, Position.z); bx::mtxScale(scale.M, Scale.x, Scale.y, Scale.z); Mat4 temp; bx::mtxMul(temp.M, scale.M, Rotation.M); bx::mtxMul(M.M, pos.M, temp.M); bx::mtxInverse(MI.M, M.M); } namespace Game { SharedData& GetShared() { assert(SharedInstance != nullptr); return *SharedInstance; } void SetShared(SharedData& instance) { SharedInstance = &instance; } GameInstance& GetInstance() { assert(GameInst != nullptr); return *GameInst; } void SetInstance(Game::GameInstance& instance) { GameInst = &instance; } void* AllocateScratch(size_t byteCount, size_t align) { size_t offset = GetInstance().UsedScratchAmount; uint8_t* base = static_cast(GetShared().Game.TransientStorage); uint8_t* current = base + offset; size_t offsetAligned = ((offset + align - 1) / align) * align; uint8_t* ptrAligned = base + offsetAligned; size_t newOffset = offsetAligned + byteCount; if (newOffset > GetShared().Game.TransientStorageSize) return nullptr; GetInstance().UsedScratchAmount = newOffset; return reinterpret_cast(ptrAligned); } } // namespace Game Vec3 Transform::GlobalToLocalDirection(Vec3 global) { UpdateMatrix(); float in[4]{global.x, global.y, global.z, 0.0f}; float out[4]{0.0f}; bx::vec4MulMtx(out, in, MI.M); return {out[0], out[1], out[2]}; } bx::Vec3 Transform::GlobalToLocalPoint(bx::Vec3 global) { UpdateMatrix(); float in[4]{global.x, global.y, global.z, 1.0f}; float out[4]{0.0f}; bx::vec4MulMtx(out, in, MI.M); return {out[0], out[1], out[2]}; } Vec3 Transform::LocalToGlobalDirection(Vec3 local) { UpdateMatrix(); float in[4]{local.x, local.y, local.z, 0.0f}; float out[4]{0.0f}; Mat4 test = M.Transpose(); bx::vec4MulMtx(out, in, test.M); return {out[0], out[1], out[2]}; } bx::Vec3 Transform::LocalToGlobalPoint(bx::Vec3 local) { UpdateMatrix(); float in[4]{local.x, local.y, local.z, 1.0f}; float out[4]{0.0f}; bx::vec4MulMtx(out, in, M.M); return {out[0], out[1], out[2]}; } void Transform::SetPosition(Vec3 pos) { Position = {pos.x, pos.y, pos.z}; } Vec3 Transform::GetPosition() { return {Position.x, Position.y, Position.z}; } Mat4 Mat4::Inverse() { Mat4 result; bx::mtxInverse(result.M, M); return result; } Mat4 Mat4::Transpose() { Mat4 result; bx::mtxTranspose(result.M, M); return result; }