Commit for 2022.07.13 22-34-59.7z
This commit is contained in:
parent
403aa11343
commit
14e7a9aa6d
7
Makefile
7
Makefile
@ -58,9 +58,9 @@ DEPS +=
|
||||
|
||||
ifneq (,$(findstring win64,$(ARCH)))
|
||||
ifneq (,$(findstring zig,$(CC)))
|
||||
REQ_DEPS += $(RENDERER) json:nlohmann png zlib luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt curl freetype openal ogg # ncurses openvr draco discord bullet ultralight-ux
|
||||
REQ_DEPS += $(RENDERER) json:nlohmann toml png zlib luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt curl freetype openal ogg # ncurses openvr draco discord bullet ultralight-ux
|
||||
else
|
||||
REQ_DEPS += $(RENDERER) json:nlohmann png zlib luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt curl freetype openal ogg # ncurses openvr draco discord bullet ultralight-ux
|
||||
REQ_DEPS += $(RENDERER) json:nlohmann toml png zlib luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt curl freetype openal ogg # ncurses openvr draco discord bullet ultralight-ux
|
||||
endif
|
||||
FLAGS += -DUF_ENV_WINDOWS -DUF_ENV_WIN64 -DWIN32_LEAN_AND_MEAN
|
||||
DEPS += -lgdi32 -ldwmapi
|
||||
@ -224,6 +224,9 @@ ifneq (,$(findstring ctti,$(REQ_DEPS)))
|
||||
else
|
||||
FLAGS += -DUF_RTTI -rtti
|
||||
endif
|
||||
ifneq (,$(findstring toml,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_TOML
|
||||
endif
|
||||
|
||||
# SRCS_DLL += $(wildcard $(ENGINE_SRC_DIR)/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*/*.cpp)
|
||||
#SRCS_DLL += $(wildcard $(ENGINE_SRC_DIR)/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*/*/*.cpp)
|
||||
|
@ -40,7 +40,7 @@
|
||||
"rt": {
|
||||
// "size": [ 1280, 720 ],
|
||||
"filter": "nearest",
|
||||
"defaultRayBounds": [ 0.001, 1024.0 ],
|
||||
"defaultRayBounds": [ 0.0001, 256.0 ],
|
||||
"alphaTestOffset": 0.001,
|
||||
"samples": 1,
|
||||
"paths": 2,
|
||||
@ -186,7 +186,7 @@
|
||||
"compression": "gz"
|
||||
},
|
||||
"imgui": {
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
"reactphysics": {
|
||||
"timescale": 0.01666666666,
|
||||
|
@ -5,7 +5,9 @@
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
// "/burger/burger.glb"
|
||||
"/burger/burger/graph.json"
|
||||
// "/burger/burger_simpler.glb"
|
||||
// "/burger/burger/graph.json"
|
||||
"/burger/burger_simpler/graph.json"
|
||||
],
|
||||
"behaviors": [],
|
||||
"transform": {
|
||||
|
@ -4,7 +4,7 @@
|
||||
"assets": [
|
||||
],
|
||||
"transform": {
|
||||
"track": "parent",
|
||||
// "track": "parent",
|
||||
"position": [ 0, 1.7, 0 ]
|
||||
},
|
||||
"system": {
|
||||
@ -16,7 +16,7 @@
|
||||
"light": {
|
||||
"type": "point",
|
||||
"color": [1, 1, 1],
|
||||
"power": 15,
|
||||
"power": 30,
|
||||
"fov": 90,
|
||||
"bias": {
|
||||
"constant": 1.25,
|
||||
|
@ -1,12 +1,51 @@
|
||||
local timer = Timer.new()
|
||||
if not timer:running() then timer:start(); end
|
||||
|
||||
local scene = entities.currentScene()
|
||||
local metadata = ent:getComponent("Metadata")
|
||||
local transform = ent:getComponent("Transform")
|
||||
local physicsState = ent:getComponent("PhysicsState")
|
||||
local camera = ent:getComponent("Camera")
|
||||
local cameraTransform = camera:getTransform()
|
||||
|
||||
-- setup all timers
|
||||
local timers = {
|
||||
use = Timer.new(),
|
||||
holp = Timer.new(),
|
||||
flashlight = Timer.new(),
|
||||
physcannon = Timer.new()
|
||||
}
|
||||
if not timers.use:running() then timers.use:start(); end
|
||||
if not timers.holp:running() then timers.holp:start(); end
|
||||
if not timers.flashlight:running() then timers.flashlight:start(); end
|
||||
if not timers.physcannon:running() then timers.physcannon:start(); end
|
||||
|
||||
-- setup held object locals
|
||||
local heldObject = {
|
||||
uid = 0,
|
||||
distance = 0,
|
||||
smoothSpeed = 4,
|
||||
scrollSpeed = 16,
|
||||
momentum = Vector3f(0,0,0),
|
||||
rotate = false,
|
||||
}
|
||||
-- setup light locals
|
||||
local light = {
|
||||
entity = nil
|
||||
}
|
||||
for k, v in pairs(ent:getChildren()) do
|
||||
if v:name() == "Light" then
|
||||
light.entity = v
|
||||
end
|
||||
end
|
||||
|
||||
if light.entity == nil then
|
||||
light.entity = ent:loadChild("./playerLight.json",true)
|
||||
end
|
||||
light.metadata = light.entity:getComponent("Metadata")
|
||||
light.transform = light.entity:getComponent("Transform")
|
||||
light.power = light.metadata["light"]["power"]
|
||||
light.origin = Vector3f(light.transform.position)
|
||||
light.entity:setComponent("Metadata", { light = { power = 0 } })
|
||||
|
||||
-- sound emitter
|
||||
local playSound = function( key, loop )
|
||||
if not loop then loop = false end
|
||||
local url = "/ui/" .. key .. ".ogg"
|
||||
@ -25,19 +64,82 @@ local stopSound = function( key )
|
||||
}, 0)
|
||||
end
|
||||
|
||||
local heldObject = {
|
||||
uid = 0,
|
||||
distance = 0,
|
||||
smoothSpeed = 4,
|
||||
scrollSpeed = 16,
|
||||
momentum = Vector3f(0,0,0)
|
||||
}
|
||||
local useDistance = 6
|
||||
local pullDistance = useDistance * 4
|
||||
|
||||
-- on tick
|
||||
ent:bind( "tick", function(self)
|
||||
if heldObject.uid ~= 0 then
|
||||
local wheel = inputs.analog("MouseWheel")
|
||||
-- eye transform
|
||||
local flattenedTransform = cameraTransform:flatten()
|
||||
flattenedTransform.forward = ( transform.forward + Vector3f( 0, cameraTransform.forward.y, 0 ) ):normalize();
|
||||
|
||||
-- toggle flashlight
|
||||
light.transform.position = flattenedTransform.position + flattenedTransform.forward * 2
|
||||
if timers.flashlight:elapsed() > 0.5 and inputs.key("F") then
|
||||
timers.flashlight:reset()
|
||||
|
||||
local metadata = { light = { power = light.power } }
|
||||
if light.entity:getComponent("Metadata")["light"]["power"] ~= light.power then
|
||||
metadata["light"]["power"] = light.power
|
||||
else
|
||||
metadata["light"]["power"] = 0
|
||||
end
|
||||
light.entity:setComponent("Metadata", metadata)
|
||||
|
||||
playSound("flashlight")
|
||||
end
|
||||
|
||||
-- fire use ray
|
||||
if timers.use:elapsed() > 0.5 and inputs.key("E") then
|
||||
timers.use:reset()
|
||||
|
||||
local center = flattenedTransform.position
|
||||
local direction = flattenedTransform.forward * useDistance
|
||||
|
||||
local prop, depth = physicsState:rayCast( center, direction )
|
||||
local payload = {
|
||||
user = ent:uid(),
|
||||
uid = prop and prop:uid() or 0,
|
||||
depth = depth,
|
||||
}
|
||||
if prop then
|
||||
prop:callHook("entity:Use.%UID%", payload)
|
||||
end
|
||||
ent:callHook("entity:Use.%UID%", payload)
|
||||
end
|
||||
|
||||
-- update HOLP
|
||||
if heldObject.uid == 0 then
|
||||
local mouse2 = inputs.key("Mouse2");
|
||||
if mouse2 then
|
||||
--[[
|
||||
local center = transform.position + cameraTransform.position
|
||||
local direction = transform.forward + Vector3f( 0, cameraTransform.forward.y, 0 )
|
||||
direction = direction:normalize() * 4
|
||||
]]
|
||||
local center = flattenedTransform.position
|
||||
local direction = flattenedTransform.forward * pullDistance
|
||||
local prop, depth = physicsState:rayCast( center, direction )
|
||||
if depth >= 0 and prop and not string.matched( prop:name(), "/^worldspawn/" ) then
|
||||
local heldObjectTransform = prop:getComponent("Transform")
|
||||
local heldObjectPhysicsState = prop:getComponent("PhysicsState")
|
||||
|
||||
local strength = 500
|
||||
local distanceSquared = (heldObjectTransform.position - flattenedTransform.position):magnitude()
|
||||
|
||||
heldObjectPhysicsState:applyImpulse( flattenedTransform.forward * -heldObjectPhysicsState:getMass() * strength / distanceSquared )
|
||||
if timers.physcannon:elapsed() > 1.0 then
|
||||
timers.physcannon:reset()
|
||||
|
||||
playSound("phys_tooHeavy")
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local mouse1 = inputs.key("Mouse1");
|
||||
local mouse3 = inputs.key("Mouse3");
|
||||
local wheel = inputs.analog("MouseWheel")
|
||||
|
||||
if wheel ~= 0 then
|
||||
heldObject.distance = heldObject.distance + (wheel / 120 * heldObject.scrollSpeed) * time.delta()
|
||||
end
|
||||
@ -48,27 +150,38 @@ ent:bind( "tick", function(self)
|
||||
local prop = entities.get( heldObject.uid )
|
||||
local heldObjectTransform = prop:getComponent("Transform")
|
||||
local heldObjectPhysicsState = prop:getComponent("PhysicsState")
|
||||
if heldObject.rotate then
|
||||
heldObjectTransform.orientation = transform.orientation
|
||||
end
|
||||
|
||||
local transform = cameraTransform:flatten()
|
||||
local forward = transform.orientation:rotate( Vector3f(0,0,1) ) * heldObject.distance
|
||||
|
||||
if heldObject.smoothSpeed ~= 0 then
|
||||
local target = transform.position + forward
|
||||
local offset = target - heldObjectTransform.position
|
||||
local delta = offset * time.delta() * heldObject.smoothSpeed
|
||||
local distance = delta:norm()
|
||||
if mouse1 and timers.physcannon:elapsed() > 0.5 then
|
||||
timers.physcannon:reset()
|
||||
|
||||
if distance > 0.001 then
|
||||
heldObjectTransform.position = heldObjectTransform.position + delta
|
||||
heldObject.momentum = offset * 1000
|
||||
else
|
||||
heldObjectTransform.position = target
|
||||
end
|
||||
heldObject.uid = 0
|
||||
heldObjectPhysicsState:enableGravity(true)
|
||||
heldObjectPhysicsState:applyImpulse( flattenedTransform.forward * heldObjectPhysicsState:getMass() * 1000 )
|
||||
|
||||
playSound("phys_launch"..math.random(1,4))
|
||||
else
|
||||
heldObjectTransform.position = transform.position + forward
|
||||
if heldObject.rotate then
|
||||
heldObjectTransform.orientation = Quaternion.lookAt( (heldObjectTransform.position - flattenedTransform.position):normalize(), transform.up )
|
||||
end
|
||||
|
||||
local forward = flattenedTransform.forward * heldObject.distance --flattenedTransform.orientation:rotate( Vector3f(0,0,1) )
|
||||
if heldObject.smoothSpeed ~= 0 then
|
||||
local target = flattenedTransform.position + forward
|
||||
local offset = target - heldObjectTransform.position
|
||||
local delta = offset * time.delta() * heldObject.smoothSpeed
|
||||
|
||||
local distance = delta:norm()
|
||||
if distance > 0.001 then
|
||||
if timers.holp:elapsed() > 0.125 then
|
||||
timers.holp:reset()
|
||||
heldObjectPhysicsState:setVelocity( delta * 20 )
|
||||
end
|
||||
else
|
||||
heldObjectPhysicsState:setVelocity( Vector3f(0,0,0) )
|
||||
end
|
||||
else
|
||||
heldObjectTransform.position = flattenedTransform.position + forward
|
||||
end
|
||||
end
|
||||
end
|
||||
end )
|
||||
@ -102,7 +215,7 @@ ent:addHook( "entity:Use.%UID%", function( payload )
|
||||
heldObject.momentum = Vector3f(0,0,0)
|
||||
elseif payload.uid ~= 0 then
|
||||
local hit = entities.get( heldObject.uid )
|
||||
validUse = not string.match( hit:name(), "/^worldspawn_/" )
|
||||
validUse = not string.matched( hit:name(), "/^worldspawn/" )
|
||||
end
|
||||
|
||||
if validUse then
|
||||
|
@ -7,7 +7,7 @@
|
||||
// { "filename": "./models/sh_mcd/graph.json" }
|
||||
|
||||
// { "filename": "./models/mcdonalds.glb" }
|
||||
{ "filename": "./models/mcdonalds/graph.json" },
|
||||
{ "filename": "./models/mcdonalds/graph.json" }
|
||||
|
||||
// { "filename": "./models/mini_mcd.glb" }
|
||||
// { "filename": "./models/mini_mcd/graph.json" }
|
||||
@ -15,7 +15,7 @@
|
||||
// { "filename": "/cornell/cornell.glb" }
|
||||
// { "filename": "/cornell/cornell/graph.json" }
|
||||
|
||||
{ "filename": "/burger.json" }
|
||||
// { "filename": "/burger.json" }
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
@ -38,7 +38,6 @@
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
"grid": { "size": [6,1,6], "epsilon": 1.0, "cleanup": true, "print": true }
|
||||
},
|
||||
// "worldspawn_sh2": { "physics": { "type": "mesh", "static": true } },
|
||||
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },
|
||||
|
||||
"func_door_rotating_5409": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
|
@ -318,5 +318,8 @@ struct Triangle {
|
||||
|
||||
struct RayTracePayload {
|
||||
bool hit;
|
||||
Triangle triangle;
|
||||
uint instanceID;
|
||||
uint primitiveID;
|
||||
vec2 attributes;
|
||||
// Triangle triangle;
|
||||
};
|
@ -13,6 +13,7 @@ layout (constant_id = 3) const uint CASCADES = 1;
|
||||
#define PBR 1
|
||||
#define VXGI 0
|
||||
#define RAYTRACE 1
|
||||
#define BUFFER_REFERENCE 1
|
||||
#define FOG 0
|
||||
#define BLOOM 0
|
||||
#define WHITENOISE 0
|
||||
@ -41,27 +42,42 @@ layout (binding = 2) uniform UBO {
|
||||
layout (std140, binding = 3) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 4) readonly buffer Materials {
|
||||
layout (std140, binding = 4) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 5) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 5) readonly buffer Textures {
|
||||
layout (std140, binding = 6) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 6) readonly buffer Lights {
|
||||
layout (std140, binding = 7) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 9) uniform sampler3D samplerNoise;
|
||||
layout (binding = 8) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 9) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 10) uniform sampler3D samplerNoise;
|
||||
#if VXGI
|
||||
layout (binding = 10) uniform usampler3D voxelId[CASCADES];
|
||||
layout (binding = 11) uniform sampler3D voxelNormal[CASCADES];
|
||||
layout (binding = 12) uniform sampler3D voxelRadiance[CASCADES];
|
||||
layout (binding = 11) uniform usampler3D voxelId[CASCADES];
|
||||
layout (binding = 12) uniform sampler3D voxelNormal[CASCADES];
|
||||
layout (binding = 13) uniform sampler3D voxelRadiance[CASCADES];
|
||||
#endif
|
||||
|
||||
layout (location = 0) rayPayloadEXT RayTracePayload payload;
|
||||
|
||||
layout(buffer_reference, scalar) buffer Vertices { Vertex v[]; };
|
||||
layout(buffer_reference, scalar) buffer Indices { uvec3 i[]; };
|
||||
layout(buffer_reference, scalar) buffer Indirects { DrawCommand dc[]; };
|
||||
|
||||
layout(buffer_reference, scalar) buffer VPos { vec3 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VUv { vec2 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VColor { uint v[]; };
|
||||
layout(buffer_reference, scalar) buffer VSt { vec2 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VNormal { vec3 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VTangent { vec3 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VID { uint v[]; };
|
||||
|
||||
#include "../common/functions.h"
|
||||
#include "../common/light.h"
|
||||
#include "../common/fog.h"
|
||||
@ -69,6 +85,65 @@ layout (location = 0) rayPayloadEXT RayTracePayload payload;
|
||||
#include "../common/vxgi.h"
|
||||
#endif
|
||||
|
||||
Triangle parsePayload( RayTracePayload payload ) {
|
||||
Triangle triangle;
|
||||
triangle.instanceID = payload.instanceID;
|
||||
|
||||
if ( !payload.hit ) return triangle;
|
||||
|
||||
const vec3 bary = vec3(
|
||||
1.0 - payload.attributes.x - payload.attributes.y,
|
||||
payload.attributes.x,
|
||||
payload.attributes.y
|
||||
);
|
||||
const InstanceAddresses instanceAddresses = instanceAddresses[triangle.instanceID];
|
||||
|
||||
if ( !(0 < instanceAddresses.index) ) return triangle;
|
||||
|
||||
const DrawCommand drawCommand = Indirects(nonuniformEXT(instanceAddresses.indirect)).dc[instanceAddresses.drawID];
|
||||
const uint triangleID = payload.primitiveID + (drawCommand.indexID / 3);
|
||||
|
||||
Vertex points[3];
|
||||
uvec3 indices = Indices(nonuniformEXT(instanceAddresses.index)).i[triangleID];
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/indices[_] += drawCommand.vertexID;
|
||||
|
||||
if ( 0 < instanceAddresses.vertex ) {
|
||||
Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex));
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_] = vertices.v[/*triangle.*/indices[_]];
|
||||
} else {
|
||||
if ( 0 < instanceAddresses.position ) {
|
||||
VPos buf = VPos(nonuniformEXT(instanceAddresses.position));
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( 0 < instanceAddresses.uv ) {
|
||||
VUv buf = VUv(nonuniformEXT(instanceAddresses.uv));
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].uv = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( 0 < instanceAddresses.st ) {
|
||||
VSt buf = VSt(nonuniformEXT(instanceAddresses.st));
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].st = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( 0 < instanceAddresses.normal ) {
|
||||
VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal));
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( 0 < instanceAddresses.tangent ) {
|
||||
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
}
|
||||
|
||||
triangle.point.position = /*triangle.*/points[0].position * bary[0] + /*triangle.*/points[1].position * bary[1] + /*triangle.*/points[2].position * bary[2];
|
||||
triangle.point.uv = /*triangle.*/points[0].uv * bary[0] + /*triangle.*/points[1].uv * bary[1] + /*triangle.*/points[2].uv * bary[2];
|
||||
triangle.point.st = /*triangle.*/points[0].st * bary[0] + /*triangle.*/points[1].st * bary[1] + /*triangle.*/points[2].st * bary[2];
|
||||
triangle.point.normal = /*triangle.*/points[0].normal * bary[0] + /*triangle.*/points[1].normal * bary[1] + /*triangle.*/points[2].normal * bary[2];
|
||||
triangle.point.tangent = /*triangle.*/points[0].tangent * bary[0] + /*triangle.*/points[1].tangent * bary[1] + /*triangle.*/points[2].tangent * bary[2];
|
||||
|
||||
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
|
||||
|
||||
return triangle;
|
||||
}
|
||||
|
||||
void trace( Ray ray, float tMin, float tMax ) {
|
||||
uint rayFlags = gl_RayFlagsOpaqueEXT;
|
||||
uint cullMask = 0xFF;
|
||||
@ -110,38 +185,39 @@ float shadowFactor( const Light light, float def ) {
|
||||
}
|
||||
|
||||
void setupSurface( RayTracePayload payload ) {
|
||||
const Instance instance = instances[payload.triangle.instanceID];
|
||||
const Triangle triangle = parsePayload( payload );
|
||||
const Instance instance = instances[triangle.instanceID];
|
||||
surface.instance = instance;
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
|
||||
// bind position
|
||||
{
|
||||
surface.position.world = vec3( instance.model * vec4(payload.triangle.point.position, 1.0 ) );
|
||||
surface.position.world = vec3( instance.model * vec4(triangle.point.position, 1.0 ) );
|
||||
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) );
|
||||
}
|
||||
// bind normals
|
||||
{
|
||||
surface.normal.world = normalize(vec3( instance.model * vec4(payload.triangle.point.normal, 0.0 ) ));
|
||||
surface.normal.world = normalize(vec3( instance.model * vec4(triangle.point.normal, 0.0 ) ));
|
||||
// surface.normal.world = faceforward( surface.normal.world, surface.ray.direction, surface.normal.world );
|
||||
// surface.normal.eye = normalize(vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ));
|
||||
|
||||
// surface.tbn[0] = normalize(vec3( instance.model * vec4(payload.triangle.tbn[0], 0.0 ) ));
|
||||
// surface.tbn[1] = normalize(vec3( instance.model * vec4(payload.triangle.tbn[1], 0.0 ) ));
|
||||
// surface.tbn[0] = normalize(vec3( instance.model * vec4(triangle.tbn[0], 0.0 ) ));
|
||||
// surface.tbn[1] = normalize(vec3( instance.model * vec4(triangle.tbn[1], 0.0 ) ));
|
||||
// surface.tbn[2] = surface.normal.world;
|
||||
|
||||
vec3 tangent = normalize(vec3( instance.model * vec4(payload.triangle.point.tangent, 0.0) ));
|
||||
vec3 bitangent = normalize(vec3( instance.model * vec4(cross( payload.triangle.point.normal, payload.triangle.point.tangent ), 0.0) ));
|
||||
if ( payload.triangle.point.tangent != vec3(0) ) {
|
||||
surface.tbn = mat3(tangent, bitangent, payload.triangle.point.normal);
|
||||
vec3 tangent = normalize(vec3( instance.model * vec4(triangle.point.tangent, 0.0) ));
|
||||
vec3 bitangent = normalize(vec3( instance.model * vec4(cross( triangle.point.normal, triangle.point.tangent ), 0.0) ));
|
||||
if ( triangle.point.tangent != vec3(0) ) {
|
||||
surface.tbn = mat3(tangent, bitangent, triangle.point.normal);
|
||||
} else {
|
||||
surface.tbn = mat3(1);
|
||||
}
|
||||
}
|
||||
// bind UVs
|
||||
{
|
||||
surface.uv.xy = payload.triangle.point.uv;
|
||||
surface.st.xy = payload.triangle.point.st;
|
||||
surface.uv.xy = triangle.point.uv;
|
||||
surface.st.xy = triangle.point.st;
|
||||
}
|
||||
|
||||
const Material material = materials[surface.instance.materialID];
|
||||
|
@ -18,7 +18,7 @@ layout (constant_id = 2) const uint CUBEMAPS = 128;
|
||||
#include "../common/macros.h"
|
||||
#include "../common/structs.h"
|
||||
|
||||
|
||||
/*
|
||||
layout (std140, binding = 10) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
@ -34,20 +34,25 @@ layout(buffer_reference, scalar) buffer VSt { vec2 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VNormal { vec3 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VTangent { vec3 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VID { uint v[]; };
|
||||
*/
|
||||
|
||||
layout(location = 0) rayPayloadInEXT RayTracePayload payload;
|
||||
|
||||
hitAttributeEXT vec2 attribs;
|
||||
|
||||
void main() {
|
||||
payload.hit = true;
|
||||
payload.instanceID = gl_InstanceCustomIndexEXT;
|
||||
payload.primitiveID = gl_PrimitiveID;
|
||||
payload.attributes = attribs;
|
||||
|
||||
#if 0
|
||||
const vec3 bary = vec3(
|
||||
1.0 - attribs.x - attribs.y,
|
||||
attribs.x,
|
||||
attribs.y
|
||||
);
|
||||
|
||||
const uint instanceID = gl_InstanceCustomIndexEXT;
|
||||
|
||||
const InstanceAddresses instanceAddresses = instanceAddresses[instanceID];
|
||||
|
||||
if ( !(0 < instanceAddresses.index) ) return;
|
||||
@ -108,4 +113,5 @@ void main() {
|
||||
*/
|
||||
payload.hit = true;
|
||||
payload.triangle = triangle;
|
||||
#endif
|
||||
}
|
@ -16,6 +16,7 @@ layout (constant_id = 2) const uint CUBEMAPS = 128;
|
||||
#include "../common/macros.h"
|
||||
#include "../common/structs.h"
|
||||
|
||||
/*
|
||||
layout (std140, binding = 9) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
@ -31,18 +32,23 @@ layout(buffer_reference, scalar) buffer VSt { vec2 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VNormal { vec3 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VTangent { vec3 v[]; };
|
||||
layout(buffer_reference, scalar) buffer VID { uint v[]; };
|
||||
|
||||
*/
|
||||
layout(location = 0) rayPayloadInEXT RayTracePayload payload;
|
||||
|
||||
hitAttributeEXT vec2 attribs;
|
||||
|
||||
void main() {
|
||||
payload.hit = true;
|
||||
payload.instanceID = gl_InstanceCustomIndexEXT;
|
||||
payload.primitiveID = gl_PrimitiveID;
|
||||
payload.attributes = attribs;
|
||||
|
||||
#if 0
|
||||
const vec3 bary = vec3(
|
||||
1.0 - attribs.x - attribs.y,
|
||||
attribs.x,
|
||||
attribs.y
|
||||
);
|
||||
|
||||
const uint instanceID = gl_InstanceCustomIndexEXT;
|
||||
|
||||
const InstanceAddresses instanceAddresses = instanceAddresses[instanceID];
|
||||
@ -105,4 +111,5 @@ void main() {
|
||||
*/
|
||||
payload.hit = true;
|
||||
payload.triangle = triangle;
|
||||
#endif
|
||||
}
|
@ -61,4 +61,12 @@ public:\
|
||||
OBJ ## Behavior::attach( *this );\
|
||||
}
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_END( OBJ )
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_END( OBJ )
|
||||
|
||||
#define UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS( METADATA, JSON ) {\
|
||||
this->addHook( "object:Serialize.%UID%", [&]{ METADATA.serialize(self, JSON); });\
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ METADATA.serialize(self, (uf::Serializer&) json); });\
|
||||
this->addHook( "object:Deserialize.%UID%", [&]{ METADATA.deserialize(self, JSON); });\
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ METADATA.deserialize(self, (uf::Serializer&) json); });\
|
||||
METADATA.deserialize(self, JSON);\
|
||||
}
|
||||
|
@ -11,6 +11,9 @@
|
||||
#if UF_USE_LUA
|
||||
#include <uf/ext/lua/lua.h>
|
||||
#endif
|
||||
#if UF_USE_TOML
|
||||
#include <uf/ext/toml/toml.h>
|
||||
#endif
|
||||
|
||||
namespace ext {
|
||||
namespace json {
|
||||
@ -18,8 +21,8 @@ namespace ext {
|
||||
extern uf::stl::string PREFERRED_ENCODING;
|
||||
|
||||
struct UF_API EncodingSettings {
|
||||
uf::stl::string compression = ""; // auto-assume compression scheme
|
||||
uf::stl::string encoding = ""; // auto-assume re-encoding scheme
|
||||
uf::stl::string compression = ""; // auto-assume compression scheme
|
||||
bool pretty = false;
|
||||
bool quantize = false;
|
||||
uint8_t precision = 0;
|
||||
@ -101,6 +104,12 @@ T& ext::json::encode( const ext::json::Value& json, T& output, const ext::json::
|
||||
else UF_JSON_PARSE_ENCODING(msgpack)
|
||||
else UF_JSON_PARSE_ENCODING(ubjson)
|
||||
else UF_JSON_PARSE_ENCODING(bjdata)
|
||||
#if UF_USE_TOML
|
||||
else if ( settings.encoding == "toml" ) {
|
||||
uf::stl::string buffer = ext::toml::fromJson( json.dump() );
|
||||
output = T( buffer.begin(), buffer.end() );
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
// should probably default to json, not my problem
|
||||
UF_MSG_ERROR("invalid encoding requested: {}", settings.encoding);
|
||||
@ -129,6 +138,15 @@ ext::json::Value& ext::json::decode( ext::json::Value& json, const T& input, con
|
||||
else UF_JSON_PARSE_ENCODING(msgpack)
|
||||
else UF_JSON_PARSE_ENCODING(ubjson)
|
||||
else UF_JSON_PARSE_ENCODING(bjdata)
|
||||
#if UF_USE_TOML
|
||||
else if ( settings.encoding == "toml" ) {
|
||||
// UF_MSG_DEBUG("TOML: {}", std::string_view{ (const char*) input.data(), input.size() });
|
||||
T parsed = ext::toml::toJson( input );
|
||||
// UF_MSG_DEBUG("JSON: {}", std::string_view{ (const char*) parsed.data(), parsed.size() });
|
||||
json = nlohmann::json::parse(parsed, nullptr, exceptions, comments);
|
||||
// UF_MSG_DEBUG("ENCODED: {}", json.dump());
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
// should probably default to json, not my problem
|
||||
UF_MSG_ERROR("invalid encoding requested: {}", settings.encoding);
|
||||
|
@ -104,11 +104,18 @@ namespace ext {
|
||||
void UF_API applyRotation( pod::PhysicsState&, const pod::Vector3f&, float );
|
||||
|
||||
// ray casting
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f& );
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*, uf::Object*& );
|
||||
uf::Object* UF_API rayCast( const pod::Vector3f&, const pod::Vector3f& );
|
||||
uf::Object* UF_API rayCast( pod::PhysicsState&, const pod::Vector3f&, const pod::Vector3f& );
|
||||
uf::Object* UF_API rayCast( pod::PhysicsState&, const pod::Vector3f&, const pod::Vector3f&, float& );
|
||||
uf::Object* UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*, float& );
|
||||
// float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*, uf::Object*& );
|
||||
|
||||
// allows noclip
|
||||
void UF_API activateCollision( pod::PhysicsState&, bool = true );
|
||||
|
||||
//
|
||||
float UF_API getMass( pod::PhysicsState& );
|
||||
void UF_API setMass( pod::PhysicsState&, float );
|
||||
}
|
||||
}
|
||||
#endif
|
17
engine/inc/uf/ext/toml/toml.h
Normal file
17
engine/inc/uf/ext/toml/toml.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/utils/memory/vector.h>
|
||||
|
||||
#if UF_USE_TOML
|
||||
namespace ext {
|
||||
namespace toml {
|
||||
|
||||
uf::stl::string toJson( const uf::stl::string& );
|
||||
uf::stl::vector<uint8_t> toJson( const uf::stl::vector<uint8_t>& );
|
||||
|
||||
uf::stl::string fromJson( const uf::stl::string& );
|
||||
uf::stl::vector<uint8_t> fromJson( const uf::stl::vector<uint8_t>& );
|
||||
}
|
||||
}
|
||||
#endif
|
@ -50,6 +50,7 @@ namespace ext {
|
||||
bool update( const void*, VkDeviceSize, bool = VK_DEFAULT_STAGE_BUFFERS ) const;
|
||||
void destroy();
|
||||
|
||||
void swap( Buffer& );
|
||||
Buffer alias() const;
|
||||
void aliasBuffer( const Buffer& );
|
||||
};
|
||||
|
@ -40,6 +40,8 @@ namespace ext {
|
||||
extern UF_API PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
|
||||
extern UF_API PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
|
||||
extern UF_API PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
|
||||
extern UF_API PFN_vkCmdWriteAccelerationStructuresPropertiesKHR vkCmdWriteAccelerationStructuresPropertiesKHR;
|
||||
extern UF_API PFN_vkCmdCopyAccelerationStructureKHR vkCmdCopyAccelerationStructureKHR;
|
||||
|
||||
uf::stl::string errorString( VkResult result );
|
||||
VkSampleCountFlagBits sampleCount( uint8_t );
|
||||
@ -47,13 +49,16 @@ namespace ext {
|
||||
typedef VmaAllocator Allocator;
|
||||
|
||||
namespace settings {
|
||||
constexpr size_t maxViews = 6;
|
||||
|
||||
extern UF_API uint32_t width;
|
||||
extern UF_API uint32_t height;
|
||||
extern UF_API uint8_t msaa;
|
||||
extern UF_API bool validation;
|
||||
extern UF_API size_t viewCount;
|
||||
extern UF_API size_t gpuID;
|
||||
constexpr size_t maxViews = 6;
|
||||
extern UF_API size_t scratchBufferAlignment;
|
||||
extern UF_API size_t scratchBufferInitialSize;
|
||||
|
||||
extern UF_API uf::stl::vector<uf::stl::string> validationFilters;
|
||||
extern UF_API uf::stl::vector<uf::stl::string> requestedDeviceFeatures;
|
||||
@ -122,6 +127,8 @@ namespace ext {
|
||||
extern UF_API uf::stl::unordered_map<uf::stl::string, RenderMode*> renderModesMap;
|
||||
extern UF_API uf::ThreadUnique<RenderMode*> currentRenderMode;
|
||||
|
||||
extern UF_API Buffer scratchBuffer;
|
||||
|
||||
bool UF_API hasRenderMode( const uf::stl::string&, bool = true );
|
||||
RenderMode& UF_API addRenderMode( RenderMode*, const uf::stl::string& = "" );
|
||||
RenderMode& UF_API getRenderMode( const uf::stl::string&, bool = true );
|
||||
|
@ -65,6 +65,7 @@ namespace uf {
|
||||
}
|
||||
|
||||
static uf::stl::string resolveFilename( const uf::stl::string& filename, bool compareTimes = true );
|
||||
static uf::stl::string resolveFilename( const uf::stl::string& filename, const ext::json::EncodingSettings&, bool compareTimes = true );
|
||||
bool readFromFile( const uf::stl::string& from, const uf::stl::string& hash = "" );
|
||||
bool writeToFile( const uf::stl::string& to, const ext::json::EncodingSettings& = {} ) const;
|
||||
|
||||
|
@ -109,6 +109,7 @@ uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, cons
|
||||
{ "msgpack",uf::Asset::Type::JSON },
|
||||
{ "ubjson", uf::Asset::Type::JSON },
|
||||
{ "bjdata", uf::Asset::Type::JSON },
|
||||
{ "toml", uf::Asset::Type::JSON },
|
||||
|
||||
{ "lua", uf::Asset::Type::LUA },
|
||||
|
||||
@ -129,6 +130,7 @@ uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, cons
|
||||
else if ( basename == "graph.msgpack" ) payload.type = uf::Asset::Type::GRAPH;
|
||||
else if ( basename == "graph.ubjson" ) payload.type = uf::Asset::Type::GRAPH;
|
||||
else if ( basename == "graph.bjdata" ) payload.type = uf::Asset::Type::GRAPH;
|
||||
else if ( basename == "graph.toml" ) payload.type = uf::Asset::Type::GRAPH;
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
if ( json["type"].as<uf::stl::string>() == "merge" ) metadataJson.merge(json["value"], true);
|
||||
else if ( json["type"].as<uf::stl::string>() == "import" ) metadataJson.import(json["value"]);
|
||||
else if ( json["path"].is<uf::stl::string>() ) metadataJson.path(json["path"].as<uf::stl::string>()) = json["value"];
|
||||
else metadataJson.merge(json, true);
|
||||
// else metadataJson.merge(json, true);
|
||||
});
|
||||
this->addHook( "asset:QueueLoad.%UID%", [&](pod::payloads::assetLoad& payload){
|
||||
uf::stl::string callback = this->formatHookName("asset:FinishedLoad.%UID%");
|
||||
@ -97,9 +97,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
});
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
|
||||
if ( ext::json::isObject(metadataJson["physics"]) ) {
|
||||
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||
@ -247,7 +245,7 @@ void uf::ObjectBehavior::Metadata::serialize( uf::Object& self, uf::Serializer&
|
||||
if ( /*this->*/transform.trackParent ) serializer["system"]["transform"]["track"] = "parent";
|
||||
}
|
||||
void uf::ObjectBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ) {
|
||||
/*this->*/transform.initial = self.getComponent<pod::Transform<>>();
|
||||
/*this->*/transform.trackParent = serializer["system"]["transform"]["track"].as<uf::stl::string>() == "parent";
|
||||
if ( !transform.trackParent ) /*this->*/transform.initial = self.getComponent<pod::Transform<>>();
|
||||
/*this->*/transform.trackParent = serializer["system"]["transform"]["track"].as<uf::stl::string>(/*this->*/transform.trackParent ? "parent" : "") == "parent";
|
||||
}
|
||||
UF_BEHAVIOR_ENTITY_CPP_END(Object)
|
@ -40,11 +40,17 @@ namespace binds {
|
||||
if ( type == "Metadata" ) {
|
||||
auto encoded = ext::lua::encode( value.as<sol::table>() );
|
||||
if ( encoded ) {
|
||||
/*
|
||||
self.callHook( "object:Serialize.%UID%" );
|
||||
auto& metadata = self.getComponent<uf::Serializer>();
|
||||
uf::stl::string str = encoded.value();
|
||||
metadata.merge( str, false );
|
||||
self.callHook( "object:Deserialize.%UID%" );
|
||||
*/
|
||||
uf::stl::string str = encoded.value();
|
||||
ext::json::Value json;
|
||||
ext::json::decode( json, str );
|
||||
self.callHook( "object:Deserialize.%UID%", json );
|
||||
}
|
||||
}
|
||||
UF_LUA_UPDATE_COMPONENT(pod::Transform<>)
|
||||
|
@ -13,6 +13,13 @@ namespace binds {
|
||||
if ( !state.body ) return;
|
||||
state.body->enableGravity(s);
|
||||
}
|
||||
|
||||
std::tuple<uf::Object*, float> rayCast( pod::Physics& self, const pod::Vector3f& center, const pod::Vector3f& direction ) {
|
||||
float depth = -1;
|
||||
uf::Object* object = uf::physics::impl::rayCast(self, center, direction, depth);
|
||||
|
||||
return std::make_tuple( object, depth );
|
||||
}
|
||||
}
|
||||
|
||||
UF_LUA_REGISTER_USERTYPE(pod::Physics,
|
||||
@ -31,7 +38,12 @@ UF_LUA_REGISTER_USERTYPE(pod::PhysicsState,
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( applyVelocity, UF_LUA_C_FUN(uf::physics::impl::applyVelocity) ),
|
||||
// UF_LUA_REGISTER_USERTYPE_DEFINE( applyRotation, UF_LUA_C_FUN(uf::physics::impl::applyRotation) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( enableGravity, UF_LUA_C_FUN(::binds::enableGravity) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( activateCollision, UF_LUA_C_FUN(uf::physics::impl::activateCollision) )
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( activateCollision, UF_LUA_C_FUN(uf::physics::impl::activateCollision) ),
|
||||
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( rayCast, UF_LUA_C_FUN(::binds::rayCast) ),
|
||||
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( getMass, UF_LUA_C_FUN(uf::physics::impl::getMass) ),
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( setMass, UF_LUA_C_FUN(uf::physics::impl::setMass) )
|
||||
)
|
||||
|
||||
#endif
|
@ -572,28 +572,32 @@ void ext::reactphysics::applyRotation( pod::PhysicsState& state, const pod::Vect
|
||||
|
||||
// ray casting
|
||||
|
||||
float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction ) {
|
||||
if ( !::world )
|
||||
return -1;
|
||||
|
||||
::RaycastCallback callback;
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( center + direction ) ), &callback );
|
||||
if ( !callback.isHit ) return -1;
|
||||
return callback.raycastInfo.hitFraction;
|
||||
uf::Object* ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction ) {
|
||||
float depth = -1;
|
||||
return rayCast( center, direction, NULL, depth );
|
||||
}
|
||||
float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction, uf::Object* source, uf::Object*& object ) {
|
||||
if ( !::world )
|
||||
return -1;
|
||||
|
||||
uf::Object* ext::reactphysics::rayCast( pod::PhysicsState& state, const pod::Vector3f& center, const pod::Vector3f& direction ) {
|
||||
float depth = -1;
|
||||
return rayCast( center, direction, state.object, depth );
|
||||
}
|
||||
uf::Object* ext::reactphysics::rayCast( pod::PhysicsState& state, const pod::Vector3f& center, const pod::Vector3f& direction, float& depth ) {
|
||||
return rayCast( center, direction, state.object, depth );
|
||||
}
|
||||
|
||||
uf::Object* ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction, uf::Object* source, float& depth ) {
|
||||
depth = -1;
|
||||
|
||||
if ( !::world ) return NULL;
|
||||
|
||||
::RaycastCallback callback;
|
||||
callback.source = source;
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( center + direction ) ), &callback );
|
||||
object = NULL;
|
||||
if ( !callback.isHit ) {
|
||||
return -1;
|
||||
}
|
||||
object = (uf::Object*) callback.raycastInfo.body->getUserData();
|
||||
return callback.raycastInfo.hitFraction;
|
||||
if ( !callback.isHit ) return NULL;
|
||||
|
||||
depth = callback.raycastInfo.hitFraction;
|
||||
|
||||
return (uf::Object*) callback.raycastInfo.body->getUserData();
|
||||
}
|
||||
|
||||
// allows noclip
|
||||
@ -608,4 +612,14 @@ void ext::reactphysics::activateCollision( pod::PhysicsState& state, bool s ) {
|
||||
}
|
||||
}
|
||||
|
||||
float ext::reactphysics::getMass( pod::PhysicsState& state ) {
|
||||
if ( !state.body ) return state.stats.mass;
|
||||
|
||||
return (state.stats.mass = state.body->getMass());
|
||||
}
|
||||
void ext::reactphysics::setMass( pod::PhysicsState& state, float mass ) {
|
||||
state.stats.mass = mass;
|
||||
state.body->setMass(mass);
|
||||
}
|
||||
|
||||
#endif
|
157
engine/src/ext/toml/toml.cpp
Normal file
157
engine/src/ext/toml/toml.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
#if UF_USE_TOML
|
||||
|
||||
#define TOML_HEADER_ONLY 0
|
||||
#define TOML_ENABLE_FORMATTERS 1
|
||||
#define TOML_IMPLEMENTATION
|
||||
|
||||
#if UF_EXCEPTIONS
|
||||
#define TOML_EXCEPTIONS 1
|
||||
#elif UF_NO_EXCEPTIONS
|
||||
#define TOML_EXCEPTIONS 0
|
||||
#else
|
||||
#define TOML_EXCEPTIONS 0
|
||||
#endif
|
||||
#include <toml++/toml.h>
|
||||
#include <uf/ext/toml/toml.h>
|
||||
|
||||
|
||||
#include <uf/ext/json/json.h>
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template<typename T>
|
||||
static void from_json(const ext::json::Value& j, value<T>& val) {
|
||||
assert(j.is<T>());
|
||||
*val = j.as<T>();
|
||||
}
|
||||
static void from_json(const ext::json::Value&, array&);
|
||||
|
||||
template <typename T, typename Key>
|
||||
static void insert_from_json(table & tbl, Key && key, const ext::json::Value& val) {
|
||||
T v;
|
||||
from_json(val, v);
|
||||
|
||||
tbl.insert_or_assign(static_cast<Key&&>(key), std::move(v));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void insert_from_json(array & arr, const ext::json::Value& val) {
|
||||
T v;
|
||||
from_json(val, v);
|
||||
arr.push_back(std::move(v));
|
||||
}
|
||||
|
||||
static void from_json(const ext::json::Value& j, table& tbl) {
|
||||
if ( j.is_null() ) return;
|
||||
|
||||
if( !j.is_object() ) {
|
||||
UF_MSG_ERROR("ERROR: {}", j.dump());
|
||||
return;
|
||||
}
|
||||
|
||||
ext::json::forEach(j, [&]( const uf::stl::string& k, const ext::json::Value& v ){
|
||||
if ( v.is<std::string>() ) insert_from_json<toml::value<std::string>>(tbl, k, v);
|
||||
else if ( v.is<double>(true) ) insert_from_json<toml::value<double>>(tbl, k, v);
|
||||
else if ( v.is<int64_t>() ) insert_from_json<toml::value<int64_t>>(tbl, k, v);
|
||||
else if ( v.is<bool>() ) insert_from_json<toml::value<bool>>(tbl, k, v);
|
||||
else if (v.is_array()) insert_from_json<toml::array>(tbl, k, v);
|
||||
else insert_from_json<toml::table>(tbl, k, v);
|
||||
});
|
||||
}
|
||||
|
||||
static void from_json(const ext::json::Value& j, array& arr) {
|
||||
ext::json::forEach(j, [&]( const ext::json::Value& v ){
|
||||
if ( v.is<std::string>() )
|
||||
insert_from_json<toml::value<std::string>>(arr, v);
|
||||
else if ( v.is<double>(true) ) insert_from_json<toml::value<double>>(arr, v);
|
||||
else if ( v.is<int64_t>() ) insert_from_json<toml::value<int64_t>>(arr, v);
|
||||
else if ( v.is<bool>() ) insert_from_json<toml::value<bool>>(arr, v);
|
||||
else if (v.is_array()) insert_from_json<toml::array>(arr, v);
|
||||
else insert_from_json<toml::table>(arr, v);
|
||||
});
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
uf::stl::string UF_API ext::toml::fromJson( const uf::stl::string& source ) {
|
||||
ext::json::Value j;
|
||||
ext::json::decode( j, source );
|
||||
|
||||
#if UF_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
::toml::table tbl;
|
||||
::toml::from_json( j, tbl );
|
||||
|
||||
std::stringstream ss; ss << tbl;
|
||||
return ss.str();
|
||||
#if UF_EXCEPTIONS
|
||||
} catch ( const ::toml::parse_error& err ) {
|
||||
UF_MSG_ERROR("TOML error: {}", e.what());
|
||||
}
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
uf::stl::vector<uint8_t> UF_API ext::toml::fromJson( const uf::stl::vector<uint8_t>& source ) {
|
||||
ext::json::Value j;
|
||||
ext::json::decode( j, source );
|
||||
|
||||
#if UF_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
::toml::table tbl;
|
||||
::toml::from_json( j, tbl );
|
||||
|
||||
std::stringstream ss; ss << tbl;
|
||||
uf::stl::string str = ss.str();
|
||||
return uf::stl::vector<uint8_t>{ str.begin(), str.end() };
|
||||
#if UF_EXCEPTIONS
|
||||
} catch ( const ::toml::parse_error& err ) {
|
||||
UF_MSG_ERROR("TOML error: {}", e.what());
|
||||
}
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
uf::stl::string UF_API ext::toml::toJson( const uf::stl::string& source ) {
|
||||
#if UF_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
::toml::parse_result result = ::toml::parse( source );
|
||||
if ( !result ) {
|
||||
std::stringstream error; error << result.error();
|
||||
UF_MSG_ERROR("TOML error: {}", error.str());
|
||||
return "";
|
||||
}
|
||||
std::stringstream ss; ss << ::toml::json_formatter{ result };
|
||||
return ss.str();
|
||||
#if UF_EXCEPTIONS
|
||||
} catch ( const ::toml::parse_error& err ) {
|
||||
UF_MSG_ERROR("TOML error: {}", e.what());
|
||||
}
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
uf::stl::vector<uint8_t> UF_API ext::toml::toJson( const uf::stl::vector<uint8_t>& source ) {
|
||||
#if UF_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
std::string_view source_view( (const char*) source.data(), source.size() );
|
||||
::toml::parse_result result = ::toml::parse( source_view );
|
||||
if ( !result ) {
|
||||
std::stringstream error; error << result.error();
|
||||
UF_MSG_ERROR("TOML error: {}", error.str());
|
||||
return {};
|
||||
}
|
||||
std::stringstream ss; ss << ::toml::json_formatter{ result };
|
||||
uf::stl::string str = ss.str();
|
||||
return uf::stl::vector<uint8_t>{ str.begin(), str.end() };
|
||||
#if UF_EXCEPTIONS
|
||||
} catch ( const ::toml::parse_error& err ) {
|
||||
UF_MSG_ERROR("TOML error: {}", e.what());
|
||||
}
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
#endif
|
@ -7,6 +7,20 @@
|
||||
#include <uf/ext/vulkan/vulkan.h>
|
||||
#include <uf/ext/vulkan/device.h>
|
||||
|
||||
void ext::vulkan::Buffer::swap( ext::vulkan::Buffer& buffer ) {
|
||||
std::swap(this->aliased, buffer.aliased);
|
||||
std::swap(this->device, buffer.device);
|
||||
std::swap(this->buffer, buffer.buffer);
|
||||
std::swap(this->memory, buffer.memory);
|
||||
std::swap(this->descriptor, buffer.descriptor);
|
||||
std::swap(this->alignment, buffer.alignment);
|
||||
std::swap(this->address, buffer.address);
|
||||
std::swap(this->mapped, buffer.mapped);
|
||||
std::swap(this->usage, buffer.usage);
|
||||
std::swap(this->memoryProperties, buffer.memoryProperties);
|
||||
std::swap(this->allocation, buffer.allocation);
|
||||
std::swap(this->allocationInfo, buffer.allocationInfo);
|
||||
}
|
||||
ext::vulkan::Buffer ext::vulkan::Buffer::alias() const {
|
||||
ext::vulkan::Buffer buffer;
|
||||
buffer.aliasBuffer(*this);
|
||||
|
@ -1150,6 +1150,8 @@ void ext::vulkan::Device::initialize() {
|
||||
vkCmdTraceRaysKHR = reinterpret_cast<PFN_vkCmdTraceRaysKHR>(vkGetDeviceProcAddr(device, "vkCmdTraceRaysKHR"));
|
||||
vkGetRayTracingShaderGroupHandlesKHR = reinterpret_cast<PFN_vkGetRayTracingShaderGroupHandlesKHR>(vkGetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesKHR"));
|
||||
vkCreateRayTracingPipelinesKHR = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR"));
|
||||
vkCmdWriteAccelerationStructuresPropertiesKHR = reinterpret_cast<PFN_vkCmdWriteAccelerationStructuresPropertiesKHR>(vkGetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesKHR"));
|
||||
vkCmdCopyAccelerationStructureKHR = reinterpret_cast<PFN_vkCmdCopyAccelerationStructureKHR>(vkGetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureKHR"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@ PFN_vkGetAccelerationStructureDeviceAddressKHR ext::vulkan::vkGetAccelerationStr
|
||||
PFN_vkCmdTraceRaysKHR ext::vulkan::vkCmdTraceRaysKHR = NULL; // = reinterpret_cast<PFN_vkCmdTraceRaysKHR>(vkGetDeviceProcAddr(device, "vkCmdTraceRaysKHR"));
|
||||
PFN_vkGetRayTracingShaderGroupHandlesKHR ext::vulkan::vkGetRayTracingShaderGroupHandlesKHR = NULL; // = reinterpret_cast<PFN_vkGetRayTracingShaderGroupHandlesKHR>(vkGetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesKHR"));
|
||||
PFN_vkCreateRayTracingPipelinesKHR ext::vulkan::vkCreateRayTracingPipelinesKHR = NULL; // = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR"));
|
||||
PFN_vkCmdWriteAccelerationStructuresPropertiesKHR ext::vulkan::vkCmdWriteAccelerationStructuresPropertiesKHR = NULL; // = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR"));
|
||||
PFN_vkCmdCopyAccelerationStructureKHR ext::vulkan::vkCmdCopyAccelerationStructureKHR = NULL; // = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR"));
|
||||
|
||||
void ext::vulkan::Pipeline::initialize( const Graphic& graphic ) {
|
||||
return this->initialize( graphic, graphic.descriptor );
|
||||
@ -1180,12 +1182,10 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
||||
|
||||
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo;
|
||||
uf::renderer::AccelerationStructure as;
|
||||
uf::renderer::AccelerationStructure cleanup;
|
||||
};
|
||||
uf::stl::vector<BlasData> blasDatas;
|
||||
|
||||
uf::renderer::Buffer scratchBuffer;
|
||||
uf::renderer::Buffer blasBuffer;
|
||||
|
||||
// setup BLAS geometry
|
||||
{
|
||||
auto& mesh = this->descriptor.inputs;
|
||||
@ -1299,8 +1299,11 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldCompact = true;
|
||||
|
||||
// determine BLAS size and its scratch buffer
|
||||
VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
|
||||
if ( shouldCompact) flags |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
|
||||
size_t totalBlasBufferSize{};
|
||||
size_t maxScratchBufferSize{};
|
||||
for ( auto& blasData : blasDatas ) {
|
||||
@ -1328,72 +1331,140 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
||||
totalBlasBufferSize += blasData.sizeInfo.accelerationStructureSize;
|
||||
}
|
||||
|
||||
#define VK_UNIFIED_BLAS_BUFFER 1
|
||||
|
||||
#if VK_UNIFIED_BLAS_BUFFER
|
||||
// create BLAS buffer and handle
|
||||
size_t blasBufferIndex = this->initializeBuffer( NULL, totalBlasBufferSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS );
|
||||
size_t blasBufferOffset = 0;
|
||||
this->metadata.buffers["blasBuffer"] = blasBufferIndex;
|
||||
#endif
|
||||
|
||||
scratchBuffer.alignment = acclerationStructureProperties.minAccelerationStructureScratchOffsetAlignment;
|
||||
scratchBuffer.initialize( NULL, maxScratchBufferSize, uf::renderer::enums::Buffer::STORAGE | uf::renderer::enums::Buffer::ADDRESS );
|
||||
|
||||
for ( auto& blasData : blasDatas ) {
|
||||
#if VK_UNIFIED_BLAS_BUFFER
|
||||
blasData.as.buffer = this->buffers[blasBufferIndex].alias();
|
||||
blasData.as.buffer.descriptor.offset = blasBufferOffset;
|
||||
VkQueryPool queryPool{VK_NULL_HANDLE};
|
||||
if ( shouldCompact ) {
|
||||
VkQueryPoolCreateInfo queryPoolCreateInfo{VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO};
|
||||
queryPoolCreateInfo.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR;
|
||||
queryPoolCreateInfo.queryCount = blasDatas.size();
|
||||
|
||||
VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR};
|
||||
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
createInfo.size = blasData.sizeInfo.accelerationStructureSize;
|
||||
createInfo.buffer = blasData.as.buffer.buffer;
|
||||
createInfo.offset = blasData.as.buffer.descriptor.offset;
|
||||
|
||||
blasBufferOffset += blasData.sizeInfo.accelerationStructureSize;
|
||||
#else
|
||||
size_t blasBufferIndex = this->initializeBuffer( NULL, blasData.sizeInfo.accelerationStructureSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS );
|
||||
blasData.as.buffer = this->buffers[blasBufferIndex].alias();
|
||||
|
||||
VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR};
|
||||
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
createInfo.size = blasData.sizeInfo.accelerationStructureSize;
|
||||
createInfo.buffer = blasData.as.buffer.buffer;
|
||||
createInfo.offset = blasData.as.buffer.descriptor.offset;
|
||||
#endif
|
||||
|
||||
VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &blasData.as.handle));
|
||||
|
||||
VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
|
||||
accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
|
||||
accelerationDeviceAddressInfo.accelerationStructure = blasData.as.handle;
|
||||
blasData.as.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo);
|
||||
|
||||
// write to BLAS
|
||||
|
||||
blasData.buildInfo.dstAccelerationStructure = blasData.as.handle;
|
||||
blasData.buildInfo.scratchData.deviceAddress = scratchBuffer.getAddress();
|
||||
|
||||
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
uf::renderer::vkCmdBuildAccelerationStructuresKHR(
|
||||
commandBuffer,
|
||||
1,
|
||||
&blasData.buildInfo,
|
||||
&blasData.rangeInfo
|
||||
);
|
||||
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
VK_CHECK_RESULT(vkCreateQueryPool(device, &queryPoolCreateInfo, nullptr, &queryPool));
|
||||
vkResetQueryPool(device, queryPool, 0, blasDatas.size());
|
||||
}
|
||||
|
||||
for ( auto& blasData : blasDatas ) this->accelerationStructures.bottoms.emplace_back(blasData.as);
|
||||
uint32_t queryCount{};
|
||||
{
|
||||
size_t blasBufferOffset = 0;
|
||||
scratchBuffer.alignment = acclerationStructureProperties.minAccelerationStructureScratchOffsetAlignment;
|
||||
scratchBuffer.update( NULL, maxScratchBufferSize );
|
||||
|
||||
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
for ( auto& blasData : blasDatas ) {
|
||||
blasData.as.buffer = this->buffers[blasBufferIndex].alias();
|
||||
blasData.as.buffer.descriptor.offset = blasBufferOffset;
|
||||
blasBufferOffset += blasData.sizeInfo.accelerationStructureSize;
|
||||
|
||||
scratchBuffer.destroy();
|
||||
VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR};
|
||||
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
createInfo.size = blasData.sizeInfo.accelerationStructureSize;
|
||||
createInfo.buffer = blasData.as.buffer.buffer;
|
||||
createInfo.offset = blasData.as.buffer.descriptor.offset;
|
||||
|
||||
VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &blasData.as.handle));
|
||||
|
||||
VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
|
||||
accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
|
||||
accelerationDeviceAddressInfo.accelerationStructure = blasData.as.handle;
|
||||
blasData.as.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo);
|
||||
|
||||
// write to BLAS
|
||||
blasData.buildInfo.dstAccelerationStructure = blasData.as.handle;
|
||||
blasData.buildInfo.scratchData.deviceAddress = scratchBuffer.getAddress();
|
||||
|
||||
uf::renderer::vkCmdBuildAccelerationStructuresKHR(
|
||||
commandBuffer,
|
||||
1,
|
||||
&blasData.buildInfo,
|
||||
&blasData.rangeInfo
|
||||
);
|
||||
|
||||
// pipeline barrier here for scratch buffer
|
||||
VkMemoryBarrier barrier{VK_STRUCTURE_TYPE_MEMORY_BARRIER};
|
||||
barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
|
||||
barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
|
||||
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
|
||||
|
||||
if ( queryPool ) uf::renderer::vkCmdWriteAccelerationStructuresPropertiesKHR(
|
||||
commandBuffer,
|
||||
1,
|
||||
&blasData.buildInfo.dstAccelerationStructure,
|
||||
VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR,
|
||||
queryPool,
|
||||
queryCount++
|
||||
);
|
||||
}
|
||||
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
}
|
||||
// compact
|
||||
if ( queryPool ) {
|
||||
uf::stl::vector<VkDeviceSize> compactSizes(blasDatas.size());
|
||||
vkGetQueryPoolResults(device, queryPool, 0, (uint32_t) compactSizes.size(), compactSizes.size() * sizeof(VkDeviceSize), compactSizes.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_WAIT_BIT);
|
||||
|
||||
size_t queryIndex{};
|
||||
size_t totalBlasBufferSize{};
|
||||
for ( auto& blasData : blasDatas ) {
|
||||
size_t compactedSize = compactSizes[queryIndex++];
|
||||
size_t oldSize = blasData.sizeInfo.accelerationStructureSize;
|
||||
|
||||
blasData.cleanup = blasData.as;
|
||||
blasData.sizeInfo.accelerationStructureSize = ALIGNED_SIZE(compactedSize, 256);
|
||||
totalBlasBufferSize += blasData.sizeInfo.accelerationStructureSize;
|
||||
// UF_MSG_DEBUG("Reduced size to {}% ({} -> {} = {})", (oldSize - compactedSize) * 100.0f / oldSize, oldSize, compactedSize, oldSize - compactedSize);
|
||||
}
|
||||
|
||||
ext::vulkan::Buffer oldBuffer;
|
||||
oldBuffer.initialize( NULL, totalBlasBufferSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS );
|
||||
this->buffers[blasBufferIndex].swap(oldBuffer);
|
||||
|
||||
size_t blasBufferOffset{};
|
||||
for ( auto& blasData : blasDatas ) {
|
||||
blasData.as.buffer = this->buffers[blasBufferIndex].alias();
|
||||
blasData.as.buffer.descriptor.offset = blasBufferOffset;
|
||||
blasBufferOffset += blasData.sizeInfo.accelerationStructureSize;
|
||||
|
||||
VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR};
|
||||
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
createInfo.size = blasData.sizeInfo.accelerationStructureSize;
|
||||
createInfo.buffer = blasData.as.buffer.buffer;
|
||||
createInfo.offset = blasData.as.buffer.descriptor.offset;
|
||||
|
||||
VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &blasData.as.handle));
|
||||
|
||||
VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
|
||||
accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
|
||||
accelerationDeviceAddressInfo.accelerationStructure = blasData.as.handle;
|
||||
blasData.as.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo);
|
||||
|
||||
VkCopyAccelerationStructureInfoKHR copyInfo{VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR};
|
||||
copyInfo.src = blasData.cleanup.handle;
|
||||
copyInfo.dst = blasData.as.handle;
|
||||
copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR;
|
||||
|
||||
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
uf::renderer::vkCmdCopyAccelerationStructureKHR(commandBuffer, ©Info);
|
||||
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
}
|
||||
|
||||
oldBuffer.destroy();
|
||||
}
|
||||
|
||||
for ( auto& blasData : blasDatas ) {
|
||||
this->accelerationStructures.bottoms.emplace_back(blasData.as);
|
||||
|
||||
if ( blasData.cleanup.handle ) uf::renderer::vkDestroyAccelerationStructureKHR(device, blasData.cleanup.handle, nullptr);
|
||||
}
|
||||
|
||||
if ( queryPool ) vkDestroyQueryPool(device, queryPool, nullptr);
|
||||
}
|
||||
void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vector<uf::renderer::Graphic*>& graphics, const uf::stl::vector<pod::Instance>& instances ) {
|
||||
auto& device = *this->device;
|
||||
|
||||
bool rebuild = false;
|
||||
bool update = this->accelerationStructures.top.handle != VK_NULL_HANDLE;
|
||||
bool shouldCompact = false;
|
||||
|
||||
VkPhysicalDeviceAccelerationStructurePropertiesKHR acclerationStructureProperties{};
|
||||
VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingPipelineProperties{};
|
||||
@ -1409,6 +1480,16 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
|
||||
vkGetPhysicalDeviceProperties2(device.physicalDevice, &deviceProperties2);
|
||||
}
|
||||
|
||||
VkQueryPool queryPool{VK_NULL_HANDLE};
|
||||
if ( shouldCompact ) {
|
||||
VkQueryPoolCreateInfo queryPoolCreateInfo{VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO};
|
||||
queryPoolCreateInfo.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR;
|
||||
queryPoolCreateInfo.queryCount = 1;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateQueryPool(device, &queryPoolCreateInfo, nullptr, &queryPool));
|
||||
vkResetQueryPool(device, queryPool, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
uf::stl::vector<VkAccelerationStructureInstanceKHR> instancesVK; instancesVK.reserve( instances.size() );
|
||||
for ( auto& graphic : graphics ) {
|
||||
@ -1429,20 +1510,15 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
|
||||
}
|
||||
}
|
||||
|
||||
// do not stage, because apparently vkQueueWaitIdle doesn't actually wait for the transfer to complete
|
||||
size_t instanceIndex{};
|
||||
size_t tlasBufferIndex{};
|
||||
if ( !update ) {
|
||||
const size_t EXTRANEOUS_SIZE = 2048;
|
||||
size_t bufferSize = MAX( instancesVK.size(), EXTRANEOUS_SIZE );
|
||||
|
||||
// do not stage, because apparently vkQueueWaitIdle doesn't actually wait for the transfer to complete
|
||||
instanceIndex = this->initializeBuffer(
|
||||
NULL, bufferSize * sizeof(VkAccelerationStructureInstanceKHR),
|
||||
(const void*) instancesVK.data(), instancesVK.size() * sizeof(VkAccelerationStructureInstanceKHR),
|
||||
uf::renderer::enums::Buffer::ADDRESS | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, false
|
||||
);
|
||||
|
||||
this->updateBuffer( (const void*) instancesVK.data(), instancesVK.size() * sizeof(VkAccelerationStructureInstanceKHR), instanceIndex, false );
|
||||
|
||||
this->metadata.buffers["tlasInstance"] = instanceIndex;
|
||||
} else {
|
||||
if ( this->metadata.buffers.count("tlasInstance") > 0 ) {
|
||||
@ -1455,10 +1531,12 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
|
||||
rebuild = rebuild || this->updateBuffer( (const void*) instancesVK.data(), instancesVK.size() * sizeof(VkAccelerationStructureInstanceKHR), instanceIndex, false );
|
||||
}
|
||||
size_t instanceBufferAddress = this->buffers[instanceIndex].getAddress();
|
||||
|
||||
auto& tlas = this->accelerationStructures.top;
|
||||
{
|
||||
VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR | VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR;
|
||||
if ( shouldCompact ) flags |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
|
||||
uint32_t countInstance = instancesVK.size();
|
||||
auto& tlas = this->accelerationStructures.top;
|
||||
|
||||
VkAccelerationStructureGeometryInstancesDataKHR instancesVk{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR};
|
||||
instancesVk.data.deviceAddress = instanceBufferAddress;
|
||||
@ -1518,10 +1596,9 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
|
||||
tlas.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo);
|
||||
}
|
||||
|
||||
// write to BLAS
|
||||
uf::renderer::Buffer scratchBuffer;
|
||||
// write to TLAS
|
||||
scratchBuffer.alignment = acclerationStructureProperties.minAccelerationStructureScratchOffsetAlignment;
|
||||
scratchBuffer.initialize( NULL, sizeInfo.buildScratchSize, uf::renderer::enums::Buffer::STORAGE | uf::renderer::enums::Buffer::ADDRESS );
|
||||
scratchBuffer.update( NULL, sizeInfo.buildScratchSize );
|
||||
|
||||
buildInfo.srcAccelerationStructure = update ? tlas.handle : VK_NULL_HANDLE;
|
||||
buildInfo.dstAccelerationStructure = tlas.handle;
|
||||
@ -1537,11 +1614,63 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
|
||||
&buildInfo,
|
||||
&rangeInfo
|
||||
);
|
||||
|
||||
if ( queryPool ) uf::renderer::vkCmdWriteAccelerationStructuresPropertiesKHR(
|
||||
commandBuffer,
|
||||
1,
|
||||
&buildInfo.dstAccelerationStructure,
|
||||
VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR,
|
||||
queryPool,
|
||||
0
|
||||
);
|
||||
|
||||
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
}
|
||||
|
||||
// compact
|
||||
if ( queryPool ) {
|
||||
VkDeviceSize compactSize{};
|
||||
vkGetQueryPoolResults(device, queryPool, 0, 1, sizeof(VkDeviceSize), &compactSize, sizeof(VkDeviceSize), VK_QUERY_RESULT_WAIT_BIT);
|
||||
|
||||
auto cleanup = tlas;
|
||||
size_t tlasBufferSize = ALIGNED_SIZE(compactSize, 256);
|
||||
// UF_MSG_DEBUG("Reduced size to {}% ({} -> {} = {})", (float) (oldSize - compactedSize) / (float) (oldSize), oldSize, compactedSize, oldSize - compactedSize);
|
||||
|
||||
ext::vulkan::Buffer oldBuffer;
|
||||
oldBuffer.initialize( NULL, tlasBufferSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS );
|
||||
this->buffers[tlasBufferIndex].swap(oldBuffer);
|
||||
|
||||
tlas.buffer = this->buffers[tlasBufferIndex].alias();
|
||||
tlas.buffer.descriptor.offset = 0;
|
||||
|
||||
VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR};
|
||||
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
createInfo.size = tlasBufferSize;
|
||||
createInfo.buffer = tlas.buffer.buffer;
|
||||
createInfo.offset = tlas.buffer.descriptor.offset;
|
||||
|
||||
VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &tlas.handle));
|
||||
|
||||
VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
|
||||
accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
|
||||
accelerationDeviceAddressInfo.accelerationStructure = tlas.handle;
|
||||
tlas.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo);
|
||||
|
||||
VkCopyAccelerationStructureInfoKHR copyInfo{VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR};
|
||||
copyInfo.src = cleanup.handle;
|
||||
copyInfo.dst = tlas.handle;
|
||||
copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR;
|
||||
|
||||
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
uf::renderer::vkCmdCopyAccelerationStructureKHR(commandBuffer, ©Info);
|
||||
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
|
||||
|
||||
scratchBuffer.destroy();
|
||||
uf::renderer::vkDestroyAccelerationStructureKHR(device, cleanup.handle, nullptr);
|
||||
oldBuffer.destroy();
|
||||
}
|
||||
|
||||
if ( queryPool ) vkDestroyQueryPool(device, queryPool, nullptr);
|
||||
|
||||
if ( rebuild ) {
|
||||
// uf::renderer::states::rebuild = true;
|
||||
auto& renderMode = ext::vulkan::getRenderMode( descriptor.renderMode, true );
|
||||
@ -1744,6 +1873,12 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, const GraphicD
|
||||
}
|
||||
}
|
||||
void ext::vulkan::Graphic::destroy() {
|
||||
for ( auto& as : accelerationStructures.bottoms ) {
|
||||
uf::renderer::vkDestroyAccelerationStructureKHR(*device, as.handle, nullptr);
|
||||
}
|
||||
if ( accelerationStructures.top.handle ) {
|
||||
uf::renderer::vkDestroyAccelerationStructureKHR(*device, accelerationStructures.top.handle, nullptr);
|
||||
}
|
||||
for ( auto& pair : pipelines ) pair.second.destroy();
|
||||
pipelines.clear();
|
||||
material.destroy();
|
||||
|
@ -26,6 +26,8 @@ bool ext::vulkan::settings::defaultStageBuffers = true;
|
||||
// constexpr size_t ext::vulkan::settings::maxViews = 6;
|
||||
size_t ext::vulkan::settings::viewCount = 2;
|
||||
size_t ext::vulkan::settings::gpuID = -1;
|
||||
size_t ext::vulkan::settings::scratchBufferAlignment = 256;
|
||||
size_t ext::vulkan::settings::scratchBufferInitialSize = 1024 * 1024;
|
||||
|
||||
uf::stl::vector<uf::stl::string> ext::vulkan::settings::validationFilters;
|
||||
uf::stl::vector<uf::stl::string> ext::vulkan::settings::requestedDeviceFeatures;
|
||||
@ -81,6 +83,8 @@ bool ext::vulkan::states::rebuild = false;
|
||||
uint32_t ext::vulkan::states::currentBuffer = 0;
|
||||
uf::ThreadUnique<ext::vulkan::RenderMode*> ext::vulkan::currentRenderMode;
|
||||
|
||||
ext::vulkan::Buffer ext::vulkan::scratchBuffer;
|
||||
|
||||
uf::stl::vector<ext::vulkan::RenderMode*> ext::vulkan::renderModes = {
|
||||
new ext::vulkan::BaseRenderMode,
|
||||
};
|
||||
@ -251,6 +255,9 @@ void ext::vulkan::initialize() {
|
||||
ext::vulkan::mutex.lock();
|
||||
device.initialize();
|
||||
swapchain.initialize( device );
|
||||
|
||||
ext::vulkan::scratchBuffer.alignment = ext::vulkan::settings::scratchBufferAlignment;
|
||||
ext::vulkan::scratchBuffer.initialize( NULL, ext::vulkan::settings::scratchBufferInitialSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS );
|
||||
|
||||
if ( uf::io::exists(uf::io::root + "/textures/missing.png") ) {
|
||||
uf::Image image;
|
||||
@ -516,33 +523,23 @@ void ext::vulkan::destroy() {
|
||||
ext::vulkan::mutex.lock();
|
||||
synchronize();
|
||||
|
||||
for ( auto& fence : ::auxFencesGraphics ) vkDestroyFence( device, fence, nullptr);
|
||||
for ( auto& fence : ::auxFencesCompute ) vkDestroyFence( device, fence, nullptr);
|
||||
|
||||
Texture2D::empty.destroy();
|
||||
Texture3D::empty.destroy();
|
||||
TextureCube::empty.destroy();
|
||||
|
||||
/*
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& graph = scene.getGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
uf::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
graphic.destroy();
|
||||
}
|
||||
*/
|
||||
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode || !renderMode->device ) continue;
|
||||
renderMode->destroy();
|
||||
// delete renderMode;
|
||||
delete renderMode;
|
||||
renderMode = NULL;
|
||||
}
|
||||
|
||||
for ( auto& s : ext::vulkan::Sampler::samplers ) {
|
||||
s.destroy();
|
||||
}
|
||||
Texture2D::empty.destroy();
|
||||
Texture3D::empty.destroy();
|
||||
TextureCube::empty.destroy();
|
||||
for ( auto& s : ext::vulkan::Sampler::samplers ) s.destroy();
|
||||
|
||||
for ( auto& fence : ::auxFencesGraphics ) vkDestroyFence( device, fence, nullptr);
|
||||
for ( auto& fence : ::auxFencesCompute ) vkDestroyFence( device, fence, nullptr);
|
||||
|
||||
ext::vulkan::scratchBuffer.destroy();
|
||||
|
||||
swapchain.destroy();
|
||||
device.destroy();
|
||||
|
@ -178,7 +178,7 @@ bool UF_API uf::io::exists( const uf::stl::string& _filename ) {
|
||||
size_t UF_API uf::io::mtime( const uf::stl::string& _filename ) {
|
||||
uf::stl::string filename = sanitize(_filename);
|
||||
static struct stat buffer;
|
||||
if ( stat(filename.c_str(), &buffer) != 0 ) return -1;
|
||||
if ( stat(filename.c_str(), &buffer) != 0 ) return 0;
|
||||
return buffer.st_mtime;
|
||||
}
|
||||
bool UF_API uf::io::mkdir( const uf::stl::string& _filename ) {
|
||||
|
@ -40,12 +40,18 @@ uf::Serializer::output_t uf::Serializer::serialize( const ext::json::EncodingSet
|
||||
}
|
||||
|
||||
uf::stl::string uf::Serializer::resolveFilename( const uf::stl::string& filename, bool compareTimes ) {
|
||||
return resolveFilename( filename, ext::json::EncodingSettings{
|
||||
.encoding = ext::json::PREFERRED_ENCODING,
|
||||
.compression = ext::json::PREFERRED_COMPRESSION,
|
||||
}, compareTimes );
|
||||
}
|
||||
uf::stl::string uf::Serializer::resolveFilename( const uf::stl::string& filename, const ext::json::EncodingSettings& settings, bool compareTimes ) {
|
||||
uf::stl::string _filename = filename;
|
||||
if ( ext::json::PREFERRED_ENCODING != "" && ext::json::PREFERRED_ENCODING != "json" ) {
|
||||
_filename = uf::string::replace( _filename, "/\\.json$/", "." + ext::json::PREFERRED_ENCODING );
|
||||
if ( settings.encoding != "" && settings.encoding != "json" ) {
|
||||
_filename = uf::string::replace( _filename, "/\\.json$/", "." + settings.encoding );
|
||||
}
|
||||
if ( ext::json::PREFERRED_COMPRESSION != "" ) {
|
||||
_filename = _filename + "." + ext::json::PREFERRED_COMPRESSION;
|
||||
if ( settings.compression != "" ) {
|
||||
_filename = _filename + "." + settings.compression;
|
||||
}
|
||||
if ( !compareTimes ) return _filename;
|
||||
|
||||
@ -61,7 +67,14 @@ bool uf::Serializer::readFromFile( const uf::stl::string& filename, const uf::st
|
||||
#if UF_SERIALIZER_IMPLICIT_LOAD
|
||||
// implicitly check for optimal format for plain .json requests
|
||||
if ( uf::string::matched( filename, "/\\.json$/" ) ) {
|
||||
uf::stl::string _filename = uf::Serializer::resolveFilename( filename );
|
||||
#if UF_USE_TOML
|
||||
uf::stl::string toml_filename = uf::string::replace( filename, "/\\.json$/", ".toml" ); // load from toml if newer
|
||||
if ( uf::io::mtime( toml_filename ) > uf::io::mtime( filename ) ) {
|
||||
UF_MSG_DEBUG("Deserialize redirect: {} -> {}", filename, toml_filename);
|
||||
return readFromFile( toml_filename, hash );
|
||||
}
|
||||
#endif
|
||||
uf::stl::string _filename = resolveFilename( filename );
|
||||
if ( _filename != filename ) return readFromFile( _filename, hash );
|
||||
}
|
||||
#endif
|
||||
@ -82,12 +95,32 @@ bool uf::Serializer::readFromFile( const uf::stl::string& filename, const uf::st
|
||||
else if ( uf::string::matched( filename, "/\\.msgpack/" ) ) settings.encoding = "msgpack";
|
||||
else if ( uf::string::matched( filename, "/\\.ubjson/" ) ) settings.encoding = "ubjson";
|
||||
else if ( uf::string::matched( filename, "/\\.bjdata/" ) ) settings.encoding = "bjdata";
|
||||
// else UF_MSG_DEBUG( string );
|
||||
else if ( uf::string::matched( filename, "/\\.toml/" ) ) settings.encoding = "toml";
|
||||
else if ( uf::string::matched( filename, "/\\.json/" ) ) settings.encoding = "json";
|
||||
else UF_MSG_DEBUG( "invalid encoding filetype requested: {}", filename );
|
||||
|
||||
this->deserialize( buffer, settings );
|
||||
|
||||
#if UF_SERIALIZER_AUTO_CONVERT
|
||||
if ( uf::string::matched( filename, "/\\.json$/" ) ) {
|
||||
if ( ext::json::PREFERRED_ENCODING != "toml" ) {
|
||||
uf::stl::string _filename = uf::string::replace( filename, "/\\.json$/", ".toml" );
|
||||
|
||||
ext::json::EncodingSettings _settings{
|
||||
.encoding = "toml",
|
||||
.compression = "",
|
||||
};
|
||||
bool should = !uf::io::exists( _filename ); // auto convert if preferred file doesn't already exist
|
||||
if ( !should ) should = uf::io::mtime( _filename ) < uf::io::mtime( filename ); // auto convert if preferred file is older than source file
|
||||
if ( should ) {
|
||||
writeToFile( _filename, _settings );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( uf::string::matched( filename, "/\\.(json|toml)$/" ) ) {
|
||||
// auto convert read JSON file to TOML
|
||||
|
||||
// auto convert read file to preferred filetype
|
||||
if ( ext::json::PREFERRED_COMPRESSION != "" || (ext::json::PREFERRED_ENCODING != "" || ext::json::PREFERRED_ENCODING != "json") ) {
|
||||
ext::json::EncodingSettings _settings;
|
||||
_settings.encoding = ext::json::PREFERRED_ENCODING;
|
||||
@ -122,7 +155,7 @@ bool uf::Serializer::writeToFile( const uf::stl::string& filename, const ext::js
|
||||
output += "." + settings.compression;
|
||||
|
||||
uf::stl::string buffer = this->serialize( settings );
|
||||
size_t written = uf::io::write( output, buffer.c_str(), buffer.size() );
|
||||
size_t written = uf::io::write( output, buffer.data(), buffer.size() );
|
||||
#if UF_SERIALIZER_AUTO_CONVERT
|
||||
// implicitly check for optimal format for plain .json requests
|
||||
if ( uf::string::matched( output, "/\\.json$/" ) && settings.compression != ext::json::PREFERRED_COMPRESSION ) {
|
||||
|
@ -62,9 +62,7 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<ext::CraetureBehavior::Metadata>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
}
|
||||
void ext::CraetureBehavior::tick( uf::Object& self ) {}
|
||||
void ext::CraetureBehavior::render( uf::Object& self ){}
|
||||
|
@ -99,9 +99,7 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
uf::renderer::addRenderMode( &renderMode, name );
|
||||
}
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
}
|
||||
void ext::LightBehavior::tick( uf::Object& self ) {
|
||||
#if !UF_ENV_DREAMCAST
|
||||
@ -248,29 +246,30 @@ void ext::LightBehavior::Metadata::serialize( uf::Object& self, uf::Serializer&
|
||||
serializer["light"]["shadows"] = /*this->*/shadows;
|
||||
serializer["system"]["renderer"]["mode"] = /*this->*/renderer.mode;
|
||||
serializer["light"]["external update"] = /*this->*/renderer.external;
|
||||
serializer["system"]["renderer"]["timer"] = /*this->*/renderer.limiter;
|
||||
// serializer["system"]["renderer"]["timer"] = /*this->*/renderer.limiter;
|
||||
switch ( /*this->*/type ) {
|
||||
case 0: serializer["light"]["type"] = "point"; break;
|
||||
case 1: serializer["light"]["type"] = "spot"; break;
|
||||
case 1: serializer["light"]["type"] = "point"; break;
|
||||
case 2: serializer["light"]["type"] = "spot"; break;
|
||||
}
|
||||
}
|
||||
void ext::LightBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ){
|
||||
/*this->*/color = uf::vector::decode( serializer["light"]["color"], pod::Vector3f{1,1,1} );
|
||||
/*this->*/power = serializer["light"]["power"].as<float>();
|
||||
/*this->*/bias = serializer["light"]["bias"]["shader"].as<float>();
|
||||
/*this->*/shadows = serializer["light"]["shadows"].as<bool>();
|
||||
/*this->*/renderer.mode = serializer["system"]["renderer"]["mode"].as<uf::stl::string>();
|
||||
/*this->*/renderer.rendered = false;
|
||||
/*this->*/renderer.external = serializer["light"]["external update"].as<bool>();
|
||||
/*this->*/renderer.limiter = serializer["system"]["renderer"]["timer"].as<float>();
|
||||
/*this->*/color = uf::vector::decode( serializer["light"]["color"], /*this->*/color );
|
||||
/*this->*/power = serializer["light"]["power"].as<float>(/*this->*/power);
|
||||
/*this->*/bias = serializer["light"]["bias"]["shader"].as<float>(/*this->*/bias);
|
||||
/*this->*/shadows = serializer["light"]["shadows"].as<bool>(/*this->*/shadows);
|
||||
/*this->*/renderer.mode = serializer["system"]["renderer"]["mode"].as<uf::stl::string>(/*this->*/renderer.mode);
|
||||
// /*this->*/renderer.rendered = false;
|
||||
/*this->*/renderer.external = serializer["light"]["external update"].as<bool>(/*this->*/renderer.external);
|
||||
// /*this->*/renderer.limiter = serializer["system"]["renderer"]["timer"].as<float>(/*this->*/renderer.limiter);
|
||||
if ( serializer["light"]["type"].is<size_t>() ) {
|
||||
/*this->*/type = serializer["light"]["type"].as<size_t>();
|
||||
/*this->*/type = serializer["light"]["type"].as<size_t>(/*this->*/type);
|
||||
if ( serializer["light"]["dynamic"].as<bool>() ) /*this->*/type = -/*this->*/type;
|
||||
} else if ( serializer["light"]["type"].is<uf::stl::string>() ) {
|
||||
uf::stl::string lightType = serializer["light"]["type"].as<uf::stl::string>();
|
||||
if ( lightType == "point" ) /*this->*/type = 1;
|
||||
else if ( lightType == "spot" ) /*this->*/type = 2;
|
||||
if ( serializer["light"]["dynamic"].as<bool>() ) /*this->*/type = -/*this->*/type;
|
||||
}
|
||||
if ( serializer["light"]["dynamic"].as<bool>() ) /*this->*/type = -/*this->*/type;
|
||||
}
|
||||
#undef this
|
@ -107,9 +107,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
this->queueHook("discord.Activity.Update.%UID%", ext::json::null(), 1.0);
|
||||
#endif
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
}
|
||||
void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
@ -132,6 +130,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
bool jump = false;
|
||||
bool crouch = false;
|
||||
bool paused = false;
|
||||
bool console = false;
|
||||
bool vee = false;
|
||||
bool use = false;
|
||||
} keys;
|
||||
@ -149,6 +148,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
.jump = uf::inputs::kbm::states::Space,
|
||||
.crouch = uf::inputs::kbm::states::LControl,
|
||||
.paused = uf::inputs::kbm::states::Escape,
|
||||
.console = uf::inputs::kbm::states::Tilde,
|
||||
.vee = uf::inputs::kbm::states::V,
|
||||
.use = uf::inputs::kbm::states::E,
|
||||
};
|
||||
@ -205,24 +205,28 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||
|
||||
{
|
||||
float t = -1;
|
||||
uf::Object* hit = NULL;
|
||||
pod::Vector3f center = transform.position + metadata.movement.floored.feet;
|
||||
pod::Vector3f direction = metadata.movement.floored.floor;
|
||||
float t = 0.0f;
|
||||
if ( !stats.floored && collider.body && (t = uf::physics::impl::rayCast( center, direction, this, hit )) >= 0.0f ) {
|
||||
if ( !stats.floored && collider.body && (hit = uf::physics::impl::rayCast( collider, center, direction, t )) ) {
|
||||
if ( metadata.movement.floored.print ) UF_MSG_DEBUG("Floored: {} | {}", hit->getName(), t);
|
||||
stats.floored = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
TIMER(0.25, keys.use && ) {
|
||||
size_t uid = 0;
|
||||
float depth = -1;
|
||||
uf::Object* pointer = NULL;
|
||||
float length = metadata.use.length;
|
||||
pod::Vector3f center = transform.position + cameraTransform.position;
|
||||
pod::Vector3f direction = uf::vector::normalize( transform.forward + pod::Vector3f{ 0, cameraTransform.forward.y, 0 } ) * length;
|
||||
// pod::Vector3f center = transform.position + cameraTransform.position;
|
||||
// pod::Vector3f direction = uf::vector::normalize( transform.forward + pod::Vector3f{ 0, cameraTransform.forward.y, 0 } ) * length;
|
||||
auto flattened = uf::transform::flatten( cameraTransform );
|
||||
pod::Vector3f center = flattened.position;
|
||||
pod::Vector3f direction = flattened.forward * length;
|
||||
|
||||
float depth = uf::physics::impl::rayCast( center, direction, this, pointer );
|
||||
pointer = uf::physics::impl::rayCast( center, direction, this, depth );
|
||||
ext::json::Value payload;
|
||||
if ( pointer ) {
|
||||
payload["user"] = this->getUid();
|
||||
@ -235,7 +239,6 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
payload["depth"] = -1;
|
||||
}
|
||||
this->callHook( "entity:Use.%UID%", payload );
|
||||
|
||||
/*
|
||||
auto& emitter = this->getComponent<uf::MappedSoundEmitter>();
|
||||
uf::stl::string filename = pointer ? "./ui/select.ogg" : "./ui/deny.ogg";
|
||||
@ -254,6 +257,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( collider.stats.gravity == pod::Vector3f{0,0,0} ) stats.noclipped = true;
|
||||
|
||||
|
@ -27,9 +27,7 @@ void ext::PlayerModelBehavior::initialize( uf::Object& self ) {
|
||||
// transform.reference = &controllerTransform;
|
||||
// metadata.reference = &controllerTransform;
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
}
|
||||
void ext::PlayerModelBehavior::tick( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<ext::PlayerModelBehavior::Metadata>();
|
||||
|
@ -37,9 +37,7 @@ void ext::RayTraceSceneBehavior::initialize( uf::Object& self ) {
|
||||
uf::renderer::addRenderMode( renderMode, "Compute" );
|
||||
}
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
}
|
||||
void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<ext::RayTraceSceneBehavior::Metadata>();
|
||||
@ -115,6 +113,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
||||
size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(16);
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.alias() );
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.material.alias() );
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.texture.alias() );
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.light.alias() );
|
||||
@ -141,6 +140,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
||||
|
||||
metadata.renderer.bound = true;
|
||||
}
|
||||
/*
|
||||
if ( graphic.material.hasShader("ray:hit:closest", uf::renderer::settings::pipelines::names::rt) ) {
|
||||
auto& shader = graphic.material.getShader("ray:hit:closest", uf::renderer::settings::pipelines::names::rt);
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.alias() );
|
||||
@ -149,6 +149,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
||||
auto& shader = graphic.material.getShader("ray:hit:any", uf::renderer::settings::pipelines::names::rt);
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.alias() );
|
||||
}
|
||||
*/
|
||||
|
||||
graphic.process = false;
|
||||
}
|
||||
|
@ -113,9 +113,7 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
if ( !payload.transform.reference ) transform.reference = payload.transform.reference;
|
||||
});
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
|
||||
// lock control
|
||||
{
|
||||
|
@ -40,9 +40,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
|
||||
} );
|
||||
}
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
|
||||
// initialize voxel map
|
||||
#if 0
|
||||
|
@ -487,9 +487,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<ext::GuiBehavior::Metadata>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
|
||||
this->addHook( "asset:Load.%UID%", [&](pod::payloads::assetLoad& payload){
|
||||
if ( !uf::Asset::isExpected( payload, uf::Asset::Type::IMAGE ) ) return;
|
||||
@ -642,9 +640,12 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
||||
metadataJson["text settings"][key] = value;
|
||||
});
|
||||
auto& metadataGlyph = this->getComponent<ext::GuiBehavior::GlyphMetadata>();
|
||||
// UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadataGlyph, metadataJson);
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
this->addHook( "object:Serialize.%UID%", [&](){ metadataGlyph.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadataGlyph.serialize(self, (uf::Serializer&) json); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](){ metadataGlyph.deserialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadataGlyph.deserialize(self, (uf::Serializer&) json); });
|
||||
// metadataGlyph.deserialize(self, metadataJson);
|
||||
|
||||
this->addHook( "object:Reload.%UID%", [&](ext::json::Value& json){
|
||||
|
@ -84,9 +84,7 @@ void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
});
|
||||
|
||||
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
}
|
||||
void ext::GuiManagerBehavior::tick( uf::Object& self ) {
|
||||
#if UF_USE_VULKAN
|
||||
|
Loading…
Reference in New Issue
Block a user