Nimbin[12]?SDL & Graphics / sdl_runtime_compiler / src/entities/game_object.hpp

sdl_runtime_compiler git · main

SDL3 game for running and compiling code at runtime

sdl3 c++ compiler dlopen cmake · first commit 2026-04-19 · last commit 2026-07-03 (3 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-runtime-compiler

C++ 72.3% C 26.2%
git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gz
src/entities/game_object.hpp 3 KB · 135 lines raw
#pragma once

#include <SDL3/SDL.h>

#include "utils/globals.hpp"
#include "utils/light.hpp"

namespace
Nimbin
{
class Camera;
class GlRenderer;


enum class ObjectType : uint8_t
{
    Text,
    Prop,
};


enum class PhysicsMode : uint8_t
{
    AiHover,
    Carried,
    Dynamic,
    Hover,
    Projectile,
    Static,
};


struct CollisionShape
{
    Vec3 half_extents{0.5, 0.5, 0.5};
};


struct RigidBody
{
    Vec3        vel  {};
    Vec3        force{};
    double      friction    {0.8};
    double      hover_height{0.0};
    double      hover_phase {0.0};
    double      mass        {1.0};
    double      restitution {0.3};
    bool        hover_disturbed{false};
    PhysicsMode mode {PhysicsMode::Hover};


    RigidBody(PhysicsMode m = PhysicsMode::Hover,
              double      mass_        = 1.0,
              double      restitution_ = 0.3,
              double      friction_    = 0.8
            ) : friction(friction_),
                mass(mass_),
                restitution(restitution_),
                mode(m)
    {}

    void apply_Force(const Vec3& f)
    {
        force.x += f.x;
        force.y += f.y;
        force.z += f.z;
    }

    void apply_KickImpulse(const Vec3& impulse)
    {
        if ( mode == PhysicsMode::Hover ||
             mode == PhysicsMode::AiHover) {
            mode = PhysicsMode::Dynamic;
            vel  = impulse;
        }
        else if (mode == PhysicsMode::Dynamic) {
            vel += impulse;
        }
    }

    void integrate(double dt)
    {
        if (mode != PhysicsMode::Dynamic) return;
        vel.x += (force.x / mass) * dt;
        vel.y += (force.y / mass) * dt;
        vel.z += (force.z / mass) * dt;
        force = {};
    }
};


struct GameObject
{
    CollisionShape shape;
    RigidBody      body;
    ObjectType     type{ObjectType::Text};

    Vec3  pos {};

    float yaw {0.0f};

    bool  carriable    {true};
    bool  interactable {true};
    bool  solid        {true};

    GameObject() {}

    GameObject(Vec3 p, ObjectType t, CollisionShape sh, RigidBody b,
               bool c = true, bool i = true, bool s = true)
        : shape(sh), body(b), type(t), pos(p), carriable(c), interactable(i), solid(s) {}

    virtual
         ~GameObject() = default;
    virtual void
         draw       (GlRenderer&, const Camera&, const Light&) const = 0;

    Vec3 aabb_Min   () const
    {
        const double c = SDL_fabs(SDL_cosf(yaw));
        const double s = SDL_fabs(SDL_sinf(yaw));
        const double ex = shape.half_extents.x * c + shape.half_extents.z * s;
        const double ez = shape.half_extents.x * s + shape.half_extents.z * c;
        return { pos.x - ex, pos.y - shape.half_extents.y, pos.z - ez };
    }
    Vec3 aabb_Max   () const
    {
        const double c  = SDL_fabs(SDL_cosf(yaw));
        const double s  = SDL_fabs(SDL_sinf(yaw));
        const double ex = shape.half_extents.x * c + shape.half_extents.z * s;
        const double ez = shape.half_extents.x * s + shape.half_extents.z * c;
        return { pos.x + ex, pos.y + shape.half_extents.y, pos.z + ez };
    }
};

} // namespace Nimbin