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 +=
|
DEPS +=
|
||||||
|
|
||||||
ifneq (,$(findstring win64,$(ARCH)))
|
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 +=
|
FLAGS +=
|
||||||
DEPS += -lgdi32
|
DEPS += -lgdi32
|
||||||
else ifneq (,$(findstring dreamcast,$(ARCH)))
|
else ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||||
@ -153,6 +153,10 @@ ifneq (,$(findstring bullet,$(REQ_DEPS)))
|
|||||||
INCS += -I./dep/bullet/
|
INCS += -I./dep/bullet/
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
ifneq (,$(findstring reactphysics,$(REQ_DEPS)))
|
||||||
|
FLAGS += -DUF_USE_REACTPHYSICS
|
||||||
|
DEPS += -lreactphysics3d
|
||||||
|
endif
|
||||||
ifneq (,$(findstring simd,$(REQ_DEPS)))
|
ifneq (,$(findstring simd,$(REQ_DEPS)))
|
||||||
FLAGS += -DUF_USE_SIMD -DUF_MATRIX_ALIGNED #-DUF_VECTOR_ALIGNED #-march=native
|
FLAGS += -DUF_USE_SIMD -DUF_MATRIX_ALIGNED #-DUF_VECTOR_ALIGNED #-march=native
|
||||||
|
|
||||||
|
@ -141,14 +141,22 @@
|
|||||||
"json": "/json.lua"
|
"json": "/json.lua"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"reactphysics": {
|
||||||
|
"timescale": 0.01666666666,
|
||||||
|
"debug draw": {
|
||||||
|
"enabled": false,
|
||||||
|
// "layer": "Gui",
|
||||||
|
"rate": 0.0125
|
||||||
|
}
|
||||||
|
},
|
||||||
"bullet": {
|
"bullet": {
|
||||||
"iterations": 1,
|
"iterations": 1,
|
||||||
"substeps": 12,
|
"substeps": 4,
|
||||||
"timescale": 1,
|
"timescale": 1,
|
||||||
"multithreaded": false,
|
"multithreaded": false,
|
||||||
"pool size": {
|
"pool size": {
|
||||||
"max collision algorithm": 1024,
|
"max collision algorithm": 65535,
|
||||||
"max persistent manifold": 1024
|
"max persistent manifold": 65535
|
||||||
},
|
},
|
||||||
"debug draw": {
|
"debug draw": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"gravity": [ 0, -9.81, 0 ],
|
"gravity": [ 0, -9.81, 0 ],
|
||||||
"inertia": [ 10, 10, 10 ],
|
"inertia": [ 0, 0, 0 ],
|
||||||
|
|
||||||
"type": "capsule",
|
"type": "capsule",
|
||||||
"radius": 1,
|
"radius": 1,
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
"assets": ["./scripts/door.lua"],
|
"assets": ["./scripts/door.lua"],
|
||||||
"system": {
|
"system": {
|
||||||
"physics": {
|
"physics": {
|
||||||
|
"mass": 0,
|
||||||
|
"inertia": [0, 0, 0],
|
||||||
"type": "bounding box",
|
"type": "bounding box",
|
||||||
"recenter": true
|
"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",
|
"import": "/scene.json",
|
||||||
"assets": [
|
"assets": [
|
||||||
"./audio/soundscape/ambience.ogg",
|
"./audio/soundscape/ambience.ogg",
|
||||||
"./loading.json",
|
"./loading.json"
|
||||||
"./static.json"
|
// "./static.json"
|
||||||
],
|
],
|
||||||
"system": {
|
"system": {
|
||||||
"hot reload": {
|
"hot reload": {
|
||||||
|
@ -86,7 +86,7 @@ ent:bind( "tick", function(self)
|
|||||||
end )
|
end )
|
||||||
-- on use
|
-- on use
|
||||||
ent:addHook( "entity:Use.%UID%", function( payload )
|
ent:addHook( "entity:Use.%UID%", function( payload )
|
||||||
if state == 0 then
|
if state == 0 or state == 3 then
|
||||||
state = 1
|
state = 1
|
||||||
playSound("default_move")
|
playSound("default_move")
|
||||||
if payload.uid ~= nil then
|
if payload.uid ~= nil then
|
||||||
@ -100,11 +100,8 @@ ent:addHook( "entity:Use.%UID%", function( payload )
|
|||||||
polarity = -1
|
polarity = -1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
io.print(ent:name())
|
elseif state == 2 or state == 1 then
|
||||||
end
|
|
||||||
if state == 2 then
|
|
||||||
state = 3
|
state = 3
|
||||||
playSound("default_move")
|
playSound("default_move")
|
||||||
end
|
end
|
||||||
io.print( state, json.encode( payload ) )
|
|
||||||
end )
|
end )
|
@ -13,16 +13,12 @@
|
|||||||
"alpha mode": "BLEND",
|
"alpha mode": "BLEND",
|
||||||
"tags": {
|
"tags": {
|
||||||
"worldspawn": { "physics": { "type": "mesh", "static": true } },
|
"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 },
|
"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_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_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_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_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_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] } } },
|
"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_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_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"
|
#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
|
||||||
#endif
|
#endif
|
||||||
namespace pod {
|
namespace pod {
|
||||||
struct UF_API Bullet {
|
struct UF_API Physics {
|
||||||
size_t uid = 0;
|
size_t uid = 0;
|
||||||
uf::Object* pointer = NULL;
|
uf::Object* pointer = NULL;
|
||||||
|
|
||||||
pod::Transform<> transform;
|
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
|
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;
|
btRigidBody* body = NULL;
|
||||||
btCollisionShape* shape = NULL;
|
btCollisionShape* shape = NULL;
|
||||||
#else
|
|
||||||
void* body = NULL;
|
|
||||||
void* shape = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct {
|
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 mass = 0.0f;
|
||||||
float friction = 0.8f;
|
float friction = 0.8f;
|
||||||
float restitution = 0.0f;
|
float restitution = 0.0f;
|
||||||
pod::Vector3f inertia = {};
|
pod::Vector3f inertia = {0, 0, 0};
|
||||||
pod::Vector3f gravity = {};
|
pod::Vector3f gravity = {0, 0, 0};
|
||||||
} stats;
|
} stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef Physics PhysicsState;
|
||||||
}
|
}
|
||||||
#if UF_USE_BULLET
|
#if UF_USE_BULLET
|
||||||
namespace ext {
|
namespace ext {
|
||||||
@ -48,52 +59,43 @@ namespace ext {
|
|||||||
extern UF_API bool debugDrawEnabled;
|
extern UF_API bool debugDrawEnabled;
|
||||||
extern UF_API float debugDrawRate;
|
extern UF_API float debugDrawRate;
|
||||||
extern UF_API uf::stl::string debugDrawLayer;
|
extern UF_API uf::stl::string debugDrawLayer;
|
||||||
|
extern UF_API float debugDrawLineWidth;
|
||||||
|
|
||||||
void UF_API initialize();
|
void UF_API initialize();
|
||||||
void UF_API tick( float = 0 );
|
void UF_API tick( float = 0 );
|
||||||
void UF_API terminate();
|
void UF_API terminate();
|
||||||
|
|
||||||
// base collider creation
|
// base collider creation
|
||||||
pod::Bullet& create( uf::Object& );
|
pod::PhysicsState& UF_API create( uf::Object& );
|
||||||
|
|
||||||
void destroy( uf::Object& );
|
void UF_API destroy( uf::Object& );
|
||||||
void destroy( pod::Bullet& );
|
void UF_API destroy( pod::PhysicsState& );
|
||||||
|
|
||||||
void UF_API attach( pod::Bullet& );
|
void UF_API attach( pod::PhysicsState& );
|
||||||
void UF_API detach( pod::Bullet& );
|
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)
|
// 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
|
// collider for boundingbox
|
||||||
pod::Bullet& UF_API create( uf::Object&, const pod::Vector3f& );
|
pod::PhysicsState& 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>& );
|
uf::stl::vector<pod::PhysicsState>& UF_API create( uf::Object&, const uf::stl::vector<pod::Instance::Bounds>& );
|
||||||
// collider for capsule
|
// 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
|
// synchronize engine transforms to bullet transforms
|
||||||
void UF_API syncToBullet();
|
void UF_API syncTo();
|
||||||
// synchronize bullet transforms to engine transforms
|
// synchronize bullet transforms to engine transforms
|
||||||
void UF_API syncFromBullet();
|
void UF_API syncFrom();
|
||||||
// apply impulse
|
// apply impulse
|
||||||
void UF_API applyImpulse( pod::Bullet&, const pod::Vector3f& );
|
void UF_API applyImpulse( pod::PhysicsState&, const pod::Vector3f& );
|
||||||
// directly move a transform
|
// 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
|
// directly apply a velocity
|
||||||
void UF_API setVelocity( pod::Bullet&, const pod::Vector3f& );
|
void UF_API setVelocity( pod::PhysicsState&, const pod::Vector3f& );
|
||||||
void UF_API applyVelocity( pod::Bullet&, const pod::Vector3f& );
|
void UF_API applyVelocity( pod::PhysicsState&, const pod::Vector3f& );
|
||||||
// directly rotate a transform
|
// directly rotate a transform
|
||||||
void UF_API applyRotation( pod::Bullet&, const pod::Quaternion<>& );
|
void UF_API applyRotation( pod::PhysicsState&, const pod::Quaternion<>& );
|
||||||
void UF_API applyRotation( pod::Bullet&, const pod::Vector3f&, float );
|
void UF_API applyRotation( pod::PhysicsState&, const pod::Vector3f&, float );
|
||||||
|
|
||||||
// picks an appropriate movement option
|
|
||||||
// void UF_API move( pod::Bullet&, const pod::Vector3f&, bool = false );
|
|
||||||
|
|
||||||
// ray casting
|
// ray casting
|
||||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f& );
|
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*& );
|
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*& );
|
||||||
|
|
||||||
// allows noclip
|
// allows noclip
|
||||||
void UF_API activateCollision( pod::Bullet&, bool = true );
|
void UF_API activateCollision( pod::PhysicsState&, bool = true );
|
||||||
|
|
||||||
// allows showing collision models
|
// allows showing collision models
|
||||||
void UF_API debugDraw( uf::Object& );
|
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/math/transform.h>
|
||||||
#include <uf/utils/time/time.h>
|
#include <uf/utils/time/time.h>
|
||||||
|
|
||||||
namespace pod {
|
#if UF_USE_BULLET
|
||||||
struct UF_API Physics {
|
#include <uf/ext/bullet/bullet.h>
|
||||||
struct {
|
#elif UF_USE_REACTPHYSICS
|
||||||
pod::Vector3 velocity;
|
#include <uf/ext/reactphysics/reactphysics.h>
|
||||||
pod::Vector3 acceleration;
|
#endif
|
||||||
} linear;
|
|
||||||
struct {
|
|
||||||
pod::Quaternion<> velocity;
|
|
||||||
pod::Quaternion<> acceleration;
|
|
||||||
} rotational;
|
|
||||||
pod::Transform<> previous;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace uf {
|
namespace uf {
|
||||||
namespace physics {
|
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;
|
typedef pod::Math::num_t num_t;
|
||||||
namespace time {
|
namespace time {
|
||||||
|
|
||||||
@ -29,7 +27,9 @@ namespace uf {
|
|||||||
extern UF_API uf::physics::num_t delta;
|
extern UF_API uf::physics::num_t delta;
|
||||||
extern UF_API uf::physics::num_t clamp;
|
extern UF_API uf::physics::num_t clamp;
|
||||||
}
|
}
|
||||||
|
void UF_API initialize();
|
||||||
void UF_API tick();
|
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::Transform<T>& transform, pod::Physics& physics );
|
||||||
template<typename T> pod::Transform<T>& update( pod::Physics& physics, pod::Transform<T>& transform );
|
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/engine/graph/graph.h>
|
||||||
#include <uf/ext/bullet/bullet.h>
|
|
||||||
#include <uf/ext/gltf/gltf.h>
|
#include <uf/ext/gltf/gltf.h>
|
||||||
#include <uf/utils/math/physics.h>
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/utils/mesh/grid.h>
|
#include <uf/utils/mesh/grid.h>
|
||||||
#include <uf/utils/thread/thread.h>
|
#include <uf/utils/thread/thread.h>
|
||||||
#include <uf/utils/string/base64.h>
|
#include <uf/utils/string/base64.h>
|
||||||
#include <uf/utils/graphic/graphic.h>
|
#include <uf/utils/graphic/graphic.h>
|
||||||
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/utils/camera/camera.h>
|
#include <uf/utils/camera/camera.h>
|
||||||
#include <uf/ext/xatlas/xatlas.h>
|
#include <uf/ext/xatlas/xatlas.h>
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include <uf/engine/graph/graph.h>
|
#include <uf/engine/graph/graph.h>
|
||||||
#include <uf/ext/bullet/bullet.h>
|
|
||||||
#include <uf/ext/gltf/gltf.h>
|
#include <uf/ext/gltf/gltf.h>
|
||||||
#include <uf/utils/math/physics.h>
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/utils/mesh/grid.h>
|
#include <uf/utils/mesh/grid.h>
|
||||||
@ -7,6 +6,7 @@
|
|||||||
#include <uf/utils/string/base64.h>
|
#include <uf/utils/string/base64.h>
|
||||||
#include <uf/utils/graphic/graphic.h>
|
#include <uf/utils/graphic/graphic.h>
|
||||||
#include <uf/utils/camera/camera.h>
|
#include <uf/utils/camera/camera.h>
|
||||||
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/ext/xatlas/xatlas.h>
|
#include <uf/ext/xatlas/xatlas.h>
|
||||||
|
|
||||||
#if UF_ENV_DREAMCAST
|
#if UF_ENV_DREAMCAST
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include <uf/engine/graph/graph.h>
|
#include <uf/engine/graph/graph.h>
|
||||||
#include <uf/ext/bullet/bullet.h>
|
|
||||||
#include <uf/ext/gltf/gltf.h>
|
#include <uf/ext/gltf/gltf.h>
|
||||||
#include <uf/utils/math/physics.h>
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/utils/mesh/grid.h>
|
#include <uf/utils/mesh/grid.h>
|
||||||
@ -7,6 +6,7 @@
|
|||||||
#include <uf/utils/string/base64.h>
|
#include <uf/utils/string/base64.h>
|
||||||
#include <uf/utils/graphic/graphic.h>
|
#include <uf/utils/graphic/graphic.h>
|
||||||
#include <uf/utils/camera/camera.h>
|
#include <uf/utils/camera/camera.h>
|
||||||
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/ext/xatlas/xatlas.h>
|
#include <uf/ext/xatlas/xatlas.h>
|
||||||
|
|
||||||
#if UF_ENV_DREAMCAST
|
#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 ) ) {
|
if ( ext::json::isObject( info ) ) {
|
||||||
uf::stl::string type = info["type"].as<uf::stl::string>();
|
uf::stl::string type = info["type"].as<uf::stl::string>();
|
||||||
#if UF_USE_BULLET
|
|
||||||
|
|
||||||
if ( type == "mesh" ) {
|
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.mass = info["mass"].as(collider.stats.mass);
|
||||||
collider.stats.friction = info["friction"].as(collider.stats.friction);
|
collider.stats.friction = info["friction"].as(collider.stats.friction);
|
||||||
collider.stats.restitution = info["restitution"].as(collider.stats.restitution);
|
collider.stats.restitution = info["restitution"].as(collider.stats.restitution);
|
||||||
collider.stats.inertia = uf::vector::decode( info["inertia"], collider.stats.inertia );
|
collider.stats.inertia = uf::vector::decode( info["inertia"], collider.stats.inertia );
|
||||||
collider.stats.gravity = uf::vector::decode( info["gravity"], collider.stats.gravity );
|
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 {
|
} else {
|
||||||
auto min = uf::matrix::multiply<float>( model, bounds.min, 1.0f );
|
auto min = uf::matrix::multiply<float>( model, bounds.min, 1.0f );
|
||||||
auto max = uf::matrix::multiply<float>( model, bounds.max, 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"]["center"] = uf::vector::encode( center );
|
||||||
metadataJson["system"]["physics"]["corner"] = uf::vector::encode( corner );
|
metadataJson["system"]["physics"]["corner"] = uf::vector::encode( corner );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#include <uf/utils/camera/camera.h>
|
#include <uf/utils/camera/camera.h>
|
||||||
#include <uf/utils/mesh/mesh.h>
|
#include <uf/utils/mesh/mesh.h>
|
||||||
#include <uf/utils/renderer/renderer.h>
|
#include <uf/utils/renderer/renderer.h>
|
||||||
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/ext/gltf/gltf.h>
|
#include <uf/ext/gltf/gltf.h>
|
||||||
#include <uf/ext/bullet/bullet.h>
|
|
||||||
|
|
||||||
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Object)
|
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Object)
|
||||||
UF_BEHAVIOR_TRAITS_CPP(uf::ObjectBehavior, ticks = true, renders = false, multithread = false)
|
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);
|
metadata.deserialize(self, metadataJson);
|
||||||
|
|
||||||
#if UF_USE_BULLET
|
|
||||||
if ( ext::json::isObject(metadataJson["system"]["physics"]) ) {
|
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.mass = metadataJson["system"]["physics"]["mass"].as(collider.stats.mass);
|
||||||
collider.stats.restitution = metadataJson["system"]["physics"]["restitution"].as(collider.stats.restitution);
|
collider.stats.restitution = metadataJson["system"]["physics"]["restitution"].as(collider.stats.restitution);
|
||||||
collider.stats.friction = metadataJson["system"]["physics"]["friction"].as(collider.stats.friction);
|
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 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} );
|
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) * 0.5f;
|
||||||
|
|
||||||
if ( metadataJson["system"]["physics"]["recenter"].as<bool>() ) collider.transform.position = center - transform.position;
|
|
||||||
|
|
||||||
|
uf::physics::impl::create( *this, corner );
|
||||||
} else if ( metadataJson["system"]["physics"]["type"].as<uf::stl::string>() == "capsule" ) {
|
} else if ( metadataJson["system"]["physics"]["type"].as<uf::stl::string>() == "capsule" ) {
|
||||||
float radius = metadataJson["system"]["physics"]["radius"].as<float>();
|
float radius = metadataJson["system"]["physics"]["radius"].as<float>();
|
||||||
float height = metadataJson["system"]["physics"]["height"].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 ) {
|
void uf::ObjectBehavior::destroy( uf::Object& self ) {
|
||||||
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
|
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>() ) {
|
if ( this->hasComponent<pod::PhysicsState>() && this->hasComponent<pod::Physics>() ) {
|
||||||
auto& collider = this->getComponent<pod::Bullet>();
|
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||||
auto& transform = this->getComponent<pod::Transform<>>();
|
auto& transform = this->getComponent<pod::Transform<>>();
|
||||||
auto& physics = this->getComponent<pod::Physics>();
|
auto& physics = this->getComponent<pod::Physics>();
|
||||||
UF_MSG_DEBUG( this->getName() << ": " << this->getUid() << " " << uf::vector::toString( physics.linear.velocity ) << " " << uf::vector::toString( transform.position ) );
|
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
|
#if UF_USE_BULLET
|
||||||
|
#include <uf/ext/bullet/bullet.h>
|
||||||
|
|
||||||
#include <uf/utils/math/physics.h>
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/utils/renderer/renderer.h>
|
#include <uf/utils/renderer/renderer.h>
|
||||||
@ -80,6 +80,7 @@ size_t ext::bullet::defaultMaxPersistentManifoldPoolSize = 65535;
|
|||||||
bool ext::bullet::debugDrawEnabled = false;
|
bool ext::bullet::debugDrawEnabled = false;
|
||||||
float ext::bullet::debugDrawRate = 1.0f;
|
float ext::bullet::debugDrawRate = 1.0f;
|
||||||
uf::stl::string ext::bullet::debugDrawLayer = "";
|
uf::stl::string ext::bullet::debugDrawLayer = "";
|
||||||
|
float ext::bullet::debugDrawLineWidth = 1.0f;
|
||||||
|
|
||||||
namespace ext {
|
namespace ext {
|
||||||
namespace bullet {
|
namespace bullet {
|
||||||
@ -143,12 +144,24 @@ void ext::bullet::initialize() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void ext::bullet::tick( float delta ) { if ( delta == 0.0f ) delta = uf::physics::time::delta;
|
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;
|
delta = delta * ext::bullet::timescale / ext::bullet::iterations;
|
||||||
for ( size_t i = 0; i < ext::bullet::iterations; ++i ) {
|
for ( size_t i = 0; i < ext::bullet::iterations; ++i ) {
|
||||||
ext::bullet::dynamicsWorld->stepSimulation(delta, ext::bullet::substeps, delta / ext::bullet::substeps);
|
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 && ) {
|
TIMER(ext::bullet::debugDrawRate, ext::bullet::debugDrawEnabled && ) {
|
||||||
ext::bullet::dynamicsWorld->debugDrawWorld();
|
ext::bullet::dynamicsWorld->debugDrawWorld();
|
||||||
}
|
}
|
||||||
@ -174,8 +187,7 @@ void ext::bullet::terminate() {
|
|||||||
if ( ext::bullet::collisionConfiguration ) delete ext::bullet::collisionConfiguration;
|
if ( ext::bullet::collisionConfiguration ) delete ext::bullet::collisionConfiguration;
|
||||||
ext::bullet::collisionShapes.clear();
|
ext::bullet::collisionShapes.clear();
|
||||||
}
|
}
|
||||||
void ext::bullet::syncToBullet() {
|
void ext::bullet::syncTo() {
|
||||||
auto& scene = uf::scene::getCurrentScene();
|
|
||||||
// update bullet transforms
|
// update bullet transforms
|
||||||
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {
|
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {
|
||||||
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
|
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
|
||||||
@ -184,16 +196,15 @@ void ext::bullet::syncToBullet() {
|
|||||||
if ( !body || !body->getMotionState() ) return;
|
if ( !body || !body->getMotionState() ) return;
|
||||||
|
|
||||||
uf::Object* entity = (uf::Object*) body->getUserPointer();
|
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;
|
if ( !collider.shared ) continue;
|
||||||
|
|
||||||
auto& physics = entity->getComponent<pod::Physics>();
|
auto& physics = entity->getComponent<pod::Physics>();
|
||||||
auto model = uf::transform::model( collider.transform );
|
auto model = uf::transform::model( collider.transform );
|
||||||
|
|
||||||
btTransform t;
|
btTransform t = body->getWorldTransform();
|
||||||
t = body->getWorldTransform();
|
|
||||||
t.setFromOpenGLMatrix(&model[0]);
|
t.setFromOpenGLMatrix(&model[0]);
|
||||||
// t.setOrigin( btVector3( transform.position.x, transform.position.y, transform.position.z ) );
|
// 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 ) );
|
// 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 ) );
|
body->setLinearVelocity( btVector3( physics.linear.velocity.x, physics.linear.velocity.y, physics.linear.velocity.z ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ext::bullet::syncFromBullet() {
|
void ext::bullet::syncFrom() {
|
||||||
auto& scene = uf::scene::getCurrentScene();
|
|
||||||
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {
|
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {
|
||||||
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
|
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
|
||||||
btRigidBody* body = btRigidBody::upcast(obj);
|
btRigidBody* body = btRigidBody::upcast(obj);
|
||||||
if ( !body || !body->getMotionState() ) return;
|
if ( !body || !body->getMotionState() ) return;
|
||||||
btTransform t;
|
btTransform t = body->getWorldTransform();
|
||||||
body->getMotionState()->getWorldTransform(t);
|
// body->getMotionState()->getWorldTransform(t);
|
||||||
|
|
||||||
uf::Object* entity = (uf::Object*) body->getUserPointer();
|
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;
|
||||||
size_t uid = entity->getUid();
|
|
||||||
|
|
||||||
auto& collider = entity->getComponent<pod::Bullet>();
|
auto& collider = entity->getComponent<pod::PhysicsState>();
|
||||||
|
|
||||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||||
transform.position.x = t.getOrigin().getX();
|
transform.position.x = t.getOrigin().getX();
|
||||||
@ -243,8 +252,8 @@ void ext::bullet::syncFromBullet() {
|
|||||||
transform = uf::transform::reorient( transform );
|
transform = uf::transform::reorient( transform );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pod::Bullet& ext::bullet::create( uf::Object& object ) {
|
pod::PhysicsState& ext::bullet::create( uf::Object& object ) {
|
||||||
auto& collider = object.getComponent<pod::Bullet>();
|
auto& collider = object.getComponent<pod::PhysicsState>();
|
||||||
|
|
||||||
collider.uid = object.getUid();
|
collider.uid = object.getUid();
|
||||||
collider.pointer = &object;
|
collider.pointer = &object;
|
||||||
@ -252,7 +261,7 @@ pod::Bullet& ext::bullet::create( uf::Object& object ) {
|
|||||||
collider.shared = true;
|
collider.shared = true;
|
||||||
return collider;
|
return collider;
|
||||||
}
|
}
|
||||||
void ext::bullet::attach( pod::Bullet& collider ) {
|
void ext::bullet::attach( pod::PhysicsState& collider ) {
|
||||||
if ( !collider.shape ) return;
|
if ( !collider.shape ) return;
|
||||||
|
|
||||||
auto model = uf::transform::model( collider.transform );
|
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->setFriction(collider.stats.friction);
|
||||||
collider.body->setGravity( btVector3( collider.stats.gravity.x, collider.stats.gravity.y, collider.stats.gravity.z ) );
|
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->setCollisionFlags(collider.body->getCollisionFlags() | collider.stats.flags);
|
||||||
// collider.body->activate(true);
|
if ( collider.stats.mass != 0.0f ) {
|
||||||
// collider.body->setActivationState(DISABLE_DEACTIVATION);
|
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::dynamicsWorld->addRigidBody(collider.body);
|
||||||
ext::bullet::collisionShapes.push_back(collider.shape);
|
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;
|
if ( !collider.body || !collider.shape ) return;
|
||||||
ext::bullet::dynamicsWorld->removeCollisionObject( collider.body );
|
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();
|
btTriangleIndexVertexArray* bMesh = new btTriangleIndexVertexArray();
|
||||||
|
|
||||||
if ( mesh.index.count ) {
|
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 );
|
auto& collider = ext::bullet::create( object );
|
||||||
collider.shape = new btBvhTriangleMeshShape( bMesh, true, true );
|
collider.shape = new btBvhTriangleMeshShape( bMesh, true, true );
|
||||||
|
collider.stats.mass = 0;
|
||||||
ext::bullet::attach( collider );
|
ext::bullet::attach( collider );
|
||||||
|
|
||||||
auto& transform = object.getComponent<pod::Transform<>>();
|
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->setWorldTransform(t);
|
||||||
collider.body->setCenterOfMassTransform(t);
|
collider.body->setCenterOfMassTransform(t);
|
||||||
|
|
||||||
|
/*
|
||||||
btBvhTriangleMeshShape* triangleMeshShape = (btBvhTriangleMeshShape*) collider.shape;
|
btBvhTriangleMeshShape* triangleMeshShape = (btBvhTriangleMeshShape*) collider.shape;
|
||||||
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
|
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
|
||||||
triangleInfoMap->m_edgeDistanceThreshold = 0.01f;
|
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 );
|
btGenerateInternalEdgeInfo( triangleMeshShape, triangleInfoMap );
|
||||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
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 );
|
auto& collider = ext::bullet::create( object );
|
||||||
collider.shape = new btBoxShape(btVector3(corner.x, corner.y, corner.z));
|
collider.shape = new btBoxShape(btVector3(corner.x, corner.y, corner.z));
|
||||||
ext::bullet::attach( collider );
|
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& transform = object.getComponent<pod::Transform<>>();
|
||||||
auto model = uf::transform::model( collider.transform );
|
auto model = uf::transform::model( collider.transform );
|
||||||
|
|
||||||
collider.body->setContactProcessingThreshold(0.0);
|
// collider.body->setContactProcessingThreshold(0.0);
|
||||||
collider.body->setAngularFactor(0.0);
|
// collider.body->setAngularFactor(0.0);
|
||||||
collider.body->setCcdMotionThreshold(1e-7);
|
// collider.body->setCcdMotionThreshold(1e-7);
|
||||||
collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
|
// collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
|
||||||
return collider;
|
return collider;
|
||||||
}
|
}
|
||||||
uf::stl::vector<pod::Bullet>& ext::bullet::create( uf::Object& object, const uf::stl::vector<pod::Instance::Bounds>& bounds ) {
|
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::Bullet>>();
|
auto& colliders = object.getComponent<uf::stl::vector<pod::PhysicsState>>();
|
||||||
colliders.reserve(colliders.size() + bounds.size());
|
colliders.reserve(colliders.size() + bounds.size());
|
||||||
|
|
||||||
auto& transform = object.getComponent<pod::Transform<>>();
|
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));
|
collider.shape = new btBoxShape(btVector3(corner.x, corner.y, corner.z));
|
||||||
ext::bullet::attach( collider );
|
ext::bullet::attach( collider );
|
||||||
|
|
||||||
collider.body->setContactProcessingThreshold(0.0);
|
// collider.body->setContactProcessingThreshold(0.0);
|
||||||
collider.body->setAngularFactor(0.0);
|
// collider.body->setAngularFactor(0.0);
|
||||||
collider.body->setCcdMotionThreshold(1e-7);
|
// collider.body->setCcdMotionThreshold(1e-7);
|
||||||
collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
|
// collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
|
||||||
}
|
}
|
||||||
return colliders;
|
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 );
|
auto& collider = ext::bullet::create( object );
|
||||||
collider.shape = new btCapsuleShape(radius, height);
|
collider.shape = new btCapsuleShape(radius, height);
|
||||||
ext::bullet::attach( collider );
|
ext::bullet::attach( collider );
|
||||||
@ -470,7 +437,7 @@ pod::Bullet& ext::bullet::create( uf::Object& object, float radius, float height
|
|||||||
return collider;
|
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;
|
if ( !collider.body ) return;
|
||||||
collider.body->activate(true);
|
collider.body->activate(true);
|
||||||
if ( collider.shared ) {
|
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 ) );
|
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;
|
if ( !collider.body ) return;
|
||||||
collider.body->activate(true);
|
collider.body->activate(true);
|
||||||
collider.body->applyCentralImpulse( btVector3( v.x, v.y, v.z ) /** uf::physics::time::delta*/ );
|
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;
|
if ( !collider.body ) return;
|
||||||
btTransform transform;
|
|
||||||
collider.body->activate(true);
|
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 );
|
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);
|
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;
|
if ( !collider.body ) return;
|
||||||
collider.body->activate(true);
|
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 ) );
|
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 ) );
|
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;
|
if ( !collider.body ) return;
|
||||||
collider.body->activate(true);
|
collider.body->activate(true);
|
||||||
|
|
||||||
@ -521,8 +490,8 @@ void UF_API ext::bullet::applyRotation( pod::Bullet& collider, const pod::Quater
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
btTransform transform;
|
btTransform transform = collider.body->getWorldTransform();
|
||||||
collider.body->getMotionState()->getWorldTransform(transform);
|
// collider.body->getMotionState()->getWorldTransform(transform);
|
||||||
|
|
||||||
pod::Quaternion<> orientation = uf::vector::normalize(uf::quaternion::multiply({
|
pod::Quaternion<> orientation = uf::vector::normalize(uf::quaternion::multiply({
|
||||||
transform.getRotation().getX(),
|
transform.getRotation().getX(),
|
||||||
@ -532,10 +501,11 @@ void UF_API ext::bullet::applyRotation( pod::Bullet& collider, const pod::Quater
|
|||||||
}, q));
|
}, q));
|
||||||
transform.setRotation( btQuaternion( orientation.x, orientation.y, orientation.z, orientation.w ) );
|
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);
|
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;
|
if ( !collider.body ) return;
|
||||||
collider.body->activate(enabled);
|
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.topology = uf::renderer::enums::PrimitiveTopology::LINE_LIST;
|
||||||
graphic.descriptor.fill = uf::renderer::enums::PolygonMode::LINE;
|
graphic.descriptor.fill = uf::renderer::enums::PolygonMode::LINE;
|
||||||
graphic.descriptor.lineWidth = 8.0f;
|
graphic.descriptor.lineWidth = ext::bullet::debugDrawLineWidth;
|
||||||
} else {
|
} else {
|
||||||
if ( graphic.updateMesh( mesh ) ) {
|
if ( graphic.updateMesh( mesh ) ) {
|
||||||
graphic.getPipeline().update( graphic );
|
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/engine/asset/asset.h>
|
||||||
#include <uf/utils/math/physics.h>
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/engine/object/behaviors/lua.h>
|
#include <uf/engine/object/behaviors/lua.h>
|
||||||
#if UF_USE_BULLET
|
|
||||||
#include <uf/ext/bullet/bullet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace binds {
|
namespace binds {
|
||||||
uf::stl::string formatHookName(uf::Object& self, const uf::stl::string n ){
|
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::Asset)
|
||||||
UF_LUA_RETRIEVE_COMPONENT(uf::Camera)
|
UF_LUA_RETRIEVE_COMPONENT(uf::Camera)
|
||||||
UF_LUA_RETRIEVE_COMPONENT(pod::Physics)
|
UF_LUA_RETRIEVE_COMPONENT(pod::Physics)
|
||||||
#if UF_USE_BULLET
|
UF_LUA_RETRIEVE_COMPONENT(pod::PhysicsState)
|
||||||
UF_LUA_RETRIEVE_COMPONENT(pod::Bullet)
|
|
||||||
#endif
|
|
||||||
return sol::make_object( ext::lua::state, sol::lua_nil );
|
return sol::make_object( ext::lua::state, sol::lua_nil );
|
||||||
}
|
}
|
||||||
void setComponent(uf::Object& self, const uf::stl::string& type, sol::object value ) {
|
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::Asset)
|
||||||
UF_LUA_UPDATE_COMPONENT(uf::Camera)
|
UF_LUA_UPDATE_COMPONENT(uf::Camera)
|
||||||
UF_LUA_UPDATE_COMPONENT(pod::Physics)
|
UF_LUA_UPDATE_COMPONENT(pod::Physics)
|
||||||
#if UF_USE_BULLET
|
UF_LUA_UPDATE_COMPONENT(pod::PhysicsState)
|
||||||
UF_LUA_UPDATE_COMPONENT(pod::Bullet)
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
bool bind(uf::Object& self, const uf::stl::string& type, sol::protected_function fun ) {
|
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 );
|
// 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( setLinearVelocity, UF_LUA_C_FUN(::binds::setLinearVelocity) ),
|
||||||
UF_LUA_REGISTER_USERTYPE_DEFINE( setRotationalVelocity, UF_LUA_C_FUN(::binds::setRotationalVelocity) )
|
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
|
#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 <uf/utils/math/physics.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
uf::Timer<> uf::physics::time::timer;
|
uf::Timer<> uf::physics::time::timer;
|
||||||
uf::physics::num_t uf::physics::time::current;
|
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::delta;
|
||||||
uf::physics::num_t uf::physics::time::clamp;
|
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() {
|
void UF_API uf::physics::tick() {
|
||||||
uf::physics::time::previous = uf::physics::time::current;
|
uf::physics::time::previous = uf::physics::time::current;
|
||||||
uf::physics::time::current = uf::physics::time::timer.elapsed();
|
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 ) {
|
if ( uf::physics::time::delta > uf::physics::time::clamp ) {
|
||||||
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/utils/audio/audio.h>
|
||||||
#include <uf/ext/openvr/openvr.h>
|
#include <uf/ext/openvr/openvr.h>
|
||||||
#include <uf/engine/graph/graph.h>
|
#include <uf/engine/graph/graph.h>
|
||||||
#include <uf/ext/bullet/bullet.h>
|
|
||||||
#include <uf/utils/math/physics.h>
|
#include <uf/utils/math/physics.h>
|
||||||
#include <uf/spec/controller/controller.h>
|
#include <uf/spec/controller/controller.h>
|
||||||
#include <uf/utils/io/inputs.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 ) {
|
void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||||
auto& transform = this->getComponent<pod::Transform<>>();
|
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& metadata = this->getComponent<ext::PlayerBehavior::Metadata>();
|
||||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
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;
|
if ( metadata.camera.invert.x ) relta.x *= -1;
|
||||||
metadata.camera.limit.current.x += relta.x;
|
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 ( 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 ) uf::physics::impl::applyRotation( collider, transform.up, relta.x ); else
|
||||||
if ( collider.body ) ext::bullet::applyRotation( collider, transform.up, relta.x ); else
|
|
||||||
#endif
|
|
||||||
uf::transform::rotate( transform, transform.up, relta.x );
|
uf::transform::rotate( transform, transform.up, relta.x );
|
||||||
} else metadata.camera.limit.current.x -= 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;
|
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 ( 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 ) {
|
// if ( collider.body && !collider.shared ) {
|
||||||
// ext::bullet::applyRotation( collider, cameraTransform.right, relta.y );
|
// uf::physics::impl::applyRotation( collider, cameraTransform.right, relta.y );
|
||||||
// } else {
|
// } else {
|
||||||
uf::transform::rotate( cameraTransform, cameraTransform.right, relta.y );
|
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.menu = metadata.system.menu;
|
||||||
stats.noclipped = metadata.system.noclipped;
|
stats.noclipped = metadata.system.noclipped;
|
||||||
stats.floored = stats.noclipped;
|
stats.floored = stats.noclipped;
|
||||||
#if UF_USE_BULLET
|
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||||
auto& collider = this->getComponent<pod::Bullet>();
|
if ( !stats.floored && collider.body && uf::physics::impl::rayCast( transform.position, transform.position - pod::Vector3f{0,1,0} ) >= 0.0f ) stats.floored = true; else
|
||||||
if ( !stats.floored && collider.body && ext::bullet::rayCast( transform.position, transform.position - pod::Vector3f{0,1,0} ) >= 0.0f ) stats.floored = true; else
|
|
||||||
#endif
|
|
||||||
stats.floored |= fabs(physics.linear.velocity.y) < 0.01f;
|
stats.floored |= fabs(physics.linear.velocity.y) < 0.01f;
|
||||||
|
|
||||||
#if UF_USE_BULLET
|
|
||||||
|
|
||||||
TIMER(0.125, keys.use && ) {
|
TIMER(0.125, keys.use && ) {
|
||||||
size_t uid = 0;
|
size_t uid = 0;
|
||||||
uf::Object* pointer = NULL;
|
uf::Object* pointer = NULL;
|
||||||
@ -224,7 +217,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
|||||||
pod::Vector3f pos = transform.position + cameraTransform.position;
|
pod::Vector3f pos = transform.position + cameraTransform.position;
|
||||||
pod::Vector3f dir = uf::vector::normalize( transform.forward + pod::Vector3f{ 0, cameraTransform.forward.y, 0 } ) * length;
|
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 ) {
|
if ( pointer ) {
|
||||||
uf::Serializer payload;
|
uf::Serializer payload;
|
||||||
payload["uid"] = this->getUid();
|
payload["uid"] = this->getUid();
|
||||||
@ -248,7 +241,6 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
float move = 4;
|
float move = 4;
|
||||||
@ -324,21 +316,19 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
|||||||
metadata.system.noclipped = state;
|
metadata.system.noclipped = state;
|
||||||
|
|
||||||
UF_MSG_DEBUG( (state ? "En" : "Dis") << "abled noclip: " << uf::vector::toString(transform.position));
|
UF_MSG_DEBUG( (state ? "En" : "Dis") << "abled noclip: " << uf::vector::toString(transform.position));
|
||||||
|
#if 0
|
||||||
if ( state ) {
|
if ( state ) {
|
||||||
#if UF_USE_BULLET
|
|
||||||
if ( collider.body ) {
|
if ( collider.body ) {
|
||||||
collider.body->setGravity(btVector3(0,0.0,0));
|
collider.body->setGravity(btVector3(0,0.0,0));
|
||||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
#if UF_USE_BULLET
|
|
||||||
if ( collider.body ) {
|
if ( collider.body ) {
|
||||||
collider.body->setGravity(btVector3(0,-9.81,0));
|
collider.body->setGravity(btVector3(0,-9.81,0));
|
||||||
collider.body->setCollisionFlags(collider.body->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
collider.body->setCollisionFlags(collider.body->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
stats.noclipped = state;
|
stats.noclipped = state;
|
||||||
}
|
}
|
||||||
// movement handler
|
// movement handler
|
||||||
@ -376,15 +366,11 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( keys.lookRight ^ keys.lookLeft ) {
|
if ( keys.lookRight ^ keys.lookLeft ) {
|
||||||
#if UF_USE_BULLET
|
if ( collider.body ) uf::physics::impl::applyRotation( collider, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) ); else
|
||||||
if ( collider.body ) ext::bullet::applyRotation( collider, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) ); else
|
|
||||||
#endif
|
|
||||||
uf::transform::rotate( transform, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) );
|
uf::transform::rotate( transform, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) );
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
#if UF_USE_BULLET
|
if ( collider.body ) uf::physics::impl::setVelocity( collider, physics.linear.velocity ); else
|
||||||
if ( collider.body ) ext::bullet::setVelocity( collider, physics.linear.velocity ); else
|
|
||||||
#endif
|
|
||||||
transform.position += physics.linear.velocity * uf::physics::time::delta;
|
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/openvr/openvr.h>
|
||||||
#include <uf/ext/lua/lua.h>
|
#include <uf/ext/lua/lua.h>
|
||||||
#include <uf/ext/ultralight/ultralight.h>
|
#include <uf/ext/ultralight/ultralight.h>
|
||||||
#include <uf/ext/bullet/bullet.h>
|
|
||||||
|
|
||||||
bool ext::ready = false;
|
bool ext::ready = false;
|
||||||
uf::stl::vector<uf::stl::string> ext::arguments;
|
uf::stl::vector<uf::stl::string> ext::arguments;
|
||||||
@ -216,12 +215,19 @@ void EXT_API ext::initialize() {
|
|||||||
// Set worker threads
|
// Set worker threads
|
||||||
if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "async" ) {
|
if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "async" ) {
|
||||||
uf::thread::async = true;
|
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");
|
UF_MSG_DEBUG("Using async worker threads");
|
||||||
} else if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "auto" ) {
|
} else if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "auto" ) {
|
||||||
auto threads = std::max( 1, (int) std::thread::hardware_concurrency() - 1 );
|
auto threads = std::max( 1, (int) std::thread::hardware_concurrency() - 1 );
|
||||||
::config["engine"]["threads"]["workers"] = threads;
|
::config["engine"]["threads"]["workers"] = threads;
|
||||||
uf::thread::workers = ::config["engine"]["threads"]["workers"].as<size_t>();
|
uf::thread::workers = ::config["engine"]["threads"]["workers"].as<size_t>();
|
||||||
UF_MSG_DEBUG("Using " << threads << " worker threads");
|
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
|
// 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::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::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::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
|
#endif
|
||||||
|
|
||||||
@ -341,12 +356,9 @@ void EXT_API ext::initialize() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UF_USE_BULLET
|
/* Physics */ {
|
||||||
/* Bullet */ {
|
uf::physics::initialize();
|
||||||
ext::bullet::initialize();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if UF_USE_OPENVR
|
#if UF_USE_OPENVR
|
||||||
{
|
{
|
||||||
ext::openvr::enabled = ::config["engine"]["ext"]["vr"]["enable"].as( ext::openvr::enabled );
|
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
|
#if UF_USE_VULKAN
|
||||||
/* Callbacks for 2KHR stuffs */ {
|
/* Callbacks for 2KHR stuffs */ {
|
||||||
uf::hooks.addHook("vulkan:Instance.ExtensionsEnabled", []( const ext::json::Value& json ) {
|
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::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::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{};
|
VkPhysicalDeviceFeatures2KHR deviceFeatures2{};
|
||||||
VkPhysicalDeviceMultiviewFeaturesKHR extFeatures{};
|
VkPhysicalDeviceMultiviewFeaturesKHR extFeatures{};
|
||||||
@ -424,10 +436,10 @@ void EXT_API ext::initialize() {
|
|||||||
deviceFeatures2.pNext = &extFeatures;
|
deviceFeatures2.pNext = &extFeatures;
|
||||||
PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(vkGetInstanceProcAddr(uf::renderer::device.instance, "vkGetPhysicalDeviceFeatures2KHR"));
|
PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(vkGetInstanceProcAddr(uf::renderer::device.instance, "vkGetPhysicalDeviceFeatures2KHR"));
|
||||||
vkGetPhysicalDeviceFeatures2KHR(uf::renderer::device.physicalDevice, &deviceFeatures2);
|
vkGetPhysicalDeviceFeatures2KHR(uf::renderer::device.physicalDevice, &deviceFeatures2);
|
||||||
UF_MSG_DEBUG("Multiview features:" );
|
// UF_MSG_DEBUG("Multiview features:" );
|
||||||
UF_MSG_DEBUG("\tmultiview = " << extFeatures.multiview );
|
// UF_MSG_DEBUG("\tmultiview = " << extFeatures.multiview );
|
||||||
UF_MSG_DEBUG("\tmultiviewGeometryShader = " << extFeatures.multiviewGeometryShader );
|
// UF_MSG_DEBUG("\tmultiviewGeometryShader = " << extFeatures.multiviewGeometryShader );
|
||||||
UF_MSG_DEBUG("\tmultiviewTessellationShader = " << extFeatures.multiviewTessellationShader );
|
// UF_MSG_DEBUG("\tmultiviewTessellationShader = " << extFeatures.multiviewTessellationShader );
|
||||||
|
|
||||||
VkPhysicalDeviceProperties2KHR deviceProps2{};
|
VkPhysicalDeviceProperties2KHR deviceProps2{};
|
||||||
VkPhysicalDeviceMultiviewPropertiesKHR extProps{};
|
VkPhysicalDeviceMultiviewPropertiesKHR extProps{};
|
||||||
@ -436,9 +448,9 @@ void EXT_API ext::initialize() {
|
|||||||
deviceProps2.pNext = &extProps;
|
deviceProps2.pNext = &extProps;
|
||||||
PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>(vkGetInstanceProcAddr(uf::renderer::device.instance, "vkGetPhysicalDeviceProperties2KHR"));
|
PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>(vkGetInstanceProcAddr(uf::renderer::device.instance, "vkGetPhysicalDeviceProperties2KHR"));
|
||||||
vkGetPhysicalDeviceProperties2KHR(uf::renderer::device.physicalDevice, &deviceProps2);
|
vkGetPhysicalDeviceProperties2KHR(uf::renderer::device.physicalDevice, &deviceProps2);
|
||||||
UF_MSG_DEBUG("Multiview properties:");
|
// UF_MSG_DEBUG("Multiview properties:");
|
||||||
UF_MSG_DEBUG("\tmaxMultiviewViewCount = " << extProps.maxMultiviewViewCount);
|
// UF_MSG_DEBUG("\tmaxMultiviewViewCount = " << extProps.maxMultiviewViewCount);
|
||||||
UF_MSG_DEBUG("\tmaxMultiviewInstanceIndex = " << extProps.maxMultiviewInstanceIndex);
|
// UF_MSG_DEBUG("\tmaxMultiviewInstanceIndex = " << extProps.maxMultiviewInstanceIndex);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -561,11 +573,6 @@ void EXT_API ext::tick() {
|
|||||||
/* Update physics timer */ {
|
/* Update physics timer */ {
|
||||||
uf::physics::tick();
|
uf::physics::tick();
|
||||||
}
|
}
|
||||||
#if UF_USE_BULLET
|
|
||||||
/* Update bullet */ {
|
|
||||||
ext::bullet::tick();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Update graph */ {
|
/* Update graph */ {
|
||||||
uf::graph::tick();
|
uf::graph::tick();
|
||||||
}
|
}
|
||||||
@ -659,11 +666,9 @@ void EXT_API ext::terminate() {
|
|||||||
/* Terminate controllers */ {
|
/* Terminate controllers */ {
|
||||||
spec::controller::terminate();
|
spec::controller::terminate();
|
||||||
}
|
}
|
||||||
#if UF_USE_BULLET
|
/* Kill physics */ {
|
||||||
/* Kill bullet */ {
|
uf::physics::terminate();
|
||||||
ext::bullet::terminate();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if UF_USE_ULTRALIGHT
|
#if UF_USE_ULTRALIGHT
|
||||||
/* Ultralight-UX */ if ( ::config["engine"]["ext"]["ultralight"]["enabled"].as<bool>() ) {
|
/* Ultralight-UX */ if ( ::config["engine"]["ext"]["ultralight"]["enabled"].as<bool>() ) {
|
||||||
ext::ultralight::terminate();
|
ext::ultralight::terminate();
|
||||||
|
Loading…
Reference in New Issue
Block a user