diff --git a/engine/inc/uf/utils/math/math.h b/engine/inc/uf/utils/math/math.h index e14bccd2..58231883 100644 --- a/engine/inc/uf/utils/math/math.h +++ b/engine/inc/uf/utils/math/math.h @@ -16,6 +16,12 @@ #define M_PI 3.141592653589793f #endif +#define EPS 1.0e-6f +#define EPS2 (EPS * EPS) + +#define RAD_2_DEG (180.0f / M_PI) +#define DEG_2_RAD (M_PI / 180.0f) + namespace pod { namespace Math { typedef float num_t; diff --git a/engine/inc/uf/utils/math/physics/structs.h b/engine/inc/uf/utils/math/physics/structs.h index 84277007..076cb745 100644 --- a/engine/inc/uf/utils/math/physics/structs.h +++ b/engine/inc/uf/utils/math/physics/structs.h @@ -16,9 +16,6 @@ #include - -#define EPS 1.0e-6f -#define EPS2 (EPS * EPS) #define ASSERT_COLLIDER_TYPES( A, B ) UF_ASSERT( a.collider.type == pod::ShapeType::A && b.collider.type == pod::ShapeType::B ); #define REORIENT_NORMALS_ON_FETCH 0 diff --git a/engine/inc/uf/utils/math/quaternion/pod.inl b/engine/inc/uf/utils/math/quaternion/pod.inl index fd567c21..3c5d73ae 100644 --- a/engine/inc/uf/utils/math/quaternion/pod.inl +++ b/engine/inc/uf/utils/math/quaternion/pod.inl @@ -150,14 +150,12 @@ template pod::Quaternion uf::quaternion::axisAngle( const pod::Ve return uf::quaternion::normalize( q ); } template pod::Quaternion uf::quaternion::unitVectors( const pod::Vector3t& u, const pod::Vector3t& v ) { - static const T EPSILON = static_cast(1e-6); - pod::Vector3t uNorm = uf::vector::normalize( u ); pod::Vector3t vNorm = uf::vector::normalize( v ); T dot = uf::vector::dot( uNorm, vNorm ); - if ( dot < -1 + EPSILON ) { + if ( dot < -1 + EPS ) { pod::Vector3t orthogonal = (fabs(uNorm.x) > fabs(uNorm.z)) ? pod::Vector3t{ -uNorm.y, uNorm.x, 0 } : pod::Vector3t{ 0, -uNorm.z, uNorm.y }; orthogonal = uf::vector::normalize( orthogonal ); return uf::quaternion::axisAngle( orthogonal, static_cast(M_PI) ); diff --git a/engine/inc/uf/utils/math/vector.h b/engine/inc/uf/utils/math/vector.h index 627271e1..898b4503 100644 --- a/engine/inc/uf/utils/math/vector.h +++ b/engine/inc/uf/utils/math/vector.h @@ -171,7 +171,7 @@ namespace uf { template /*FORCE_INLINE*/ T /*UF_API*/ orthonormalize( const T& x, const T& y ); // orthonormalizes a vector against another vector template /*FORCE_INLINE*/ size_t /*UF_API*/ hash( const T& vector ); // hashes a vector - template /*FORCE_INLINE*/ uf::stl::string /*UF_API*/ toString( const T& vector ); // parses a vector as a string + template /*FORCE_INLINE*/ uf::stl::string /*UF_API*/ toString( const T& vector, const uf::stl::string& = "Vector({})" ); // parses a vector as a string template /*FORCE_INLINE*/ ext::json::Value encode( const pod::Vector& v, const ext::json::EncodingSettings& = {} ); // parses a vector into a JSON value template /*FORCE_INLINE*/ pod::Vector& decode( const ext::json::Value& v, pod::Vector& ); // parses a JSON value into a vector @@ -273,7 +273,7 @@ DEFINE_VECTOR_EXT(T, 4); // stringify namespace uf { namespace string { - template FORCE_INLINE uf::stl::string toString( const pod::Vector& v ); + template FORCE_INLINE uf::stl::string toString( const pod::Vector& v, const uf::stl::string& = "Vector({})" ); } } // jsonify diff --git a/engine/inc/uf/utils/math/vector/pod.inl b/engine/inc/uf/utils/math/vector/pod.inl index 5d5928dd..48b44597 100644 --- a/engine/inc/uf/utils/math/vector/pod.inl +++ b/engine/inc/uf/utils/math/vector/pod.inl @@ -794,16 +794,13 @@ size_t uf::vector::hash( const T& v ) { } template -uf::stl::string uf::vector::toString( const T& v ) { +uf::stl::string uf::vector::toString( const T& v, const uf::stl::string& s ) { uf::stl::stringstream ss; - ss << "Vector("; - #pragma unroll // GCC unroll T::size - for ( auto i = 0; i < T::size; ++i ) { + FOR_EACH( T::size, { ss << v[i]; if ( i + 1 < T::size ) ss << ", "; - } - ss << ")"; - return ss.str(); + }); + return ::fmt::format( fmt::runtime(s), ss.str() ); } template diff --git a/engine/inc/uf/utils/math/vector/vector.inl b/engine/inc/uf/utils/math/vector/vector.inl index a41a5361..c4b2b8e4 100644 --- a/engine/inc/uf/utils/math/vector/vector.inl +++ b/engine/inc/uf/utils/math/vector/vector.inl @@ -1,8 +1,8 @@ #include "pod.inl" template -uf::stl::string /*UF_API*/ uf::string::toString( const pod::Vector& v ) { - return uf::vector::toString(v); +uf::stl::string /*UF_API*/ uf::string::toString( const pod::Vector& v, const uf::stl::string& s ) { + return uf::vector::toString(v, s); } template diff --git a/engine/src/engine/entity/entity.cpp b/engine/src/engine/entity/entity.cpp index 23858c0c..198f67e0 100644 --- a/engine/src/engine/entity/entity.cpp +++ b/engine/src/engine/entity/entity.cpp @@ -172,8 +172,8 @@ uf::Entity* uf::Entity::globalFindByName( const uf::stl::string& name ) { uf::stl::string uf::string::toString( const uf::Entity& entity ) { #if UF_USE_FMT - return ::fmt::format("{} ({}): {}", entity.getName(), entity.getUid(), (void*) &entity); + return ::fmt::format("({}): {}", entity.getUid(), entity.getName()); #else - return entity.getName() + " (" + std::to_string(entity.getUid()) + "): " + std::to_string(&entity); + return "(" + std::to_string(entity.getUid()) + ") :" + entity.getName(); #endif } \ No newline at end of file diff --git a/engine/src/engine/ext/player/behavior.cpp b/engine/src/engine/ext/player/behavior.cpp index f67dae72..e14f241e 100644 --- a/engine/src/engine/ext/player/behavior.cpp +++ b/engine/src/engine/ext/player/behavior.cpp @@ -426,8 +426,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { metadata.system.noclipped = state; if ( !state ) { uf::physics::setGravity( physicsBody ); - uf::physics::setColliderCategory( physicsBody, "ALL"); - uf::physics::setColliderMask( physicsBody, "ALL"); + uf::physics::setColliderCategory( physicsBody, "DYNAMIC"); + uf::physics::setColliderMask( physicsBody, "DYNAMIC"); } else { uf::physics::setGravity( physicsBody, pod::Vector3f{0,0,0}); uf::physics::setColliderCategory( physicsBody, "NONE"); diff --git a/engine/src/utils/debug/draw.cpp b/engine/src/utils/debug/draw.cpp index cab2dc87..c325256f 100644 --- a/engine/src/utils/debug/draw.cpp +++ b/engine/src/utils/debug/draw.cpp @@ -40,7 +40,7 @@ namespace impl { pod::GlyphSettings textSettings = { .alignment = "center", .font = "FragmentMono.ttf", - .size = 96, + .size = 24, .sdf = false, }; } @@ -220,20 +220,26 @@ void uf::debug::drawLines( float dt ) { } } - if ( impl::lines.empty() ) return; - // double buffer STATIC_THREAD_LOCAL(uf::stl::vector, lines); std::swap( impl::lines, lines ); impl::lineMesh.clear(); impl::lineMesh.bind(); + + // to-do: only do this when the previous mesh already had lines in it + // and if it was already empty just return + if ( lines.empty() ) { + lines.emplace_back( impl::Vertex{} ); + lines.emplace_back( impl::Vertex{} ); + } + impl::lineMesh.insertVertices(lines); impl::lineMesh.generateIndirect(); auto& scene = uf::scene::getCurrentScene(); auto& graphics = scene.getComponent(); - auto& graphic = graphics["immediate:lines"]; + if ( !graphic.initialized ) { graphic.device = &uf::renderer::device; graphic.material.device = &uf::renderer::device; @@ -275,8 +281,6 @@ void uf::debug::drawText( const uf::stl::string& string, const pod::Vector3f& po } void uf::debug::drawTexts( float dt ) { - if ( impl::texts.empty() ) return; - // double buffer STATIC_THREAD_LOCAL(uf::stl::vector, texts); std::swap( impl::texts, texts ); @@ -287,7 +291,7 @@ void uf::debug::drawTexts( float dt ) { uf::stl::vector textLayout; // pre-init with ASCII characters - if ( !impl::textAtlas.generated() ) { + if ( !impl::textAtlas.generated() || texts.empty() ) { uf::stl::string ascii = ""; for ( char c = 32; c < 127; ++c ) ascii += c; auto tokens = uf::glyph::parseTextTokens( ascii, {0,0,0,0} ); diff --git a/engine/src/utils/math/physics/constraints/contact.cpp b/engine/src/utils/math/physics/constraints/contact.cpp index 5dc75215..822c39aa 100644 --- a/engine/src/utils/math/physics/constraints/contact.cpp +++ b/engine/src/utils/math/physics/constraints/contact.cpp @@ -342,6 +342,9 @@ void impl::warmupManifold( pod::PhysicsBody& a, pod::PhysicsBody& b, const pod:: } void impl::resolveManifold( pod::PhysicsBody& a, pod::PhysicsBody& b, pod::Manifold& manifold, float dt ) { + // ignore if a body is a trigger + if ( (a.collider.category & pod::Collider::CATEGORY_TRIGGER) || (b.collider.category & pod::Collider::CATEGORY_TRIGGER) ) return; + if ( uf::physics::settings.blockContactSolver ) { if ( impl::blockSolver( a, b, manifold, dt ) ) return; } diff --git a/engine/src/utils/math/physics/draw.cpp b/engine/src/utils/math/physics/draw.cpp index d9b6d651..a8abea6c 100644 --- a/engine/src/utils/math/physics/draw.cpp +++ b/engine/src/utils/math/physics/draw.cpp @@ -55,37 +55,35 @@ void impl::drawBody( const pod::PhysicsBody& body ) { auto cameraAxes = uf::transform::axes( cameraTransform ); auto& projection = camera.getProjection(); auto fov = std::atan(1.0f / fabs(projection(1,1))); - auto viewThreshold = std::cos(fov * 1.5f); + auto angleThreshold = std::cos(fov * 1.5f); + auto viewThresholdSq = std::pow(5, 2); -#if 1 - // (an attempt to) continuously pick the closest point on the AABB + // continuously pick the closest point on the AABB auto position = impl::closestPointOnAABB( cameraTransform.position, bounds ); auto dir = position - cameraTransform.position; auto magSq = uf::vector::magnitude( dir ); if ( magSq > EPS2 ) dir /= std::sqrt( magSq ); auto dot = uf::vector::dot( cameraAxes.forward, dir ); position -= cameraAxes.forward * 0.1f; - if ( dot > viewThreshold ) uf::debug::drawText( body.object->getName(), position ); -#else - // picks the closest corner - int closestCorner = -1; - float closestDistanceSq = FLT_MAX; - float closestDot = FLT_MAX; // - pod::Vector3f corners[8]; - impl::getCorners( bounds, corners ); - for ( auto i = 0; i < 8; ++i ) { - auto dir = corners[i] - cameraTransform.position; - auto distanceSq = uf::vector::magnitude( dir ); - if ( distanceSq > EPS2 ) dir /= std::sqrt( distanceSq ); - auto dot = uf::vector::dot( cameraAxes.forward, dir ); - if ( dot <= viewThreshold ) continue; - if ( distanceSq >= closestDistanceSq ) continue; - closestDistanceSq = distanceSq; - closestCorner = i; - } - if ( 0 <= closestCorner ) uf::debug::drawText( body.object->getName(), corners[closestCorner] ); -#endif + if ( magSq < viewThresholdSq && dot > angleThreshold ) { + STATIC_THREAD_LOCAL(uf::stl::vector, strings); + strings.emplace_back( ::fmt::format("{}\n", uf::string::toString( *body.object ) ) ); + strings.emplace_back( ::fmt::format("Mass: {:.3f} kg\n", body.inverseMass == 0.0f ? 0.0f : 1.0f / body.inverseMass) ); + strings.emplace_back( ::fmt::format( + "Position: {} | Pitch: {:.1f} | Yaw: {:.1f} | Roll: {:.1f}\n", + uf::vector::toString( transform.position, "{}" ), + (RAD_2_DEG) * uf::quaternion::pitch( transform.orientation ), + (RAD_2_DEG) * uf::quaternion::yaw( transform.orientation ), + (RAD_2_DEG) * uf::quaternion::roll( transform.orientation ) + ) ); + if ( body.velocity != pod::Vector3f{} && body.angularVelocity != pod::Vector3f{} ) { + strings.emplace_back( ::fmt::format( "Velocity: {} | Angular Velocity: {}\n", uf::vector::toString( body.velocity, "{}" ), uf::vector::toString( body.angularVelocity, "{}" ) ) ); + } + strings.emplace_back( ::fmt::format("Awake: {} | Timer: {:.3f} | Grounded: {}\n", body.activity.awake, body.activity.sleepTimer, body.activity.grounded) ); + strings.emplace_back( ::fmt::format("Category: {:#X} | Mask: {:#X}", body.collider.category, body.collider.mask) ); + uf::debug::drawText( uf::string::join(strings, ""), position ); + } } void impl::drawConstraint( const pod::Constraint& constraint ) { if ( !uf::physics::settings.debugDraw.constraints ) return; diff --git a/engine/src/utils/text/glyph_.cpp b/engine/src/utils/text/glyph_.cpp index d6c13780..65118a7b 100644 --- a/engine/src/utils/text/glyph_.cpp +++ b/engine/src/utils/text/glyph_.cpp @@ -300,9 +300,6 @@ void uf::glyph::generateMesh( const uf::stl::vector& layout, cons for ( const auto& g : layout ) { auto hash = std::to_string( uf::glyph::hashSettings(g.code, metadata) ); - // zero-width - if ( g.box.w == 0 || g.box.h == 0 || g.color.w == 0.0f ) continue; - #if EXT_COLOR_FLOATS auto& color = g.color; #else