Commit for 2022.03.27 22-01-29.7z
This commit is contained in:
parent
4a96f148ad
commit
b904c7f280
9
Makefile
9
Makefile
@ -3,7 +3,7 @@ CC = $(shell cat "./bin/exe/default.config")
|
||||
TARGET_NAME = program
|
||||
TARGET_EXTENSION = exe
|
||||
TARGET_LIB_EXTENSION = dll
|
||||
RENDERER = opengl
|
||||
RENDERER = vulkan
|
||||
|
||||
include makefiles/$(ARCH).$(CC).make
|
||||
|
||||
@ -32,9 +32,10 @@ EXT_LIB_NAME += ext
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.176.1/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.182.0/
|
||||
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.198.1/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.3.204.1/
|
||||
|
||||
#GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin/glslangValidator
|
||||
GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin/glslc
|
||||
#GLSLC += $(VULKAN_SDK_PATH)/Bin/glslangValidator
|
||||
GLSLC += $(VULKAN_SDK_PATH)/Bin/glslc
|
||||
SPV_OPTIMIZER += $(VULKAN_SDK_PATH)/Bin/spirv-opt
|
||||
# Base Engine's DLL
|
||||
INC_DIR += $(ENGINE_INC_DIR)/$(ARCH)/$(CC)
|
||||
@ -282,7 +283,7 @@ $(TARGET): $(OBJS)
|
||||
endif
|
||||
|
||||
%.spv: %.glsl
|
||||
$(GLSL_VALIDATOR) -std=450 -o $@ $<
|
||||
$(GLSLC) -std=450 -o $@ $<
|
||||
$(SPV_OPTIMIZER) --preserve-bindings --preserve-spec-constants -O $@ -o $@
|
||||
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "SS2",
|
||||
"meshes": { "interleaved": true },
|
||||
"meshes": { "interleave": false },
|
||||
"matrix": { "reverseInfinite": true },
|
||||
"lights": {
|
||||
"max": 24,
|
||||
@ -46,8 +46,11 @@
|
||||
"ext": {
|
||||
"vulkan": {
|
||||
"validation": {
|
||||
"enabled": false,
|
||||
"enabled": true,
|
||||
"filters": [
|
||||
"MessageID = 0x124ffb34", // VUID-VkImageMemoryBarrier-oldLayout-01197
|
||||
"MessageID = 0x8ab1932c", // VUID-VkImageViewCreateInfo-imageViewType-04973
|
||||
|
||||
"MessageID = 0x4dae5635", // UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout (false positive for cubemaps)
|
||||
// "MessageID = 0x71500fba", // VUID-vkDestroyDevice-device-00378 (don't care about a clean cleanup)
|
||||
"MessageID = 0x609a13b", // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed (from depth-only calls)
|
||||
@ -71,11 +74,11 @@
|
||||
"deferred reconstruct position": true,
|
||||
"deferred alias output to swapchain": false,
|
||||
"vsync": true,
|
||||
"hdr": false,
|
||||
"hdr": true,
|
||||
"vxgi": true,
|
||||
"deferred sampling": false,
|
||||
"culling": true,
|
||||
"bloom": true
|
||||
"bloom": false
|
||||
},
|
||||
"formats": {
|
||||
"depth": "D32_SFLOAT",
|
||||
@ -143,10 +146,11 @@
|
||||
},
|
||||
"reactphysics": {
|
||||
"timescale": 0.01666666666,
|
||||
"interpolate": false,
|
||||
"debug draw": {
|
||||
"enabled": false,
|
||||
// "layer": "Gui",
|
||||
"rate": 0.06666666666
|
||||
"rate": 0.0125
|
||||
}
|
||||
},
|
||||
"bullet": {
|
||||
@ -201,11 +205,11 @@
|
||||
},
|
||||
"render modes": { "gui": true, "deferred": true },
|
||||
"limiters": {
|
||||
"deltaTime": 10,
|
||||
"deltaTime": 5,
|
||||
"framerate": "auto"
|
||||
},
|
||||
"threads": {
|
||||
"workers" : "async", // "auto"
|
||||
"workers" : "auto", // "async"
|
||||
"frame limiter": "auto"
|
||||
},
|
||||
"debug": {
|
||||
@ -241,9 +245,9 @@
|
||||
"mode" : "windowed", // fullscreen, borderless, windowed
|
||||
"icon" : "./data/textures/icon.png",
|
||||
// "size" : [ 1920, 1080 ],
|
||||
// "size" : [ 1280, 720 ],
|
||||
"size" : [ 1280, 720 ],
|
||||
// "size" : [ 960, 540 ],
|
||||
"size" : [ 640, 480 ],
|
||||
// "size" : [ 640, 480 ],
|
||||
// "size" : [ 256, 224 ],
|
||||
"title" : "Grimgram",
|
||||
"visible" : true
|
||||
|
||||
@ -15,8 +15,8 @@
|
||||
"print tree": false,
|
||||
"print stats": false
|
||||
},
|
||||
"export": {
|
||||
"should": true,
|
||||
"exporter": {
|
||||
"enabled": true,
|
||||
"pretty": false,
|
||||
"compress": true,
|
||||
"quantize": false,
|
||||
@ -26,7 +26,7 @@
|
||||
"unwrap": true
|
||||
},
|
||||
"baking": {
|
||||
"enabled": true,
|
||||
"enabled": false,
|
||||
"resolution": 8192,
|
||||
"shadows": 1024,
|
||||
"trigger": { "mode": "rendered" },
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
{
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
// { "filename": "./models/tiny_msci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
{ "filename": "./models/tiny_msci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
{ "filename": "./models/tiny_msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
|
||||
// { "filename": "./models/micro_sci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/micro_sci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
@ -20,6 +20,14 @@
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
"chunk": {
|
||||
"enabled": true,
|
||||
"size": 3, // [3,3,3],
|
||||
"target": "worldspawn"
|
||||
},
|
||||
"exporter": {
|
||||
"enabled": false
|
||||
},
|
||||
"baking": {
|
||||
"enabled": false,
|
||||
"resolution": 8192,
|
||||
|
||||
@ -65,6 +65,7 @@
|
||||
},
|
||||
"reactphysics": {
|
||||
"timescale": 0.03333333333,
|
||||
"interpolate": false,
|
||||
"debug draw": {
|
||||
"enabled": false,
|
||||
// "layer": "Gui",
|
||||
@ -75,8 +76,8 @@
|
||||
"audio": {
|
||||
"mute": false,
|
||||
"buffers": {
|
||||
"size": 4096,
|
||||
"count": 2
|
||||
"size": 16384,
|
||||
"count": 3
|
||||
},
|
||||
"volumes": {
|
||||
"sfx": 1.0,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "../main.h"
|
||||
|
||||
#include <uf/utils/io/inputs.h>
|
||||
#include <uf/utils/window/window.h>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/image/image.h>
|
||||
@ -102,8 +103,8 @@ void client::initialize() {
|
||||
} );
|
||||
}
|
||||
#if !UF_ENV_DREAMCAST
|
||||
if ( client::config["window"]["mode"].as<std::string>() == "fullscreen" ) client::window.switchToFullscreen();
|
||||
else if ( client::config["window"]["mode"].as<std::string>() == "borderless" ) client::window.switchToFullscreen( true );
|
||||
if ( client::config["window"]["mode"].as<std::string>() == "fullscreen" ) client::window.toggleFullscreen();
|
||||
else if ( client::config["window"]["mode"].as<std::string>() == "borderless" ) client::window.toggleFullscreen( true );
|
||||
#endif
|
||||
|
||||
client::ready = true;
|
||||
@ -116,28 +117,37 @@ void client::tick() {
|
||||
client::window.bufferInputs();
|
||||
client::window.pollEvents();
|
||||
|
||||
if ( client::window.hasFocus() && client::config["window"]["mouse"]["center"].as<bool>() ) {
|
||||
auto previous = client::window.getMousePosition();
|
||||
client::window.setMousePosition(client::window.getSize()/2);
|
||||
auto current = client::window.getMousePosition();
|
||||
auto size = client::window.getSize();
|
||||
if ( client::window.hasFocus() ) {
|
||||
// fullscreener
|
||||
TIMER(1, (uf::inputs::kbm::states::LAlt || uf::inputs::kbm::states::RAlt) && uf::inputs::kbm::states::Enter && ) {
|
||||
UF_MSG_DEBUG("mpoop fullscreen");
|
||||
client::window.toggleFullscreen( false );
|
||||
uf::renderer::states::resized = true;
|
||||
}
|
||||
// mouse move
|
||||
if ( client::config["window"]["mouse"]["center"].as<bool>() ) {
|
||||
auto previous = client::window.getMousePosition();
|
||||
client::window.setMousePosition(client::window.getSize()/2);
|
||||
auto current = client::window.getMousePosition();
|
||||
auto size = client::window.getSize();
|
||||
|
||||
uf::hooks.call("window:Mouse.Moved", pod::payloads::windowMouseMoved{
|
||||
{
|
||||
uf::hooks.call("window:Mouse.Moved", pod::payloads::windowMouseMoved{
|
||||
{
|
||||
"window:Mouse.Moved",
|
||||
"client",
|
||||
{
|
||||
"window:Mouse.Moved",
|
||||
"client",
|
||||
},
|
||||
{
|
||||
pod::Vector2ui{ size.x, size.y },
|
||||
},
|
||||
},
|
||||
{
|
||||
pod::Vector2ui{ size.x, size.y },
|
||||
},
|
||||
},
|
||||
{
|
||||
current,
|
||||
previous - current,
|
||||
0
|
||||
}
|
||||
});
|
||||
current,
|
||||
previous - current,
|
||||
0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -56,10 +56,12 @@ namespace ext {
|
||||
extern UF_API size_t defaultMaxCollisionAlgorithmPoolSize;
|
||||
extern UF_API size_t defaultMaxPersistentManifoldPoolSize;
|
||||
|
||||
extern UF_API bool debugDrawEnabled;
|
||||
extern UF_API float debugDrawRate;
|
||||
extern UF_API uf::stl::string debugDrawLayer;
|
||||
extern UF_API float debugDrawLineWidth;
|
||||
namespace debugDraw {
|
||||
extern UF_API bool enabled;
|
||||
extern UF_API float rate;
|
||||
extern UF_API uf::stl::string layer;
|
||||
extern UF_API float lineWidth;
|
||||
}
|
||||
|
||||
void UF_API initialize();
|
||||
void UF_API tick( float = 0 );
|
||||
@ -78,14 +80,13 @@ namespace ext {
|
||||
pod::PhysicsState& create( uf::Object&, const uf::Mesh&, bool );
|
||||
// collider for boundingbox
|
||||
pod::PhysicsState& UF_API create( uf::Object&, const pod::Vector3f& );
|
||||
uf::stl::vector<pod::PhysicsState>& UF_API create( uf::Object&, const uf::stl::vector<pod::Instance::Bounds>& );
|
||||
// collider for capsule
|
||||
pod::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();
|
||||
void UF_API syncFrom( float = 1 );
|
||||
// apply impulse
|
||||
void UF_API applyImpulse( pod::PhysicsState&, const pod::Vector3f& );
|
||||
// directly move a transform
|
||||
@ -104,9 +105,6 @@ namespace ext {
|
||||
|
||||
// allows noclip
|
||||
void UF_API activateCollision( pod::PhysicsState&, bool = true );
|
||||
|
||||
// allows showing collision models
|
||||
void UF_API debugDraw( uf::Object& );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -22,18 +22,25 @@ namespace pod {
|
||||
rp3d::CollisionShape* shape = NULL;
|
||||
|
||||
pod::Transform<> transform = {};
|
||||
pod::Transform<> previous = {};
|
||||
|
||||
struct {
|
||||
pod::Vector3 velocity;
|
||||
pod::Vector3 acceleration;
|
||||
|
||||
struct Linear {
|
||||
pod::Vector3f velocity;
|
||||
pod::Vector3f acceleration;
|
||||
} linear;
|
||||
|
||||
struct {
|
||||
struct Angular {
|
||||
pod::Quaternion<> velocity;
|
||||
pod::Quaternion<> acceleration;
|
||||
} rotational;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
pod::Transform<> transform = {};
|
||||
Linear linear;
|
||||
Angular rotational;
|
||||
} current, previous;
|
||||
} internal;
|
||||
|
||||
|
||||
struct {
|
||||
uint32_t flags = 0;
|
||||
float mass = 0.0f;
|
||||
@ -54,10 +61,15 @@ namespace ext {
|
||||
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;
|
||||
extern UF_API bool interpolate;
|
||||
extern UF_API bool shared;
|
||||
|
||||
namespace debugDraw {
|
||||
extern UF_API bool enabled;
|
||||
extern UF_API float rate;
|
||||
extern UF_API uf::stl::string layer;
|
||||
extern UF_API float lineWidth;
|
||||
}
|
||||
|
||||
// base collider creation
|
||||
pod::PhysicsState& UF_API create( uf::Object& );
|
||||
@ -78,7 +90,7 @@ namespace ext {
|
||||
// synchronize engine transforms to bullet transforms
|
||||
void UF_API syncTo();
|
||||
// synchronize bullet transforms to engine transforms
|
||||
void UF_API syncFrom();
|
||||
void UF_API syncFrom( float = 1 );
|
||||
// apply impulse
|
||||
void UF_API applyImpulse( pod::PhysicsState&, const pod::Vector3f& );
|
||||
// directly move a transform
|
||||
@ -97,9 +109,6 @@ namespace ext {
|
||||
|
||||
// allows noclip
|
||||
void UF_API activateCollision( pod::PhysicsState&, bool = true );
|
||||
|
||||
// allows showing collision models
|
||||
void UF_API debugDraw( uf::Object& );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -24,7 +24,7 @@
|
||||
#define TIMER_LAMBDA(x) []() {\
|
||||
static uf::Timer<long long> timer(false);\
|
||||
if ( !timer.running() ) timer.start(uf::Time<long long>(-1000000));\
|
||||
uf::physics::num_t time = timer.elapsed();\
|
||||
double time = timer.elapsed();\
|
||||
if ( time >= every ) timer.reset();\
|
||||
static bool first = true; if ( first ) { first = false; return every; }\
|
||||
return time;\
|
||||
@ -33,7 +33,7 @@
|
||||
#define TIMER(x, ...)\
|
||||
static uf::Timer<long long> timer(false);\
|
||||
if ( !timer.running() ) timer.start(uf::Time<long long>(-1000000));\
|
||||
uf::physics::num_t time = timer.elapsed();\
|
||||
double time = timer.elapsed();\
|
||||
if ( time >= x ) timer.reset();\
|
||||
if ( __VA_ARGS__ time >= x )
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ namespace spec {
|
||||
|
||||
void UF_API setTracking(bool state);
|
||||
static pod::Vector2ui UF_API getResolution();
|
||||
void UF_API switchToFullscreen( bool borderless = false );
|
||||
void UF_API toggleFullscreen( bool borderless = false );
|
||||
};
|
||||
}
|
||||
typedef spec::dreamcast::Window Window;
|
||||
|
||||
@ -71,7 +71,7 @@ namespace spec {
|
||||
|
||||
void UF_API_CALL setTracking(bool state);
|
||||
static pod::Vector2ui UF_API_CALL getResolution();
|
||||
void UF_API_CALL switchToFullscreen( bool borderless = false );
|
||||
void UF_API_CALL toggleFullscreen( bool borderless = false );
|
||||
#if defined(UF_USE_VULKAN) && UF_USE_VULKAN == 1
|
||||
uf::stl::vector<uf::stl::string> UF_API_CALL getExtensions( bool validationEnabled );
|
||||
void UF_API_CALL createSurface( VkInstance instance, VkSurfaceKHR& surface );
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include <iostream>
|
||||
template<typename T> pod::Transform<T>& uf::physics::update( pod::Transform<T>& transform, pod::Physics& physics ) {
|
||||
physics.previous = transform;
|
||||
// physics.internal.previous = transform;
|
||||
|
||||
if ( physics.linear.acceleration != pod::Vector3t<T>{0,0,0} )
|
||||
physics.linear.velocity += (physics.linear.acceleration * uf::physics::time::delta);
|
||||
|
||||
@ -52,6 +52,7 @@ namespace uf {
|
||||
template<typename T> pod::Matrix4t<T> /*UF_API*/ model( const pod::Transform<T>& transform, bool flatten = false, size_t depth = SIZE_MAX );
|
||||
template<typename T> pod::Transform<T> /*UF_API*/ fromMatrix( const pod::Matrix4t<T>& matrix );
|
||||
template<typename T> pod::Transform<T>& /*UF_API*/ reference( pod::Transform<T>& transform, const pod::Transform<T>& parent, bool reorient = true );
|
||||
template<typename T> pod::Transform<T> /*UF_API*/ interpolate( const pod::Transform<T>& from, const pod::Transform<T>& to, float factor, bool reorient = true );
|
||||
|
||||
template<typename T> uf::stl::string /*UF_API*/ toString( const pod::Transform<T>&, bool flatten = true );
|
||||
template<typename T> ext::json::Value /*UF_API*/ encode( const pod::Transform<T>&, bool flatten = true, const ext::json::EncodingSettings& = {} );
|
||||
|
||||
@ -150,7 +150,12 @@ template<typename T> pod::Transform<T>& /*UF_API*/ uf::transform::reference( pod
|
||||
transform.reference = const_cast<pod::Transform<T>*>(&parent);
|
||||
return transform;
|
||||
}
|
||||
|
||||
template<typename T> pod::Transform<T> /*UF_API*/ uf::transform::interpolate( const pod::Transform<T>& from, const pod::Transform<T>& to, float factor, bool reorient ) {
|
||||
pod::Transform transform = to;
|
||||
transform.position = uf::vector::lerp( from.position, to.position, factor );
|
||||
transform.orientation = uf::quaternion::slerp( from.orientation, to.orientation, factor );
|
||||
return reorient ? uf::transform::reorient( transform ) : transform;
|
||||
}
|
||||
template<typename T> // Normalizes a vector
|
||||
uf::stl::string /*UF_API*/ uf::transform::toString( const pod::Transform<T>& t, bool flatten ) {
|
||||
pod::Transform<T> transform = flatten ? uf::transform::flatten(t) : t;
|
||||
|
||||
@ -172,10 +172,8 @@ T /*UF_API*/ uf::vector::negate( const T& vector ) {
|
||||
}
|
||||
template<typename T> //
|
||||
T /*UF_API*/ uf::vector::abs( const T& vector ) {
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = abs(vector[i]);
|
||||
T res;
|
||||
for ( auto i = 0; i < T::size; ++i ) res[i] = std::abs( vector[i] );
|
||||
return res;
|
||||
}
|
||||
// Writes to first value
|
||||
|
||||
@ -1,10 +1,27 @@
|
||||
#if 0
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/utils/mesh/mesh.h>
|
||||
#include <limits>
|
||||
|
||||
|
||||
namespace uf {
|
||||
namespace meshgrid {
|
||||
struct UF_API Node {
|
||||
struct {
|
||||
pod::Vector3f min = {};
|
||||
pod::Vector3f max = {};
|
||||
} extents;
|
||||
|
||||
pod::Vector3ui id = {};
|
||||
uf::stl::vector<uf::stl::vector<uint32_t>> indices;
|
||||
};
|
||||
|
||||
uf::stl::vector<Node> UF_API partition( uf::Mesh&, int );
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
namespace uf {
|
||||
class UF_API MeshGrid {
|
||||
protected:
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
template<typename T, typename U>
|
||||
void uf::MeshGrid::initialize( const uf::Mesh<T,U>& mesh, size_t divisions ) {
|
||||
return initialize<T,U>( mesh, pod::Vector3ui{ divisions, divisions, divisions } );
|
||||
@ -62,4 +63,5 @@ const uf::stl::vector<U>& uf::MeshGrid::get( const pod::Vector3f& point ) const
|
||||
#else
|
||||
return at( point ).indices;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -124,6 +124,7 @@ namespace uf {
|
||||
void generateIndirect();
|
||||
|
||||
bool isInterleaved() const;
|
||||
bool isInterleaved( const uf::Mesh::Input& ) const;
|
||||
bool isInterleaved( size_t ) const;
|
||||
|
||||
buffer_t& getBuffer( const uf::Mesh::Input&, size_t = 0 );
|
||||
@ -132,6 +133,13 @@ namespace uf {
|
||||
const buffer_t& getBuffer( const uf::Mesh::Input&, size_t = 0 ) const;
|
||||
const buffer_t& getBuffer( const uf::Mesh::Input&, const uf::Mesh::Attribute& ) const;
|
||||
|
||||
void eraseAttribute( uf::Mesh::Input&, const uf::Mesh::Attribute& );
|
||||
void eraseAttribute( uf::Mesh::Input&, size_t );
|
||||
|
||||
uf::Mesh::Input remapInput( const uf::Mesh::Input&, size_t i = 0 ) const;
|
||||
uf::Mesh::Input remapVertexInput( size_t i = 0 ) const;
|
||||
uf::Mesh::Input remapIndexInput( size_t i = 0 ) const;
|
||||
|
||||
void print( bool = true ) const;
|
||||
|
||||
std::string printVertices( bool = true ) const;
|
||||
@ -139,10 +147,6 @@ namespace uf {
|
||||
std::string printInstances( bool = true ) const;
|
||||
std::string printIndirects( bool = true ) const;
|
||||
|
||||
uf::Mesh::Input remapInput( const uf::Mesh::Input&, size_t i = 0 ) const;
|
||||
uf::Mesh::Input remapVertexInput( size_t i = 0 ) const;
|
||||
uf::Mesh::Input remapIndexInput( size_t i = 0 ) const;
|
||||
|
||||
inline bool hasVertex( const uf::stl::vector<ext::RENDERER::AttributeDescriptor>& descriptors ) const { return _hasV( vertex, descriptors ); }
|
||||
inline bool hasVertex( const uf::Mesh& mesh ) const { return _hasV( vertex, mesh.vertex ); }
|
||||
inline void bindVertex( const uf::stl::vector<ext::RENDERER::AttributeDescriptor>& descriptors ) { return _bindV( vertex, descriptors ); }
|
||||
|
||||
@ -40,7 +40,7 @@ namespace uf {
|
||||
void UF_API_CALL requestFocus();
|
||||
bool UF_API_CALL hasFocus() const;
|
||||
static pod::Vector2ui UF_API_CALL getResolution();
|
||||
void UF_API_CALL switchToFullscreen( bool borderless = false );
|
||||
void UF_API_CALL toggleFullscreen( bool borderless = false );
|
||||
|
||||
#if defined(UF_USE_VULKAN) && UF_USE_VULKAN == 1
|
||||
uf::stl::vector<uf::stl::string> getExtensions( bool validationEnabled = true );
|
||||
|
||||
@ -292,12 +292,11 @@ uf::stl::string uf::Asset::load(const uf::Asset::Payload& payload ) {
|
||||
UF_ASSET_REGISTER(pod::Graph)
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
|
||||
#if UF_USE_OPENGL_FIXED_FUNCTION
|
||||
#if UF_USE_OPENGL
|
||||
// combining mesh is only really a (negligent) gain on Vulkan
|
||||
// collision meshes still use separated meshes, so avoid having to duplicate a mesh for very little gains, if any
|
||||
metadata[payload.filename]["flags"]["ATLAS"] = false;
|
||||
// metadata[payload.filename]["flags"]["SEPARATE"] = true;
|
||||
#elif UF_GRAPH_INDIRECT_DRAW
|
||||
// metadata[payload.filename]["flags"]["ATLAS"] = false;
|
||||
// metadata[payload.filename]["flags"]["SEPARATE"] = false;
|
||||
metadata[payload.filename]["flags"]["SEPARATE"] = true;
|
||||
#endif
|
||||
asset = uf::graph::load( filename, metadata[payload.filename] );
|
||||
uf::graph::process( asset );
|
||||
|
||||
@ -222,10 +222,22 @@ namespace {
|
||||
const uf::stl::string directory = uf::io::directory( graph.name );
|
||||
auto& buffer = mesh.buffers.emplace_back(uf::io::readAsBuffer( directory + "/" + filename ));
|
||||
});
|
||||
|
||||
// remove extraneous buffers
|
||||
#if UF_USE_OPENGL
|
||||
for ( auto& attribute : mesh.vertex.attributes ) {
|
||||
if ( attribute.descriptor.name == "position" ) continue;
|
||||
if ( attribute.descriptor.name == "color" ) continue;
|
||||
if ( attribute.descriptor.name == "uv" ) continue;
|
||||
if ( attribute.descriptor.name == "st" ) continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
mesh.updateDescriptor();
|
||||
|
||||
// return mesh.expand();
|
||||
// if ( mesh.isInterleaved() != uf::Mesh::defaultInterleaved ) return mesh.copy(true);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
||||
@ -225,14 +225,14 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
|
||||
|
||||
const ::EncodingSettings settings = ::EncodingSettings{
|
||||
{
|
||||
/*.pretty = */graph.metadata["export"]["pretty"].as<bool>(),
|
||||
/*.compress = */graph.metadata["export"]["compress"].as<bool>(),
|
||||
/*.quantize = */graph.metadata["export"]["quantize"].as<bool>(),
|
||||
/*.precision = */graph.metadata["export"]["precision"].as<uint8_t>(),
|
||||
/*.pretty = */graph.metadata["exporter"]["pretty"].as<bool>(),
|
||||
/*.compress = */graph.metadata["exporter"]["compress"].as<bool>(),
|
||||
/*.quantize = */graph.metadata["exporter"]["quantize"].as<bool>(),
|
||||
/*.precision = */graph.metadata["exporter"]["precision"].as<uint8_t>(),
|
||||
},
|
||||
/*.combined = */graph.metadata["export"]["combined"].as<bool>(),
|
||||
/*.encodeBuffers = */graph.metadata["export"]["encode buffers"].as<bool>(true),
|
||||
/*.unwrap = */graph.metadata["export"]["unwrap"].as<bool>(true),
|
||||
/*.combined = */graph.metadata["exporter"]["combined"].as<bool>(),
|
||||
/*.encodeBuffers = */graph.metadata["exporter"]["encode buffers"].as<bool>(true),
|
||||
/*.unwrap = */graph.metadata["exporter"]["unwrap"].as<bool>(true),
|
||||
/*.filename = */directory + "/graph.json",
|
||||
};
|
||||
if ( !settings.combined ) uf::io::mkdir(directory);
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include <uf/ext/xatlas/xatlas.h>
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 0
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 1
|
||||
#else
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 1
|
||||
#endif
|
||||
@ -490,43 +490,32 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
mesh.insertVertices( m );
|
||||
mesh.insertIndices( m );
|
||||
mesh.insertInstances( m );
|
||||
|
||||
// mesh.insertIndirects( m );
|
||||
pod::DrawCommand* dc = (pod::DrawCommand*) m.getBuffer( m.indirect ).data();
|
||||
for ( size_t i = 0; i < m.indirect.count; ++i ) drawCommands.emplace_back( dc[i] );
|
||||
}
|
||||
mesh.insertIndirects( drawCommands );
|
||||
|
||||
mesh = mesh.expand();
|
||||
mesh = mesh.copy(true);
|
||||
|
||||
// fix up draw command for combined mesh
|
||||
{
|
||||
auto& attribute = mesh.indirect.attributes.front();
|
||||
auto& buffer = mesh.getBuffer(mesh.indirect); // mesh.buffers[mesh.isInterleaved(mesh.indirect.interleaved) ? mesh.indirect.interleaved : attribute.buffer];
|
||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) buffer.data();
|
||||
|
||||
size_t totalIndices = 0;
|
||||
size_t totalVertices = 0;
|
||||
for ( auto i = 0; i < mesh.indirect.count; ++i ) {
|
||||
auto& drawCommand = drawCommands[i];
|
||||
for ( auto& drawCommand : drawCommands ) {
|
||||
drawCommand.indexID = totalIndices;
|
||||
drawCommand.vertexID = totalVertices;
|
||||
|
||||
totalIndices += drawCommand.indices;
|
||||
totalVertices += drawCommand.vertices;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( totalIndices > mesh.index.count ) {
|
||||
UF_MSG_ERROR("Calculated total indices exceed actual indices count: expecting " << mesh.index.count << ", got " << totalIndices);
|
||||
UF_EXCEPTION("invalid drawCommand");
|
||||
}
|
||||
if ( totalVertices > mesh.vertex.count ) {
|
||||
UF_MSG_ERROR("Calculated total vertices exceed actual vertices count: expecting " << mesh.vertex.count << ", got " << totalVertices);
|
||||
UF_EXCEPTION("invalid drawCommand");
|
||||
}
|
||||
*/
|
||||
|
||||
mesh.insertIndirects( drawCommands );
|
||||
}
|
||||
|
||||
// slice mesh
|
||||
{
|
||||
auto slices = uf::meshgrid::partition( mesh, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
auto& graphic = graph.root.entity->getComponent<uf::Graphic>();
|
||||
graphic.initialize();
|
||||
@ -726,10 +715,10 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
auto max = uf::matrix::multiply<float>( model, bounds.max, 1.0f );
|
||||
|
||||
pod::Vector3f center = (max + min) * 0.5f;
|
||||
pod::Vector3f corner = (max - min) * 0.5f;
|
||||
corner.x = abs(corner.x);
|
||||
corner.y = abs(corner.y);
|
||||
corner.z = abs(corner.z);
|
||||
pod::Vector3f corner = uf::vector::abs(max - min) * 0.5f;
|
||||
// corner.x = abs(corner.x);
|
||||
// corner.y = abs(corner.y);
|
||||
// corner.z = abs(corner.z);
|
||||
|
||||
metadataJson["system"]["physics"]["center"] = uf::vector::encode( center );
|
||||
metadataJson["system"]["physics"]["corner"] = uf::vector::encode( corner );
|
||||
|
||||
@ -8,67 +8,102 @@
|
||||
#include <uf/engine/graph/graph.h>
|
||||
#include <BulletCollision/CollisionShapes/btTriangleShape.h>
|
||||
|
||||
struct VertexLine {
|
||||
pod::Vector3f position;
|
||||
pod::Vector3f color;
|
||||
namespace {
|
||||
struct VertexLine {
|
||||
pod::Vector3f position;
|
||||
pod::Vector3f color;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
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)
|
||||
);
|
||||
UF_VERTEX_DESCRIPTOR(VertexLine,
|
||||
UF_VERTEX_DESCRIPTION(VertexLine, R32G32B32_SFLOAT, position)
|
||||
UF_VERTEX_DESCRIPTION(VertexLine, R32G32B32_SFLOAT, color)
|
||||
);
|
||||
|
||||
class BulletDebugDrawer : public btIDebugDraw {
|
||||
protected:
|
||||
int m;
|
||||
uf::Mesh mesh;
|
||||
public:
|
||||
virtual void drawLine( const btVector3& from, const btVector3& to, const btVector3& color ) {
|
||||
drawLine( from, to, color, color );
|
||||
}
|
||||
virtual void drawLine( const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor ) {
|
||||
uf::stl::vector<VertexLine> vertices;
|
||||
{
|
||||
auto& vertex = vertices.emplace_back();
|
||||
vertex.position = { from.getX(), from.getY(), from.getZ() };
|
||||
vertex.color = { fromColor.getX(), fromColor.getY(), fromColor.getZ() };
|
||||
class BulletDebugDrawer : public btIDebugDraw {
|
||||
protected:
|
||||
int m;
|
||||
uf::Mesh mesh;
|
||||
public:
|
||||
virtual void drawLine( const btVector3& from, const btVector3& to, const btVector3& color ) {
|
||||
drawLine( from, to, color, color );
|
||||
}
|
||||
{
|
||||
auto& vertex = vertices.emplace_back();
|
||||
vertex.position = { to.getX(), to.getY(), to.getZ() };
|
||||
vertex.color = { toColor.getX(), toColor.getY(), toColor.getZ() };
|
||||
virtual void drawLine( const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor ) {
|
||||
uf::stl::vector<VertexLine> vertices;
|
||||
{
|
||||
auto& vertex = vertices.emplace_back();
|
||||
vertex.position = { from.getX(), from.getY(), from.getZ() };
|
||||
vertex.color = { fromColor.getX(), fromColor.getY(), fromColor.getZ() };
|
||||
}
|
||||
{
|
||||
auto& vertex = vertices.emplace_back();
|
||||
vertex.position = { to.getX(), to.getY(), to.getZ() };
|
||||
vertex.color = { toColor.getX(), toColor.getY(), toColor.getZ() };
|
||||
}
|
||||
if ( !mesh.hasVertex<VertexLine>() ) mesh.bind<VertexLine>();
|
||||
mesh.insertVertices(vertices);
|
||||
}
|
||||
if ( !mesh.hasVertex<VertexLine>() ) mesh.bind<VertexLine>();
|
||||
mesh.insertVertices(vertices);
|
||||
}
|
||||
virtual void drawContactPoint(const btVector3&, const btVector3&, btScalar, int, const btVector3&) {
|
||||
virtual void drawContactPoint(const btVector3&, const btVector3&, btScalar, int, const btVector3&) {
|
||||
|
||||
}
|
||||
virtual void reportErrorWarning(const char* str ) {
|
||||
UF_MSG_WARNING("[Bullet] " << str);
|
||||
}
|
||||
virtual void draw3dText(const btVector3& , const char* str ) {
|
||||
}
|
||||
virtual void reportErrorWarning(const char* str ) {
|
||||
UF_MSG_WARNING("[Bullet] " << str);
|
||||
}
|
||||
virtual void draw3dText(const btVector3& , const char* str ) {
|
||||
|
||||
}
|
||||
virtual void setDebugMode(int p) {
|
||||
m = p;
|
||||
}
|
||||
virtual void clearLines() {
|
||||
for ( auto& buffer : mesh.buffers ) buffer.clear();
|
||||
mesh.vertex.count = 0;
|
||||
mesh.index.count = 0;
|
||||
}
|
||||
virtual void flushLines() {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
ext::bullet::debugDraw( scene );
|
||||
}
|
||||
int getDebugMode(void) const { return m; }
|
||||
}
|
||||
virtual void setDebugMode(int p) {
|
||||
m = p;
|
||||
}
|
||||
virtual void clearLines() {
|
||||
for ( auto& buffer : mesh.buffers ) buffer.clear();
|
||||
mesh.vertex.count = 0;
|
||||
mesh.index.count = 0;
|
||||
}
|
||||
virtual void flushLines() {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
ext::bullet::debugDraw( scene );
|
||||
}
|
||||
int getDebugMode(void) const { return m; }
|
||||
|
||||
uf::Mesh& getMesh() { return mesh; }
|
||||
const uf::Mesh& getMesh() const { return mesh; }
|
||||
};
|
||||
uf::Mesh& getMesh() { return mesh; }
|
||||
const uf::Mesh& getMesh() const { return mesh; }
|
||||
};
|
||||
|
||||
void UF_API ext::bullet::debugDraw( uf::Object& object ) {
|
||||
auto& mesh = ext::bullet::debugDrawer.getMesh();
|
||||
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::bullet::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::bullet::debugDrawLineWidth;
|
||||
} else {
|
||||
if ( graphic.updateMesh( mesh ) ) {
|
||||
graphic.getPipeline().update( graphic );
|
||||
}
|
||||
}
|
||||
graphic.process = true;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ext::bullet::iterations = 1;
|
||||
size_t ext::bullet::substeps = 12;
|
||||
@ -314,7 +349,7 @@ pod::PhysicsState& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh
|
||||
auto& indexAttribute = mesh.index.attributes.front();
|
||||
PHY_ScalarType indexType = PHY_INTEGER;
|
||||
PHY_ScalarType vertexType = PHY_FLOAT;
|
||||
switch ( mesh.index.stride ) {
|
||||
switch ( mesh.index.size ) {
|
||||
case sizeof(uint8_t): indexType = PHY_UCHAR; break;
|
||||
case sizeof(uint16_t): indexType = PHY_SHORT; break;
|
||||
case sizeof(uint32_t): indexType = PHY_INTEGER; break;
|
||||
@ -323,18 +358,24 @@ pod::PhysicsState& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh
|
||||
|
||||
btIndexedMesh iMesh;
|
||||
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 );
|
||||
uf::Mesh::Attribute remappedVertexAttribute = vertexAttribute;
|
||||
uf::Mesh::Attribute remappedIndexAttribute = indexAttribute;
|
||||
|
||||
iMesh.m_numTriangles = remappedIndexAttribute.length / 3;
|
||||
iMesh.m_triangleIndexBase = (const uint8_t*) remappedIndexAttribute.pointer;
|
||||
uf::Mesh::Input remappedVertexInput;
|
||||
uf::Mesh::Input remappedIndexInput;
|
||||
for ( auto i = 0; i < mesh.indirect.count; ++i ) {
|
||||
remappedVertexInput = mesh.remapVertexInput( i );
|
||||
remappedIndexInput = mesh.remapIndexInput( i );
|
||||
|
||||
// remappedVertexAttribute = mesh.remapVertexAttribute( vertexAttribute, i );
|
||||
// remappedIndexAttribute = mesh.remapIndexAttribute( indexAttribute, i );
|
||||
|
||||
iMesh.m_numTriangles = remappedIndexInput.count / 3;
|
||||
iMesh.m_triangleIndexBase = (const uint8_t*) remappedIndexAttribute.pointer + remappedIndexAttribute.stride * remappedIndexInput.first;
|
||||
iMesh.m_triangleIndexStride = remappedIndexAttribute.stride * 3;
|
||||
|
||||
iMesh.m_numVertices = remappedVertexAttribute.length;
|
||||
iMesh.m_vertexBase = (const uint8_t*) remappedVertexAttribute.pointer;
|
||||
iMesh.m_numVertices = remappedVertexInput.count;
|
||||
iMesh.m_vertexBase = (const uint8_t*) remappedVertexAttribute.pointer + remappedVertexAttribute.stride * remappedVertexInput.first;
|
||||
iMesh.m_vertexStride = remappedVertexAttribute.stride;
|
||||
iMesh.m_indexType = indexType;
|
||||
iMesh.m_vertexType = vertexType;
|
||||
@ -342,12 +383,12 @@ pod::PhysicsState& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh
|
||||
bMesh->addIndexedMesh( iMesh, indexType );
|
||||
}
|
||||
} else {
|
||||
iMesh.m_numTriangles = indexAttribute.length / 3;
|
||||
iMesh.m_triangleIndexBase = (const uint8_t*) indexAttribute.pointer;
|
||||
iMesh.m_numTriangles = mesh.index.count / 3;
|
||||
iMesh.m_triangleIndexBase = (const uint8_t*) indexAttribute.pointer + indexAttribute.stride * mesh.index.count;
|
||||
iMesh.m_triangleIndexStride = indexAttribute.stride * 3;
|
||||
|
||||
iMesh.m_numVertices = vertexAttribute.length;
|
||||
iMesh.m_vertexBase = (const uint8_t*) vertexAttribute.pointer;
|
||||
iMesh.m_numVertices = mesh.vertex.count;
|
||||
iMesh.m_vertexBase = (const uint8_t*) vertexAttribute.pointer + vertexAttribute.stride * mesh.vertex.count;
|
||||
iMesh.m_vertexStride = vertexAttribute.stride;
|
||||
iMesh.m_indexType = indexType;
|
||||
iMesh.m_vertexType = vertexType;
|
||||
@ -544,37 +585,4 @@ float UF_API ext::bullet::rayCast( const pod::Vector3f& from, const pod::Vector3
|
||||
uid = (uf::Object*) body->getUserPointer();
|
||||
return pen;
|
||||
}
|
||||
|
||||
void UF_API ext::bullet::debugDraw( uf::Object& object ) {
|
||||
auto& mesh = ext::bullet::debugDrawer.getMesh();
|
||||
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::bullet::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::bullet::debugDrawLineWidth;
|
||||
} else {
|
||||
if ( graphic.updateMesh( mesh ) ) {
|
||||
graphic.getPipeline().update( graphic );
|
||||
}
|
||||
}
|
||||
graphic.process = true;
|
||||
}
|
||||
#endif
|
||||
@ -406,6 +406,6 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
}
|
||||
}
|
||||
|
||||
if ( graph.metadata["export"]["should"].as<bool>() ) uf::graph::save( graph, filename );
|
||||
if ( graph.metadata["exporter"]["enabled"].as<bool>() ) uf::graph::save( graph, filename );
|
||||
return graph;
|
||||
}
|
||||
@ -411,23 +411,6 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
||||
else if ( attribute.descriptor.name == "normal" ) drawCommandInfo.attributes.normal = attribute;
|
||||
else if ( attribute.descriptor.name == "color" ) drawCommandInfo.attributes.color = attribute;
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
float* p = (float*) (drawCommandInfo.attributes.position.pointer + drawCommandInfo.attributes.position.stride * drawCommandInfo.descriptor.inputs.vertex.first);
|
||||
// float* p = (float*) drawCommandInfo.attributes.position.pointer;
|
||||
UF_MSG_DEBUG( "[" << i << "] [" << drawCommandInfo.descriptor.inputs.vertex.first << "] (" << p[0] << ", " << p[1] << ", " << p[2] << ")" );
|
||||
}
|
||||
*/
|
||||
/*
|
||||
for ( size_t i = 0; i < drawCommand.vertices; ++i ) {
|
||||
float* p = (float*) (drawCommandInfo.attributes.position.pointer + drawCommandInfo.attributes.position.stride * (i + drawCommand.vertexID));
|
||||
float* uv = (float*) (drawCommandInfo.attributes.uv.pointer + drawCommandInfo.attributes.uv.stride * (i + drawCommand.vertexID));
|
||||
std::cout << "(" << p[0] << ", " << p[1] << ", " << p[2] << "|" << uv[0] << ", " << uv[1] << ") ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
*/
|
||||
|
||||
|
||||
drawCommandInfo.attributes.instance.pointer = &instance;
|
||||
drawCommandInfo.attributes.instance.length = sizeof(instance);
|
||||
|
||||
@ -6,8 +6,6 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/engine/graph/graph.h>
|
||||
|
||||
#define UF_PHYSICS_SHARED 1
|
||||
|
||||
namespace {
|
||||
rp3d::PhysicsCommon common;
|
||||
rp3d::PhysicsWorld* world;
|
||||
@ -40,13 +38,158 @@ namespace {
|
||||
|
||||
|
||||
rp3d::DefaultLogger* logger = NULL;
|
||||
|
||||
pod::Vector3f convert( const rp3d::Vector3& v ) { return pod::Vector3f{ v.x, v.y, v.z }; }
|
||||
rp3d::Vector3 convert( const pod::Vector3f& v ) { return rp3d::Vector3( v.x, v.y, v.z ); }
|
||||
|
||||
pod::Quaternion<> convert( const rp3d::Quaternion& q ) { return pod::Quaternion<>{ q.x, q.y, q.z, q.w }; }
|
||||
rp3d::Quaternion convert( const pod::Quaternion<>& q ) { return rp3d::Quaternion( q.x, q.y, q.z, q.w ); }
|
||||
|
||||
pod::Transform<> convert( const rp3d::Transform& t ) {
|
||||
pod::Transform<> transform;
|
||||
|
||||
/*state.*/transform.position = ::convert(t.getPosition());
|
||||
/*state.*/transform.orientation = ::convert(t.getOrientation());
|
||||
return uf::transform::reorient(/*state.*/transform);
|
||||
}
|
||||
rp3d::Transform convert( const pod::Transform<>& t ) {
|
||||
auto model = uf::transform::model( t );
|
||||
|
||||
rp3d::Transform transform;
|
||||
transform.setFromOpenGL(&model[0]);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
pod::Quaternion<> convertQ( const rp3d::Vector3& _v ) {
|
||||
pod::Quaternion<> q = uf::quaternion::identity();
|
||||
pod::Vector3f v = ::convert( _v );
|
||||
q.w = uf::vector::norm( v );
|
||||
if ( q.w > 0 ) q = { v.x / q.w, v.y / q.w, v.z / q.w, q.w };
|
||||
return q;
|
||||
}
|
||||
rp3d::Vector3 convertQ( const pod::Quaternion<>& q ) {
|
||||
rp3d::Vector3 v;
|
||||
v.x = q.x * q.w;
|
||||
v.y = q.y * q.w;
|
||||
v.z = q.z * q.w;
|
||||
return v;
|
||||
}
|
||||
|
||||
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{};
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
// allows showing collision models
|
||||
void 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 = ::convert( line.point1 );
|
||||
vertex1.color = ::uintToVector( line.color1 );
|
||||
|
||||
auto& vertex2 = vertices.emplace_back();
|
||||
vertex2.position = ::convert( line.point2 );
|
||||
vertex2.color = ::uintToVector( line.color2 );
|
||||
}
|
||||
for ( size_t i = 0; i < triCount; ++i ) {
|
||||
auto& tri = tris[i];
|
||||
|
||||
auto& vertex1 = vertices.emplace_back();
|
||||
vertex1.position = ::convert( tri.point1 );
|
||||
vertex1.color = ::uintToVector( tri.color1 );
|
||||
|
||||
auto& vertex2 = vertices.emplace_back();
|
||||
vertex2.position = ::convert( tri.point2 );
|
||||
vertex2.color = ::uintToVector( tri.color2 );
|
||||
|
||||
auto& vertex3 = vertices.emplace_back();
|
||||
vertex3.position = ::convert( tri.point3 );
|
||||
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::debugDraw::layer);
|
||||
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::debugDraw::lineWidth;
|
||||
} else {
|
||||
if ( graphic.updateMesh( mesh ) ) {
|
||||
graphic.getPipeline().update( graphic );
|
||||
}
|
||||
}
|
||||
graphic.process = true;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
bool ext::reactphysics::shared = true;
|
||||
bool ext::reactphysics::interpolate = true;
|
||||
|
||||
bool ext::reactphysics::debugDraw::enabled = false;
|
||||
float ext::reactphysics::debugDraw::rate = 1.0f;
|
||||
uf::stl::string ext::reactphysics::debugDraw::layer = "";
|
||||
float ext::reactphysics::debugDraw::lineWidth = 1.0f;
|
||||
|
||||
void ext::reactphysics::initialize() {
|
||||
rp3d::PhysicsWorld::WorldSettings settings;
|
||||
@ -60,7 +203,7 @@ void ext::reactphysics::initialize() {
|
||||
::world = ::common.createPhysicsWorld(settings);
|
||||
// ::world->setEventListener(&::listener);
|
||||
|
||||
if ( ext::reactphysics::debugDrawEnabled ) {
|
||||
if ( ext::reactphysics::debugDraw::enabled ) {
|
||||
::world->setIsDebugRenderingEnabled(true);
|
||||
rp3d::DebugRenderer& debugRenderer = ::world->getDebugRenderer();
|
||||
// Select the contact points and contact normals to be displayed
|
||||
@ -71,9 +214,7 @@ void ext::reactphysics::initialize() {
|
||||
}
|
||||
}
|
||||
void ext::reactphysics::tick( float delta ) {
|
||||
#if UF_PHYSICS_SHARED
|
||||
ext::reactphysics::syncTo();
|
||||
#endif
|
||||
|
||||
static float accumulator = 0;
|
||||
|
||||
@ -84,12 +225,12 @@ void ext::reactphysics::tick( float delta ) {
|
||||
accumulator -= ext::reactphysics::timescale;
|
||||
}
|
||||
|
||||
TIMER(ext::reactphysics::debugDrawRate, ext::reactphysics::debugDrawEnabled && ) {
|
||||
TIMER(ext::reactphysics::debugDraw::rate, ext::reactphysics::debugDraw::enabled && ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
ext::reactphysics::debugDraw( scene );
|
||||
::debugDraw( scene );
|
||||
}
|
||||
|
||||
ext::reactphysics::syncFrom();
|
||||
ext::reactphysics::syncFrom( accumulator / ext::reactphysics::timescale );
|
||||
}
|
||||
void ext::reactphysics::terminate() {
|
||||
::common.destroyPhysicsWorld(::world);
|
||||
@ -103,11 +244,8 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object ) {
|
||||
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
|
||||
state.shared = ext::reactphysics::shared;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -121,38 +259,21 @@ void ext::reactphysics::destroy( pod::PhysicsState& 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 ) );
|
||||
rp3d::Transform colliderTransform = rp3d::Transform::identity();
|
||||
colliderTransform.setPosition( ::convert( state.transform.position ) );
|
||||
colliderTransform.setOrientation( ::convert( state.transform.orientation ) );
|
||||
|
||||
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);
|
||||
state.body = ::world->createRigidBody( ::convert( *state.transform.reference ) );
|
||||
|
||||
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();
|
||||
@ -164,7 +285,7 @@ void ext::reactphysics::attach( pod::PhysicsState& state ) {
|
||||
auto& material = collider->getMaterial();
|
||||
material.setBounciness(0);
|
||||
|
||||
state.body->setLocalInertiaTensor( rp3d::Vector3( state.stats.inertia.x, state.stats.inertia.y, state.stats.inertia.z ) );
|
||||
state.body->setLocalInertiaTensor( ::convert( state.stats.inertia ) );
|
||||
}
|
||||
void ext::reactphysics::detach( pod::PhysicsState& state ) {
|
||||
if ( !state.body ) return;
|
||||
@ -178,8 +299,6 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const uf::Mesh
|
||||
|
||||
auto* rMesh = ::common.createTriangleMesh();
|
||||
|
||||
mesh.print( false );
|
||||
|
||||
uf::Mesh::Input vertexInput = mesh.vertex;
|
||||
uf::Mesh::Input indexInput = mesh.index;
|
||||
|
||||
@ -229,62 +348,6 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const uf::Mesh
|
||||
indexType
|
||||
));
|
||||
}
|
||||
/*
|
||||
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.size ) {
|
||||
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 / mesh.vertex.size,
|
||||
(const uint8_t*) remappedVertexAttribute.pointer,
|
||||
remappedVertexAttribute.stride,
|
||||
|
||||
remappedIndexAttribute.length / mesh.index.size / 3,
|
||||
(const uint8_t*) remappedIndexAttribute.pointer,
|
||||
remappedIndexAttribute.stride * 3,
|
||||
|
||||
vertexType,
|
||||
indexType
|
||||
);
|
||||
|
||||
rMesh->addSubpart(vArray);
|
||||
}
|
||||
} else {
|
||||
vArray = new rp3d::TriangleVertexArray(
|
||||
mesh.vertex.count,
|
||||
(const uint8_t*) vertexAttribute.pointer,
|
||||
vertexAttribute.stride,
|
||||
|
||||
mesh.index.count / 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 );
|
||||
@ -316,56 +379,63 @@ void ext::reactphysics::syncTo() {
|
||||
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& 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 ) );
|
||||
if ( state.shared ) {
|
||||
if ( !ext::reactphysics::interpolate ) body->setTransform(::convert(state.transform));
|
||||
// body->setTransform(::convert(state.transform));
|
||||
body->setLinearVelocity( ::convert(state.linear.velocity) );
|
||||
body->setAngularVelocity( ::convertQ(state.rotational.velocity) );
|
||||
}
|
||||
state.internal.previous = state.internal.current;
|
||||
}
|
||||
}
|
||||
// synchronize bullet transforms to engine transforms
|
||||
void ext::reactphysics::syncFrom() {
|
||||
void ext::reactphysics::syncFrom( float interp ) {
|
||||
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;
|
||||
|
||||
/*
|
||||
transform.position = ::convert( body->getTransform().getPosition() );
|
||||
transform.orientation = ::convert( body->getTransform().getOrientation() );
|
||||
|
||||
// state transform is an offset, un-offset
|
||||
if ( state.transform.reference ) {
|
||||
transform.position -= state.transform.position;
|
||||
if ( state.transform.reference ) transform.position -= state.transform.position;
|
||||
|
||||
// transform = uf::transform::reorient( transform );
|
||||
*/
|
||||
|
||||
state.internal.current.transform = ::convert( body->getTransform() );
|
||||
state.internal.current.linear.velocity = ::convert( body->getLinearVelocity() );
|
||||
state.internal.current.rotational.velocity = ::convertQ( body->getAngularVelocity() );
|
||||
|
||||
physics.linear.velocity = state.internal.current.linear.velocity;
|
||||
physics.rotational.velocity = state.internal.current.rotational.velocity;
|
||||
|
||||
if ( !ext::reactphysics::interpolate ) {
|
||||
transform.position = state.internal.current.transform.position;
|
||||
transform.orientation = state.internal.current.transform.orientation;
|
||||
|
||||
// state transform is an offset, un-offset
|
||||
if ( state.transform.reference ) transform.position -= state.transform.position;
|
||||
|
||||
// transform = uf::transform::reorient( transform );
|
||||
} else {
|
||||
// transform = uf::transform::interpolate( state.internal.previous.transform, state.internal.current.transform, interp );
|
||||
|
||||
transform.position = state.internal.previous.transform.position * ( 1.0f - interp ) + state.internal.current.transform.position * interp;
|
||||
transform.orientation = uf::quaternion::slerp( state.internal.previous.transform.orientation, state.internal.current.transform.orientation, interp);
|
||||
if ( state.transform.reference ) transform.position -= state.transform.position;
|
||||
|
||||
// physics.linear.velocity = uf::vector::lerp( state.internal.previous.linear.velocity, state.internal.current.linear.velocity, interp );
|
||||
// physics.rotational.velocity = uf::quaternion::slerp( state.internal.previous.rotational.velocity, state.internal.current.rotational.velocity, interp );
|
||||
}
|
||||
|
||||
/*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;
|
||||
|
||||
transform = uf::transform::reorient( transform );
|
||||
}
|
||||
}
|
||||
// apply impulse
|
||||
@ -376,7 +446,7 @@ void ext::reactphysics::applyMovement( pod::PhysicsState& state, const pod::Vect
|
||||
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 );
|
||||
transform.setPosition( transform.getPosition() + ::convert(v) * uf::physics::time::delta );
|
||||
state.body->setTransform(transform);
|
||||
}
|
||||
// directly apply a velocity
|
||||
@ -385,9 +455,9 @@ void ext::reactphysics::setVelocity( pod::PhysicsState& state, const pod::Vector
|
||||
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 ) );
|
||||
// return;
|
||||
}
|
||||
state.body->setLinearVelocity( ::convert(v) );
|
||||
}
|
||||
void ext::reactphysics::applyVelocity( pod::PhysicsState& state, const pod::Vector3f& v ) {
|
||||
if ( !state.body ) return;
|
||||
@ -395,9 +465,9 @@ void ext::reactphysics::applyVelocity( pod::PhysicsState& state, const pod::Vect
|
||||
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 ) );
|
||||
// return;
|
||||
}
|
||||
state.body->setLinearVelocity( state.body->getLinearVelocity() + ::convert(v) );
|
||||
}
|
||||
// directly rotate a transform
|
||||
void ext::reactphysics::applyRotation( pod::PhysicsState& state, const pod::Quaternion<>& q ) {
|
||||
@ -406,14 +476,10 @@ void ext::reactphysics::applyRotation( pod::PhysicsState& state, const pod::Quat
|
||||
if ( state.shared ) {
|
||||
auto& transform = state.object->getComponent<pod::Transform<>>();
|
||||
uf::transform::rotate( transform, q );
|
||||
return;
|
||||
// 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 ) );
|
||||
|
||||
transform.setOrientation( transform.getOrientation() * ::convert( q ) );
|
||||
state.body->setTransform(transform);
|
||||
}
|
||||
void ext::reactphysics::applyRotation( pod::PhysicsState& state, const pod::Vector3f& axis, float delta ) {
|
||||
@ -427,7 +493,7 @@ float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector
|
||||
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 );
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( direction ) ), &callback );
|
||||
if ( !callback.isHit ) return -1;
|
||||
return callback.raycastInfo.hitFraction;
|
||||
}
|
||||
@ -436,7 +502,7 @@ float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector
|
||||
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 );
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( direction ) ), &callback );
|
||||
uid = 0;
|
||||
if ( !callback.isHit ) {
|
||||
return -1;
|
||||
@ -450,7 +516,7 @@ float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector
|
||||
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 );
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( direction ) ), &callback );
|
||||
object = NULL;
|
||||
if ( !callback.isHit ) {
|
||||
return -1;
|
||||
@ -464,111 +530,4 @@ 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
|
||||
@ -14,6 +14,7 @@ namespace {
|
||||
int endian = 0;
|
||||
namespace funs {
|
||||
size_t read( void* destination, size_t size, size_t nmemb, void* userdata ) {
|
||||
//UF_MSG_DEBUG( size * nmemb );
|
||||
uf::Audio::Metadata& metadata = *((uf::Audio::Metadata*) userdata);
|
||||
std::ifstream& file = *metadata.stream.file;
|
||||
|
||||
@ -54,6 +55,7 @@ namespace {
|
||||
return length;
|
||||
}
|
||||
int seek( void* userdata, ogg_int64_t to, int type ) {
|
||||
//UF_MSG_DEBUG(type << " " << to);
|
||||
uf::Audio::Metadata& metadata = *((uf::Audio::Metadata*) userdata);
|
||||
switch ( type ) {
|
||||
case SEEK_CUR: metadata.stream.consumed += to; break; // increment
|
||||
@ -73,6 +75,7 @@ namespace {
|
||||
return 0;
|
||||
}
|
||||
int close( void* userdata ) {
|
||||
//UF_MSG_DEBUG( userdata );
|
||||
uf::Audio::Metadata& metadata = *((uf::Audio::Metadata*) userdata);
|
||||
if ( !metadata.stream.file ) return 0;
|
||||
|
||||
@ -83,6 +86,7 @@ namespace {
|
||||
return 0;
|
||||
}
|
||||
long tell( void* userdata ) {
|
||||
//UF_MSG_DEBUG( userdata );
|
||||
uf::Audio::Metadata& metadata = *((uf::Audio::Metadata*) userdata);
|
||||
return metadata.stream.consumed;
|
||||
}
|
||||
@ -194,10 +198,13 @@ void ext::vorbis::stream( uf::Audio::Metadata& metadata ) {
|
||||
else if ( metadata.info.channels == 2 && metadata.info.bitDepth == 8 ) metadata.info.format = AL_FORMAT_STEREO8;
|
||||
else if ( metadata.info.channels == 2 && metadata.info.bitDepth == 16 ) metadata.info.format = AL_FORMAT_STEREO16;
|
||||
else {
|
||||
UF_MSG_ERROR("Vorbis: unrecognized OGG format: " << metadata.info.channels << " channels, " << metadata.info.bitDepth << " bps");
|
||||
UF_MSG_ERROR("Vorbis: unrecognized OGG format: " << (int) metadata.info.channels << " channels, " << (int) metadata.info.bitDepth << " bps");
|
||||
return;
|
||||
}
|
||||
|
||||
// UF_MSG_DEBUG( "filename\tchannels\tbitDepth\tfrequency\tduration\tchannels" );
|
||||
// UF_MSG_DEBUG( metadata.filename << "\t" << (int)metadata.info.channels << "\t" << (int)metadata.info.bitDepth << "\t" << (int)metadata.info.frequency << "\t" << metadata.info.duration << "\t" << (int) metadata.info.channels );
|
||||
|
||||
// fill and queue initial buffers
|
||||
char buffer[uf::audio::bufferSize];
|
||||
uint8_t queuedBuffers = 0;
|
||||
@ -230,8 +237,9 @@ void ext::vorbis::stream( uf::Audio::Metadata& metadata ) {
|
||||
}
|
||||
read += result;
|
||||
}
|
||||
|
||||
if ( read == 0 ) {
|
||||
// UF_MSG_WARNING("Vorbis: consumed file stream before buffers are filled: " << (int) queuedBuffers << " " << metadata.filename);
|
||||
// UF_MSG_WARNING("Vorbis: consumed file stream before buffers are filled: " << (int) queuedBuffers << " " << metadata.filename);
|
||||
// if ( metadata.settings.loopMode == 0 ) metadata.settings.loopMode = 1;
|
||||
// if ( metadata.settings.loop ) metadata.al.source.set( AL_LOOPING, AL_TRUE );
|
||||
break;
|
||||
@ -241,7 +249,7 @@ void ext::vorbis::stream( uf::Audio::Metadata& metadata ) {
|
||||
AL_CHECK_RESULT(alSourceQueueBuffers(metadata.al.source.getIndex(), queuedBuffers, &metadata.al.buffer.getIndex()));
|
||||
// switch to soft looping
|
||||
if ( queuedBuffers >= metadata.settings.buffers ) {
|
||||
// UF_MSG_WARNING("Vorbis: file not completely consumed from initial buffer filled, yet looping is enabled. Soft looping...: " << metadata.filename );
|
||||
// UF_MSG_WARNING("Vorbis: file not completely consumed from initial buffer filled, yet looping is enabled. Soft looping...: " << metadata.filename );
|
||||
metadata.settings.loopMode = 1;
|
||||
metadata.al.source.set( AL_LOOPING, AL_FALSE );
|
||||
}
|
||||
@ -256,11 +264,11 @@ void ext::vorbis::update( uf::Audio::Metadata& metadata ) {
|
||||
metadata.al.source.get( AL_SOURCE_STATE, state );
|
||||
if ( state != AL_PLAYING ) {
|
||||
if ( !metadata.settings.loop && metadata.stream.consumed >= metadata.info.size ) {
|
||||
// UF_MSG_INFO("Vorbis stream finished: " << metadata.filename);
|
||||
// UF_MSG_INFO("Vorbis stream finished: " << metadata.filename);
|
||||
return;
|
||||
}
|
||||
// stream stalled, restart it
|
||||
// UF_MSG_INFO("Vorbis stream stalled: " << metadata.filename);
|
||||
// UF_MSG_INFO("Vorbis stream stalled: " << metadata.filename);
|
||||
metadata.al.source.play();
|
||||
}
|
||||
|
||||
@ -325,7 +333,7 @@ void ext::vorbis::update( uf::Audio::Metadata& metadata ) {
|
||||
if ( metadata.settings.loopMode == 1 ) metadata.al.source.set( AL_LOOPING, AL_TRUE );
|
||||
}
|
||||
void ext::vorbis::close( uf::Audio::Metadata& metadata ) {
|
||||
// UF_MSG_INFO("Vorbis " << ( metadata.settings.streamed ? "stream" : "load" ) << " closed: " << metadata.filename);
|
||||
// UF_MSG_INFO("Vorbis " << ( metadata.settings.streamed ? "stream" : "load" ) << " closed: " << metadata.filename);
|
||||
if ( metadata.stream.handle ) {
|
||||
ov_clear((OggVorbis_File*) metadata.stream.handle);
|
||||
delete (OggVorbis_File*) metadata.stream.handle;
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
|
||||
#define UF_MSG_VALIDATION(X) if ( ext::vulkan::settings::validation ) UF_MSG("VULKAN", X);
|
||||
|
||||
namespace {
|
||||
#if UF_USE_OPENVR
|
||||
void VRInstanceExtensions( uf::stl::vector<uf::stl::string>& requested ) {
|
||||
@ -23,7 +25,6 @@ namespace {
|
||||
vr::VRCompositor()->GetVulkanInstanceExtensionsRequired( pExtensionStr, nBufferSize );
|
||||
uf::stl::vector<uf::stl::string> extensions = uf::string::split( pExtensionStr, " " );
|
||||
for ( auto& str : extensions ) {
|
||||
// uf::iostream << str << "\n";
|
||||
requested.push_back(str);
|
||||
}
|
||||
// requested.insert( requested.end(), extensions.begin(), extensions.end() );
|
||||
@ -55,9 +56,7 @@ namespace {
|
||||
supportedExtensions.push_back( extensionName );
|
||||
break;
|
||||
}
|
||||
if ( !found ) {
|
||||
uf::iostream << "Vulkan missing requested extension: " << requestedExtension << "\n";
|
||||
}
|
||||
if ( !found ) UF_MSG_ERROR("Vulkan missing requested extension: " << requestedExtension);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,8 +67,8 @@ namespace {
|
||||
if ( feature == #NAME ) {\
|
||||
if ( device.features.NAME == VK_TRUE ) {\
|
||||
device.enabledFeatures.NAME = true;\
|
||||
if ( ext::vulkan::settings::validation ) uf::iostream << "Enabled feature: " << feature << "\n";\
|
||||
} else if ( ext::vulkan::settings::validation ) uf::iostream << "Failed to enable feature: " << feature << "\n";\
|
||||
UF_MSG_VALIDATION("Enabled feature: " << feature);\
|
||||
} else UF_MSG_VALIDATION("Failed to enable feature: " << feature);\
|
||||
}
|
||||
|
||||
for ( auto& feature : ext::vulkan::settings::requestedDeviceFeatures ) {
|
||||
@ -135,8 +134,8 @@ namespace {
|
||||
if ( feature == #NAME ) {\
|
||||
if ( device.features2.NAME == VK_TRUE ) {\
|
||||
device.enabledFeatures2.NAME = true;\
|
||||
if ( ext::vulkan::settings::validation ) uf::iostream << "Enabled feature: " << feature << "\n";\
|
||||
} else if ( ext::vulkan::settings::validation ) uf::iostream << "Failed to enable feature: " << feature << "\n";\
|
||||
UF_MSG_VALIDATION("Enabled feature: " << feature);\
|
||||
} else UF_MSG_VALIDATION("Failed to enable feature: " << feature);\
|
||||
}
|
||||
#undef CHECK_FEATURE2
|
||||
}
|
||||
@ -546,8 +545,7 @@ void ext::vulkan::Device::initialize() {
|
||||
{
|
||||
uf::stl::vector<const char*> instanceExtensions;
|
||||
for ( auto& s : supportedExtensions.instance ) {
|
||||
if ( ext::vulkan::settings::validation )
|
||||
uf::iostream << "Enabled instance extension: " << s << "\n";
|
||||
UF_MSG_VALIDATION("Enabled instance extension: " << s);
|
||||
instanceExtensions.push_back( s.c_str() );
|
||||
}
|
||||
|
||||
@ -669,8 +667,7 @@ void ext::vulkan::Device::initialize() {
|
||||
#endif
|
||||
{
|
||||
// Allocate enough ExtensionProperties to support all extensions being enabled
|
||||
if ( ext::vulkan::settings::validation )
|
||||
for ( auto ext : requestedExtensions ) uf::iostream << "Requested device extension: " << ext << "\n";
|
||||
for ( auto ext : requestedExtensions ) UF_MSG_VALIDATION("Requested device extension: " << ext);
|
||||
|
||||
uint32_t extensionsCount = 0;
|
||||
uint32_t enabledExtensionsCount = 0;
|
||||
@ -685,7 +682,7 @@ void ext::vulkan::Device::initialize() {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
for ( auto& s : supportedExtensions.device ) {
|
||||
if ( ext::vulkan::settings::validation ) uf::iostream << "Enabled device extension: " << s << "\n";
|
||||
UF_MSG_VALIDATION("Enabled device extension: " << s);
|
||||
deviceExtensions.push_back( s.c_str() );
|
||||
}
|
||||
|
||||
@ -762,6 +759,7 @@ void ext::vulkan::Device::initialize() {
|
||||
|
||||
VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{};
|
||||
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures{};
|
||||
VkPhysicalDeviceShaderDrawParametersFeatures shaderDrawParametersFeatures{};
|
||||
{
|
||||
deviceCreateInfo.pEnabledFeatures = nullptr;
|
||||
deviceCreateInfo.pNext = &physicalDeviceFeatures2;
|
||||
@ -769,7 +767,7 @@ void ext::vulkan::Device::initialize() {
|
||||
{
|
||||
physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||
physicalDeviceFeatures2.features = enabledFeatures;
|
||||
physicalDeviceFeatures2.pNext = &descriptorIndexingFeatures;
|
||||
physicalDeviceFeatures2.pNext = &descriptorIndexingFeatures;
|
||||
}
|
||||
{
|
||||
descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
|
||||
@ -777,6 +775,11 @@ void ext::vulkan::Device::initialize() {
|
||||
descriptorIndexingFeatures.shaderStorageImageArrayNonUniformIndexing = VK_TRUE;
|
||||
descriptorIndexingFeatures.runtimeDescriptorArray = VK_TRUE;
|
||||
descriptorIndexingFeatures.descriptorBindingVariableDescriptorCount = VK_TRUE;
|
||||
descriptorIndexingFeatures.pNext = &shaderDrawParametersFeatures;
|
||||
}
|
||||
{
|
||||
shaderDrawParametersFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES;
|
||||
shaderDrawParametersFeatures.shaderDrawParameters = VK_TRUE;
|
||||
}
|
||||
|
||||
if ( vkCreateDevice( this->physicalDevice, &deviceCreateInfo, nullptr, &this->logicalDevice) != VK_SUCCESS ) {
|
||||
@ -789,7 +792,7 @@ void ext::vulkan::Device::initialize() {
|
||||
}
|
||||
{
|
||||
ext::json::Value payload = retrieveDeviceFeatures( *this );
|
||||
if ( ext::vulkan::settings::validation ) uf::iostream << payload.dump() << "\n";
|
||||
UF_MSG_VALIDATION(payload.dump());
|
||||
uf::hooks.call("vulkan:Device.FeaturesEnabled", payload);
|
||||
}
|
||||
}
|
||||
@ -917,6 +920,7 @@ void ext::vulkan::Device::initialize() {
|
||||
}
|
||||
// setup allocator
|
||||
{
|
||||
/*
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2;
|
||||
allocatorInfo.physicalDevice = physicalDevice;
|
||||
@ -924,6 +928,19 @@ void ext::vulkan::Device::initialize() {
|
||||
allocatorInfo.device = logicalDevice;
|
||||
|
||||
allocatorInfo.frameInUseCount = 1;
|
||||
vmaCreateAllocator(&allocatorInfo, &allocator);
|
||||
*/
|
||||
VmaVulkanFunctions vulkanFunctions = {};
|
||||
vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
|
||||
vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
|
||||
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2;
|
||||
allocatorInfo.physicalDevice = physicalDevice;
|
||||
allocatorInfo.instance = instance;
|
||||
allocatorInfo.device = logicalDevice;
|
||||
allocatorInfo.pVulkanFunctions = &vulkanFunctions;
|
||||
|
||||
vmaCreateAllocator(&allocatorInfo, &allocator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,9 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
|
||||
if ( settings::experimental::bloom ) settings::experimental::deferredAliasOutputToSwapchain = false;
|
||||
|
||||
auto HDR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
auto SDR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
|
||||
ext::vulkan::RenderMode::initialize( device );
|
||||
renderTarget.device = &device;
|
||||
renderTarget.views = metadata.eyes;
|
||||
@ -76,7 +79,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
});
|
||||
} else {
|
||||
attachments.albedo = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */ext::vulkan::settings::experimental::hdr ? VK_FORMAT_R16G16B16A16_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.format = */ext::vulkan::settings::experimental::hdr ? HDR_FORMAT : VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */blend,
|
||||
@ -91,21 +94,21 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
attachments.color = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.format =*/ ext::vulkan::settings::experimental::hdr ? HDR_FORMAT : SDR_FORMAT,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
/*.blend =*/ blend,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
attachments.bright = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.format =*/ ext::vulkan::settings::experimental::hdr ? HDR_FORMAT : SDR_FORMAT,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
/*.blend =*/ blend,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
attachments.scratch = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.format =*/ ext::vulkan::settings::experimental::hdr ? HDR_FORMAT : SDR_FORMAT,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
/*.blend =*/ blend,
|
||||
@ -139,7 +142,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
}
|
||||
} else {
|
||||
attachments.output = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.format =*/ ext::vulkan::settings::experimental::hdr ? HDR_FORMAT : SDR_FORMAT,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
/*.blend =*/ blend,
|
||||
|
||||
@ -22,10 +22,19 @@ pod::Vector2ui UF_API ext::xatlas::unwrap( pod::Graph& graph ) {
|
||||
auto& name = graph.meshes[index];
|
||||
auto& mesh = /*graph.storage*/uf::graph::storage.meshes[name];
|
||||
|
||||
UF_ASSERT( !mesh.isInterleaved() );
|
||||
|
||||
/*
|
||||
if ( mesh.isInterleaved() ) {
|
||||
sources.emplace_back(mesh.convert()).updateDescriptor();
|
||||
} else {
|
||||
sources.emplace_back(mesh).updateDescriptor();
|
||||
}
|
||||
*/
|
||||
if ( mesh.isInterleaved() ) {
|
||||
UF_EXCEPTION("unwrapping interleaved mesh is not supported");
|
||||
}
|
||||
sources.emplace_back(mesh).updateDescriptor();
|
||||
|
||||
|
||||
uf::Mesh::Input vertexInput = mesh.vertex;
|
||||
|
||||
uf::Mesh::Attribute positionAttribute;
|
||||
@ -102,10 +111,10 @@ pod::Vector2ui UF_API ext::xatlas::unwrap( pod::Graph& graph ) {
|
||||
}
|
||||
|
||||
::xatlas::ChartOptions chartOptions{};
|
||||
// chartOptions.useInputMeshUvs = true;
|
||||
chartOptions.useInputMeshUvs = true;
|
||||
|
||||
::xatlas::PackOptions packOptions{};
|
||||
packOptions.bruteForce = true;
|
||||
packOptions.bruteForce = false;
|
||||
// packOptions.resolution = resolution;
|
||||
// packOptions.texelsPerUnit = 64.0f;
|
||||
packOptions.blockAlign = true;
|
||||
@ -162,21 +171,29 @@ pod::Vector2ui UF_API ext::xatlas::unwrap( pod::Graph& graph ) {
|
||||
auto& vertex = xmesh.vertexArray[j];
|
||||
auto ref = vertex.xref;
|
||||
for ( auto k = 0; k < mesh.vertex.attributes.size(); ++k ) {
|
||||
auto srcAttribute = source.remapVertexAttribute( source.vertex.attributes[k], entry.command );
|
||||
auto dstAttribute = mesh.remapVertexAttribute( mesh.vertex.attributes[k], entry.command );
|
||||
// auto srcAttribute = source.remapVertexAttribute( source.vertex.attributes[k], entry.command );
|
||||
// auto dstAttribute = mesh.remapVertexAttribute( mesh.vertex.attributes[k], entry.command );
|
||||
|
||||
auto srcInput = source.remapVertexInput( entry.command );
|
||||
auto dstInput = mesh.remapVertexInput( entry.command );
|
||||
|
||||
auto srcAttribute = source.vertex.attributes[k];
|
||||
auto dstAttribute = mesh.vertex.attributes[k];
|
||||
|
||||
if ( dstAttribute.descriptor.name == "st" ) {
|
||||
pod::Vector2f& st = *(pod::Vector2f*) ( ((uint8_t*) dstAttribute.pointer) + dstAttribute.stride * j);
|
||||
pod::Vector2f& st = *(pod::Vector2f*) ( dstAttribute.pointer + dstAttribute.stride * (j + dstInput.first) );
|
||||
st = pod::Vector2f{ vertex.uv[0] / atlas->width, vertex.uv[1] / atlas->height };
|
||||
} else {
|
||||
memcpy( dstAttribute.pointer + dstAttribute.stride * j, srcAttribute.pointer + srcAttribute.stride * ref, srcAttribute.stride );
|
||||
memcpy( dstAttribute.pointer + dstAttribute.stride * (j + dstInput.first), srcAttribute.pointer + srcAttribute.stride * (ref + srcInput.first), srcAttribute.stride );
|
||||
}
|
||||
}
|
||||
}
|
||||
// indices
|
||||
if ( mesh.index.count ) {
|
||||
uf::Mesh::Attribute indexAttribute = mesh.remapIndexAttribute( mesh.index.attributes.front(), entry.command );
|
||||
uint8_t* pointer = (uint8_t*) indexAttribute.pointer;
|
||||
uf::Mesh::Input indexInput = mesh.remapIndexInput( entry.command );
|
||||
uf::Mesh::Attribute indexAttribute = mesh.index.attributes.front();
|
||||
// uf::Mesh::Attribute indexAttribute = mesh.remapIndexAttribute( mesh.index.attributes.front(), entry.command );
|
||||
uint8_t* pointer = (uint8_t*) indexAttribute.pointer + indexAttribute.stride * indexInput.first;
|
||||
for ( auto index = 0; index < xmesh.indexCount; ++index ) {
|
||||
switch ( mesh.index.size ) {
|
||||
case 1: (( uint8_t*) pointer)[index] = xmesh.indexArray[index]; break;
|
||||
|
||||
@ -1413,18 +1413,38 @@ void UF_API_CALL spec::win32::Window::grabMouse(bool state) {
|
||||
pod::Vector2ui UF_API_CALL spec::win32::Window::getResolution() {
|
||||
return { GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN) };
|
||||
}
|
||||
void UF_API_CALL spec::win32::Window::switchToFullscreen( bool borderless ) {
|
||||
void UF_API_CALL spec::win32::Window::toggleFullscreen( bool borderless ) {
|
||||
static pod::Vector2ui lastSize = this->getSize();
|
||||
static LONG lastStyle;
|
||||
static LONG lastExStyle;
|
||||
|
||||
if ( fullscreenWindow == (void*) this ) {
|
||||
fullscreenWindow = NULL;
|
||||
SetWindowLong(this->m_handle, GWL_STYLE, lastStyle);
|
||||
SetWindowLong(this->m_handle, GWL_EXSTYLE, lastExStyle);
|
||||
|
||||
this->setSize( lastSize );
|
||||
this->centerWindow();
|
||||
return;
|
||||
}
|
||||
|
||||
lastSize = this->getSize();
|
||||
lastStyle = GetWindowLong(this->m_handle, GWL_STYLE);
|
||||
lastExStyle = GetWindowLong(this->m_handle, GWL_EXSTYLE);
|
||||
|
||||
if ( borderless ) {
|
||||
SetWindowLong(this->m_handle, GWL_STYLE, WS_POPUP );
|
||||
// SetWindowLong(this->m_handle, GWL_EXSTYLE, 0);
|
||||
// SetWindowPos(this->m_handle, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
|
||||
SetWindowPos(this->m_handle, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
|
||||
ShowWindow(this->m_handle, SW_SHOW);
|
||||
return;
|
||||
}
|
||||
|
||||
SetWindowLong(this->m_handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
|
||||
SetWindowLong(this->m_handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
|
||||
SetWindowPos(this->m_handle, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
|
||||
ShowWindow(this->m_handle, SW_SHOW);
|
||||
|
||||
fullscreenWindow = (void*) this;
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,135 @@
|
||||
#include <uf/utils/mesh/grid.h>
|
||||
|
||||
namespace {
|
||||
inline bool isInside( const pod::Vector3f& p, const pod::Vector3f& min, const pod::Vector3f& max ) {
|
||||
// return ( min.x <= p.x && p.x <= max.x && min.y <= p.y && p.y <= max.y && min.z <= p.z && p.z <= max.z );
|
||||
return (p.x <= max.x && p.x >= min.x) && (p.y <= max.y && p.y >= min.y) && (p.z <= max.z && p.z >= min.z);
|
||||
}
|
||||
}
|
||||
|
||||
uf::stl::vector<uf::meshgrid::Node> UF_API uf::meshgrid::partition( uf::Mesh& mesh, int divisions ) {
|
||||
struct {
|
||||
pod::Vector3f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
||||
pod::Vector3f max = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
||||
|
||||
pod::Vector3f center = {};
|
||||
pod::Vector3f corner = {};
|
||||
|
||||
pod::Vector3f size = {};
|
||||
pod::Vector3f piece = {};
|
||||
} extents;
|
||||
|
||||
uf::Mesh::Input vertexInput = mesh.vertex;
|
||||
uf::Mesh::Input indexInput = mesh.index;
|
||||
|
||||
uf::Mesh::Attribute vertexAttribute = mesh.vertex.attributes.front();
|
||||
uf::Mesh::Attribute indexAttribute = mesh.index.attributes.front();
|
||||
|
||||
for ( auto& attribute : mesh.vertex.attributes ) if ( attribute.descriptor.name == "position" ) { vertexAttribute = attribute; break; }
|
||||
UF_ASSERT( vertexAttribute.descriptor.name == "position" );
|
||||
|
||||
for ( size_t i = 0; i < mesh.vertex.count; ++i ) {
|
||||
pod::Vector3f& position = *(pod::Vector3f*) (vertexAttribute.pointer + vertexAttribute.stride * (vertexInput.first + i));
|
||||
extents.min = uf::vector::min( position, extents.min );
|
||||
extents.max = uf::vector::max( position, extents.max );
|
||||
}
|
||||
constexpr float epsilon = std::numeric_limits<float>::epsilon();
|
||||
extents.min -= pod::Vector3f{ epsilon, epsilon, epsilon }; // dilate
|
||||
extents.max += pod::Vector3f{ epsilon, epsilon, epsilon }; // dilate
|
||||
extents.size = uf::vector::abs(extents.max - extents.min);
|
||||
extents.piece = extents.size / divisions;
|
||||
|
||||
extents.center = (extents.max + extents.min) * 0.5f;
|
||||
extents.corner = extents.size * 0.5f;
|
||||
|
||||
uf::stl::vector<uf::meshgrid::Node> nodes;
|
||||
nodes.reserve( divisions * divisions * divisions );
|
||||
|
||||
for ( int z = 0; z < divisions; ++z ) {
|
||||
for ( int y = 0; y < divisions; ++y ) {
|
||||
for ( int x = 0; x < divisions; ++x ) {
|
||||
nodes.emplace_back(uf::meshgrid::Node{
|
||||
.extents = {
|
||||
.min = extents.min + extents.piece * pod::Vector3f{ x, y, z },
|
||||
.max = extents.min + extents.piece * pod::Vector3f{ x+1, y+1, z+1 },
|
||||
},
|
||||
.id = pod::Vector3ui{ x, y, z },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < indexInput.count; i+=3 ) {
|
||||
size_t indexA = 0;
|
||||
size_t indexB = 0;
|
||||
size_t indexC = 0;
|
||||
|
||||
uint8_t* indexPointerA = (uint8_t*) (indexAttribute.pointer + indexAttribute.stride * (indexInput.first + i + 0));
|
||||
uint8_t* indexPointerB = (uint8_t*) (indexAttribute.pointer + indexAttribute.stride * (indexInput.first + i + 1));
|
||||
uint8_t* indexPointerC = (uint8_t*) (indexAttribute.pointer + indexAttribute.stride * (indexInput.first + i + 2));
|
||||
|
||||
switch ( indexInput.size ) {
|
||||
case sizeof(uint8_t): {
|
||||
indexA = *( uint8_t*) indexPointerA;
|
||||
indexB = *( uint8_t*) indexPointerB;
|
||||
indexC = *( uint8_t*) indexPointerC;
|
||||
} break;
|
||||
case sizeof(uint16_t): {
|
||||
indexA = *(uint16_t*) indexPointerA;
|
||||
indexB = *(uint16_t*) indexPointerB;
|
||||
indexC = *(uint16_t*) indexPointerC;
|
||||
} break;
|
||||
case sizeof(uint32_t): {
|
||||
indexA = *(uint32_t*) indexPointerA;
|
||||
indexB = *(uint32_t*) indexPointerB;
|
||||
indexC = *(uint32_t*) indexPointerC;
|
||||
} break;
|
||||
}
|
||||
|
||||
pod::Vector3f& positionA = *(pod::Vector3f*) (vertexAttribute.pointer + vertexAttribute.stride * (vertexInput.first + indexA));
|
||||
pod::Vector3f& positionB = *(pod::Vector3f*) (vertexAttribute.pointer + vertexAttribute.stride * (vertexInput.first + indexB));
|
||||
pod::Vector3f& positionC = *(pod::Vector3f*) (vertexAttribute.pointer + vertexAttribute.stride * (vertexInput.first + indexC));
|
||||
|
||||
for ( auto& node : nodes ) {
|
||||
// if ( isInside( positionA, node.extents.min, node.extents.max ) || isInside( positionB, node.extents.min, node.extents.max ) || isInside( positionC, node.extents.min, node.extents.max ) ) {
|
||||
if ( isInside( (positionA + positionB + positionC) / 3.0f, node.extents.min, node.extents.max ) ) {
|
||||
node.indices.emplace_back( indexA );
|
||||
node.indices.emplace_back( indexB );
|
||||
node.indices.emplace_back( indexC );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
float total = 0.0f;
|
||||
for ( auto& node : nodes ) {
|
||||
float percentage = 100.8f * node.indices.size() / indexInput.count;
|
||||
total += percentage;
|
||||
UF_MSG_DEBUG(
|
||||
"[" << node.id.x << "," << node.id.y << "," << node.id.z << "] "
|
||||
"[" << percentage << "%|" << total << "%] "
|
||||
"Min: " << uf::vector::toString( node.extents.min ) << " | "
|
||||
"Max: " << uf::vector::toString( node.extents.max )
|
||||
);
|
||||
}
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
UF_MSG_DEBUG( "Min: " << uf::vector::toString( extents.min ) );
|
||||
UF_MSG_DEBUG( "Max: " << uf::vector::toString( extents.max ) );
|
||||
UF_MSG_DEBUG( "Center: " << uf::vector::toString( extents.center ) );
|
||||
UF_MSG_DEBUG( "Corner: " << uf::vector::toString( extents.corner ) );
|
||||
UF_MSG_DEBUG( "Size: " << uf::vector::toString( extents.size ) );
|
||||
UF_MSG_DEBUG( "Piece: " << uf::vector::toString( extents.piece ) );
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include <uf/utils/memory/pool.h>
|
||||
#include <uf/utils/mesh/grid.h>
|
||||
#include <uf/utils/math/collision/mesh.h>
|
||||
#include <uf/utils/math/collision/boundingbox.h>
|
||||
#if 0
|
||||
|
||||
uf::MeshGrid::~MeshGrid() {
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
@ -47,7 +47,12 @@ UF_VERTEX_DESCRIPTOR(pod::Vertex_3F,
|
||||
UF_VERTEX_DESCRIPTION(pod::Vertex_3F, R32G32B32_SFLOAT, position)
|
||||
)
|
||||
|
||||
bool uf::Mesh::defaultInterleaved = false;
|
||||
#if UF_USE_OPENGL
|
||||
bool uf::Mesh::defaultInterleaved = true;
|
||||
#else
|
||||
bool uf::Mesh::defaultInterleaved = false;
|
||||
#endif
|
||||
|
||||
void uf::Mesh::initialize() {}
|
||||
void uf::Mesh::destroy() {
|
||||
_destroy(vertex);
|
||||
@ -164,37 +169,17 @@ uf::Mesh uf::Mesh::expand( bool interleaved ) {
|
||||
|
||||
return res;
|
||||
}
|
||||
uf::Mesh::Input uf::Mesh::remapInput( const uf::Mesh::Input& input, size_t i ) const {
|
||||
uf::Mesh::Input res = input;
|
||||
UF_ASSERT( &input == &vertex || &input == &index );
|
||||
UF_ASSERT( i < indirect.count );
|
||||
|
||||
const auto& drawCommand = ((const pod::DrawCommand*) getBuffer(indirect).data())[i];
|
||||
res.first = &input == &vertex ? drawCommand.vertexID : drawCommand.indexID;
|
||||
res.count = &input == &vertex ? drawCommand.vertices : drawCommand.indices;
|
||||
|
||||
return res;
|
||||
void uf::Mesh::eraseAttribute( uf::Mesh::Input& input, const uf::Mesh::Attribute& attribute ) {
|
||||
for ( size_t i = 0; i < input.attributes.size(); ++i ) if ( input.attributes[i].descriptor == attribute.descriptor ) return eraseAttribute( input, i );
|
||||
}
|
||||
uf::Mesh::Input uf::Mesh::remapVertexInput( size_t i ) const {
|
||||
uf::Mesh::Input res = vertex;
|
||||
UF_ASSERT( i < indirect.count );
|
||||
void uf::Mesh::eraseAttribute( uf::Mesh::Input& input, size_t i ) {
|
||||
UF_ASSERT( !isInterleaved( input ) ); // can't be assed to de-interleave, erase, and then interleave again
|
||||
|
||||
const auto& drawCommand = ((const pod::DrawCommand*) getBuffer(indirect).data())[i];
|
||||
res.first = drawCommand.vertexID;
|
||||
res.count = drawCommand.vertices;
|
||||
|
||||
return res;
|
||||
auto attribute = input.attributes[i];
|
||||
buffers[attribute.buffer].clear();
|
||||
}
|
||||
uf::Mesh::Input uf::Mesh::remapIndexInput( size_t i ) const {
|
||||
uf::Mesh::Input res = index;
|
||||
UF_ASSERT( i < indirect.count );
|
||||
|
||||
const auto& drawCommand = ((const pod::DrawCommand*) getBuffer(indirect).data())[i];
|
||||
res.first = drawCommand.indexID;
|
||||
res.count = drawCommand.indices;
|
||||
|
||||
return res;
|
||||
}
|
||||
void uf::Mesh::generateIndirect() {
|
||||
if ( index.count == 0 ) generateIndices();
|
||||
|
||||
@ -209,7 +194,7 @@ void uf::Mesh::generateIndirect() {
|
||||
.instanceID = 0,
|
||||
// .materialID = 0,
|
||||
// .objectID = 0,
|
||||
// .vertices = vertex.count,
|
||||
.vertices = vertex.count,
|
||||
});
|
||||
}
|
||||
|
||||
@ -219,6 +204,7 @@ void uf::Mesh::generateIndirect() {
|
||||
insertIndirects( commands );
|
||||
}
|
||||
bool uf::Mesh::isInterleaved() const { return isInterleaved( vertex.interleaved ); }
|
||||
bool uf::Mesh::isInterleaved( const uf::Mesh::Input& input ) const { return isInterleaved( input.interleaved ); }
|
||||
bool uf::Mesh::isInterleaved( size_t i ) const { return 0 <= i && i < buffers.size(); }
|
||||
uf::Mesh::buffer_t& uf::Mesh::getBuffer( const uf::Mesh::Input& input, size_t i ) {
|
||||
return getBuffer( input, input.attributes[i] );
|
||||
@ -232,13 +218,13 @@ const uf::Mesh::buffer_t& uf::Mesh::getBuffer( const uf::Mesh::Input& input, siz
|
||||
const uf::Mesh::buffer_t& uf::Mesh::getBuffer( const uf::Mesh::Input& input, const uf::Mesh::Attribute& attribute ) const {
|
||||
return buffers[isInterleaved(input.interleaved) ? input.interleaved : attribute.buffer];
|
||||
}
|
||||
|
||||
#define PRINT_HEADER(input) "Count: " << input.count << " | First: " << input.first << " | Size: " << input.size << " | Offset: " << input.offset << " | " << (isInterleaved(input.interleaved) ? "interleaved" : "deinterleaved") << "\n"
|
||||
|
||||
void uf::Mesh::print( bool full ) const {
|
||||
std::cout << "Buffers: " << buffers.size() << "\n" << printVertices(full) << printIndices(full) << printInstances(full) << printIndirects() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
#define PRINT_HEADER(input) "Count: " << input.count << " | First: " << input.first << " | Size: " << input.size << " | Offset: " << input.offset << " | " << (isInterleaved(input.interleaved) ? "interleaved" : "deinterleaved") << "\n"
|
||||
|
||||
std::string uf::Mesh::printVertices( bool full ) const {
|
||||
std::stringstream str;
|
||||
str << "Vertices: " << PRINT_HEADER( vertex );
|
||||
@ -306,6 +292,38 @@ std::string uf::Mesh::printIndirects( bool full ) const {
|
||||
}
|
||||
return str.str();
|
||||
}
|
||||
|
||||
uf::Mesh::Input uf::Mesh::remapInput( const uf::Mesh::Input& input, size_t i ) const {
|
||||
uf::Mesh::Input res = input;
|
||||
UF_ASSERT( &input == &vertex || &input == &index );
|
||||
UF_ASSERT( i < indirect.count );
|
||||
|
||||
const auto& drawCommand = ((const pod::DrawCommand*) getBuffer(indirect).data())[i];
|
||||
res.first = &input == &vertex ? drawCommand.vertexID : drawCommand.indexID;
|
||||
res.count = &input == &vertex ? drawCommand.vertices : drawCommand.indices;
|
||||
|
||||
return res;
|
||||
}
|
||||
uf::Mesh::Input uf::Mesh::remapVertexInput( size_t i ) const {
|
||||
uf::Mesh::Input res = vertex;
|
||||
UF_ASSERT( i < indirect.count );
|
||||
|
||||
const auto& drawCommand = ((const pod::DrawCommand*) getBuffer(indirect).data())[i];
|
||||
res.first = drawCommand.vertexID;
|
||||
res.count = drawCommand.vertices;
|
||||
|
||||
return res;
|
||||
}
|
||||
uf::Mesh::Input uf::Mesh::remapIndexInput( size_t i ) const {
|
||||
uf::Mesh::Input res = index;
|
||||
UF_ASSERT( i < indirect.count );
|
||||
|
||||
const auto& drawCommand = ((const pod::DrawCommand*) getBuffer(indirect).data())[i];
|
||||
res.first = drawCommand.indexID;
|
||||
res.count = drawCommand.indices;
|
||||
|
||||
return res;
|
||||
}
|
||||
//
|
||||
void uf::Mesh::_destroy( uf::Mesh::Input& input ) {
|
||||
for ( auto& attribute : input.attributes ) {
|
||||
@ -351,9 +369,11 @@ void uf::Mesh::_updateDescriptor( uf::Mesh::Input& input ) {
|
||||
}
|
||||
}
|
||||
uf::Mesh::Attribute uf::Mesh::_remapAttribute( const uf::Mesh::Input& input, const uf::Mesh::Attribute& attribute, size_t i ) const {
|
||||
uf::Mesh::Attribute res = attribute;
|
||||
UF_ASSERT( i < indirect.count );
|
||||
UF_ASSERT( &input == &vertex || &input == &index );
|
||||
UF_MSG_WARNING( "deprecated, please use remapInput" );
|
||||
|
||||
uf::Mesh::Attribute res = attribute;
|
||||
|
||||
auto& drawCommand = ((const pod::DrawCommand*) getBuffer(indirect).data())[i];
|
||||
if ( &input == &vertex ) {
|
||||
|
||||
@ -115,9 +115,9 @@ bool UF_API_CALL uf::Window::hasFocus() const {
|
||||
pod::Vector2ui UF_API_CALL uf::Window::getResolution() {
|
||||
return uf::Window::window_t::getResolution();
|
||||
}
|
||||
void UF_API_CALL uf::Window::switchToFullscreen( bool borderless ) {
|
||||
void UF_API_CALL uf::Window::toggleFullscreen( bool borderless ) {
|
||||
if ( !this->m_window ) return;
|
||||
this->m_window->switchToFullscreen( borderless );
|
||||
this->m_window->toggleFullscreen( borderless );
|
||||
}
|
||||
// Update
|
||||
void UF_API_CALL uf::Window::bufferInputs() {
|
||||
|
||||
@ -179,6 +179,8 @@ uf::stl::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const uf::stl::string&
|
||||
glyph.setSpread( metadataGlyph.spread );
|
||||
#if UF_USE_VULKAN
|
||||
if ( metadataGlyph.sdf ) glyph.useSdf(true);
|
||||
#else
|
||||
glyph.useSdf(false);
|
||||
#endif
|
||||
glyph.generate( ::glyphs.glyph, c, metadataGlyph.size );
|
||||
}
|
||||
|
||||
19
ext/main.cpp
19
ext/main.cpp
@ -311,20 +311,23 @@ void EXT_API ext::initialize() {
|
||||
ext::bullet::defaultMaxCollisionAlgorithmPoolSize = configEngineBulletJson["pool size"]["max collision algorithm"].as( ext::bullet::defaultMaxCollisionAlgorithmPoolSize );
|
||||
ext::bullet::defaultMaxPersistentManifoldPoolSize = configEngineBulletJson["pool size"]["max persistent manifold"].as( ext::bullet::defaultMaxPersistentManifoldPoolSize );
|
||||
|
||||
ext::bullet::debugDrawEnabled = configEngineBulletJson["debug draw"]["enabled"].as( ext::bullet::debugDrawEnabled );
|
||||
ext::bullet::debugDrawRate = configEngineBulletJson["debug draw"]["rate"].as( ext::bullet::debugDrawRate );
|
||||
ext::bullet::debugDrawLayer = configEngineBulletJson["debug draw"]["layer"].as( ext::bullet::debugDrawLayer );
|
||||
ext::bullet::debugDrawLineWidth = configEngineBulletJson["debug draw"]["line width"].as( ext::bullet::debugDrawLineWidth );
|
||||
ext::bullet::debugDraw::enabled = configEngineBulletJson["debug draw"]["enabled"].as( ext::bullet::debugDraw::enabled );
|
||||
ext::bullet::debugDraw::rate = configEngineBulletJson["debug draw"]["rate"].as( ext::bullet::debugDraw::rate );
|
||||
ext::bullet::debugDraw::layer = configEngineBulletJson["debug draw"]["layer"].as( ext::bullet::debugDraw::layer );
|
||||
ext::bullet::debugDraw::lineWidth = configEngineBulletJson["debug draw"]["line width"].as( ext::bullet::debugDraw::lineWidth );
|
||||
}
|
||||
#elif UF_USE_REACTPHYSICS
|
||||
{
|
||||
auto& configEngineReactJson = ::json["engine"]["ext"]["reactphysics"];
|
||||
|
||||
ext::reactphysics::timescale = configEngineReactJson["timescale"].as( ext::reactphysics::timescale );
|
||||
ext::reactphysics::debugDrawEnabled = configEngineReactJson["debug draw"]["enabled"].as( ext::reactphysics::debugDrawEnabled );
|
||||
ext::reactphysics::debugDrawRate = configEngineReactJson["debug draw"]["rate"].as( ext::reactphysics::debugDrawRate );
|
||||
ext::reactphysics::debugDrawLayer = configEngineReactJson["debug draw"]["layer"].as( ext::reactphysics::debugDrawLayer );
|
||||
ext::reactphysics::debugDrawLineWidth = configEngineReactJson["debug draw"]["line width"].as( ext::reactphysics::debugDrawLineWidth );
|
||||
ext::reactphysics::interpolate = configEngineReactJson["interpolate"].as( ext::reactphysics::interpolate );
|
||||
ext::reactphysics::shared = configEngineReactJson["shared"].as( ext::reactphysics::shared );
|
||||
|
||||
ext::reactphysics::debugDraw::enabled = configEngineReactJson["debug draw"]["enabled"].as( ext::reactphysics::debugDraw::enabled );
|
||||
ext::reactphysics::debugDraw::rate = configEngineReactJson["debug draw"]["rate"].as( ext::reactphysics::debugDraw::rate );
|
||||
ext::reactphysics::debugDraw::layer = configEngineReactJson["debug draw"]["layer"].as( ext::reactphysics::debugDraw::layer );
|
||||
ext::reactphysics::debugDraw::lineWidth = configEngineReactJson["debug draw"]["line width"].as( ext::reactphysics::debugDraw::lineWidth );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user