Commit for 2021.11.01 00-13-09.7z
This commit is contained in:
parent
386bf04eb9
commit
e16f3d77d7
6
Makefile
6
Makefile
@ -46,7 +46,7 @@ LINKS += $(UF_LIBS) $(EXT_LIBS) $(DEPS)
|
||||
DEPS +=
|
||||
|
||||
ifneq (,$(findstring win64,$(ARCH)))
|
||||
REQ_DEPS += $(RENDERER) json:nlohmann png zlib openal ogg freetype ncurses curl luajit bullet meshoptimizer xatlas simd ctti # openvr draco discord
|
||||
REQ_DEPS += $(RENDERER) json:nlohmann png zlib openal ogg freetype ncurses curl luajit reactphysics meshoptimizer xatlas simd ctti # openvr draco discord bullet
|
||||
FLAGS +=
|
||||
DEPS += -lgdi32
|
||||
else ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
@ -153,6 +153,10 @@ ifneq (,$(findstring bullet,$(REQ_DEPS)))
|
||||
INCS += -I./dep/bullet/
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring reactphysics,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_REACTPHYSICS
|
||||
DEPS += -lreactphysics3d
|
||||
endif
|
||||
ifneq (,$(findstring simd,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_SIMD -DUF_MATRIX_ALIGNED #-DUF_VECTOR_ALIGNED #-march=native
|
||||
|
||||
|
@ -141,14 +141,22 @@
|
||||
"json": "/json.lua"
|
||||
}
|
||||
},
|
||||
"reactphysics": {
|
||||
"timescale": 0.01666666666,
|
||||
"debug draw": {
|
||||
"enabled": false,
|
||||
// "layer": "Gui",
|
||||
"rate": 0.0125
|
||||
}
|
||||
},
|
||||
"bullet": {
|
||||
"iterations": 1,
|
||||
"substeps": 12,
|
||||
"substeps": 4,
|
||||
"timescale": 1,
|
||||
"multithreaded": false,
|
||||
"pool size": {
|
||||
"max collision algorithm": 1024,
|
||||
"max persistent manifold": 1024
|
||||
"max collision algorithm": 65535,
|
||||
"max persistent manifold": 65535
|
||||
},
|
||||
"debug draw": {
|
||||
"enabled": false,
|
||||
|
@ -32,7 +32,7 @@
|
||||
},
|
||||
|
||||
"gravity": [ 0, -9.81, 0 ],
|
||||
"inertia": [ 10, 10, 10 ],
|
||||
"inertia": [ 0, 0, 0 ],
|
||||
|
||||
"type": "capsule",
|
||||
"radius": 1,
|
||||
|
@ -2,6 +2,8 @@
|
||||
"assets": ["./scripts/door.lua"],
|
||||
"system": {
|
||||
"physics": {
|
||||
"mass": 0,
|
||||
"inertia": [0, 0, 0],
|
||||
"type": "bounding box",
|
||||
"recenter": true
|
||||
}
|
||||
|
11
bin/data/scenes/sh2_mcdonalds/prop.json
Normal file
11
bin/data/scenes/sh2_mcdonalds/prop.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"assets": [],
|
||||
"system": {
|
||||
"physics": {
|
||||
"mass": 0,
|
||||
"inertia": [0, 0, 0],
|
||||
"type": "bounding box",
|
||||
"recenter": true
|
||||
}
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
"import": "/scene.json",
|
||||
"assets": [
|
||||
"./audio/soundscape/ambience.ogg",
|
||||
"./loading.json",
|
||||
"./static.json"
|
||||
"./loading.json"
|
||||
// "./static.json"
|
||||
],
|
||||
"system": {
|
||||
"hot reload": {
|
||||
|
@ -86,7 +86,7 @@ ent:bind( "tick", function(self)
|
||||
end )
|
||||
-- on use
|
||||
ent:addHook( "entity:Use.%UID%", function( payload )
|
||||
if state == 0 then
|
||||
if state == 0 or state == 3 then
|
||||
state = 1
|
||||
playSound("default_move")
|
||||
if payload.uid ~= nil then
|
||||
@ -100,11 +100,8 @@ ent:addHook( "entity:Use.%UID%", function( payload )
|
||||
polarity = -1
|
||||
end
|
||||
end
|
||||
io.print(ent:name())
|
||||
end
|
||||
if state == 2 then
|
||||
elseif state == 2 or state == 1 then
|
||||
state = 3
|
||||
playSound("default_move")
|
||||
end
|
||||
io.print( state, json.encode( payload ) )
|
||||
end )
|
@ -13,16 +13,12 @@
|
||||
"alpha mode": "BLEND",
|
||||
"tags": {
|
||||
"worldspawn": { "physics": { "type": "mesh", "static": true } },
|
||||
"worldspawn_sh2": { "physics": { "type": "mesh", "static": true } },
|
||||
// "worldspawn_sh2": { "physics": { "type": "mesh", "static": true } },
|
||||
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },
|
||||
|
||||
"func_door_rotating_5409": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_door_rotating_5487": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
|
||||
"func_door_rotating_5495": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
|
||||
"func_door_rotating_5568": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_door_rotating_5568": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_door_rotating_5576": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_door_rotating_5584": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_door_rotating_5656": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
|
||||
"func_door_rotating_5664": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_door_rotating_5689": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
@ -31,7 +27,69 @@
|
||||
|
||||
"func_physbox_5212": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_physbox_5548": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_physbox_5931": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } }
|
||||
"func_physbox_5931": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
|
||||
"func_door_rotating_5568": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_door_rotating_5576": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_door_rotating_5584": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
|
||||
"func_physbox_5212": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_5548": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_5931": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5839": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5848": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5857": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5864": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5872": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5879": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5886": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5893": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5905": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"func_physbox_multiplayer_5913": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5563": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5564": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5687": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5719": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5721": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5722": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5815": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5816": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5817": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5818": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5819": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5820": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_multiplayer_5821": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5227": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5373": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5374": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5375": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5545": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5546": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5565": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5566": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5591": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5675": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5680": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5681": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5682": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5683": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5684": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5685": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5696": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5707": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5723": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5749": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5750": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5760": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5764": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5787": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5807": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5808": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5809": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5810": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5814": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5822": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5824": { "action": "load", "payload": { "import": "./prop.json" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,28 +12,39 @@
|
||||
#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
|
||||
#endif
|
||||
namespace pod {
|
||||
struct UF_API Bullet {
|
||||
struct UF_API Physics {
|
||||
size_t uid = 0;
|
||||
uf::Object* pointer = NULL;
|
||||
|
||||
pod::Transform<> transform;
|
||||
pod::Transform<> previous;
|
||||
|
||||
bool shared = false; // share control of the transform both in-engine and bullet, set to true if you're directly modifying the transform
|
||||
|
||||
#if UF_USE_BULLET
|
||||
btRigidBody* body = NULL;
|
||||
btCollisionShape* shape = NULL;
|
||||
#else
|
||||
void* body = NULL;
|
||||
void* shape = NULL;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
pod::Vector3 velocity;
|
||||
pod::Vector3 acceleration;
|
||||
} linear;
|
||||
|
||||
struct {
|
||||
pod::Quaternion<> velocity;
|
||||
pod::Quaternion<> acceleration;
|
||||
} rotational;
|
||||
|
||||
struct {
|
||||
uint32_t flags = 0;
|
||||
float mass = 0.0f;
|
||||
float friction = 0.8f;
|
||||
float restitution = 0.0f;
|
||||
pod::Vector3f inertia = {};
|
||||
pod::Vector3f gravity = {};
|
||||
pod::Vector3f inertia = {0, 0, 0};
|
||||
pod::Vector3f gravity = {0, 0, 0};
|
||||
} stats;
|
||||
};
|
||||
|
||||
typedef Physics PhysicsState;
|
||||
}
|
||||
#if UF_USE_BULLET
|
||||
namespace ext {
|
||||
@ -48,52 +59,43 @@ namespace ext {
|
||||
extern UF_API bool debugDrawEnabled;
|
||||
extern UF_API float debugDrawRate;
|
||||
extern UF_API uf::stl::string debugDrawLayer;
|
||||
extern UF_API float debugDrawLineWidth;
|
||||
|
||||
void UF_API initialize();
|
||||
void UF_API tick( float = 0 );
|
||||
void UF_API terminate();
|
||||
|
||||
// base collider creation
|
||||
pod::Bullet& create( uf::Object& );
|
||||
pod::PhysicsState& UF_API create( uf::Object& );
|
||||
|
||||
void destroy( uf::Object& );
|
||||
void destroy( pod::Bullet& );
|
||||
void UF_API destroy( uf::Object& );
|
||||
void UF_API destroy( pod::PhysicsState& );
|
||||
|
||||
void UF_API attach( pod::Bullet& );
|
||||
void UF_API detach( pod::Bullet& );
|
||||
void UF_API attach( pod::PhysicsState& );
|
||||
void UF_API detach( pod::PhysicsState& );
|
||||
|
||||
/*
|
||||
pod::Bullet& create( uf::Object&, const void* verticesPointer, size_t verticesCount, size_t verticesStride, const void* indicesPointer, size_t indicesCount, size_t indicesStride, bool );
|
||||
template<typename T, typename U>
|
||||
pod::Bullet& create( uf::Object& o, const uf::Mesh_T<T,U>& m, bool b ) {
|
||||
return create( o, m.vertices.data() + offsetof(T, position), m.vertices.size(), sizeof(T), m.indices.data(), m.indices.size(), sizeof(U), b );
|
||||
}
|
||||
*/
|
||||
// collider for mesh (static or dynamic)
|
||||
pod::Bullet& create( uf::Object&, const uf::Mesh&, bool );
|
||||
pod::PhysicsState& create( uf::Object&, const uf::Mesh&, bool );
|
||||
// collider for boundingbox
|
||||
pod::Bullet& UF_API create( uf::Object&, const pod::Vector3f& );
|
||||
uf::stl::vector<pod::Bullet>& UF_API create( uf::Object&, const uf::stl::vector<pod::Instance::Bounds>& );
|
||||
pod::PhysicsState& UF_API create( uf::Object&, const pod::Vector3f& );
|
||||
uf::stl::vector<pod::PhysicsState>& UF_API create( uf::Object&, const uf::stl::vector<pod::Instance::Bounds>& );
|
||||
// collider for capsule
|
||||
pod::Bullet& UF_API create( uf::Object&, float, float );
|
||||
pod::PhysicsState& UF_API create( uf::Object&, float, float );
|
||||
|
||||
// synchronize engine transforms to bullet transforms
|
||||
void UF_API syncToBullet();
|
||||
void UF_API syncTo();
|
||||
// synchronize bullet transforms to engine transforms
|
||||
void UF_API syncFromBullet();
|
||||
void UF_API syncFrom();
|
||||
// apply impulse
|
||||
void UF_API applyImpulse( pod::Bullet&, const pod::Vector3f& );
|
||||
void UF_API applyImpulse( pod::PhysicsState&, const pod::Vector3f& );
|
||||
// directly move a transform
|
||||
void UF_API applyMovement( pod::Bullet&, const pod::Vector3f& );
|
||||
void UF_API applyMovement( pod::PhysicsState&, const pod::Vector3f& );
|
||||
// directly apply a velocity
|
||||
void UF_API setVelocity( pod::Bullet&, const pod::Vector3f& );
|
||||
void UF_API applyVelocity( pod::Bullet&, const pod::Vector3f& );
|
||||
void UF_API setVelocity( pod::PhysicsState&, const pod::Vector3f& );
|
||||
void UF_API applyVelocity( pod::PhysicsState&, const pod::Vector3f& );
|
||||
// directly rotate a transform
|
||||
void UF_API applyRotation( pod::Bullet&, const pod::Quaternion<>& );
|
||||
void UF_API applyRotation( pod::Bullet&, const pod::Vector3f&, float );
|
||||
|
||||
// picks an appropriate movement option
|
||||
// void UF_API move( pod::Bullet&, const pod::Vector3f&, bool = false );
|
||||
void UF_API applyRotation( pod::PhysicsState&, const pod::Quaternion<>& );
|
||||
void UF_API applyRotation( pod::PhysicsState&, const pod::Vector3f&, float );
|
||||
|
||||
// ray casting
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f& );
|
||||
@ -101,7 +103,7 @@ namespace ext {
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*& );
|
||||
|
||||
// allows noclip
|
||||
void UF_API activateCollision( pod::Bullet&, bool = true );
|
||||
void UF_API activateCollision( pod::PhysicsState&, bool = true );
|
||||
|
||||
// allows showing collision models
|
||||
void UF_API debugDraw( uf::Object& );
|
||||
|
105
engine/inc/uf/ext/reactphysics/reactphysics.h
Normal file
105
engine/inc/uf/ext/reactphysics/reactphysics.h
Normal file
@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/engine/object/object.h>
|
||||
#include <uf/utils/math/transform.h>
|
||||
#include <uf/utils/mesh/mesh.h>
|
||||
#include <uf/utils/math/collision.h>
|
||||
#include <uf/engine/graph/graph.h>
|
||||
|
||||
#if UF_USE_REACTPHYSICS
|
||||
#include <reactphysics3d/reactphysics3d.h>
|
||||
|
||||
namespace rp3d = reactphysics3d;
|
||||
|
||||
namespace pod {
|
||||
struct UF_API Physics {
|
||||
size_t uid = 0;
|
||||
uf::Object* object = NULL;
|
||||
bool shared = false; // share control of the transform both in-engine and bullet, set to true if you're directly modifying the transform
|
||||
rp3d::RigidBody* body = NULL;
|
||||
rp3d::CollisionShape* shape = NULL;
|
||||
|
||||
pod::Transform<> transform = {};
|
||||
pod::Transform<> previous = {};
|
||||
|
||||
struct {
|
||||
pod::Vector3 velocity;
|
||||
pod::Vector3 acceleration;
|
||||
} linear;
|
||||
|
||||
struct {
|
||||
pod::Quaternion<> velocity;
|
||||
pod::Quaternion<> acceleration;
|
||||
} rotational;
|
||||
|
||||
struct {
|
||||
uint32_t flags = 0;
|
||||
|
||||
float mass = 0.0f;
|
||||
float friction = 0.8f;
|
||||
float restitution = 0.0f;
|
||||
pod::Vector3f inertia = {0, 0, 0};
|
||||
pod::Vector3f gravity = {0, 0, 0};
|
||||
} stats;
|
||||
};
|
||||
|
||||
typedef Physics PhysicsState;
|
||||
}
|
||||
|
||||
namespace ext {
|
||||
namespace reactphysics {
|
||||
void UF_API initialize();
|
||||
void UF_API tick( float = 0 );
|
||||
void UF_API terminate();
|
||||
|
||||
extern UF_API float timescale;
|
||||
extern UF_API bool debugDrawEnabled;
|
||||
extern UF_API float debugDrawRate;
|
||||
extern UF_API uf::stl::string debugDrawLayer;
|
||||
extern UF_API float debugDrawLineWidth;
|
||||
|
||||
// base collider creation
|
||||
pod::PhysicsState& UF_API create( uf::Object& );
|
||||
|
||||
void UF_API destroy( uf::Object& );
|
||||
void UF_API destroy( pod::PhysicsState& );
|
||||
|
||||
void UF_API attach( pod::PhysicsState& );
|
||||
void UF_API detach( pod::PhysicsState& );
|
||||
|
||||
// collider for mesh (static or dynamic)
|
||||
pod::PhysicsState& create( uf::Object&, const uf::Mesh&, bool );
|
||||
// collider for boundingbox
|
||||
pod::PhysicsState& UF_API create( uf::Object&, const pod::Vector3f& );
|
||||
// collider for capsule
|
||||
pod::PhysicsState& UF_API create( uf::Object&, float, float );
|
||||
|
||||
// synchronize engine transforms to bullet transforms
|
||||
void UF_API syncTo();
|
||||
// synchronize bullet transforms to engine transforms
|
||||
void UF_API syncFrom();
|
||||
// apply impulse
|
||||
void UF_API applyImpulse( pod::PhysicsState&, const pod::Vector3f& );
|
||||
// directly move a transform
|
||||
void UF_API applyMovement( pod::PhysicsState&, const pod::Vector3f& );
|
||||
// directly apply a velocity
|
||||
void UF_API setVelocity( pod::PhysicsState&, const pod::Vector3f& );
|
||||
void UF_API applyVelocity( pod::PhysicsState&, const pod::Vector3f& );
|
||||
// directly rotate a transform
|
||||
void UF_API applyRotation( pod::PhysicsState&, const pod::Quaternion<>& );
|
||||
void UF_API applyRotation( pod::PhysicsState&, const pod::Vector3f&, float );
|
||||
|
||||
// ray casting
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f& );
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, size_t& );
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*& );
|
||||
|
||||
// allows noclip
|
||||
void UF_API activateCollision( pod::PhysicsState&, bool = true );
|
||||
|
||||
// allows showing collision models
|
||||
void UF_API debugDraw( uf::Object& );
|
||||
}
|
||||
}
|
||||
#endif
|
@ -4,22 +4,20 @@
|
||||
#include <uf/utils/math/transform.h>
|
||||
#include <uf/utils/time/time.h>
|
||||
|
||||
namespace pod {
|
||||
struct UF_API Physics {
|
||||
struct {
|
||||
pod::Vector3 velocity;
|
||||
pod::Vector3 acceleration;
|
||||
} linear;
|
||||
struct {
|
||||
pod::Quaternion<> velocity;
|
||||
pod::Quaternion<> acceleration;
|
||||
} rotational;
|
||||
pod::Transform<> previous;
|
||||
};
|
||||
}
|
||||
#if UF_USE_BULLET
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#elif UF_USE_REACTPHYSICS
|
||||
#include <uf/ext/reactphysics/reactphysics.h>
|
||||
#endif
|
||||
|
||||
namespace uf {
|
||||
namespace physics {
|
||||
#if UF_USE_BULLET
|
||||
namespace impl = ext::bullet;
|
||||
#elif UF_USE_REACTPHYSICS
|
||||
namespace impl = ext::reactphysics;
|
||||
#endif
|
||||
|
||||
typedef pod::Math::num_t num_t;
|
||||
namespace time {
|
||||
|
||||
@ -29,7 +27,9 @@ namespace uf {
|
||||
extern UF_API uf::physics::num_t delta;
|
||||
extern UF_API uf::physics::num_t clamp;
|
||||
}
|
||||
void UF_API initialize();
|
||||
void UF_API tick();
|
||||
void UF_API terminate();
|
||||
template<typename T> pod::Transform<T>& update( pod::Transform<T>& transform, pod::Physics& physics );
|
||||
template<typename T> pod::Transform<T>& update( pod::Physics& physics, pod::Transform<T>& transform );
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include <uf/engine/graph/graph.h>
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#include <uf/ext/gltf/gltf.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/utils/mesh/grid.h>
|
||||
#include <uf/utils/thread/thread.h>
|
||||
#include <uf/utils/string/base64.h>
|
||||
#include <uf/utils/graphic/graphic.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/utils/camera/camera.h>
|
||||
#include <uf/ext/xatlas/xatlas.h>
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include <uf/engine/graph/graph.h>
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#include <uf/ext/gltf/gltf.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/utils/mesh/grid.h>
|
||||
@ -7,6 +6,7 @@
|
||||
#include <uf/utils/string/base64.h>
|
||||
#include <uf/utils/graphic/graphic.h>
|
||||
#include <uf/utils/camera/camera.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/ext/xatlas/xatlas.h>
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include <uf/engine/graph/graph.h>
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#include <uf/ext/gltf/gltf.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/utils/mesh/grid.h>
|
||||
@ -7,6 +6,7 @@
|
||||
#include <uf/utils/string/base64.h>
|
||||
#include <uf/utils/graphic/graphic.h>
|
||||
#include <uf/utils/camera/camera.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/ext/xatlas/xatlas.h>
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
@ -694,17 +694,16 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
|
||||
if ( ext::json::isObject( info ) ) {
|
||||
uf::stl::string type = info["type"].as<uf::stl::string>();
|
||||
#if UF_USE_BULLET
|
||||
|
||||
if ( type == "mesh" ) {
|
||||
auto& collider = entity.getComponent<pod::Bullet>();
|
||||
auto& collider = entity.getComponent<pod::PhysicsState>();
|
||||
collider.stats.mass = info["mass"].as(collider.stats.mass);
|
||||
collider.stats.friction = info["friction"].as(collider.stats.friction);
|
||||
collider.stats.restitution = info["restitution"].as(collider.stats.restitution);
|
||||
collider.stats.inertia = uf::vector::decode( info["inertia"], collider.stats.inertia );
|
||||
collider.stats.gravity = uf::vector::decode( info["gravity"], collider.stats.gravity );
|
||||
|
||||
ext::bullet::create( entity.as<uf::Object>(), mesh, !info["static"].as<bool>(true) );
|
||||
uf::physics::impl::create( entity.as<uf::Object>(), mesh, !info["static"].as<bool>(true) );
|
||||
} else {
|
||||
auto min = uf::matrix::multiply<float>( model, bounds.min, 1.0f );
|
||||
auto max = uf::matrix::multiply<float>( model, bounds.max, 1.0f );
|
||||
@ -715,7 +714,6 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
metadataJson["system"]["physics"]["center"] = uf::vector::encode( center );
|
||||
metadataJson["system"]["physics"]["corner"] = uf::vector::encode( corner );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include <uf/utils/camera/camera.h>
|
||||
#include <uf/utils/mesh/mesh.h>
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/ext/gltf/gltf.h>
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
|
||||
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Object)
|
||||
UF_BEHAVIOR_TRAITS_CPP(uf::ObjectBehavior, ticks = true, renders = false, multithread = false)
|
||||
@ -114,9 +114,9 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
});
|
||||
metadata.deserialize(self, metadataJson);
|
||||
|
||||
#if UF_USE_BULLET
|
||||
if ( ext::json::isObject(metadataJson["system"]["physics"]) ) {
|
||||
auto& collider = this->getComponent<pod::Bullet>();
|
||||
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||
collider.stats.flags = metadataJson["system"]["physics"]["flags"].as(collider.stats.flags);
|
||||
collider.stats.mass = metadataJson["system"]["physics"]["mass"].as(collider.stats.mass);
|
||||
collider.stats.restitution = metadataJson["system"]["physics"]["restitution"].as(collider.stats.restitution);
|
||||
collider.stats.friction = metadataJson["system"]["physics"]["friction"].as(collider.stats.friction);
|
||||
@ -127,18 +127,16 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
pod::Vector3f center = uf::vector::decode( metadataJson["system"]["physics"]["center"], pod::Vector3f{} );
|
||||
pod::Vector3f corner = uf::vector::decode( metadataJson["system"]["physics"]["corner"], pod::Vector3f{0.5, 0.5, 0.5} );
|
||||
|
||||
ext::bullet::create( *this, corner );
|
||||
|
||||
if ( metadataJson["system"]["physics"]["recenter"].as<bool>() ) collider.transform.position = center - transform.position;
|
||||
if ( metadataJson["system"]["physics"]["recenter"].as<bool>() ) collider.transform.position = (center - transform.position) * 0.5f;
|
||||
|
||||
uf::physics::impl::create( *this, corner );
|
||||
} else if ( metadataJson["system"]["physics"]["type"].as<uf::stl::string>() == "capsule" ) {
|
||||
float radius = metadataJson["system"]["physics"]["radius"].as<float>();
|
||||
float height = metadataJson["system"]["physics"]["height"].as<float>();
|
||||
|
||||
ext::bullet::create( *this, radius, height );
|
||||
uf::physics::impl::create( *this, radius, height );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void uf::ObjectBehavior::destroy( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
|
||||
@ -221,8 +219,8 @@ void uf::ObjectBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
|
||||
/*
|
||||
if ( this->hasComponent<pod::Bullet>() && this->hasComponent<pod::Physics>() ) {
|
||||
auto& collider = this->getComponent<pod::Bullet>();
|
||||
if ( this->hasComponent<pod::PhysicsState>() && this->hasComponent<pod::Physics>() ) {
|
||||
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& physics = this->getComponent<pod::Physics>();
|
||||
UF_MSG_DEBUG( this->getName() << ": " << this->getUid() << " " << uf::vector::toString( physics.linear.velocity ) << " " << uf::vector::toString( transform.position ) );
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#if UF_USE_BULLET
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
@ -80,6 +80,7 @@ size_t ext::bullet::defaultMaxPersistentManifoldPoolSize = 65535;
|
||||
bool ext::bullet::debugDrawEnabled = false;
|
||||
float ext::bullet::debugDrawRate = 1.0f;
|
||||
uf::stl::string ext::bullet::debugDrawLayer = "";
|
||||
float ext::bullet::debugDrawLineWidth = 1.0f;
|
||||
|
||||
namespace ext {
|
||||
namespace bullet {
|
||||
@ -143,12 +144,24 @@ void ext::bullet::initialize() {
|
||||
#endif
|
||||
}
|
||||
void ext::bullet::tick( float delta ) { if ( delta == 0.0f ) delta = uf::physics::time::delta;
|
||||
ext::bullet::syncToBullet();
|
||||
ext::bullet::syncTo();
|
||||
|
||||
static float accumulator = 0;
|
||||
static const float timeStep = 1.0f / 60.0f;
|
||||
|
||||
accumulator += uf::physics::time::delta;
|
||||
|
||||
while ( accumulator >= timeStep ) {
|
||||
ext::bullet::dynamicsWorld->stepSimulation( delta, ext::bullet::substeps, timeStep );
|
||||
accumulator -= timeStep;
|
||||
}
|
||||
/*
|
||||
delta = delta * ext::bullet::timescale / ext::bullet::iterations;
|
||||
for ( size_t i = 0; i < ext::bullet::iterations; ++i ) {
|
||||
ext::bullet::dynamicsWorld->stepSimulation(delta, ext::bullet::substeps, delta / ext::bullet::substeps);
|
||||
}
|
||||
ext::bullet::syncFromBullet();
|
||||
*/
|
||||
ext::bullet::syncFrom();
|
||||
TIMER(ext::bullet::debugDrawRate, ext::bullet::debugDrawEnabled && ) {
|
||||
ext::bullet::dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
@ -174,8 +187,7 @@ void ext::bullet::terminate() {
|
||||
if ( ext::bullet::collisionConfiguration ) delete ext::bullet::collisionConfiguration;
|
||||
ext::bullet::collisionShapes.clear();
|
||||
}
|
||||
void ext::bullet::syncToBullet() {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
void ext::bullet::syncTo() {
|
||||
// update bullet transforms
|
||||
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {
|
||||
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
|
||||
@ -184,16 +196,15 @@ void ext::bullet::syncToBullet() {
|
||||
if ( !body || !body->getMotionState() ) return;
|
||||
|
||||
uf::Object* entity = (uf::Object*) body->getUserPointer();
|
||||
if ( !entity || !entity->isValid() || !entity->hasComponent<pod::Bullet>() ) continue;
|
||||
if ( !entity || !entity->isValid() || !entity->hasComponent<pod::PhysicsState>() ) continue;
|
||||
|
||||
auto& collider = entity->getComponent<pod::Bullet>();
|
||||
auto& collider = entity->getComponent<pod::PhysicsState>();
|
||||
if ( !collider.shared ) continue;
|
||||
|
||||
auto& physics = entity->getComponent<pod::Physics>();
|
||||
auto model = uf::transform::model( collider.transform );
|
||||
|
||||
btTransform t;
|
||||
t = body->getWorldTransform();
|
||||
btTransform t = body->getWorldTransform();
|
||||
t.setFromOpenGLMatrix(&model[0]);
|
||||
// t.setOrigin( btVector3( transform.position.x, transform.position.y, transform.position.z ) );
|
||||
// t.setRotation( btQuaternion( transform.orientation.x, transform.orientation.y, transform.orientation.z, transform.orientation.w ) );
|
||||
@ -203,20 +214,18 @@ void ext::bullet::syncToBullet() {
|
||||
body->setLinearVelocity( btVector3( physics.linear.velocity.x, physics.linear.velocity.y, physics.linear.velocity.z ) );
|
||||
}
|
||||
}
|
||||
void ext::bullet::syncFromBullet() {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
void ext::bullet::syncFrom() {
|
||||
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {
|
||||
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if ( !body || !body->getMotionState() ) return;
|
||||
btTransform t;
|
||||
body->getMotionState()->getWorldTransform(t);
|
||||
btTransform t = body->getWorldTransform();
|
||||
// body->getMotionState()->getWorldTransform(t);
|
||||
|
||||
uf::Object* entity = (uf::Object*) body->getUserPointer();
|
||||
if ( !entity || !entity->isValid() || !entity->hasComponent<pod::Bullet>() ) continue;
|
||||
size_t uid = entity->getUid();
|
||||
if ( !entity || !entity->isValid() || !entity->hasComponent<pod::PhysicsState>() ) continue;
|
||||
|
||||
auto& collider = entity->getComponent<pod::Bullet>();
|
||||
auto& collider = entity->getComponent<pod::PhysicsState>();
|
||||
|
||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||
transform.position.x = t.getOrigin().getX();
|
||||
@ -243,8 +252,8 @@ void ext::bullet::syncFromBullet() {
|
||||
transform = uf::transform::reorient( transform );
|
||||
}
|
||||
}
|
||||
pod::Bullet& ext::bullet::create( uf::Object& object ) {
|
||||
auto& collider = object.getComponent<pod::Bullet>();
|
||||
pod::PhysicsState& ext::bullet::create( uf::Object& object ) {
|
||||
auto& collider = object.getComponent<pod::PhysicsState>();
|
||||
|
||||
collider.uid = object.getUid();
|
||||
collider.pointer = &object;
|
||||
@ -252,7 +261,7 @@ pod::Bullet& ext::bullet::create( uf::Object& object ) {
|
||||
collider.shared = true;
|
||||
return collider;
|
||||
}
|
||||
void ext::bullet::attach( pod::Bullet& collider ) {
|
||||
void ext::bullet::attach( pod::PhysicsState& collider ) {
|
||||
if ( !collider.shape ) return;
|
||||
|
||||
auto model = uf::transform::model( collider.transform );
|
||||
@ -273,22 +282,26 @@ void ext::bullet::attach( pod::Bullet& collider ) {
|
||||
collider.body->setFriction(collider.stats.friction);
|
||||
collider.body->setGravity( btVector3( collider.stats.gravity.x, collider.stats.gravity.y, collider.stats.gravity.z ) );
|
||||
|
||||
if ( collider.stats.mass > 0 ) {
|
||||
// collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||
// collider.body->activate(true);
|
||||
// collider.body->setActivationState(DISABLE_DEACTIVATION);
|
||||
/*
|
||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | collider.stats.flags);
|
||||
if ( collider.stats.mass != 0.0f ) {
|
||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | ~btCollisionObject::CF_STATIC_OBJECT);
|
||||
} else {
|
||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
|
||||
}
|
||||
|
||||
collider.body->activate(true);
|
||||
collider.body->setActivationState(DISABLE_DEACTIVATION);
|
||||
*/
|
||||
ext::bullet::dynamicsWorld->addRigidBody(collider.body);
|
||||
ext::bullet::collisionShapes.push_back(collider.shape);
|
||||
}
|
||||
|
||||
void ext::bullet::detach( pod::Bullet& collider ) {
|
||||
void ext::bullet::detach( pod::PhysicsState& collider ) {
|
||||
if ( !collider.body || !collider.shape ) return;
|
||||
ext::bullet::dynamicsWorld->removeCollisionObject( collider.body );
|
||||
}
|
||||
|
||||
pod::Bullet& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh, bool dynamic ) {
|
||||
pod::PhysicsState& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh, bool dynamic ) {
|
||||
btTriangleIndexVertexArray* bMesh = new btTriangleIndexVertexArray();
|
||||
|
||||
if ( mesh.index.count ) {
|
||||
@ -342,6 +355,7 @@ pod::Bullet& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh, bool
|
||||
|
||||
auto& collider = ext::bullet::create( object );
|
||||
collider.shape = new btBvhTriangleMeshShape( bMesh, true, true );
|
||||
collider.stats.mass = 0;
|
||||
ext::bullet::attach( collider );
|
||||
|
||||
auto& transform = object.getComponent<pod::Transform<>>();
|
||||
@ -351,6 +365,7 @@ pod::Bullet& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh, bool
|
||||
collider.body->setWorldTransform(t);
|
||||
collider.body->setCenterOfMassTransform(t);
|
||||
|
||||
/*
|
||||
btBvhTriangleMeshShape* triangleMeshShape = (btBvhTriangleMeshShape*) collider.shape;
|
||||
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
|
||||
triangleInfoMap->m_edgeDistanceThreshold = 0.01f;
|
||||
@ -359,58 +374,10 @@ pod::Bullet& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh, bool
|
||||
btGenerateInternalEdgeInfo( triangleMeshShape, triangleInfoMap );
|
||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
||||
}
|
||||
return collider;
|
||||
}
|
||||
/*
|
||||
pod::Bullet& ext::bullet::create( uf::Object& object, const void* verticesPointer, size_t verticesCount, size_t verticesStride, const void* indicesPointer, size_t indicesCount, size_t indicesStride, bool dynamic ) {
|
||||
btTriangleIndexVertexArray* bMesh = new btTriangleIndexVertexArray();
|
||||
|
||||
if ( indicesCount ) {
|
||||
PHY_ScalarType indexType = PHY_INTEGER;
|
||||
PHY_ScalarType vertexType = PHY_FLOAT;
|
||||
switch ( indicesStride ) {
|
||||
case 1: indexType = PHY_UCHAR; break;
|
||||
case 2: indexType = PHY_SHORT; break;
|
||||
case 4: indexType = PHY_INTEGER; break;
|
||||
}
|
||||
|
||||
const uint8_t* indicesBuffer = (const uint8_t*) indicesPointer;
|
||||
const uint8_t* verticesBuffer = (const uint8_t*) verticesPointer;
|
||||
|
||||
btIndexedMesh iMesh;
|
||||
iMesh.m_numTriangles = indicesCount / 3;
|
||||
iMesh.m_triangleIndexBase = indicesBuffer;
|
||||
iMesh.m_triangleIndexStride = 3 * indicesStride;
|
||||
iMesh.m_numVertices = verticesCount;
|
||||
iMesh.m_vertexBase = verticesBuffer;
|
||||
iMesh.m_vertexStride = verticesStride;
|
||||
iMesh.m_indexType = indexType;
|
||||
iMesh.m_vertexType = vertexType;
|
||||
bMesh->addIndexedMesh( iMesh, indexType );
|
||||
} else UF_EXCEPTION("to-do: not require indices for meshes");
|
||||
|
||||
|
||||
auto& collider = ext::bullet::create( object );
|
||||
collider.shape = new btBvhTriangleMeshShape( bMesh, true, true );
|
||||
ext::bullet::attach( collider );
|
||||
|
||||
auto& transform = object.getComponent<pod::Transform<>>();
|
||||
auto model = uf::transform::model( collider.transform );
|
||||
btTransform t = collider.body->getWorldTransform();
|
||||
t.setFromOpenGLMatrix(&model[0]);
|
||||
collider.body->setWorldTransform(t);
|
||||
collider.body->setCenterOfMassTransform(t);
|
||||
|
||||
btBvhTriangleMeshShape* triangleMeshShape = (btBvhTriangleMeshShape*) collider.shape;
|
||||
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
|
||||
triangleInfoMap->m_edgeDistanceThreshold = 0.01f;
|
||||
triangleInfoMap->m_maxEdgeAngleThreshold = SIMD_HALF_PI*0.25;
|
||||
if ( !false ) btGenerateInternalEdgeInfo( triangleMeshShape, triangleInfoMap );
|
||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
||||
return collider;
|
||||
}
|
||||
*/
|
||||
pod::Bullet& ext::bullet::create( uf::Object& object, const pod::Vector3f& corner ) {
|
||||
return collider;
|
||||
}
|
||||
pod::PhysicsState& ext::bullet::create( uf::Object& object, const pod::Vector3f& corner ) {
|
||||
auto& collider = ext::bullet::create( object );
|
||||
collider.shape = new btBoxShape(btVector3(corner.x, corner.y, corner.z));
|
||||
ext::bullet::attach( collider );
|
||||
@ -418,14 +385,14 @@ pod::Bullet& ext::bullet::create( uf::Object& object, const pod::Vector3f& corne
|
||||
auto& transform = object.getComponent<pod::Transform<>>();
|
||||
auto model = uf::transform::model( collider.transform );
|
||||
|
||||
collider.body->setContactProcessingThreshold(0.0);
|
||||
collider.body->setAngularFactor(0.0);
|
||||
collider.body->setCcdMotionThreshold(1e-7);
|
||||
collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
|
||||
// collider.body->setContactProcessingThreshold(0.0);
|
||||
// collider.body->setAngularFactor(0.0);
|
||||
// collider.body->setCcdMotionThreshold(1e-7);
|
||||
// collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
|
||||
return collider;
|
||||
}
|
||||
uf::stl::vector<pod::Bullet>& ext::bullet::create( uf::Object& object, const uf::stl::vector<pod::Instance::Bounds>& bounds ) {
|
||||
auto& colliders = object.getComponent<uf::stl::vector<pod::Bullet>>();
|
||||
uf::stl::vector<pod::PhysicsState>& ext::bullet::create( uf::Object& object, const uf::stl::vector<pod::Instance::Bounds>& bounds ) {
|
||||
auto& colliders = object.getComponent<uf::stl::vector<pod::PhysicsState>>();
|
||||
colliders.reserve(colliders.size() + bounds.size());
|
||||
|
||||
auto& transform = object.getComponent<pod::Transform<>>();
|
||||
@ -446,15 +413,15 @@ uf::stl::vector<pod::Bullet>& ext::bullet::create( uf::Object& object, const uf:
|
||||
collider.shape = new btBoxShape(btVector3(corner.x, corner.y, corner.z));
|
||||
ext::bullet::attach( collider );
|
||||
|
||||
collider.body->setContactProcessingThreshold(0.0);
|
||||
collider.body->setAngularFactor(0.0);
|
||||
collider.body->setCcdMotionThreshold(1e-7);
|
||||
collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
|
||||
// collider.body->setContactProcessingThreshold(0.0);
|
||||
// collider.body->setAngularFactor(0.0);
|
||||
// collider.body->setCcdMotionThreshold(1e-7);
|
||||
// collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
|
||||
}
|
||||
return colliders;
|
||||
}
|
||||
|
||||
pod::Bullet& ext::bullet::create( uf::Object& object, float radius, float height ) {
|
||||
pod::PhysicsState& ext::bullet::create( uf::Object& object, float radius, float height ) {
|
||||
auto& collider = ext::bullet::create( object );
|
||||
collider.shape = new btCapsuleShape(radius, height);
|
||||
ext::bullet::attach( collider );
|
||||
@ -470,7 +437,7 @@ pod::Bullet& ext::bullet::create( uf::Object& object, float radius, float height
|
||||
return collider;
|
||||
}
|
||||
|
||||
void UF_API ext::bullet::setVelocity( pod::Bullet& collider, const pod::Vector3f& v ) {
|
||||
void UF_API ext::bullet::setVelocity( pod::PhysicsState& collider, const pod::Vector3f& v ) {
|
||||
if ( !collider.body ) return;
|
||||
collider.body->activate(true);
|
||||
if ( collider.shared ) {
|
||||
@ -480,24 +447,26 @@ void UF_API ext::bullet::setVelocity( pod::Bullet& collider, const pod::Vector3f
|
||||
collider.body->setLinearVelocity( btVector3( v.x, v.y, v.z ) );
|
||||
}
|
||||
}
|
||||
void UF_API ext::bullet::applyImpulse( pod::Bullet& collider, const pod::Vector3f& v ) {
|
||||
void UF_API ext::bullet::applyImpulse( pod::PhysicsState& collider, const pod::Vector3f& v ) {
|
||||
if ( !collider.body ) return;
|
||||
collider.body->activate(true);
|
||||
collider.body->applyCentralImpulse( btVector3( v.x, v.y, v.z ) /** uf::physics::time::delta*/ );
|
||||
}
|
||||
void UF_API ext::bullet::applyMovement( pod::Bullet& collider, const pod::Vector3f& v ) {
|
||||
void UF_API ext::bullet::applyMovement( pod::PhysicsState& collider, const pod::Vector3f& v ) {
|
||||
if ( !collider.body ) return;
|
||||
btTransform transform;
|
||||
collider.body->activate(true);
|
||||
|
||||
collider.body->getMotionState()->getWorldTransform(transform);
|
||||
btTransform transform = collider.body->getWorldTransform();
|
||||
// collider.body->getMotionState()->getWorldTransform(transform);
|
||||
|
||||
transform.setOrigin( transform.getOrigin() + btVector3( v.x, v.y, v.z ) * uf::physics::time::delta );
|
||||
|
||||
collider.body->getMotionState()->setWorldTransform(transform);
|
||||
// collider.body->getMotionState()->setWorldTransform(transform);
|
||||
collider.body->setWorldTransform(transform);
|
||||
|
||||
collider.body->setCenterOfMassTransform(transform);
|
||||
}
|
||||
void UF_API ext::bullet::applyVelocity( pod::Bullet& collider, const pod::Vector3f& v ) {
|
||||
void UF_API ext::bullet::applyVelocity( pod::PhysicsState& collider, const pod::Vector3f& v ) {
|
||||
if ( !collider.body ) return;
|
||||
collider.body->activate(true);
|
||||
|
||||
@ -508,10 +477,10 @@ void UF_API ext::bullet::applyVelocity( pod::Bullet& collider, const pod::Vector
|
||||
collider.body->setLinearVelocity( collider.body->getLinearVelocity() + btVector3( v.x, v.y, v.z ) );
|
||||
}
|
||||
}
|
||||
void UF_API ext::bullet::applyRotation( pod::Bullet& collider, const pod::Vector3f& axis, float delta ) {
|
||||
void UF_API ext::bullet::applyRotation( pod::PhysicsState& collider, const pod::Vector3f& axis, float delta ) {
|
||||
ext::bullet::applyRotation( collider, uf::quaternion::axisAngle( axis, delta ) );
|
||||
}
|
||||
void UF_API ext::bullet::applyRotation( pod::Bullet& collider, const pod::Quaternion<>& q ) {
|
||||
void UF_API ext::bullet::applyRotation( pod::PhysicsState& collider, const pod::Quaternion<>& q ) {
|
||||
if ( !collider.body ) return;
|
||||
collider.body->activate(true);
|
||||
|
||||
@ -521,8 +490,8 @@ void UF_API ext::bullet::applyRotation( pod::Bullet& collider, const pod::Quater
|
||||
return;
|
||||
}
|
||||
|
||||
btTransform transform;
|
||||
collider.body->getMotionState()->getWorldTransform(transform);
|
||||
btTransform transform = collider.body->getWorldTransform();
|
||||
// collider.body->getMotionState()->getWorldTransform(transform);
|
||||
|
||||
pod::Quaternion<> orientation = uf::vector::normalize(uf::quaternion::multiply({
|
||||
transform.getRotation().getX(),
|
||||
@ -532,10 +501,11 @@ void UF_API ext::bullet::applyRotation( pod::Bullet& collider, const pod::Quater
|
||||
}, q));
|
||||
transform.setRotation( btQuaternion( orientation.x, orientation.y, orientation.z, orientation.w ) );
|
||||
|
||||
collider.body->getMotionState()->setWorldTransform(transform);
|
||||
// collider.body->getMotionState()->setWorldTransform(transform);
|
||||
collider.body->setWorldTransform(transform);
|
||||
collider.body->setCenterOfMassTransform(transform);
|
||||
}
|
||||
void UF_API ext::bullet::activateCollision( pod::Bullet& collider, bool enabled ) {
|
||||
void UF_API ext::bullet::activateCollision( pod::PhysicsState& collider, bool enabled ) {
|
||||
if ( !collider.body ) return;
|
||||
collider.body->activate(enabled);
|
||||
}
|
||||
@ -597,7 +567,7 @@ void UF_API ext::bullet::debugDraw( uf::Object& object ) {
|
||||
|
||||
graphic.descriptor.topology = uf::renderer::enums::PrimitiveTopology::LINE_LIST;
|
||||
graphic.descriptor.fill = uf::renderer::enums::PolygonMode::LINE;
|
||||
graphic.descriptor.lineWidth = 8.0f;
|
||||
graphic.descriptor.lineWidth = ext::bullet::debugDrawLineWidth;
|
||||
} else {
|
||||
if ( graphic.updateMesh( mesh ) ) {
|
||||
graphic.getPipeline().update( graphic );
|
||||
|
@ -1,15 +0,0 @@
|
||||
#include <uf/ext/lua/lua.h>
|
||||
#if UF_USE_LUA && UF_USE_BULLET
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
|
||||
UF_LUA_REGISTER_USERTYPE(pod::Bullet,
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( setVelocity, UF_LUA_C_FUN(ext::bullet::setVelocity) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( applyImpulse, UF_LUA_C_FUN(ext::bullet::applyImpulse) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( applyMovement, UF_LUA_C_FUN(ext::bullet::applyMovement) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( applyVelocity, UF_LUA_C_FUN(ext::bullet::applyVelocity) ),
|
||||
// UF_LUA_REGISTER_USERTYPE_DEFINE( applyRotation, UF_LUA_C_FUN(ext::bullet::applyRotation) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( activateCollision, UF_LUA_C_FUN(ext::bullet::activateCollision) )
|
||||
)
|
||||
|
||||
#endif
|
@ -7,9 +7,6 @@
|
||||
#include <uf/engine/asset/asset.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/engine/object/behaviors/lua.h>
|
||||
#if UF_USE_BULLET
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#endif
|
||||
|
||||
namespace binds {
|
||||
uf::stl::string formatHookName(uf::Object& self, const uf::stl::string n ){
|
||||
@ -32,9 +29,7 @@ namespace binds {
|
||||
UF_LUA_RETRIEVE_COMPONENT(uf::Asset)
|
||||
UF_LUA_RETRIEVE_COMPONENT(uf::Camera)
|
||||
UF_LUA_RETRIEVE_COMPONENT(pod::Physics)
|
||||
#if UF_USE_BULLET
|
||||
UF_LUA_RETRIEVE_COMPONENT(pod::Bullet)
|
||||
#endif
|
||||
UF_LUA_RETRIEVE_COMPONENT(pod::PhysicsState)
|
||||
return sol::make_object( ext::lua::state, sol::lua_nil );
|
||||
}
|
||||
void setComponent(uf::Object& self, const uf::stl::string& type, sol::object value ) {
|
||||
@ -56,9 +51,7 @@ namespace binds {
|
||||
UF_LUA_UPDATE_COMPONENT(uf::Asset)
|
||||
UF_LUA_UPDATE_COMPONENT(uf::Camera)
|
||||
UF_LUA_UPDATE_COMPONENT(pod::Physics)
|
||||
#if UF_USE_BULLET
|
||||
UF_LUA_UPDATE_COMPONENT(pod::Bullet)
|
||||
#endif
|
||||
UF_LUA_UPDATE_COMPONENT(pod::PhysicsState)
|
||||
}
|
||||
bool bind(uf::Object& self, const uf::stl::string& type, sol::protected_function fun ) {
|
||||
// if ( !self.hasBehavior({.type = uf::LuaBehavior::type}) ) uf::instantiator::bind( "LuaBehavior", self );
|
||||
|
@ -17,4 +17,14 @@ UF_LUA_REGISTER_USERTYPE(pod::Physics,
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( setLinearVelocity, UF_LUA_C_FUN(::binds::setLinearVelocity) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( setRotationalVelocity, UF_LUA_C_FUN(::binds::setRotationalVelocity) )
|
||||
)
|
||||
|
||||
UF_LUA_REGISTER_USERTYPE(pod::PhysicsState,
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( setVelocity, UF_LUA_C_FUN(uf::physics::impl::setVelocity) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( applyImpulse, UF_LUA_C_FUN(uf::physics::impl::applyImpulse) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( applyMovement, UF_LUA_C_FUN(uf::physics::impl::applyMovement) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( applyVelocity, UF_LUA_C_FUN(uf::physics::impl::applyVelocity) ),
|
||||
// UF_LUA_REGISTER_USERTYPE_DEFINE( applyRotation, UF_LUA_C_FUN(uf::physics::impl::applyRotation) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( activateCollision, UF_LUA_C_FUN(uf::physics::impl::activateCollision) )
|
||||
)
|
||||
|
||||
#endif
|
517
engine/src/ext/reactphysics/reactphysics.cpp
Normal file
517
engine/src/ext/reactphysics/reactphysics.cpp
Normal file
@ -0,0 +1,517 @@
|
||||
#if UF_USE_REACTPHYSICS
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/ext/reactphysics/reactphysics.h>
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
#include <uf/utils/graphic/graphic.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/engine/graph/graph.h>
|
||||
|
||||
#define UF_PHYSICS_SHARED 1
|
||||
|
||||
namespace {
|
||||
rp3d::PhysicsCommon common;
|
||||
rp3d::PhysicsWorld* world;
|
||||
|
||||
class EventListener : public rp3d::EventListener {
|
||||
public:
|
||||
virtual void onContact( const rp3d::CollisionCallback::CallbackData& callbackData ) override {
|
||||
// UF_MSG_DEBUG("Contact");
|
||||
}
|
||||
} listener;
|
||||
|
||||
class RaycastCallback : public rp3d::RaycastCallback {
|
||||
public:
|
||||
bool isHit = false;
|
||||
rp3d::RaycastInfo raycastInfo;
|
||||
|
||||
virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& info) override {
|
||||
if ( !isHit || raycastInfo.hitFraction > info.hitFraction ) {
|
||||
raycastInfo.body = info.body;
|
||||
raycastInfo.hitFraction = info.hitFraction;
|
||||
raycastInfo.collider = info.collider;
|
||||
raycastInfo.worldNormal = info.worldNormal;
|
||||
raycastInfo.worldPoint = info.worldPoint;
|
||||
isHit = true;
|
||||
}
|
||||
// return rp3d::decimal(1.0);
|
||||
return raycastInfo.hitFraction;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
rp3d::DefaultLogger* logger = NULL;
|
||||
}
|
||||
|
||||
float ext::reactphysics::timescale = 1.0f / 60.0f;
|
||||
bool ext::reactphysics::debugDrawEnabled = false;
|
||||
float ext::reactphysics::debugDrawRate = 1.0f;
|
||||
uf::stl::string ext::reactphysics::debugDrawLayer = "";
|
||||
float ext::reactphysics::debugDrawLineWidth = 1.0f;
|
||||
|
||||
void ext::reactphysics::initialize() {
|
||||
rp3d::PhysicsWorld::WorldSettings settings;
|
||||
settings.gravity = rp3d::Vector3( 0, -9.81, 0 );
|
||||
|
||||
// ::logger = ::common.createDefaultLogger();
|
||||
// size_t logLevel = static_cast<uint>(rp3d::Logger::Level::Warning) | static_cast<uint>(rp3d::Logger::Level::Error); // | static_cast<uint>(rp3d::Logger::Level::Information);
|
||||
// logger->addFileDestination("./data/logs/rp3d_log_.html", logLevel, rp3d::DefaultLogger::Format::HTML);
|
||||
// ::common.setLogger(::logger);
|
||||
|
||||
::world = ::common.createPhysicsWorld(settings);
|
||||
// ::world->setEventListener(&::listener);
|
||||
|
||||
if ( ext::reactphysics::debugDrawEnabled ) {
|
||||
::world->setIsDebugRenderingEnabled(true);
|
||||
rp3d::DebugRenderer& debugRenderer = ::world->getDebugRenderer();
|
||||
// Select the contact points and contact normals to be displayed
|
||||
debugRenderer.setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::COLLIDER_AABB, true);
|
||||
debugRenderer.setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::COLLISION_SHAPE, true);
|
||||
debugRenderer.setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, true);
|
||||
debugRenderer.setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, true);
|
||||
}
|
||||
}
|
||||
void ext::reactphysics::tick( float delta ) {
|
||||
#if UF_PHYSICS_SHARED
|
||||
ext::reactphysics::syncTo();
|
||||
#endif
|
||||
|
||||
static float accumulator = 0;
|
||||
|
||||
accumulator += uf::physics::time::delta;
|
||||
|
||||
while ( accumulator >= ext::reactphysics::timescale ) {
|
||||
::world->update(ext::reactphysics::timescale);
|
||||
accumulator -= ext::reactphysics::timescale;
|
||||
}
|
||||
|
||||
TIMER(ext::reactphysics::debugDrawRate, ext::reactphysics::debugDrawEnabled && ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
ext::reactphysics::debugDraw( scene );
|
||||
}
|
||||
|
||||
ext::reactphysics::syncFrom();
|
||||
}
|
||||
void ext::reactphysics::terminate() {
|
||||
::common.destroyPhysicsWorld(::world);
|
||||
::world = NULL;
|
||||
}
|
||||
|
||||
// base collider creation
|
||||
pod::PhysicsState& ext::reactphysics::create( uf::Object& object ) {
|
||||
auto& state = object.getComponent<pod::PhysicsState>();
|
||||
|
||||
state.uid = object.getUid();
|
||||
state.object = &object;
|
||||
state.transform.reference = &object.getComponent<pod::Transform<>>();
|
||||
#if UF_PHYSICS_SHARED
|
||||
state.shared = true;
|
||||
#else
|
||||
state.shared = false;
|
||||
#endif
|
||||
return state;
|
||||
}
|
||||
|
||||
void ext::reactphysics::destroy( uf::Object& object ) {
|
||||
auto& state = object.getComponent<pod::PhysicsState>();
|
||||
ext::reactphysics::destroy( state );
|
||||
}
|
||||
void ext::reactphysics::destroy( pod::PhysicsState& state ) {
|
||||
ext::reactphysics::detach( state );
|
||||
}
|
||||
|
||||
void ext::reactphysics::attach( pod::PhysicsState& state ) {
|
||||
if ( !state.shape ) return;
|
||||
|
||||
rp3d::Transform bodyTransform = rp3d::Transform::identity();
|
||||
rp3d::Transform colliderTransform = rp3d::Transform::identity();
|
||||
|
||||
#if !UF_SPOOKY_JANK
|
||||
colliderTransform.setPosition( rp3d::Vector3( state.transform.position.x, state.transform.position.y, state.transform.position.z ) );
|
||||
colliderTransform.setOrientation( rp3d::Quaternion( state.transform.orientation.x, state.transform.orientation.y, state.transform.orientation.z, state.transform.orientation.w ) );
|
||||
|
||||
state.transform.position = {};
|
||||
state.transform.orientation = {};
|
||||
|
||||
auto model = uf::transform::model( *state.transform.reference );
|
||||
bodyTransform.setFromOpenGL(&model[0]);
|
||||
#else
|
||||
// has a parent, separate main transform to collider, and parent transform to body
|
||||
if ( state.transform.reference ) {
|
||||
auto model = uf::transform::model( *state.transform.reference );
|
||||
bodyTransform.setFromOpenGL(&model[0]);
|
||||
|
||||
colliderTransform.setPosition( rp3d::Vector3( state.transform.position.x, state.transform.position.y, state.transform.position.z ) );
|
||||
colliderTransform.setOrientation( rp3d::Quaternion( state.transform.orientation.x, state.transform.orientation.y, state.transform.orientation.z, state.transform.orientation.w ) );
|
||||
// no parent, use for both
|
||||
} else {
|
||||
auto model = uf::transform::model( state.transform );
|
||||
bodyTransform.setFromOpenGL(&model[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
state.body = ::world->createRigidBody(bodyTransform);
|
||||
auto* collider = state.body->addCollider(state.shape, colliderTransform);
|
||||
state.body->setUserData(state.object);
|
||||
state.body->setMass(state.stats.mass);
|
||||
if ( state.stats.mass != 0.0f ) {
|
||||
state.body->setType(rp3d::BodyType::DYNAMIC);
|
||||
state.body->updateLocalCenterOfMassFromColliders();
|
||||
state.body->updateMassPropertiesFromColliders();
|
||||
} else {
|
||||
state.body->setType(rp3d::BodyType::STATIC);
|
||||
}
|
||||
|
||||
auto& material = collider->getMaterial();
|
||||
material.setBounciness(0);
|
||||
|
||||
state.body->setLocalInertiaTensor( rp3d::Vector3( state.stats.inertia.x, state.stats.inertia.y, state.stats.inertia.z ) );
|
||||
}
|
||||
void ext::reactphysics::detach( pod::PhysicsState& state ) {
|
||||
if ( !state.body ) return;
|
||||
::world->destroyRigidBody(state.body);
|
||||
state.body = NULL;
|
||||
}
|
||||
|
||||
// collider for mesh (static or dynamic)
|
||||
pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const uf::Mesh& mesh, bool dynamic ) {
|
||||
auto* rMesh = ::common.createTriangleMesh();
|
||||
|
||||
if ( mesh.index.count ) {
|
||||
uf::Mesh::Attribute vertexAttribute;
|
||||
for ( auto& attribute : mesh.vertex.attributes ) if ( attribute.descriptor.name == "position" ) { vertexAttribute = attribute; break; }
|
||||
UF_ASSERT( vertexAttribute.descriptor.name == "position" );
|
||||
|
||||
auto& indexAttribute = mesh.index.attributes.front();
|
||||
rp3d::TriangleVertexArray::IndexDataType indexType = rp3d::TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE;
|
||||
rp3d::TriangleVertexArray::VertexDataType vertexType = rp3d::TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE;
|
||||
switch ( mesh.index.stride ) {
|
||||
case sizeof(uint16_t): indexType = rp3d::TriangleVertexArray::IndexDataType::INDEX_SHORT_TYPE; break;
|
||||
case sizeof(uint32_t): indexType = rp3d::TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE; break;
|
||||
default: UF_EXCEPTION("unsupported index type"); break;
|
||||
}
|
||||
|
||||
rp3d::TriangleVertexArray* vArray;
|
||||
if ( mesh.indirect.count ) {
|
||||
uf::Mesh::Attribute remappedVertexAttribute;
|
||||
uf::Mesh::Attribute remappedIndexAttribute;
|
||||
for ( auto i = 0; i < mesh.indirect.count; ++i ) {
|
||||
remappedVertexAttribute = mesh.remapVertexAttribute( vertexAttribute, i );
|
||||
remappedIndexAttribute = mesh.remapIndexAttribute( indexAttribute, i );
|
||||
|
||||
vArray = new rp3d::TriangleVertexArray(
|
||||
remappedVertexAttribute.length,
|
||||
(const uint8_t*) remappedVertexAttribute.pointer,
|
||||
remappedVertexAttribute.stride,
|
||||
|
||||
remappedIndexAttribute.length / 3,
|
||||
(const uint8_t*) remappedIndexAttribute.pointer,
|
||||
remappedIndexAttribute.stride * 3,
|
||||
|
||||
vertexType,
|
||||
indexType
|
||||
);
|
||||
|
||||
rMesh->addSubpart(vArray);
|
||||
}
|
||||
} else {
|
||||
vArray = new rp3d::TriangleVertexArray(
|
||||
vertexAttribute.length,
|
||||
(const uint8_t*) vertexAttribute.pointer,
|
||||
vertexAttribute.stride,
|
||||
|
||||
indexAttribute.length / 3,
|
||||
(const uint8_t*) indexAttribute.pointer,
|
||||
indexAttribute.stride * 3,
|
||||
|
||||
vertexType,
|
||||
indexType
|
||||
);
|
||||
|
||||
rMesh->addSubpart(vArray);
|
||||
}
|
||||
} else UF_EXCEPTION("to-do: not require indices for meshes");
|
||||
|
||||
auto& state = ext::reactphysics::create( object );
|
||||
state.shape = ::common.createConcaveMeshShape( rMesh );
|
||||
state.stats.mass = 0;
|
||||
ext::reactphysics::attach( state );
|
||||
|
||||
return state;
|
||||
}
|
||||
// collider for boundingbox
|
||||
pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const pod::Vector3f& extent ) {
|
||||
auto& state = ext::reactphysics::create( object );
|
||||
state.shape = ::common.createBoxShape( rp3d::Vector3( abs(extent.x), abs(extent.y), abs(extent.z) ) );
|
||||
ext::reactphysics::attach( state );
|
||||
|
||||
return state;
|
||||
}
|
||||
// collider for capsule
|
||||
pod::PhysicsState& ext::reactphysics::create( uf::Object& object, float radius, float height ) {
|
||||
auto& state = ext::reactphysics::create( object );
|
||||
state.shape = ::common.createCapsuleShape( radius, height );
|
||||
ext::reactphysics::attach( state );
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
// synchronize engine transforms to bullet transforms
|
||||
void ext::reactphysics::syncTo() {
|
||||
size_t count = ::world->getNbRigidBodies();
|
||||
for ( size_t i = 0; i < count; ++i ) {
|
||||
auto* body = ::world->getRigidBody(i); if ( !body ) continue;
|
||||
uf::Object* object = (uf::Object*) body->getUserData(); if ( !object ) continue;
|
||||
auto& state = object->getComponent<pod::PhysicsState>(); if ( !state.shared ) continue;
|
||||
|
||||
auto model = uf::transform::model( state.transform );
|
||||
|
||||
rp3d::Transform transform;
|
||||
transform.setFromOpenGL(&model[0]);
|
||||
|
||||
body->setTransform(transform);
|
||||
body->setLinearVelocity( rp3d::Vector3( state.linear.velocity.x, state.linear.velocity.y, state.linear.velocity.z ) );
|
||||
}
|
||||
}
|
||||
// synchronize bullet transforms to engine transforms
|
||||
void ext::reactphysics::syncFrom() {
|
||||
size_t count = ::world->getNbRigidBodies();
|
||||
for ( size_t i = 0; i < count; ++i ) {
|
||||
auto* body = ::world->getRigidBody(i); if ( !body ) continue;
|
||||
uf::Object* object = (uf::Object*) body->getUserData(); if ( !object ) continue;
|
||||
|
||||
auto position = body->getTransform().getPosition();
|
||||
auto orientation = body->getTransform().getOrientation();
|
||||
auto linearVelocity = body->getLinearVelocity();
|
||||
auto rotationalVelocity = body->getAngularVelocity();
|
||||
|
||||
auto& state = object->getComponent<pod::PhysicsState>();;
|
||||
auto& transform = state.object->getComponent<pod::Transform<>>();
|
||||
auto& physics = state.object->getComponent<pod::Physics>();
|
||||
|
||||
/*state.*/transform.position.x = position.x;
|
||||
/*state.*/transform.position.y = position.y;
|
||||
/*state.*/transform.position.z = position.z;
|
||||
|
||||
// state transform is an offset, un-offset
|
||||
if ( state.transform.reference ) {
|
||||
transform.position -= state.transform.position;
|
||||
}
|
||||
|
||||
/*state.*/transform.orientation.x = orientation.x;
|
||||
/*state.*/transform.orientation.y = orientation.y;
|
||||
/*state.*/transform.orientation.z = orientation.z;
|
||||
/*state.*/transform.orientation.w = orientation.w;
|
||||
|
||||
physics.linear.velocity.x = linearVelocity.x;
|
||||
physics.linear.velocity.y = linearVelocity.y;
|
||||
physics.linear.velocity.z = linearVelocity.z;
|
||||
|
||||
physics.rotational.velocity.x = rotationalVelocity.x;
|
||||
physics.rotational.velocity.y = rotationalVelocity.y;
|
||||
physics.rotational.velocity.z = rotationalVelocity.z;
|
||||
}
|
||||
}
|
||||
// apply impulse
|
||||
void ext::reactphysics::applyImpulse( pod::PhysicsState& state, const pod::Vector3f& v ) {
|
||||
}
|
||||
// directly move a transform
|
||||
void ext::reactphysics::applyMovement( pod::PhysicsState& state, const pod::Vector3f& v ) {
|
||||
if ( !state.body ) return;
|
||||
|
||||
rp3d::Transform transform = state.body->getTransform();
|
||||
transform.setPosition( transform.getPosition() + rp3d::Vector3( v.x, v.y, v.z ) * uf::physics::time::delta );
|
||||
state.body->setTransform(transform);
|
||||
}
|
||||
// directly apply a velocity
|
||||
void ext::reactphysics::setVelocity( pod::PhysicsState& state, const pod::Vector3f& v ) {
|
||||
if ( !state.body ) return;
|
||||
if ( state.shared ) {
|
||||
auto& physics = state.object->getComponent<pod::Physics>();
|
||||
physics.linear.velocity = v;
|
||||
} else {
|
||||
state.body->setLinearVelocity( rp3d::Vector3( v.x, v.y, v.z ) );
|
||||
}
|
||||
}
|
||||
void ext::reactphysics::applyVelocity( pod::PhysicsState& state, const pod::Vector3f& v ) {
|
||||
if ( !state.body ) return;
|
||||
|
||||
if ( state.shared ) {
|
||||
auto& physics = state.object->getComponent<pod::Physics>();
|
||||
physics.linear.velocity += v;
|
||||
} else {
|
||||
state.body->setLinearVelocity( state.body->getLinearVelocity() + rp3d::Vector3( v.x, v.y, v.z ) );
|
||||
}
|
||||
}
|
||||
// directly rotate a transform
|
||||
void ext::reactphysics::applyRotation( pod::PhysicsState& state, const pod::Quaternion<>& q ) {
|
||||
if ( !state.body ) return;
|
||||
|
||||
if ( state.shared ) {
|
||||
auto& transform = state.object->getComponent<pod::Transform<>>();
|
||||
uf::transform::rotate( transform, q );
|
||||
return;
|
||||
}
|
||||
|
||||
auto transform = state.body->getTransform();
|
||||
auto o = transform.getOrientation();
|
||||
pod::Quaternion<> orientation = uf::vector::normalize(uf::quaternion::multiply({ o.x, o.y, o.z, o.w, }, q));
|
||||
transform.setOrientation( rp3d::Quaternion( orientation.x, orientation.y, orientation.z, orientation.w ) );
|
||||
|
||||
state.body->setTransform(transform);
|
||||
}
|
||||
void ext::reactphysics::applyRotation( pod::PhysicsState& state, const pod::Vector3f& axis, float delta ) {
|
||||
ext::reactphysics::applyRotation( state, uf::quaternion::axisAngle( axis, delta ) );
|
||||
}
|
||||
|
||||
// ray casting
|
||||
|
||||
float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction ) {
|
||||
if ( !::world )
|
||||
return -1;
|
||||
|
||||
::RaycastCallback callback;
|
||||
::world->raycast( rp3d::Ray( rp3d::Vector3( center.x, center.y, center.z ), rp3d::Vector3( direction.x, direction.y, direction.z ) ), &callback );
|
||||
if ( !callback.isHit ) return -1;
|
||||
return callback.raycastInfo.hitFraction;
|
||||
}
|
||||
float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction, size_t& uid ) {
|
||||
if ( !::world )
|
||||
return -1;
|
||||
|
||||
::RaycastCallback callback;
|
||||
::world->raycast( rp3d::Ray( rp3d::Vector3( center.x, center.y, center.z ), rp3d::Vector3( direction.x, direction.y, direction.z ) ), &callback );
|
||||
uid = 0;
|
||||
if ( !callback.isHit ) {
|
||||
return -1;
|
||||
}
|
||||
auto* object = (uf::Object*) callback.raycastInfo.body->getUserData();
|
||||
uid = object->getUid();
|
||||
return callback.raycastInfo.hitFraction;
|
||||
}
|
||||
float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction, uf::Object*& object ) {
|
||||
if ( !::world )
|
||||
return -1;
|
||||
|
||||
::RaycastCallback callback;
|
||||
::world->raycast( rp3d::Ray( rp3d::Vector3( center.x, center.y, center.z ), rp3d::Vector3( direction.x, direction.y, direction.z ) ), &callback );
|
||||
object = NULL;
|
||||
if ( !callback.isHit ) {
|
||||
return -1;
|
||||
}
|
||||
object = (uf::Object*) callback.raycastInfo.body->getUserData();
|
||||
return callback.raycastInfo.hitFraction;
|
||||
}
|
||||
|
||||
// allows noclip
|
||||
void ext::reactphysics::activateCollision( pod::PhysicsState& state, bool s ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct VertexLine {
|
||||
pod::Vector3f position;
|
||||
pod::Vector3f color;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
|
||||
UF_VERTEX_DESCRIPTOR(VertexLine,
|
||||
UF_VERTEX_DESCRIPTION(VertexLine, R32G32B32_SFLOAT, position)
|
||||
UF_VERTEX_DESCRIPTION(VertexLine, R32G32B32_SFLOAT, color)
|
||||
);
|
||||
|
||||
namespace {
|
||||
pod::Vector3f uintToVector( uint32_t u ) {
|
||||
switch ( u ) {
|
||||
case (uint) rp3d::DebugRenderer::DebugColor::RED: return pod::Vector3f{ 1.0f, 0.0f, 0.0f }; break;
|
||||
case (uint) rp3d::DebugRenderer::DebugColor::GREEN: return pod::Vector3f{ 0.0f, 1.0f, 0.0f }; break;
|
||||
case (uint) rp3d::DebugRenderer::DebugColor::BLUE: return pod::Vector3f{ 0.0f, 0.0f, 1.0f }; break;
|
||||
case (uint) rp3d::DebugRenderer::DebugColor::BLACK: return pod::Vector3f{ 0.0f, 0.0f, 0.0f }; break;
|
||||
case (uint) rp3d::DebugRenderer::DebugColor::WHITE: return pod::Vector3f{ 1.0f, 1.0f, 1.0f }; break;
|
||||
case (uint) rp3d::DebugRenderer::DebugColor::YELLOW: return pod::Vector3f{ 1.0f, 1.0f, 0.0f }; break;
|
||||
case (uint) rp3d::DebugRenderer::DebugColor::MAGENTA: return pod::Vector3f{ 1.0f, 0.0f, 1.0f }; break;
|
||||
case (uint) rp3d::DebugRenderer::DebugColor::CYAN: return pod::Vector3f{ 0.0f, 1.0f, 1.0f }; break;
|
||||
default: return pod::Vector3f{};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// allows showing collision models
|
||||
void ext::reactphysics::debugDraw( uf::Object& object ) {
|
||||
static size_t oldCount = 0;
|
||||
uf::Mesh mesh;
|
||||
rp3d::DebugRenderer& debugRenderer = ::world->getDebugRenderer();
|
||||
if ( !mesh.hasVertex<VertexLine>() ) mesh.bind<VertexLine>();
|
||||
|
||||
size_t lineCount = debugRenderer.getNbLines();
|
||||
size_t triCount = debugRenderer.getNbTriangles();
|
||||
|
||||
if ( !lineCount || !triCount ) return;
|
||||
if ( oldCount == lineCount * 2 + triCount * 3 ) return;
|
||||
oldCount = lineCount * 2 + triCount * 3;
|
||||
|
||||
auto* lines = debugRenderer.getLinesArray();
|
||||
auto* tris = debugRenderer.getTrianglesArray();
|
||||
|
||||
uf::stl::vector<VertexLine> vertices;
|
||||
vertices.reserve( lineCount * 2 + triCount * 3 );
|
||||
for ( size_t i = 0; i < lineCount; ++i ) {
|
||||
auto& line = lines[i];
|
||||
|
||||
auto& vertex1 = vertices.emplace_back();
|
||||
vertex1.position = { line.point1.x, line.point1.y, line.point1.z };
|
||||
vertex1.color = uintToVector( line.color1 );
|
||||
|
||||
auto& vertex2 = vertices.emplace_back();
|
||||
vertex2.position = { line.point2.x, line.point2.y, line.point2.z };
|
||||
vertex2.color = uintToVector( line.color2 );
|
||||
}
|
||||
for ( size_t i = 0; i < triCount; ++i ) {
|
||||
auto& tri = tris[i];
|
||||
|
||||
auto& vertex1 = vertices.emplace_back();
|
||||
vertex1.position = { tri.point1.x, tri.point1.y, tri.point1.z };
|
||||
vertex1.color = uintToVector( tri.color1 );
|
||||
|
||||
auto& vertex2 = vertices.emplace_back();
|
||||
vertex2.position = { tri.point2.x, tri.point2.y, tri.point2.z };
|
||||
vertex2.color = uintToVector( tri.color2 );
|
||||
|
||||
auto& vertex3 = vertices.emplace_back();
|
||||
vertex3.position = { tri.point3.x, tri.point3.y, tri.point3.z };
|
||||
vertex3.color = uintToVector( tri.color3 );
|
||||
}
|
||||
mesh.insertVertices(vertices);
|
||||
|
||||
if ( !mesh.vertex.count ) return;
|
||||
|
||||
bool create = !object.hasComponent<uf::Graphic>();
|
||||
auto& graphic = object.getComponent<uf::Graphic>();
|
||||
graphic.process = false;
|
||||
|
||||
if ( create ) {
|
||||
graphic.device = &uf::renderer::device;
|
||||
graphic.material.device = &uf::renderer::device;
|
||||
graphic.descriptor.cullMode = uf::renderer::enums::CullMode::NONE;
|
||||
|
||||
graphic.material.metadata.autoInitializeUniforms = false;
|
||||
graphic.material.attachShader(uf::io::root + "/shaders/bullet/base.vert.spv", uf::renderer::enums::Shader::VERTEX);
|
||||
graphic.material.attachShader(uf::io::root + "/shaders/bullet/base.frag.spv", uf::renderer::enums::Shader::FRAGMENT);
|
||||
graphic.material.metadata.autoInitializeUniforms = true;
|
||||
|
||||
graphic.material.getShader("vertex").buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.camera );
|
||||
|
||||
graphic.initialize(ext::reactphysics::debugDrawLayer);
|
||||
graphic.initializeMesh( mesh );
|
||||
|
||||
graphic.descriptor.topology = uf::renderer::enums::PrimitiveTopology::LINE_LIST;
|
||||
graphic.descriptor.fill = uf::renderer::enums::PolygonMode::LINE;
|
||||
graphic.descriptor.lineWidth = ext::reactphysics::debugDrawLineWidth;
|
||||
} else {
|
||||
if ( graphic.updateMesh( mesh ) ) {
|
||||
graphic.getPipeline().update( graphic );
|
||||
}
|
||||
}
|
||||
graphic.process = true;
|
||||
}
|
||||
#endif
|
@ -1,4 +1,5 @@
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <iostream>
|
||||
|
||||
uf::Timer<> uf::physics::time::timer;
|
||||
uf::physics::num_t uf::physics::time::current;
|
||||
@ -6,8 +7,10 @@ uf::physics::num_t uf::physics::time::previous;
|
||||
uf::physics::num_t uf::physics::time::delta;
|
||||
uf::physics::num_t uf::physics::time::clamp;
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void UF_API uf::physics::initialize() {
|
||||
uf::physics::impl::initialize();
|
||||
}
|
||||
void UF_API uf::physics::tick() {
|
||||
uf::physics::time::previous = uf::physics::time::current;
|
||||
uf::physics::time::current = uf::physics::time::timer.elapsed();
|
||||
@ -15,4 +18,8 @@ void UF_API uf::physics::tick() {
|
||||
if ( uf::physics::time::delta > uf::physics::time::clamp ) {
|
||||
uf::physics::time::delta = uf::physics::time::clamp;
|
||||
}
|
||||
uf::physics::impl::tick();
|
||||
}
|
||||
void UF_API uf::physics::terminate() {
|
||||
uf::physics::impl::terminate();
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
#include <uf/utils/audio/audio.h>
|
||||
#include <uf/ext/openvr/openvr.h>
|
||||
#include <uf/engine/graph/graph.h>
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/spec/controller/controller.h>
|
||||
#include <uf/utils/io/inputs.h>
|
||||
@ -23,7 +22,7 @@ UF_BEHAVIOR_TRAITS_CPP(ext::PlayerBehavior, ticks = true, renders = false, multi
|
||||
void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
|
||||
auto& collider = this->getComponent<pod::Bullet>();
|
||||
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||
|
||||
auto& metadata = this->getComponent<ext::PlayerBehavior::Metadata>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
@ -80,9 +79,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
if ( metadata.camera.invert.x ) relta.x *= -1;
|
||||
metadata.camera.limit.current.x += relta.x;
|
||||
if ( metadata.camera.limit.current.x != metadata.camera.limit.current.x || ( metadata.camera.limit.current.x < metadata.camera.limit.max.x && metadata.camera.limit.current.x > metadata.camera.limit.min.x ) ) {
|
||||
#if UF_USE_BULLET
|
||||
if ( collider.body ) ext::bullet::applyRotation( collider, transform.up, relta.x ); else
|
||||
#endif
|
||||
if ( collider.body ) uf::physics::impl::applyRotation( collider, transform.up, relta.x ); else
|
||||
uf::transform::rotate( transform, transform.up, relta.x );
|
||||
} else metadata.camera.limit.current.x -= relta.x;
|
||||
}
|
||||
@ -91,7 +88,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
metadata.camera.limit.current.y += relta.y;
|
||||
if ( metadata.camera.limit.current.y != metadata.camera.limit.current.y || ( metadata.camera.limit.current.y < metadata.camera.limit.max.y && metadata.camera.limit.current.y > metadata.camera.limit.min.y ) ) {
|
||||
// if ( collider.body && !collider.shared ) {
|
||||
// ext::bullet::applyRotation( collider, cameraTransform.right, relta.y );
|
||||
// uf::physics::impl::applyRotation( collider, cameraTransform.right, relta.y );
|
||||
// } else {
|
||||
uf::transform::rotate( cameraTransform, cameraTransform.right, relta.y );
|
||||
// }
|
||||
@ -209,14 +206,10 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
stats.menu = metadata.system.menu;
|
||||
stats.noclipped = metadata.system.noclipped;
|
||||
stats.floored = stats.noclipped;
|
||||
#if UF_USE_BULLET
|
||||
auto& collider = this->getComponent<pod::Bullet>();
|
||||
if ( !stats.floored && collider.body && ext::bullet::rayCast( transform.position, transform.position - pod::Vector3f{0,1,0} ) >= 0.0f ) stats.floored = true; else
|
||||
#endif
|
||||
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||
if ( !stats.floored && collider.body && uf::physics::impl::rayCast( transform.position, transform.position - pod::Vector3f{0,1,0} ) >= 0.0f ) stats.floored = true; else
|
||||
stats.floored |= fabs(physics.linear.velocity.y) < 0.01f;
|
||||
|
||||
#if UF_USE_BULLET
|
||||
|
||||
TIMER(0.125, keys.use && ) {
|
||||
size_t uid = 0;
|
||||
uf::Object* pointer = NULL;
|
||||
@ -224,7 +217,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
pod::Vector3f pos = transform.position + cameraTransform.position;
|
||||
pod::Vector3f dir = uf::vector::normalize( transform.forward + pod::Vector3f{ 0, cameraTransform.forward.y, 0 } ) * length;
|
||||
|
||||
float depth = ext::bullet::rayCast( pos, pos + dir, pointer );
|
||||
float depth = uf::physics::impl::rayCast( pos, pos + dir, pointer );
|
||||
if ( pointer ) {
|
||||
uf::Serializer payload;
|
||||
payload["uid"] = this->getUid();
|
||||
@ -248,7 +241,6 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct {
|
||||
float move = 4;
|
||||
@ -324,21 +316,19 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
metadata.system.noclipped = state;
|
||||
|
||||
UF_MSG_DEBUG( (state ? "En" : "Dis") << "abled noclip: " << uf::vector::toString(transform.position));
|
||||
#if 0
|
||||
if ( state ) {
|
||||
#if UF_USE_BULLET
|
||||
if ( collider.body ) {
|
||||
collider.body->setGravity(btVector3(0,0.0,0));
|
||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if UF_USE_BULLET
|
||||
if ( collider.body ) {
|
||||
collider.body->setGravity(btVector3(0,-9.81,0));
|
||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
stats.noclipped = state;
|
||||
}
|
||||
// movement handler
|
||||
@ -376,15 +366,11 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
|
||||
if ( keys.lookRight ^ keys.lookLeft ) {
|
||||
#if UF_USE_BULLET
|
||||
if ( collider.body ) ext::bullet::applyRotation( collider, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) ); else
|
||||
#endif
|
||||
if ( collider.body ) uf::physics::impl::applyRotation( collider, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) ); else
|
||||
uf::transform::rotate( transform, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) );
|
||||
}
|
||||
{
|
||||
#if UF_USE_BULLET
|
||||
if ( collider.body ) ext::bullet::setVelocity( collider, physics.linear.velocity ); else
|
||||
#endif
|
||||
if ( collider.body ) uf::physics::impl::setVelocity( collider, physics.linear.velocity ); else
|
||||
transform.position += physics.linear.velocity * uf::physics::time::delta;
|
||||
}
|
||||
|
||||
|
55
ext/main.cpp
55
ext/main.cpp
@ -45,7 +45,6 @@
|
||||
#include <uf/ext/openvr/openvr.h>
|
||||
#include <uf/ext/lua/lua.h>
|
||||
#include <uf/ext/ultralight/ultralight.h>
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
|
||||
bool ext::ready = false;
|
||||
uf::stl::vector<uf::stl::string> ext::arguments;
|
||||
@ -216,12 +215,19 @@ void EXT_API ext::initialize() {
|
||||
// Set worker threads
|
||||
if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "async" ) {
|
||||
uf::thread::async = true;
|
||||
auto threads = std::max( 1, (int) std::thread::hardware_concurrency() - 1 );
|
||||
::config["engine"]["threads"]["workers"] = threads;
|
||||
uf::thread::workers = ::config["engine"]["threads"]["workers"].as<size_t>();
|
||||
UF_MSG_DEBUG("Using async worker threads");
|
||||
} else if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "auto" ) {
|
||||
auto threads = std::max( 1, (int) std::thread::hardware_concurrency() - 1 );
|
||||
::config["engine"]["threads"]["workers"] = threads;
|
||||
uf::thread::workers = ::config["engine"]["threads"]["workers"].as<size_t>();
|
||||
UF_MSG_DEBUG("Using " << threads << " worker threads");
|
||||
} else if ( ::config["engine"]["threads"]["workers"].is<size_t>() ) {
|
||||
auto threads = ::config["engine"]["threads"]["workers"].as<size_t>();
|
||||
uf::thread::workers = threads;
|
||||
UF_MSG_DEBUG("Using " << threads << " worker threads");
|
||||
}
|
||||
// Audio settings
|
||||
{
|
||||
@ -259,6 +265,15 @@ void EXT_API ext::initialize() {
|
||||
ext::bullet::debugDrawEnabled = ::config["engine"]["ext"]["bullet"]["debug draw"]["enabled"].as( ext::bullet::debugDrawEnabled );
|
||||
ext::bullet::debugDrawRate = ::config["engine"]["ext"]["bullet"]["debug draw"]["rate"].as( ext::bullet::debugDrawRate );
|
||||
ext::bullet::debugDrawLayer = ::config["engine"]["ext"]["bullet"]["debug draw"]["layer"].as( ext::bullet::debugDrawLayer );
|
||||
ext::bullet::debugDrawLineWidth = ::config["engine"]["ext"]["bullet"]["debug draw"]["line width"].as( ext::bullet::debugDrawLineWidth );
|
||||
}
|
||||
#elif UF_USE_REACTPHYSICS
|
||||
{
|
||||
ext::reactphysics::timescale = ::config["engine"]["ext"]["reactphysics"]["timescale"].as( ext::reactphysics::timescale );
|
||||
ext::reactphysics::debugDrawEnabled = ::config["engine"]["ext"]["reactphysics"]["debug draw"]["enabled"].as( ext::reactphysics::debugDrawEnabled );
|
||||
ext::reactphysics::debugDrawRate = ::config["engine"]["ext"]["reactphysics"]["debug draw"]["rate"].as( ext::reactphysics::debugDrawRate );
|
||||
ext::reactphysics::debugDrawLayer = ::config["engine"]["ext"]["reactphysics"]["debug draw"]["layer"].as( ext::reactphysics::debugDrawLayer );
|
||||
ext::reactphysics::debugDrawLineWidth = ::config["engine"]["ext"]["reactphysics"]["debug draw"]["line width"].as( ext::reactphysics::debugDrawLineWidth );
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -341,12 +356,9 @@ void EXT_API ext::initialize() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UF_USE_BULLET
|
||||
/* Bullet */ {
|
||||
ext::bullet::initialize();
|
||||
/* Physics */ {
|
||||
uf::physics::initialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UF_USE_OPENVR
|
||||
{
|
||||
ext::openvr::enabled = ::config["engine"]["ext"]["vr"]["enable"].as( ext::openvr::enabled );
|
||||
@ -409,13 +421,13 @@ void EXT_API ext::initialize() {
|
||||
#if UF_USE_VULKAN
|
||||
/* Callbacks for 2KHR stuffs */ {
|
||||
uf::hooks.addHook("vulkan:Instance.ExtensionsEnabled", []( const ext::json::Value& json ) {
|
||||
UF_MSG_DEBUG("vulkan:Instance.ExtensionsEnabled: " << json);
|
||||
// UF_MSG_DEBUG("vulkan:Instance.ExtensionsEnabled: " << json);
|
||||
});
|
||||
uf::hooks.addHook("vulkan:Device.ExtensionsEnabled", []( const ext::json::Value& json ) {
|
||||
UF_MSG_DEBUG("vulkan:Device.ExtensionsEnabled: " << json);
|
||||
// UF_MSG_DEBUG("vulkan:Device.ExtensionsEnabled: " << json);
|
||||
});
|
||||
uf::hooks.addHook("vulkan:Device.FeaturesEnabled", []( const ext::json::Value& json ) {
|
||||
UF_MSG_DEBUG("vulkan:Device.FeaturesEnabled: " << json);
|
||||
// UF_MSG_DEBUG("vulkan:Device.FeaturesEnabled: " << json);
|
||||
|
||||
VkPhysicalDeviceFeatures2KHR deviceFeatures2{};
|
||||
VkPhysicalDeviceMultiviewFeaturesKHR extFeatures{};
|
||||
@ -424,10 +436,10 @@ void EXT_API ext::initialize() {
|
||||
deviceFeatures2.pNext = &extFeatures;
|
||||
PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(vkGetInstanceProcAddr(uf::renderer::device.instance, "vkGetPhysicalDeviceFeatures2KHR"));
|
||||
vkGetPhysicalDeviceFeatures2KHR(uf::renderer::device.physicalDevice, &deviceFeatures2);
|
||||
UF_MSG_DEBUG("Multiview features:" );
|
||||
UF_MSG_DEBUG("\tmultiview = " << extFeatures.multiview );
|
||||
UF_MSG_DEBUG("\tmultiviewGeometryShader = " << extFeatures.multiviewGeometryShader );
|
||||
UF_MSG_DEBUG("\tmultiviewTessellationShader = " << extFeatures.multiviewTessellationShader );
|
||||
// UF_MSG_DEBUG("Multiview features:" );
|
||||
// UF_MSG_DEBUG("\tmultiview = " << extFeatures.multiview );
|
||||
// UF_MSG_DEBUG("\tmultiviewGeometryShader = " << extFeatures.multiviewGeometryShader );
|
||||
// UF_MSG_DEBUG("\tmultiviewTessellationShader = " << extFeatures.multiviewTessellationShader );
|
||||
|
||||
VkPhysicalDeviceProperties2KHR deviceProps2{};
|
||||
VkPhysicalDeviceMultiviewPropertiesKHR extProps{};
|
||||
@ -436,9 +448,9 @@ void EXT_API ext::initialize() {
|
||||
deviceProps2.pNext = &extProps;
|
||||
PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>(vkGetInstanceProcAddr(uf::renderer::device.instance, "vkGetPhysicalDeviceProperties2KHR"));
|
||||
vkGetPhysicalDeviceProperties2KHR(uf::renderer::device.physicalDevice, &deviceProps2);
|
||||
UF_MSG_DEBUG("Multiview properties:");
|
||||
UF_MSG_DEBUG("\tmaxMultiviewViewCount = " << extProps.maxMultiviewViewCount);
|
||||
UF_MSG_DEBUG("\tmaxMultiviewInstanceIndex = " << extProps.maxMultiviewInstanceIndex);
|
||||
// UF_MSG_DEBUG("Multiview properties:");
|
||||
// UF_MSG_DEBUG("\tmaxMultiviewViewCount = " << extProps.maxMultiviewViewCount);
|
||||
// UF_MSG_DEBUG("\tmaxMultiviewInstanceIndex = " << extProps.maxMultiviewInstanceIndex);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
@ -561,11 +573,6 @@ void EXT_API ext::tick() {
|
||||
/* Update physics timer */ {
|
||||
uf::physics::tick();
|
||||
}
|
||||
#if UF_USE_BULLET
|
||||
/* Update bullet */ {
|
||||
ext::bullet::tick();
|
||||
}
|
||||
#endif
|
||||
/* Update graph */ {
|
||||
uf::graph::tick();
|
||||
}
|
||||
@ -659,11 +666,9 @@ void EXT_API ext::terminate() {
|
||||
/* Terminate controllers */ {
|
||||
spec::controller::terminate();
|
||||
}
|
||||
#if UF_USE_BULLET
|
||||
/* Kill bullet */ {
|
||||
ext::bullet::terminate();
|
||||
/* Kill physics */ {
|
||||
uf::physics::terminate();
|
||||
}
|
||||
#endif
|
||||
#if UF_USE_ULTRALIGHT
|
||||
/* Ultralight-UX */ if ( ::config["engine"]["ext"]["ultralight"]["enabled"].as<bool>() ) {
|
||||
ext::ultralight::terminate();
|
||||
|
Loading…
Reference in New Issue
Block a user