Compare commits

..

2 Commits

12 changed files with 54 additions and 54 deletions

View File

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

View File

@ -16,9 +16,6 @@
#include <cfloat>
#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

View File

@ -150,14 +150,12 @@ template<typename T> pod::Quaternion<T> uf::quaternion::axisAngle( const pod::Ve
return uf::quaternion::normalize( q );
}
template<typename T> pod::Quaternion<T> uf::quaternion::unitVectors( const pod::Vector3t<T>& u, const pod::Vector3t<T>& v ) {
static const T EPSILON = static_cast<T>(1e-6);
pod::Vector3t<T> uNorm = uf::vector::normalize( u );
pod::Vector3t<T> vNorm = uf::vector::normalize( v );
T dot = uf::vector::dot( uNorm, vNorm );
if ( dot < -1 + EPSILON ) {
if ( dot < -1 + EPS ) {
pod::Vector3t<T> orthogonal = (fabs(uNorm.x) > fabs(uNorm.z)) ? pod::Vector3t<T>{ -uNorm.y, uNorm.x, 0 } : pod::Vector3t<T>{ 0, -uNorm.z, uNorm.y };
orthogonal = uf::vector::normalize( orthogonal );
return uf::quaternion::axisAngle( orthogonal, static_cast<T>(M_PI) );

View File

@ -171,7 +171,7 @@ namespace uf {
template<typename T> /*FORCE_INLINE*/ T /*UF_API*/ orthonormalize( const T& x, const T& y ); // orthonormalizes a vector against another vector
template<typename T> /*FORCE_INLINE*/ size_t /*UF_API*/ hash( const T& vector ); // hashes a vector
template<typename T> /*FORCE_INLINE*/ uf::stl::string /*UF_API*/ toString( const T& vector ); // parses a vector as a string
template<typename T> /*FORCE_INLINE*/ uf::stl::string /*UF_API*/ toString( const T& vector, const uf::stl::string& = "Vector({})" ); // parses a vector as a string
template<typename T, size_t N> /*FORCE_INLINE*/ ext::json::Value encode( const pod::Vector<T,N>& v, const ext::json::EncodingSettings& = {} ); // parses a vector into a JSON value
template<typename T, size_t N> /*FORCE_INLINE*/ pod::Vector<T,N>& decode( const ext::json::Value& v, pod::Vector<T,N>& ); // parses a JSON value into a vector
@ -273,7 +273,7 @@ DEFINE_VECTOR_EXT(T, 4);
// stringify
namespace uf {
namespace string {
template<typename T, size_t N> FORCE_INLINE uf::stl::string toString( const pod::Vector<T,N>& v );
template<typename T, size_t N> FORCE_INLINE uf::stl::string toString( const pod::Vector<T,N>& v, const uf::stl::string& = "Vector({})" );
}
}
// jsonify

View File

@ -794,16 +794,13 @@ size_t uf::vector::hash( const T& v ) {
}
template<typename T>
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<typename T, size_t N>

View File

@ -1,8 +1,8 @@
#include "pod.inl"
template<typename T, size_t N>
uf::stl::string /*UF_API*/ uf::string::toString( const pod::Vector<T,N>& v ) {
return uf::vector::toString(v);
uf::stl::string /*UF_API*/ uf::string::toString( const pod::Vector<T,N>& v, const uf::stl::string& s ) {
return uf::vector::toString(v, s);
}
template<typename T, size_t N>

View File

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

View File

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

View File

@ -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<impl::Vertex>, lines);
std::swap( impl::lines, lines );
impl::lineMesh.clear();
impl::lineMesh.bind<impl::Vertex>();
// 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<impl::Vertex>(lines);
impl::lineMesh.generateIndirect();
auto& scene = uf::scene::getCurrentScene();
auto& graphics = scene.getComponent<uf::renderer::Graphics>();
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<impl::Text>, texts);
std::swap( impl::texts, texts );
@ -287,7 +291,7 @@ void uf::debug::drawTexts( float dt ) {
uf::stl::vector<pod::GlyphBox> 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} );

View File

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

View File

@ -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<uf::stl::string>, 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;

View File

@ -300,9 +300,6 @@ void uf::glyph::generateMesh( const uf::stl::vector<pod::GlyphBox>& 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