Commit for 2022.07.09 19-45-23.7z
This commit is contained in:
parent
967f6b768f
commit
26a933307b
33
Makefile
33
Makefile
@ -22,6 +22,7 @@ BIN_DIR += ./bin
|
||||
ENGINE_SRC_DIR += ./engine/src
|
||||
ENGINE_INC_DIR += ./engine/inc
|
||||
ENGINE_LIB_DIR += ./engine/lib
|
||||
DEP_SRC_DIR += ./dep/src
|
||||
|
||||
EXT_SRC_DIR += ./ext
|
||||
CLIENT_SRC_DIR += ./client
|
||||
@ -49,25 +50,29 @@ SPV_OPTIMIZER += $(VULKAN_SDK_PATH)/Bin/spirv-opt
|
||||
INC_DIR += $(ENGINE_INC_DIR)
|
||||
LIB_DIR += $(ENGINE_LIB_DIR)
|
||||
|
||||
INCS += -I$(ENGINE_INC_DIR) -I$(INC_DIR) -I./dep/ #-I/mingw64/include
|
||||
LIBS += -L$(ENGINE_LIB_DIR) -L$(LIB_DIR) -L$(LIB_DIR)/$(ARCH) -L$(LIB_DIR)/$(PREFIX_PATH)
|
||||
INCS += -I$(ENGINE_INC_DIR) -I./dep/include/ #-I/mingw64/include/
|
||||
LIBS += -L$(ENGINE_LIB_DIR) -L$(LIB_DIR)/$(PREFIX_PATH) -L$(LIB_DIR)/$(ARCH)/$(CC) -L$(LIB_DIR)/$(ARCH) #-L/mingw64/lib/
|
||||
|
||||
LINKS += $(UF_LIBS) $(EXT_LIBS) $(DEPS)
|
||||
DEPS +=
|
||||
|
||||
ifneq (,$(findstring win64,$(ARCH)))
|
||||
REQ_DEPS += $(RENDERER) json:nlohmann png zlib openal ogg freetype curl luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt # ncurses openvr draco discord bullet ultralight-ux
|
||||
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
|
||||
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
|
||||
endif
|
||||
FLAGS += -DUF_ENV_WINDOWS -DUF_ENV_WIN64 -DWIN32_LEAN_AND_MEAN
|
||||
DEPS += -lgdi32 -ldwmapi
|
||||
LINKS += #-Wl,-subsystem,windows
|
||||
else ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
FLAGS += -DUF_ENV_DREAMCAST
|
||||
REQ_DEPS += simd opengl gldc json:nlohmann reactphysics png zlib ctti lua fmt # lua ogg openal aldc gltf freetype bullet meshoptimizer draco luajit ultralight-ux ncurses curl openvr discord
|
||||
REQ_DEPS += simd opengl gldc json:nlohmann reactphysics png zlib ctti lua fmt # ogg openal aldc gltf freetype bullet meshoptimizer draco luajit ultralight-ux ncurses curl openvr discord
|
||||
endif
|
||||
ifneq (,$(findstring vulkan,$(REQ_DEPS)))
|
||||
FLAGS += -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN
|
||||
DEPS += -lvulkan -lspirv-cross #-lVulkanMemoryAllocator
|
||||
INCS += -I$(VULKAN_SDK_PATH)/include
|
||||
DEPS += -lvulkan -lspirv-cross-core -lspirv-cross-cpp #-lVulkanMemoryAllocator
|
||||
INCS += -I$(VULKAN_SDK_PATH)/include -I./dep/include/spirv_cross/
|
||||
LIBS += -L$(VULKAN_SDK_PATH)/Lib
|
||||
endif
|
||||
ifneq (,$(findstring opengl,$(REQ_DEPS)))
|
||||
@ -100,8 +105,8 @@ ifneq (,$(findstring fmt,$(REQ_DEPS)))
|
||||
endif
|
||||
ifneq (,$(findstring imgui,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_IMGUI
|
||||
INCS += -I./dep/imgui/
|
||||
INCS += -I./dep/imgui/backends
|
||||
INCS += -I./dep/include/imgui/
|
||||
INCS += -I./dep/include/imgui/backends
|
||||
endif
|
||||
ifneq (,$(findstring json,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_JSON
|
||||
@ -222,7 +227,11 @@ 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)
|
||||
SRCS_DLL := $(shell find $(ENGINE_SRC_DIR) -name "*.cpp") $(shell find $(EXT_SRC_DIR) -name "*.cpp")
|
||||
ifneq (,$(findstring zig,$(CC)))
|
||||
SRCS_DLL := $(shell find $(ENGINE_SRC_DIR) -name "*.cpp") $(shell find $(EXT_SRC_DIR) -name "*.cpp") $(shell find $(DEP_SRC_DIR) -name "*.cpp") $(shell find ./dep/zig/src/ -name "*.cpp")
|
||||
else
|
||||
SRCS_DLL := $(shell find $(ENGINE_SRC_DIR) -name "*.cpp") $(shell find $(EXT_SRC_DIR) -name "*.cpp") $(shell find $(DEP_SRC_DIR) -name "*.cpp")
|
||||
endif
|
||||
OBJS_DLL += $(patsubst %.cpp,%.$(PREFIX).o,$(SRCS_DLL))
|
||||
BASE_DLL += lib$(LIB_NAME)
|
||||
IM_DLL += $(ENGINE_LIB_DIR)/$(PREFIX_PATH)/$(BASE_DLL).$(TARGET_LIB_EXTENSION).a
|
||||
@ -234,8 +243,8 @@ EXT_DEPS += -l$(LIB_NAME) $(DEPS)
|
||||
EXT_LINKS += $(UF_LIBS) $(EXT_LIBS) $(EXT_DEPS)
|
||||
|
||||
EXT_LIB_DIR += $(ENGINE_LIB_DIR)/$(ARCH)
|
||||
EXT_INCS += -I$(ENGINE_INC_DIR) -I$(EXT_INC_DIR) -I/mingw64/include
|
||||
EXT_LIBS += -L$(ENGINE_LIB_DIR) -L$(EXT_LIB_DIR) -L$(EXT_LIB_DIR)/$(ARCH) -L$(EXT_LIB_DIR)/$(PREFIX_PATH) -L/mingw64/lib
|
||||
EXT_INCS += $(INCS)
|
||||
EXT_LIBS += $(LIBS)
|
||||
|
||||
#SRCS_EXT_DLL += $(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)
|
||||
SRCS_EXT_DLL := $(shell find $(EXT_SRC_DIR) -name "*.cpp")
|
||||
@ -377,4 +386,6 @@ backup:
|
||||
make CC=gcc RENDERER=vulkan clean
|
||||
make CC=clang RENDERER=opengl clean
|
||||
make CC=clang RENDERER=vulkan clean
|
||||
make CC=zig RENDERER=opengl clean
|
||||
make CC=zig RENDERER=vulkan clean
|
||||
$(7Z) a -r ../misc/backups/$(shell date +"%Y.%m.%d\ %H-%M-%S").7z .
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "SH2_McDonalds",
|
||||
"start": "McDonalds",
|
||||
"meshes": { "interleaved": false },
|
||||
"matrix": { "reverseInfinite": true },
|
||||
"lights": { "enabled": true,
|
||||
@ -16,9 +16,9 @@
|
||||
},
|
||||
"textures": {
|
||||
"max": {
|
||||
"2D": 512,
|
||||
"cube": 128,
|
||||
"3D": 64
|
||||
"2D": 1024,
|
||||
"cube": 1024,
|
||||
"3D": 128
|
||||
}
|
||||
},
|
||||
"vxgi": {
|
||||
@ -38,6 +38,8 @@
|
||||
}
|
||||
},
|
||||
"rt": {
|
||||
"size": [ 960, 540 ],
|
||||
"filter": "NEAREST",
|
||||
"defaultRayBounds": [ 0.001, 1024.0 ],
|
||||
"alphaTestOffset": 0.001,
|
||||
"samples": 1,
|
||||
@ -90,6 +92,7 @@
|
||||
},
|
||||
"invariant": {
|
||||
// "multithreaded recording": true
|
||||
"deferred alias output to swapchain": false,
|
||||
"defaultStageBuffers": true
|
||||
},
|
||||
"pipelines": {
|
||||
@ -98,7 +101,7 @@
|
||||
"vxgi": true,
|
||||
"culling": true,
|
||||
"bloom": false,
|
||||
"rt": false
|
||||
"rt": true
|
||||
},
|
||||
"formats": {
|
||||
"depth": "D32_SFLOAT",
|
||||
@ -288,13 +291,13 @@
|
||||
"cursor" : {
|
||||
"visible" : true,
|
||||
"center" : false,
|
||||
"sensitivity": [ 1.25, 1.25 ],
|
||||
"smoothing": [ 10, 10 ]
|
||||
"sensitivity": [ 0.75, 0.75 ],
|
||||
"smoothing": [ 4, 4 ]
|
||||
},
|
||||
"mode" : "borderless", // fullscreen, borderless, windowed
|
||||
"mode" : "windowed", // fullscreen, borderless, windowed
|
||||
"icon" : "./data/textures/icon.png",
|
||||
"size" : [ 1920, 1080 ],
|
||||
// "size" : [ 1280, 720 ],
|
||||
// "size" : [ 1920, 1080 ],
|
||||
"size" : [ 1280, 720 ],
|
||||
// "size" : [ 960, 540 ],
|
||||
// "size" : [ 640, 480 ],
|
||||
// "size" : [ 256, 224 ],
|
||||
|
@ -12,8 +12,16 @@
|
||||
"model": {
|
||||
"debug": {
|
||||
"no cleanup": false,
|
||||
"print tree": false,
|
||||
"print stats": false
|
||||
"print": {
|
||||
"tree": false,
|
||||
"stats": false,
|
||||
"meshes": false,
|
||||
"materials": false,
|
||||
"textures": false
|
||||
}
|
||||
},
|
||||
"sanitizer": {
|
||||
"winding order": true
|
||||
},
|
||||
"exporter": {
|
||||
"enabled": true,
|
||||
@ -24,14 +32,9 @@
|
||||
"precision": 4,
|
||||
"combined": false,
|
||||
"encode buffers": true,
|
||||
"unwrap": true,
|
||||
"unwrap": true, // "tagged",
|
||||
// "unwrap": "tagged",
|
||||
"optimize": "tagged",
|
||||
// "optimize": true,
|
||||
"quit": true,
|
||||
"mesh": {
|
||||
// "print": true
|
||||
}
|
||||
"quit": true
|
||||
},
|
||||
"baking": {
|
||||
"enabled": true,
|
||||
@ -55,8 +58,11 @@
|
||||
"rotateCharts": true
|
||||
}
|
||||
},
|
||||
// "filter": "NEAREST",
|
||||
"lightmap": "auto",
|
||||
"renderer": {
|
||||
"front face": "ccw",
|
||||
"cull mode": "back",
|
||||
"filter": "linear"
|
||||
},
|
||||
"flags": {
|
||||
"ATLAS": false,
|
||||
"INVERT": false,
|
||||
@ -68,6 +74,7 @@
|
||||
"NORMALS": false
|
||||
},
|
||||
"lights": {
|
||||
"lightmap": "auto",
|
||||
// "disable if lightmapped": false,
|
||||
"shadows": true
|
||||
}
|
||||
|
@ -14,36 +14,10 @@
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"assets": [
|
||||
{ "filename": "./playerModel.json", "delay": 1.0, "single threaded": true },
|
||||
"./playerModel.json",
|
||||
"./hands.json"
|
||||
],
|
||||
"system": {
|
||||
"physics": {
|
||||
"movement": {
|
||||
"walk": 1,
|
||||
"move": 8,
|
||||
"run": 16,
|
||||
"rotate": 1.5,
|
||||
"air": 0.1,
|
||||
|
||||
"crouch": 1,
|
||||
"jump": [ 0, 4, 0 ],
|
||||
"look": 0.75
|
||||
},
|
||||
|
||||
"gravity": [ 0, -9.81, 0 ],
|
||||
"inertia": [ 0, 0, 0 ],
|
||||
|
||||
"type": "capsule",
|
||||
"radius": 1,
|
||||
"height": 2,
|
||||
|
||||
"mass": 100,
|
||||
"friction": 0.8,
|
||||
"restitution": 0.0,
|
||||
|
||||
"shared": false
|
||||
},
|
||||
"hot reload": {
|
||||
"enabled": true
|
||||
}
|
||||
@ -74,6 +48,36 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"movement": {
|
||||
"walk": 1,
|
||||
"move": 4,
|
||||
"run": 16,
|
||||
"rotate": 1.5,
|
||||
"air": 0.1,
|
||||
|
||||
"crouch": 1,
|
||||
"jump": [ 0, 4, 0 ],
|
||||
"look": 1,
|
||||
"floored": {
|
||||
"feet": [ 0, -1.5, 0 ],
|
||||
"floor": [ 0, -0.5, 0 ],
|
||||
"print": false
|
||||
}
|
||||
},
|
||||
"physics": {
|
||||
"gravity": [ 0, -9.81, 0 ],
|
||||
"inertia": [ 0, 0, 0 ],
|
||||
|
||||
"type": "capsule",
|
||||
"radius": 1,
|
||||
"height": 2,
|
||||
|
||||
"mass": 100,
|
||||
"friction": 0.95,
|
||||
"restitution": 0.0,
|
||||
|
||||
"shared": false
|
||||
},
|
||||
"camera": {
|
||||
"offset": [ 0, 0, 0 ],
|
||||
"position" : [ 0, 1.8, 0 ],
|
||||
|
@ -3,25 +3,10 @@
|
||||
"assets": [
|
||||
// { "filename": "/gui/hud/hud.json", "delay": 0 }
|
||||
],
|
||||
"system": {
|
||||
"physics": {
|
||||
"gravity": [ 0, 0, 0 ]
|
||||
},
|
||||
"hot reload": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"overlay": {
|
||||
"floating": true
|
||||
},
|
||||
"collider": false,
|
||||
"light": {
|
||||
"should": false,
|
||||
"color": [1, 1, 1],
|
||||
"position": [ 0, 2.5, 0 ],
|
||||
"power": 1,
|
||||
"radius": [0.001, 32]
|
||||
"physics": {
|
||||
"collider": false,
|
||||
"gravity": [ 0, 0, 0 ]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"assets": ["./scripts/door.lua"],
|
||||
"system": {
|
||||
"metadata": {
|
||||
"physics": {
|
||||
"type": "bounding box",
|
||||
"recenter": true
|
||||
|
@ -15,13 +15,17 @@
|
||||
"metadata": {
|
||||
"model": {
|
||||
"baking": {
|
||||
"enabled": false,
|
||||
"enabled": true,
|
||||
"resolution": 2048,
|
||||
"settings": {
|
||||
"useInputMeshUvs": false
|
||||
}
|
||||
},
|
||||
// "cull mode": "none",
|
||||
"renderer": {
|
||||
"front face": "cw",
|
||||
"cull mode": "back",
|
||||
"filter": "linear"
|
||||
},
|
||||
"tags": {
|
||||
"/^worldspawn/": {
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
@ -49,7 +53,9 @@
|
||||
|
||||
"func_physbox_5212": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_physbox_5548": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
"func_physbox_5931": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } }
|
||||
"func_physbox_5931": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
|
||||
|
||||
"tools/toolsnodraw": { "material": { "base": [0, 0, 0, 0] } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,8 @@
|
||||
"assets": [
|
||||
// { "filename": "/gui/hud/hud.json", "delay": 0 }
|
||||
],
|
||||
"system": {
|
||||
},
|
||||
"metadata": {
|
||||
"overlay": {
|
||||
"floating": true
|
||||
},
|
||||
"collider": true,
|
||||
"light": {
|
||||
"should": false,
|
||||
"color": [1, 1, 1],
|
||||
"position": [ 0, 2.5, 0 ],
|
||||
"power": 1,
|
||||
"radius": [0.001, 32]
|
||||
}
|
||||
}
|
||||
}
|
@ -36,8 +36,8 @@
|
||||
"exposure": 1.0,
|
||||
"gamma": 1.0,
|
||||
"brightnessThreshold": 1.2,
|
||||
"ambient": [ 0, 0, 0 ],
|
||||
// "ambient": [ 0.025, 0.025, 0.025 ],
|
||||
// "ambient": [ 0, 0, 0 ],
|
||||
"ambient": [ 0.025, 0.025, 0.025 ],
|
||||
// "ambient": [ 0.075, 0.075, 0.075 ],
|
||||
// "ambient": [ 0.1, 0.1, 0.1 ],
|
||||
// "ambient": [ 0.4, 0.4, 0.4 ],
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"assets": ["./scripts/door.lua"],
|
||||
"system": {
|
||||
"metadata": {
|
||||
"physics": {
|
||||
"mass": 0,
|
||||
"inertia": [0, 0, 0],
|
||||
|
@ -5,16 +5,5 @@
|
||||
"./playerLight.json"
|
||||
],
|
||||
"metadata": {
|
||||
"overlay": {
|
||||
"floating": true
|
||||
},
|
||||
"collider": true,
|
||||
"light": {
|
||||
"should": false,
|
||||
"color": [1, 1, 1],
|
||||
"position": [ 0, 2.5, 0 ],
|
||||
"power": 1,
|
||||
"radius": [0.001, 32]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"assets": [],
|
||||
"system": {
|
||||
"metadata": {
|
||||
"physics": {
|
||||
"mass": 0,
|
||||
"inertia": [0, 0, 0],
|
||||
|
@ -8,8 +8,6 @@
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
"cull mode": "none",
|
||||
"alpha mode": "BLEND",
|
||||
"baking": {
|
||||
"enabled": true,
|
||||
"resolution": 1024,
|
||||
@ -17,12 +15,18 @@
|
||||
"useInputMeshUvs": false
|
||||
}
|
||||
},
|
||||
"renderer": {
|
||||
"front face": "cw",
|
||||
"cull mode": "back",
|
||||
"filter": "linear"
|
||||
},
|
||||
"tags": {
|
||||
"/^worldspawn/": {
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
"grid": { "size": [3,1,3], "epsilon": 1.0, "cleanup": true, "print": true }
|
||||
},
|
||||
"/^cb$/": {
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
"grid": { "size": [6,1,6], "epsilon": 1.0, "cleanup": true, "print": true }
|
||||
},
|
||||
// "worldspawn_sh2": { "physics": { "type": "mesh", "static": true } },
|
||||
@ -101,7 +105,9 @@
|
||||
"prop_physics_override_5810": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5814": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5822": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
"prop_physics_override_5824": { "action": "load", "payload": { "import": "./prop.json" } }
|
||||
"prop_physics_override_5824": { "action": "load", "payload": { "import": "./prop.json" } },
|
||||
|
||||
"tools/toolsnodraw": { "material": { "base": [0, 0, 0, 0] } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
bin/data/scenes/sm64/loading.json
Normal file
32
bin/data/scenes/sm64/loading.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "Gui: Loading",
|
||||
"type": "Object",
|
||||
"behaviors": [
|
||||
// "GuiBehavior"
|
||||
],
|
||||
"assets": [
|
||||
{ "filename": "./mcdonalds.json", "delay": 0 }
|
||||
],
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.830591, -0.699509, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.258737, 0.115371, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0.1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"text settings": {
|
||||
"stroke": [ 1, 0.749, 0.368, 1 ],
|
||||
"color": [ 1, 0.749, 0.368, 1 ],
|
||||
|
||||
"string": "Loading...",
|
||||
"string1": "コマンド"
|
||||
}
|
||||
}
|
||||
}
|
19
bin/data/scenes/sm64/player.json
Normal file
19
bin/data/scenes/sm64/player.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"import": "/player.json",
|
||||
"assets": [
|
||||
// { "filename": "/gui/hud/hud.json", "delay": 0 }
|
||||
],
|
||||
"metadata": {
|
||||
"movement": {
|
||||
"jump": [0, 1, 0],
|
||||
"floored": {
|
||||
"feet": [ 0, 0, 0 ],
|
||||
"floor": [ 0, -0.8, 0 ]
|
||||
}
|
||||
},
|
||||
"physics": {
|
||||
"radius": 0.25,
|
||||
"height": 0.25
|
||||
}
|
||||
}
|
||||
}
|
89
bin/data/scenes/sm64/scene.json
Normal file
89
bin/data/scenes/sm64/scene.json
Normal file
@ -0,0 +1,89 @@
|
||||
{
|
||||
"import": "/scene.json",
|
||||
"assets": [
|
||||
// "./loading.json",
|
||||
"./sm64.json"
|
||||
],
|
||||
"system": {
|
||||
"hot reload": {
|
||||
"enabled": true
|
||||
},
|
||||
"renderer": {
|
||||
"shader": {
|
||||
"mode": 1,
|
||||
"scalar": 16,
|
||||
"parameters": [ 0, 0, 0, "time" ],
|
||||
"frame accumulate limit": 0
|
||||
},
|
||||
"clear values": [
|
||||
[ 1, 1, 1, 0 ]
|
||||
]
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"menus": {
|
||||
"pause": "/gui/pause/menu.json"
|
||||
},
|
||||
"bloom": {
|
||||
"scale": 6.0,
|
||||
"strength": 0.125,
|
||||
"sigma": 0.125,
|
||||
"samples": 8
|
||||
},
|
||||
"light": {
|
||||
"exposure": 1.0,
|
||||
"gamma": 1.0,
|
||||
"brightnessThreshold": 1.2,
|
||||
// "ambient": [ 0, 0, 0 ],
|
||||
// "ambient": [ 0.025, 0.025, 0.025 ],
|
||||
// "ambient": [ 0.075, 0.075, 0.075 ],
|
||||
// "ambient": [ 0.1, 0.1, 0.1 ],
|
||||
"ambient": [ 0.4, 0.4, 0.4 ],
|
||||
// "ambient": [ 0.8, 0.8, 0.8 ],
|
||||
|
||||
"fog-": {
|
||||
"color": [ 0.5, 0.5, 0.5 ],
|
||||
"range": [ 16, 32 ],
|
||||
"step scale": 2,
|
||||
"absorbtion": 0.01,
|
||||
"density": {
|
||||
"threshold": 0.35,
|
||||
"multiplier": 5.0,
|
||||
"scale": 25.0,
|
||||
"offset": [0, -1, 1],
|
||||
"timescale": 8
|
||||
}
|
||||
},
|
||||
"should": true,
|
||||
"shadows": true
|
||||
},
|
||||
"noise": {
|
||||
"size": [ 32, 32, 32 ]
|
||||
},
|
||||
"vxgi": {
|
||||
/*
|
||||
"limiter": 1,
|
||||
"size": 96,
|
||||
"dispatch": 8,
|
||||
"cascades": 2,
|
||||
"cascadePower": 4,
|
||||
"voxelizeScale": 1,
|
||||
"shadows": 0,
|
||||
*/
|
||||
"occlusionFalloff": 2,
|
||||
"traceStartOffsetFactor": 1,
|
||||
"granularity": 2,
|
||||
"extents": {
|
||||
"min": [ -1.5, -1.5, -1.5 ],
|
||||
"max": [ 1.5, 1.5, 1.5 ]
|
||||
}
|
||||
},
|
||||
"rt": {
|
||||
"defaultRayBounds": [ 0.001, 1024.0 ],
|
||||
"alphaTestOffset": 1.125,
|
||||
"samples": 1,
|
||||
"paths": 1,
|
||||
"frameAccumulationMinimum": 0
|
||||
}
|
||||
}
|
||||
}
|
35
bin/data/scenes/sm64/sm64.json
Normal file
35
bin/data/scenes/sm64/sm64.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
// { "filename": "./models/sm64_bbb.glb" }
|
||||
{ "filename": "./models/sm64_bbb/graph.json" }
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
"baking": {
|
||||
"enabled": true,
|
||||
"resolution": 2048,
|
||||
"settings": {
|
||||
"useInputMeshUvs": false
|
||||
}
|
||||
},
|
||||
"renderer": {
|
||||
"front face": "cw",
|
||||
"cull mode": "none",
|
||||
"filter": "nearest"
|
||||
},
|
||||
"tags": {
|
||||
"/^worldspawn/": {
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
"grid": { "size": [3,1,3], "epsilon": 1.0, "cleanup": true, "print": true },
|
||||
// "optimize mesh": { "simplify": 0 },
|
||||
"unwrap mesh": true
|
||||
},
|
||||
"info_player_spawn": { "action": "attach", "filename": "./player.json" },
|
||||
|
||||
"Material.071_574B138E_c.bmp": { "material": { "modeAlpha": "BLEND" } },
|
||||
"Material.070_41A41EE3_c.bmp": { "material": { "modeAlpha": "BLEND" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"assets": [ "./scripts/lift.lua" ],
|
||||
"system": {
|
||||
"metadata": {
|
||||
"physics": {
|
||||
"type": "bounding box",
|
||||
"recenter": true,
|
||||
|
@ -5,7 +5,7 @@
|
||||
// { "filename": "./test.json", "delay": 1 },
|
||||
|
||||
// { "filename": "./models/tiny_msci.glb" }
|
||||
{ "filename": "./models/tiny_msci/graph.json" }
|
||||
// { "filename": "./models/tiny_msci/graph.json" }
|
||||
|
||||
// { "filename": "./models/micro_sci.glb" }
|
||||
// { "filename": "./models/micro_sci/graph.json" }
|
||||
@ -14,7 +14,7 @@
|
||||
// { "filename": "./models/msci/graph.json" }
|
||||
|
||||
// { "filename": "./models/medsci.glb" }
|
||||
// { "filename": "./models/medsci/graph.json" }
|
||||
{ "filename": "./models/medsci/graph.json" }
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
@ -22,7 +22,11 @@
|
||||
"enabled": true,
|
||||
"resolution": 1024
|
||||
},
|
||||
"filter": "LINEAR",
|
||||
"renderer": {
|
||||
"front face": "cw",
|
||||
"cull mode": "back",
|
||||
"filter": "linear"
|
||||
},
|
||||
"tags": {
|
||||
"/^worldspawn/": {
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
|
@ -12,16 +12,12 @@
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"overlay": {
|
||||
"floating": true
|
||||
},
|
||||
"collider": true,
|
||||
"light": {
|
||||
"should": false,
|
||||
"color": [1, 1, 1],
|
||||
"position": [ 0, 2.5, 0 ],
|
||||
"power": 1,
|
||||
"radius": [0.001, 32]
|
||||
"movement": {
|
||||
"floored": {
|
||||
"feet": [ 0, -1.5, 0 ],
|
||||
"floor": [ 0, -0.5, 0 ],
|
||||
"print": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -135,7 +135,7 @@ void indirectLighting() {
|
||||
const float DIFFUSE_INDIRECT_FACTOR = 1.0f / float(CONES_COUNT);
|
||||
|
||||
const float SPECULAR_CONE_APERTURE = clamp(tan(PI * 0.5f * surface.material.roughness), 0.0174533f, PI); // tan( R * PI * 0.5f * 0.1f );
|
||||
const float SPECULAR_INDIRECT_FACTOR = (1.0 - surface.material.metallic) * 0.5; // 1.0f;
|
||||
const float SPECULAR_INDIRECT_FACTOR = (1.0 - surface.material.metallic) * 0.25; // 1.0f;
|
||||
|
||||
vec4 indirectDiffuse = vec4(0);
|
||||
vec4 indirectSpecular = vec4(0);
|
||||
|
@ -6,8 +6,8 @@
|
||||
#pragma shader_stage(raygen)
|
||||
layout (constant_id = 0) const uint PASSES = 2;
|
||||
layout (constant_id = 1) const uint TEXTURES = 512;
|
||||
layout (constant_id = 2) const uint CUBEMAPS = 128;
|
||||
layout (constant_id = 3) const uint CASCADES = 4;
|
||||
layout (constant_id = 2) const uint CUBEMAPS = 8;
|
||||
layout (constant_id = 3) const uint CASCADES = 1;
|
||||
|
||||
#define COMPUTE 1
|
||||
#define PBR 1
|
||||
@ -70,17 +70,18 @@ layout (std140, binding = 6) readonly buffer Lights {
|
||||
|
||||
layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
|
||||
layout (binding = 9) uniform sampler3D samplerNoise;
|
||||
#if VXGI
|
||||
layout (binding = 14) uniform usampler3D voxelId[CASCADES];
|
||||
layout (binding = 15) uniform sampler3D voxelNormal[CASCADES];
|
||||
layout (binding = 16) uniform sampler3D voxelRadiance[CASCADES];
|
||||
layout (binding = 10) uniform usampler3D voxelId[CASCADES];
|
||||
layout (binding = 11) uniform sampler3D voxelNormal[CASCADES];
|
||||
layout (binding = 12) uniform sampler3D voxelRadiance[CASCADES];
|
||||
#endif
|
||||
|
||||
layout (location = 0) rayPayloadEXT RayTracePayload payload;
|
||||
|
||||
#include "../common/functions.h"
|
||||
#include "../common/light.h"
|
||||
#include "../common/fog.h"
|
||||
#if VXGI
|
||||
#include "../common/vxgi.h"
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "SS2",
|
||||
"start": "SM64",
|
||||
"meshes": { "interleaved": false },
|
||||
"matrix": { "reverseInfinite": false },
|
||||
"lights": { "enabled": false,
|
||||
|
@ -17,7 +17,6 @@ uf::Window client::window;
|
||||
uf::Serializer client::config;
|
||||
|
||||
void client::initialize() {
|
||||
uf::IoStream::ncurses = true;
|
||||
uf::renderer::device.window = &client::window;
|
||||
|
||||
ext::load();
|
||||
@ -111,6 +110,9 @@ void client::initialize() {
|
||||
#if UF_ENV_DREAMCAST
|
||||
client::window.pollEvents();
|
||||
#endif
|
||||
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void client::tick() {
|
||||
|
@ -67,6 +67,7 @@ int main(int argc, char** argv){
|
||||
|
||||
if ( timer.elapsed().asDouble() >= next ) {
|
||||
// UF_MSG_INFO("Waiting for " << ( client::ready ? "client" : "extension / engine" ) << " to initialize... Retrying in " << next << " seconds.");
|
||||
UF_MSG_INFO("Waiting for {} to initialize; retrying in {} seconds", ( client::ready ? "client" : "extension / engine" ), next);
|
||||
next *= 2;
|
||||
}
|
||||
}
|
||||
|
@ -61,8 +61,6 @@ namespace pod {
|
||||
|
||||
// Local storage, used for save/load
|
||||
struct Storage {
|
||||
|
||||
|
||||
uf::stl::KeyMap<pod::Instance> instances;
|
||||
uf::stl::KeyMap<pod::Instance::Addresses> instanceAddresses;
|
||||
uf::stl::KeyMap<uf::stl::vector<pod::Primitive>> primitives;
|
||||
|
@ -38,7 +38,6 @@ namespace ext {
|
||||
extern UF_API bool multithreadedRecording;
|
||||
|
||||
extern UF_API uf::stl::string deferredMode;
|
||||
extern UF_API bool deferredReconstructPosition;
|
||||
extern UF_API bool deferredAliasOutputToSwapchain;
|
||||
extern UF_API bool deferredSampling;
|
||||
extern UF_API bool multiview;
|
||||
|
@ -104,8 +104,7 @@ namespace ext {
|
||||
|
||||
// ray casting
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f& );
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, size_t& );
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*& );
|
||||
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*, uf::Object*& );
|
||||
|
||||
// allows noclip
|
||||
void UF_API activateCollision( pod::PhysicsState&, bool = true );
|
||||
|
@ -75,7 +75,6 @@ namespace ext {
|
||||
extern UF_API bool multithreadedRecording;
|
||||
|
||||
extern UF_API uf::stl::string deferredMode;
|
||||
extern UF_API bool deferredReconstructPosition;
|
||||
extern UF_API bool deferredAliasOutputToSwapchain;
|
||||
extern UF_API bool deferredSampling;
|
||||
extern UF_API bool multiview;
|
||||
|
@ -27,7 +27,7 @@
|
||||
#if UF_USE_FMT
|
||||
#define UF_MSG(CATEGORY, ...) uf::io::log(CATEGORY, __FILE__, __FUNCTION__, __LINE__, ::fmt::format(__VA_ARGS__));
|
||||
#else
|
||||
#define UF_MSG(CATEGORY, ...) uf::io::log(CATEGORY, __FILE__, __FUNCTION__, __LINE__, #__VA_ARGS__); // std::cout << "[" << CATEGORY << "] [" << __FILE__ << ":" << __FUNCTION__ << "@" << __LINE__ << "]" << std::endl;;
|
||||
#define UF_MSG(CATEGORY, ...) uf::io::log(CATEGORY, __FILE__, __FUNCTION__, __LINE__, #__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
#define UF_MSG_DEBUG(...) if (UF_DEBUG) UF_MSG("DEBUG", __VA_ARGS__);
|
||||
@ -45,7 +45,8 @@
|
||||
#define UF_NO_EXCEPTIONS 0
|
||||
#define UF_EXCEPTIONS 1
|
||||
#define UF_EXCEPTION(...) {\
|
||||
throw std::runtime_error(UF_MSG_ERROR(__VA_ARGS__));\
|
||||
auto msg = UF_MSG_ERROR(__VA_ARGS__);\
|
||||
throw std::runtime_error(msg);\
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -81,7 +82,7 @@
|
||||
TIMER_TRACE_PREV = TIMER_TRACE_CUR;\
|
||||
}
|
||||
|
||||
#define UF_TIMER_MULTITRACE_END(X) UF_MSG_DEBUG(X);
|
||||
#define UF_TIMER_MULTITRACE_END(...) UF_MSG_DEBUG(__VA_ARGS__);
|
||||
|
||||
#include <type_traits>
|
||||
#define TYPE_SANITIZE(T) std::remove_cv_t<std::remove_reference_t<T>>
|
||||
@ -108,7 +109,7 @@
|
||||
|
||||
#define ALIGNED_SIZE(V, A) ((V + A - 1) & ~(A - 1))
|
||||
|
||||
#define UF_MSG_PEEK(X) #X << ": " << X
|
||||
#define UF_MSG_PEEK(X) #X"="+std::to_string(X)
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define DC_STATS() {\
|
||||
|
@ -3,12 +3,7 @@
|
||||
#if UF_USE_FMT
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define FMT_HEADER_ONLY
|
||||
// #include <fmt-1/format.h>
|
||||
|
||||
// #include <fmt-3/format.h>
|
||||
// #include <fmt-8/format.h>
|
||||
#include <fmt-7/format.h>
|
||||
// #include <fmt-7/core.h>
|
||||
#else
|
||||
// #include <fmt/core.h>
|
||||
#endif
|
||||
|
@ -139,8 +139,11 @@ inline uf::simd::value<float> /*UF_API*/ uf::simd::sqrt( uf::simd::value<float>
|
||||
}
|
||||
inline float /*UF_API*/ uf::simd::dot( uf::simd::value<float> x, uf::simd::value<float> y ) {
|
||||
#if SSE_INSTR_SET >= 5
|
||||
float res;
|
||||
__m128 result = _mm_dp_ps(x, y, 0xFF);
|
||||
return uf::simd::vector<float,4>( result )[0];
|
||||
_mm_store_ss(&res, result);
|
||||
return res;
|
||||
// return uf::simd::vector<float,4>( result )[0];
|
||||
#elif SSE_INSTR_SET >= 3
|
||||
__m128 mulRes = _mm_mul_ps(x, y);
|
||||
__m128 shufReg = _mm_movehdup_ps(mulRes);
|
||||
@ -155,13 +158,13 @@ inline float /*UF_API*/ uf::simd::dot( uf::simd::value<float> x, uf::simd::value
|
||||
inline uf::simd::value<int32_t> /*UF_API*/ uf::simd::load( const int32_t* f ) {
|
||||
#if SSE_INSTR_SET >= 3
|
||||
#if UF_VECTOR_ALIGNED
|
||||
return _mm_load_si128(f);
|
||||
return _mm_load_si128((__m128i*) f);
|
||||
#else
|
||||
if ( uf::aligned(f, 16) ) return _mm_load_si128(f);
|
||||
if ( uf::aligned(f, 16) ) return _mm_load_si128((__m128i*) f);
|
||||
|
||||
alignas(16) int32_t s[4];
|
||||
memcpy( &s[0], f, sizeof(int32_t) * 4 );
|
||||
return _mm_load_si128(s);
|
||||
return _mm_load_si128((__m128i*) s);
|
||||
#endif
|
||||
#else
|
||||
return uf::simd::value<int32_t>( f[0], f[1], f[2], f[3] );
|
||||
@ -170,12 +173,12 @@ inline uf::simd::value<int32_t> /*UF_API*/ uf::simd::load( const int32_t* f ) {
|
||||
inline void /*UF_API*/ uf::simd::store( uf::simd::value<int32_t> v, int32_t* f ) {
|
||||
#if SSE_INSTR_SET >= 3
|
||||
#if UF_VECTOR_ALIGNED
|
||||
return _mm_store_si128(f, v);
|
||||
return _mm_store_si128((__m128i*) f, v);
|
||||
#else
|
||||
if ( uf::aligned(f, 16) ) return _mm_store_si128(f, v);
|
||||
if ( uf::aligned(f, 16) ) return _mm_store_si128((__m128i*) f, v);
|
||||
|
||||
alignas(16) int32_t s[4];
|
||||
_mm_store_si128(&s[0], v);
|
||||
_mm_store_si128((__m128i*) &s[0], v);
|
||||
memcpy( f, &s[0], sizeof(int32_t) * 4 );
|
||||
#endif
|
||||
#else
|
||||
@ -246,13 +249,13 @@ inline int32_t /*UF_API*/ uf::simd::dot( uf::simd::value<int32_t> x, uf::simd::v
|
||||
inline uf::simd::value<uint32_t> /*UF_API*/ uf::simd::load( const uint32_t* f ) {
|
||||
#if SSE_INSTR_SET >= 3
|
||||
#if UF_VECTOR_ALIGNED
|
||||
return _mm_load_si128(f);
|
||||
return _mm_load_si128((__m128i*) f);
|
||||
#else
|
||||
if ( uf::aligned(f, 16) ) return _mm_load_si128(f);
|
||||
if ( uf::aligned(f, 16) ) return _mm_load_si128((__m128i*) f);
|
||||
|
||||
alignas(16) uint32_t s[4];
|
||||
memcpy( &s[0], f, sizeof(uint32_t) * 4 );
|
||||
return _mm_load_si128(s);
|
||||
return _mm_load_si128((__m128i*) &s[0]);
|
||||
#endif
|
||||
#else
|
||||
return uf::simd::value<uint32_t>( f[0], f[1], f[2], f[3] );
|
||||
@ -261,12 +264,12 @@ inline uf::simd::value<uint32_t> /*UF_API*/ uf::simd::load( const uint32_t* f )
|
||||
inline void /*UF_API*/ uf::simd::store( uf::simd::value<uint32_t> v, uint32_t* f ) {
|
||||
#if SSE_INSTR_SET >= 3
|
||||
#if UF_VECTOR_ALIGNED
|
||||
return _mm_store_si128(f, v);
|
||||
return _mm_store_si128((__m128i*) f, v);
|
||||
#else
|
||||
if ( uf::aligned(f, 16) ) return _mm_store_si128(f, v);
|
||||
if ( uf::aligned(f, 16) ) return _mm_store_si128((__m128i*) f, v);
|
||||
|
||||
alignas(16) uint32_t s[4];
|
||||
_mm_store_si128(&s[0], v);
|
||||
_mm_store_si128((__m128i*) &s[0], v);
|
||||
memcpy( f, &s[0], sizeof(uint32_t) * 4 );
|
||||
#endif
|
||||
#else
|
||||
|
@ -15,8 +15,10 @@ namespace uf {
|
||||
uf::stl::unordered_map<Key, size_t> indices;
|
||||
|
||||
T& operator[]( const Key& key );
|
||||
|
||||
void reserve( size_t i );
|
||||
uf::stl::vector<T> flatten() const;
|
||||
void clear();
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -38,6 +40,13 @@ void uf::stl::KeyMap<T,Key>::reserve( size_t i ) {
|
||||
map.reserve(i);
|
||||
}
|
||||
|
||||
template<typename T, typename Key>
|
||||
void uf::stl::KeyMap<T,Key>::clear() {
|
||||
keys.clear();
|
||||
indices.clear();
|
||||
map.clear();
|
||||
}
|
||||
|
||||
template<typename T, typename Key>
|
||||
uf::stl::vector<T> uf::stl::KeyMap<T,Key>::flatten() const {
|
||||
uf::stl::vector<T> res; res.reserve(keys.size());
|
||||
|
@ -91,7 +91,7 @@ namespace uf {
|
||||
pod::Thread& UF_API get( const uf::stl::string& );
|
||||
|
||||
bool UF_API isMain();
|
||||
pod::Thread& currentThread();
|
||||
pod::Thread& UF_API currentThread();
|
||||
|
||||
/* Acts on thread */
|
||||
void UF_API start( pod::Thread& );
|
||||
|
BIN
engine/lib/win64/zig/libalut.pdb
Normal file
BIN
engine/lib/win64/zig/libalut.pdb
Normal file
Binary file not shown.
@ -264,8 +264,8 @@ uf::stl::string uf::Asset::load(const uf::Asset::Payload& payload ) {
|
||||
asset = uf::graph::load( filename, metadata[payload.filename] );
|
||||
uf::graph::process( asset );
|
||||
#if !UF_ENV_DREAMCAST
|
||||
if ( asset.metadata["debug"]["print stats"].as<bool>() ) UF_MSG_INFO("{}", uf::graph::stats( asset ));
|
||||
if ( asset.metadata["debug"]["print tree"].as<bool>() ) UF_MSG_INFO("{}", uf::graph::print( asset ));
|
||||
if ( asset.metadata["debug"]["print"]["stats"].as<bool>() ) UF_MSG_INFO("{}", uf::graph::stats( asset ));
|
||||
if ( asset.metadata["debug"]["print"]["tree"].as<bool>() ) UF_MSG_INFO("{}", uf::graph::print( asset ));
|
||||
#endif
|
||||
if ( !asset.metadata["debug"]["no cleanup"].as<bool>() ) uf::graph::cleanup( asset );
|
||||
} break;
|
||||
|
@ -259,6 +259,44 @@ namespace {
|
||||
|
||||
mesh.updateDescriptor();
|
||||
|
||||
#if 0
|
||||
// swap winding order
|
||||
if ( graph.metadata["decode"]["invert winding order"].as<bool>() ) {
|
||||
if ( mesh.index.count ) {
|
||||
uf::Mesh::Attribute indexAttribute = mesh.index.attributes.front();
|
||||
size_t tri[3];
|
||||
for ( size_t i = 0; i < mesh.index.count / 3; ++i ) {
|
||||
switch ( mesh.index.size ) {
|
||||
case sizeof(uint8_t): {
|
||||
uint8_t* pointer = (uint8_t*) (indexAttribute.pointer);
|
||||
tri[0] = pointer[i * 3 + 0];
|
||||
tri[2] = pointer[i * 3 + 2];
|
||||
|
||||
pointer[i * 3 + 0] = tri[2];
|
||||
pointer[i * 3 + 2] = tri[0];
|
||||
} break;
|
||||
case sizeof(uint16_t): {
|
||||
uint16_t* pointer = (uint16_t*) (indexAttribute.pointer);
|
||||
tri[0] = pointer[i * 3 + 0];
|
||||
tri[2] = pointer[i * 3 + 2];
|
||||
|
||||
pointer[i * 3 + 0] = tri[2];
|
||||
pointer[i * 3 + 2] = tri[0];
|
||||
} break;
|
||||
case sizeof(uint32_t): {
|
||||
uint32_t* pointer = (uint32_t*) (indexAttribute.pointer);
|
||||
tri[0] = pointer[i * 3 + 0];
|
||||
tri[2] = pointer[i * 3 + 2];
|
||||
|
||||
pointer[i * 3 + 0] = tri[2];
|
||||
pointer[i * 3 + 2] = tri[0];
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
@ -302,7 +340,18 @@ pod::Graph uf::graph::load( const uf::stl::string& filename, const uf::Serialize
|
||||
serializer.readFromFile( filename );
|
||||
// load metadata
|
||||
graph.name = filename; //serializer["name"].as<uf::stl::string>();
|
||||
graph.metadata = metadata; // serializer["metadata"];
|
||||
// graph.metadata = metadata; // serializer["metadata"];
|
||||
|
||||
// UF_MSG_DEBUG("A: {}", serializer["metadata"].dump(1, '\t'));
|
||||
// UF_MSG_DEBUG("B: {}", metadata.dump(1, '\t'));
|
||||
#if 0
|
||||
graph.metadata = serializer["metadata"];
|
||||
graph.metadata.merge( metadata, false );
|
||||
#else
|
||||
graph.metadata = metadata;
|
||||
graph.metadata.merge( serializer["metadata"], true );
|
||||
#endif
|
||||
// UF_MSG_DEBUG("C: {}", graph.metadata.dump(1, '\t'));
|
||||
|
||||
#if UF_GRAPH_LOAD_MULTITHREAD
|
||||
auto tasks = uf::thread::schedule(true);
|
||||
|
@ -250,15 +250,7 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
|
||||
if ( settings.compression == "auto" ) settings.compression = ext::json::PREFERRED_COMPRESSION;
|
||||
|
||||
if ( !settings.combined ) uf::io::mkdir(directory);
|
||||
#if UF_USE_XATLAS
|
||||
/*
|
||||
if ( settings.unwrap ) {
|
||||
pod::Graph& g = const_cast<pod::Graph&>(graph);
|
||||
auto size = ext::xatlas::unwrap( g );
|
||||
serializer["wrapped"] = uf::vector::encode( size );
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
serializer["metadata"] = graph.metadata;
|
||||
|
||||
#if UF_GRAPH_LOAD_MULTITHREAD
|
||||
auto tasks = uf::thread::schedule(true);
|
||||
|
@ -12,6 +12,20 @@
|
||||
|
||||
namespace {
|
||||
bool newGraphAdded = true;
|
||||
|
||||
ext::json::Value findTag( const uf::stl::string& tagName, const ext::json::Value& tags ) {
|
||||
ext::json::Value tag = ext::json::null();
|
||||
ext::json::forEach( tags, [&]( const uf::stl::string& key, const ext::json::Value& value ) {
|
||||
if ( uf::string::isRegex( key ) ) {
|
||||
if ( !uf::string::matched( tagName, key ) ) return;
|
||||
} else if ( tagName != key ) return;
|
||||
tag = value;
|
||||
});
|
||||
return tag;
|
||||
}
|
||||
ext::json::Value findTag( const uf::stl::string& tagName, pod::Graph& graph ) {
|
||||
return findTag( tagName, graph.metadata["tags"] );
|
||||
}
|
||||
}
|
||||
|
||||
pod::Graph::Storage uf::graph::storage;
|
||||
@ -64,113 +78,181 @@ pod::Node* uf::graph::find( pod::Graph& graph, const uf::stl::string& name ) {
|
||||
}
|
||||
|
||||
void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::Mesh& mesh ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
|
||||
auto& graphic = entity.getComponent<uf::renderer::Graphic>();
|
||||
graphic.initialize();
|
||||
graphic.initializeMesh( mesh );
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
|
||||
auto& graphic = entity.getComponent<uf::renderer::Graphic>();
|
||||
graphic.initialize();
|
||||
graphic.initializeMesh( mesh );
|
||||
|
||||
graphic.device = &uf::renderer::device;
|
||||
graphic.material.device = &uf::renderer::device;
|
||||
graphic.descriptor.frontFace = uf::renderer::enums::Face::CCW;
|
||||
graphic.descriptor.cullMode = !(graph.metadata["flags"]["INVERT"].as<bool>()) ? uf::renderer::enums::CullMode::BACK : uf::renderer::enums::CullMode::FRONT;
|
||||
if ( graph.metadata["cull mode"].is<uf::stl::string>() ) {
|
||||
const auto mode = graph.metadata["cull mode"].as<uf::stl::string>();
|
||||
if ( mode == "back" ) graphic.descriptor.cullMode = uf::renderer::enums::CullMode::BACK;
|
||||
else if ( mode == "front" ) graphic.descriptor.cullMode = uf::renderer::enums::CullMode::FRONT;
|
||||
else if ( mode == "none" ) graphic.descriptor.cullMode = uf::renderer::enums::CullMode::NONE;
|
||||
else if ( mode == "both" ) graphic.descriptor.cullMode = uf::renderer::enums::CullMode::BOTH;
|
||||
graphic.device = &uf::renderer::device;
|
||||
graphic.material.device = &uf::renderer::device;
|
||||
graphic.descriptor.frontFace = uf::renderer::enums::Face::CCW;
|
||||
graphic.descriptor.cullMode = !(graph.metadata["flags"]["INVERT"].as<bool>()) ? uf::renderer::enums::CullMode::BACK : uf::renderer::enums::CullMode::FRONT;
|
||||
|
||||
auto tag = ::findTag( entity.getName(), graph );
|
||||
if ( !ext::json::isObject( tag ) ) {
|
||||
tag["renderer"] = graph.metadata["renderer"];
|
||||
}
|
||||
|
||||
if ( tag["renderer"]["front face"].is<uf::stl::string>() ) {
|
||||
const auto mode = uf::string::lowercase( tag["renderer"]["front face"].as<uf::stl::string>() );
|
||||
if ( mode == "cw" ) graphic.descriptor.frontFace = uf::renderer::enums::Face::CW;
|
||||
else if ( mode == "ccw" ) graphic.descriptor.frontFace = uf::renderer::enums::Face::CCW;
|
||||
else UF_MSG_WARNING("Invalid Face enum string specified: {}", mode);
|
||||
}
|
||||
if ( tag["renderer"]["cull mode"].is<uf::stl::string>() ) {
|
||||
const auto mode = uf::string::lowercase( tag["renderer"]["cull mode"].as<uf::stl::string>() );
|
||||
if ( mode == "back" ) graphic.descriptor.cullMode = uf::renderer::enums::CullMode::BACK;
|
||||
else if ( mode == "front" ) graphic.descriptor.cullMode = uf::renderer::enums::CullMode::FRONT;
|
||||
else if ( mode == "none" ) graphic.descriptor.cullMode = uf::renderer::enums::CullMode::NONE;
|
||||
else if ( mode == "both" ) graphic.descriptor.cullMode = uf::renderer::enums::CullMode::BOTH;
|
||||
else UF_MSG_WARNING("Invalid CullMode enum string specified: {}", mode);
|
||||
}
|
||||
|
||||
{
|
||||
// for ( auto& s : graph.samplers ) graphic.material.samplers.emplace_back( uf::graph::storage.samplers.map[s] );
|
||||
// for ( auto pair : uf::graph::storage.samplers.map ) graphic.material.samplers.emplace_back( pair.second );
|
||||
// for ( auto& key : uf::graph::storage.samplers.keys ) graphic.material.samplers.emplace_back( uf::graph::storage.samplers.map[key] );
|
||||
|
||||
// for ( auto& i : graph.images ) graphic.material.textures.emplace_back().aliasTexture( uf::graph::storage.texture2Ds.map[i] );
|
||||
// for ( auto pair : uf::graph::storage.texture2Ds.map ) graphic.material.textures.emplace_back().aliasTexture( pair.second );
|
||||
for ( auto& key : uf::graph::storage.texture2Ds.keys ) graphic.material.textures.emplace_back().aliasTexture( uf::graph::storage.texture2Ds.map[key] );
|
||||
|
||||
// bind scene's voxel texture
|
||||
if ( uf::renderer::settings::pipelines::vxgi ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
|
||||
for ( auto& t : sceneTextures.voxels.id ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normal ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.uv ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.depth ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
}
|
||||
{
|
||||
// for ( auto& s : graph.samplers ) graphic.material.samplers.emplace_back( uf::graph::storage.samplers.map[s] );
|
||||
// for ( auto pair : uf::graph::storage.samplers.map ) graphic.material.samplers.emplace_back( pair.second );
|
||||
// for ( auto& key : uf::graph::storage.samplers.keys ) graphic.material.samplers.emplace_back( uf::graph::storage.samplers.map[key] );
|
||||
}
|
||||
|
||||
uf::stl::string root = uf::io::directory( graph.name );
|
||||
size_t texture2Ds = 0;
|
||||
size_t texture3Ds = 0;
|
||||
for ( auto& texture : graphic.material.textures ) {
|
||||
if ( texture.width > 1 && texture.height > 1 && texture.depth == 1 && texture.layers == 1 ) ++texture2Ds;
|
||||
else if ( texture.width > 1 && texture.height > 1 && texture.depth > 1 && texture.layers == 1 ) ++texture3Ds;
|
||||
}
|
||||
|
||||
// for ( auto& i : graph.images ) graphic.material.textures.emplace_back().aliasTexture( uf::graph::storage.texture2Ds.map[i] );
|
||||
// for ( auto pair : uf::graph::storage.texture2Ds.map ) graphic.material.textures.emplace_back().aliasTexture( pair.second );
|
||||
for ( auto& key : uf::graph::storage.texture2Ds.keys ) graphic.material.textures.emplace_back().aliasTexture( uf::graph::storage.texture2Ds.map[key] );
|
||||
// standard pipeline
|
||||
uf::stl::string vertexShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/base.vert.spv"); {
|
||||
std::pair<bool, uf::stl::string> settings[] = {
|
||||
{ graph.metadata["flags"]["SKINNED"].as<bool>(), "skinned.vert" },
|
||||
{ !graph.metadata["flags"]["SEPARATE"].as<bool>(), "instanced.vert" },
|
||||
};
|
||||
FOR_ARRAY(settings) if ( settings[i].first ) vertexShaderFilename = uf::string::replace( vertexShaderFilename, "vert", settings[i].second );
|
||||
vertexShaderFilename = entity.resolveURI( vertexShaderFilename, root );
|
||||
}
|
||||
uf::stl::string geometryShaderFilename = graph.metadata["shaders"]["geometry"].as<uf::stl::string>("");
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/base.frag.spv"); {
|
||||
std::pair<bool, uf::stl::string> settings[] = {
|
||||
{ uf::renderer::settings::invariant::deferredSampling, "deferredSampling.frag" },
|
||||
};
|
||||
FOR_ARRAY(settings) if ( settings[i].first ) fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", settings[i].second );
|
||||
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
|
||||
}
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
graphic.material.attachShader(vertexShaderFilename, uf::renderer::enums::Shader::VERTEX);
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT);
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
}
|
||||
|
||||
// bind scene's voxel texture
|
||||
if ( uf::renderer::settings::pipelines::vxgi ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
|
||||
for ( auto& t : sceneTextures.voxels.id ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normal ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.uv ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.depth ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
uf::renderer::Buffer* indirect = NULL;
|
||||
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
|
||||
|
||||
{
|
||||
auto& shader = graphic.material.getShader("vertex");
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
|
||||
// // shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
#if UF_USE_VULKAN
|
||||
shader.buffers.emplace_back( indirect->alias() );
|
||||
#endif
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.joint.alias() );
|
||||
#if UF_USE_VULKAN
|
||||
uint32_t maxPasses = 6;
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "PASSES" ) sc.value.ui = (specializationConstants[sc.index] = maxPasses);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
{
|
||||
auto& shader = graphic.material.getShader("fragment");
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
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() );
|
||||
|
||||
#if UF_USE_VULKAN
|
||||
uint32_t maxTextures = graph.textures.size(); // texture2Ds;
|
||||
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
}
|
||||
}
|
||||
|
||||
uf::stl::string root = uf::io::directory( graph.name );
|
||||
size_t texture2Ds = 0;
|
||||
size_t texture3Ds = 0;
|
||||
for ( auto& texture : graphic.material.textures ) {
|
||||
if ( texture.width > 1 && texture.height > 1 && texture.depth == 1 && texture.layers == 1 ) ++texture2Ds;
|
||||
else if ( texture.width > 1 && texture.height > 1 && texture.depth > 1 && texture.layers == 1 ) ++texture3Ds;
|
||||
}
|
||||
|
||||
// standard pipeline
|
||||
uf::stl::string vertexShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/base.vert.spv"); {
|
||||
std::pair<bool, uf::stl::string> settings[] = {
|
||||
{ graph.metadata["flags"]["SKINNED"].as<bool>(), "skinned.vert" },
|
||||
{ !graph.metadata["flags"]["SEPARATE"].as<bool>(), "instanced.vert" },
|
||||
};
|
||||
FOR_ARRAY(settings) if ( settings[i].first ) vertexShaderFilename = uf::string::replace( vertexShaderFilename, "vert", settings[i].second );
|
||||
vertexShaderFilename = entity.resolveURI( vertexShaderFilename, root );
|
||||
}
|
||||
uf::stl::string geometryShaderFilename = graph.metadata["shaders"]["geometry"].as<uf::stl::string>("");
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/base.frag.spv"); {
|
||||
std::pair<bool, uf::stl::string> settings[] = {
|
||||
{ uf::renderer::settings::invariant::deferredSampling, "deferredSampling.frag" },
|
||||
};
|
||||
FOR_ARRAY(settings) if ( settings[i].first ) fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", settings[i].second );
|
||||
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
|
||||
}
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
graphic.material.attachShader(vertexShaderFilename, uf::renderer::enums::Shader::VERTEX);
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT);
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
#if UF_USE_VULKAN
|
||||
// culling pipeline
|
||||
if ( uf::renderer::settings::pipelines::culling ) {
|
||||
uf::renderer::Buffer* indirect = NULL;
|
||||
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
|
||||
UF_ASSERT( indirect );
|
||||
if ( indirect ) {
|
||||
uf::stl::string compShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/cull.comp.spv");
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
compShaderFilename = entity.resolveURI( compShaderFilename, root );
|
||||
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, uf::renderer::settings::pipelines::names::culling);
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
}
|
||||
graphic.descriptor.inputs.dispatch = { graphic.descriptor.inputs.indirect.count, 1, 1 };
|
||||
|
||||
{
|
||||
auto& shader = graphic.material.getShader("vertex");
|
||||
auto& shader = graphic.material.getShader("compute", uf::renderer::settings::pipelines::names::culling);
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
|
||||
// // shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
#if UF_USE_VULKAN
|
||||
shader.buffers.emplace_back( indirect->alias() );
|
||||
#endif
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.joint.alias() );
|
||||
#if UF_USE_VULKAN
|
||||
uint32_t maxPasses = 6;
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "PASSES" ) sc.value.ui = (specializationConstants[sc.index] = maxPasses);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
|
||||
geometryShaderFilename = entity.resolveURI( geometryShaderFilename, root );
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY);
|
||||
}
|
||||
// depth only pipeline
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/depth.frag.spv");
|
||||
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "depth");
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
{
|
||||
auto& shader = graphic.material.getShader("fragment");
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
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() );
|
||||
|
||||
#if UF_USE_VULKAN
|
||||
uint32_t maxTextures = graph.textures.size(); // texture2Ds;
|
||||
|
||||
auto& shader = graphic.material.getShader("fragment", "depth");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
@ -183,239 +265,185 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
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() );
|
||||
}
|
||||
#if UF_USE_VULKAN
|
||||
// culling pipeline
|
||||
if ( uf::renderer::settings::pipelines::culling ) {
|
||||
uf::renderer::Buffer* indirect = NULL;
|
||||
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
|
||||
UF_ASSERT( indirect );
|
||||
if ( indirect ) {
|
||||
uf::stl::string compShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/cull.comp.spv");
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
compShaderFilename = entity.resolveURI( compShaderFilename, root );
|
||||
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, uf::renderer::settings::pipelines::names::culling);
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
}
|
||||
graphic.descriptor.inputs.dispatch = { graphic.descriptor.inputs.indirect.count, 1, 1 };
|
||||
}
|
||||
// vxgi pipeline
|
||||
if ( uf::renderer::settings::pipelines::vxgi ) {
|
||||
uf::stl::string vertexShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/base.vert.spv");
|
||||
uf::stl::string geometryShaderFilename = graph.metadata["shaders"]["geometry"].as<uf::stl::string>("/graph/voxelize.geom.spv");
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/voxelize.frag.spv");
|
||||
|
||||
auto& shader = graphic.material.getShader("compute", uf::renderer::settings::pipelines::names::culling);
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
|
||||
#if UF_USE_VULKAN
|
||||
shader.buffers.emplace_back( indirect->alias() );
|
||||
#endif
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
|
||||
}
|
||||
{
|
||||
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, uf::renderer::settings::pipelines::names::vxgi);
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
}
|
||||
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
|
||||
geometryShaderFilename = entity.resolveURI( geometryShaderFilename, root );
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY);
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, uf::renderer::settings::pipelines::names::vxgi);
|
||||
}
|
||||
// depth only pipeline
|
||||
{
|
||||
uint32_t voxelTypes = 0;
|
||||
if ( !sceneTextures.voxels.id.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.normal.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.uv.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.radiance.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.depth.empty() ) ++voxelTypes;
|
||||
|
||||
uint32_t maxTextures = texture2Ds;
|
||||
uint32_t maxCascades = texture3Ds / voxelTypes;
|
||||
|
||||
auto& shader = graphic.material.getShader("fragment", uf::renderer::settings::pipelines::names::vxgi);
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures);
|
||||
else if ( sc.name == "CASCADES" ) sc.value.ui = (specializationConstants[sc.index] = maxCascades);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
else if ( tx.name == "voxelId" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelUv" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelNormal" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
|
||||
}
|
||||
}
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
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() );
|
||||
}
|
||||
}
|
||||
// baking pipeline
|
||||
if ( graph.metadata["baking"]["enabled"].as<bool>() ) {
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/depth.frag.spv");
|
||||
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "depth");
|
||||
uf::stl::string vertexShaderFilename = uf::io::resolveURI("/graph/baking/bake.vert.spv");
|
||||
uf::stl::string geometryShaderFilename = uf::io::resolveURI("/graph/baking/bake.geom.spv");
|
||||
uf::stl::string fragmentShaderFilename = uf::io::resolveURI("/graph/baking/bake.frag.spv");
|
||||
graphic.material.attachShader(vertexShaderFilename, uf::renderer::enums::Shader::VERTEX, "baking");
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, "baking");
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "baking");
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
{
|
||||
uint32_t maxTextures = graph.textures.size(); // texture2Ds;
|
||||
|
||||
auto& shader = graphic.material.getShader("fragment", "depth");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
}
|
||||
}
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
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() );
|
||||
}
|
||||
}
|
||||
// vxgi pipeline
|
||||
if ( uf::renderer::settings::pipelines::vxgi ) {
|
||||
uf::stl::string vertexShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/base.vert.spv");
|
||||
uf::stl::string geometryShaderFilename = graph.metadata["shaders"]["geometry"].as<uf::stl::string>("/graph/voxelize.geom.spv");
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/voxelize.frag.spv");
|
||||
|
||||
{
|
||||
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, uf::renderer::settings::pipelines::names::vxgi);
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
}
|
||||
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
|
||||
geometryShaderFilename = entity.resolveURI( geometryShaderFilename, root );
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, uf::renderer::settings::pipelines::names::vxgi);
|
||||
}
|
||||
{
|
||||
uint32_t voxelTypes = 0;
|
||||
if ( !sceneTextures.voxels.id.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.normal.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.uv.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.radiance.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.depth.empty() ) ++voxelTypes;
|
||||
|
||||
uint32_t maxTextures = texture2Ds;
|
||||
uint32_t maxCascades = texture3Ds / voxelTypes;
|
||||
|
||||
auto& shader = graphic.material.getShader("fragment", uf::renderer::settings::pipelines::names::vxgi);
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures);
|
||||
else if ( sc.name == "CASCADES" ) sc.value.ui = (specializationConstants[sc.index] = maxCascades);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
else if ( tx.name == "voxelId" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelUv" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelNormal" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
|
||||
}
|
||||
}
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
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() );
|
||||
}
|
||||
}
|
||||
// baking pipeline
|
||||
if ( graph.metadata["baking"]["enabled"].as<bool>() ) {
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = false;
|
||||
uf::stl::string vertexShaderFilename = uf::io::resolveURI("/graph/baking/bake.vert.spv");
|
||||
uf::stl::string geometryShaderFilename = uf::io::resolveURI("/graph/baking/bake.geom.spv");
|
||||
uf::stl::string fragmentShaderFilename = uf::io::resolveURI("/graph/baking/bake.frag.spv");
|
||||
graphic.material.attachShader(vertexShaderFilename, uf::renderer::enums::Shader::VERTEX, "baking");
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, "baking");
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "baking");
|
||||
graphic.material.metadata.autoInitializeUniformBuffers = true;
|
||||
}
|
||||
{
|
||||
uint32_t maxPasses = 6;
|
||||
|
||||
auto& shader = graphic.material.getShader("vertex", "baking");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "PASSES" ) sc.value.ui = (specializationConstants[sc.index] = maxPasses);
|
||||
}
|
||||
|
||||
// shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
|
||||
// shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
#if UF_USE_VULKAN
|
||||
shader.buffers.emplace_back( indirect->alias() );
|
||||
#endif
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.joint.alias() );
|
||||
}
|
||||
|
||||
{
|
||||
size_t maxTextures = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["2D"].as<size_t>(512);
|
||||
size_t maxCubemaps = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["cube"].as<size_t>(128);
|
||||
size_t maxTextures3D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["3D"].as<size_t>(128);
|
||||
|
||||
auto& shader = graphic.material.getShader("fragment", "baking");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures);
|
||||
else if ( sc.name == "CUBEMAPS" ) sc.value.ui = (specializationConstants[sc.index] = maxCubemaps);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
else if ( tx.name == "samplerCubemaps" ) layout.descriptorCount = maxCubemaps;
|
||||
}
|
||||
}
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
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() );
|
||||
}
|
||||
}
|
||||
// rt pipeline
|
||||
if ( uf::renderer::settings::pipelines::rt ) {
|
||||
graphic.generateBottomAccelerationStructures();
|
||||
}
|
||||
|
||||
// grab addresses
|
||||
{
|
||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer( mesh.indirect ).data();
|
||||
for ( size_t drawID = 0; drawID < mesh.indirect.count; ++drawID ) {
|
||||
auto& drawCommand = drawCommands[drawID];
|
||||
auto instanceID = drawCommand.instanceID;
|
||||
auto instanceKeyName = std::to_string(instanceID);
|
||||
uint32_t maxPasses = 6;
|
||||
|
||||
if ( uf::graph::storage.instanceAddresses.map.count(instanceKeyName) > 0 ) {
|
||||
UF_MSG_DEBUG("DUPLICATE INSTANCE ID");
|
||||
}
|
||||
auto& shader = graphic.material.getShader("vertex", "baking");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "PASSES" ) sc.value.ui = (specializationConstants[sc.index] = maxPasses);
|
||||
}
|
||||
|
||||
auto& instanceAddresses = uf::graph::storage.instanceAddresses.map[instanceKeyName];
|
||||
if ( mesh.vertex.count ) {
|
||||
if ( mesh.isInterleaved( mesh.vertex ) ) {
|
||||
instanceAddresses.vertex = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved).getAddress()/* + (drawCommand.vertexID * mesh.vertex.size)*/;
|
||||
} else {
|
||||
for ( auto& attribute : graphic.descriptor.inputs.vertex.attributes ) {
|
||||
if ( attribute.buffer < 0 ) continue;
|
||||
if ( attribute.descriptor.name == "position" ) instanceAddresses.position = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "uv" ) instanceAddresses.uv = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "color" ) instanceAddresses.color = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "st" ) instanceAddresses.st = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "normal" ) instanceAddresses.normal = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "tangent" ) instanceAddresses.tangent = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "joints" ) instanceAddresses.joints = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "weights" ) instanceAddresses.weights = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "id" ) instanceAddresses.id = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( mesh.index.count ) {
|
||||
if ( mesh.isInterleaved( mesh.index ) ) instanceAddresses.index = graphic.buffers.at(graphic.descriptor.inputs.index.interleaved).getAddress();
|
||||
else instanceAddresses.index = graphic.buffers.at(graphic.descriptor.inputs.index.attributes.front().buffer).getAddress();
|
||||
}
|
||||
// shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
|
||||
// shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
#if UF_USE_VULKAN
|
||||
shader.buffers.emplace_back( indirect->alias() );
|
||||
#endif
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.joint.alias() );
|
||||
}
|
||||
|
||||
if ( mesh.indirect.count ) {
|
||||
if ( mesh.isInterleaved( mesh.indirect ) ) instanceAddresses.indirect = graphic.buffers.at(graphic.descriptor.inputs.indirect.interleaved).getAddress();
|
||||
else instanceAddresses.indirect = graphic.buffers.at(graphic.descriptor.inputs.indirect.attributes.front().buffer).getAddress();
|
||||
{
|
||||
size_t maxTextures = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["2D"].as<size_t>(512);
|
||||
size_t maxCubemaps = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["cube"].as<size_t>(128);
|
||||
size_t maxTextures3D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["3D"].as<size_t>(128);
|
||||
|
||||
instanceAddresses.drawID = drawID;
|
||||
auto& shader = graphic.material.getShader("fragment", "baking");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures);
|
||||
else if ( sc.name == "CUBEMAPS" ) sc.value.ui = (specializationConstants[sc.index] = maxCubemaps);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
else if ( tx.name == "samplerCubemaps" ) layout.descriptorCount = maxCubemaps;
|
||||
}
|
||||
}
|
||||
|
||||
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
|
||||
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() );
|
||||
}
|
||||
#endif
|
||||
|
||||
// uf::instantiator::bind( "GraphBehavior", entity );
|
||||
// uf::instantiator::unbind( "RenderBehavior", entity );
|
||||
|
||||
graphic.process = true;
|
||||
}
|
||||
// rt pipeline
|
||||
if ( uf::renderer::settings::pipelines::rt ) {
|
||||
graphic.generateBottomAccelerationStructures();
|
||||
}
|
||||
|
||||
// grab addresses
|
||||
{
|
||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer( mesh.indirect ).data();
|
||||
for ( size_t drawID = 0; drawID < mesh.indirect.count; ++drawID ) {
|
||||
auto& drawCommand = drawCommands[drawID];
|
||||
auto instanceID = drawCommand.instanceID;
|
||||
auto instanceKeyName = std::to_string(instanceID);
|
||||
|
||||
if ( uf::graph::storage.instanceAddresses.map.count(instanceKeyName) > 0 ) {
|
||||
UF_MSG_DEBUG("DUPLICATE INSTANCE ID");
|
||||
}
|
||||
|
||||
auto& instanceAddresses = uf::graph::storage.instanceAddresses.map[instanceKeyName];
|
||||
if ( mesh.vertex.count ) {
|
||||
if ( mesh.isInterleaved( mesh.vertex ) ) {
|
||||
instanceAddresses.vertex = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved).getAddress()/* + (drawCommand.vertexID * mesh.vertex.size)*/;
|
||||
} else {
|
||||
for ( auto& attribute : graphic.descriptor.inputs.vertex.attributes ) {
|
||||
if ( attribute.buffer < 0 ) continue;
|
||||
if ( attribute.descriptor.name == "position" ) instanceAddresses.position = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "uv" ) instanceAddresses.uv = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "color" ) instanceAddresses.color = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "st" ) instanceAddresses.st = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "normal" ) instanceAddresses.normal = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "tangent" ) instanceAddresses.tangent = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "joints" ) instanceAddresses.joints = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "weights" ) instanceAddresses.weights = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
else if ( attribute.descriptor.name == "id" ) instanceAddresses.id = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( mesh.index.count ) {
|
||||
if ( mesh.isInterleaved( mesh.index ) ) instanceAddresses.index = graphic.buffers.at(graphic.descriptor.inputs.index.interleaved).getAddress();
|
||||
else instanceAddresses.index = graphic.buffers.at(graphic.descriptor.inputs.index.attributes.front().buffer).getAddress();
|
||||
}
|
||||
|
||||
if ( mesh.indirect.count ) {
|
||||
if ( mesh.isInterleaved( mesh.indirect ) ) instanceAddresses.indirect = graphic.buffers.at(graphic.descriptor.inputs.indirect.interleaved).getAddress();
|
||||
else instanceAddresses.indirect = graphic.buffers.at(graphic.descriptor.inputs.indirect.attributes.front().buffer).getAddress();
|
||||
|
||||
instanceAddresses.drawID = drawID;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// uf::instantiator::bind( "GraphBehavior", entity );
|
||||
// uf::instantiator::unbind( "RenderBehavior", entity );
|
||||
|
||||
graphic.process = true;
|
||||
}
|
||||
|
||||
void uf::graph::process( pod::Graph& graph ) {
|
||||
// copy our local storage to global storage
|
||||
@ -451,11 +479,11 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
if ( !sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["useLightmaps"].as<bool>(true) ) {
|
||||
graph.metadata["lightmap"] = false;
|
||||
graph.metadata["lights"]["lightmap"] = false;
|
||||
graph.metadata["baking"]["enabled"] = false;
|
||||
}
|
||||
|
||||
if ( graph.metadata["lightmap"].is<uf::stl::string>() && graph.metadata["lightmap"].as<uf::stl::string>() == "auto" ) {
|
||||
if ( graph.metadata["lights"]["lightmap"].is<uf::stl::string>() && graph.metadata["lights"]["lightmap"].as<uf::stl::string>() == "auto" ) {
|
||||
uint32_t mtime = uf::io::mtime( graph.name );
|
||||
// lightmaps are considered stale if they're older than the graph's source
|
||||
bool stale = false;
|
||||
@ -469,13 +497,13 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
graph.metadata["lightmap"] = !stale;
|
||||
graph.metadata["lights"]["lightmap"] = !stale;
|
||||
}
|
||||
|
||||
|
||||
graph.metadata["baking"]["layers"] = lightmapCount;
|
||||
|
||||
if ( graph.metadata["lightmap"].as<bool>() ) for ( auto& pair : filenames ) {
|
||||
if ( graph.metadata["lights"]["lightmap"].as<bool>() ) for ( auto& pair : filenames ) {
|
||||
auto i = pair.first;
|
||||
auto f = uf::io::sanitize( pair.second, uf::io::directory( graph.name ) );
|
||||
|
||||
@ -496,7 +524,7 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
|
||||
lightmapIDs[i] = textureID;
|
||||
|
||||
graph.metadata["lightmaps"][i] = f;
|
||||
graph.metadata["lights"]["lightmaps"][i] = f;
|
||||
graph.metadata["baking"]["enabled"] = false;
|
||||
|
||||
isSrgb[f] = false;
|
||||
@ -542,11 +570,18 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
auto& image = uf::graph::storage.images[key];
|
||||
auto& texture = uf::graph::storage.texture2Ds[key];
|
||||
if ( !texture.generated() ) {
|
||||
// bool isLightmap = graph.metadata["lightmapped"].as<uf::stl::string>() == key;
|
||||
// auto filter = graph.metadata["filter"].as<uf::stl::string>() == "NEAREST" && !isLightmap ? uf::renderer::enums::Filter::NEAREST : uf::renderer::enums::Filter::LINEAR;
|
||||
// auto filter = uf::renderer::enums::Filter::LINEAR;
|
||||
auto filter = uf::renderer::enums::Filter::LINEAR;
|
||||
auto tag = ::findTag( key, graph );
|
||||
if ( !ext::json::isObject( tag ) ) {
|
||||
tag["renderer"] = graph.metadata["renderer"];
|
||||
}
|
||||
if ( tag["renderer"]["filter"].is<uf::stl::string>() ) {
|
||||
const auto mode = uf::string::lowercase( tag["renderer"]["filter"].as<uf::stl::string>("linear") );
|
||||
if ( mode == "linear" ) filter = uf::renderer::enums::Filter::LINEAR;
|
||||
else if ( mode == "nearest" ) filter = uf::renderer::enums::Filter::NEAREST;
|
||||
else UF_MSG_WARNING("Invalid Filter enum string specified: {}", mode);
|
||||
}
|
||||
|
||||
auto filter = graph.metadata["filter"].as<uf::stl::string>() == "NEAREST" ? uf::renderer::enums::Filter::NEAREST : uf::renderer::enums::Filter::LINEAR;
|
||||
texture.sampler.descriptor.filter.min = filter;
|
||||
texture.sampler.descriptor.filter.mag = filter;
|
||||
texture.srgb = isSrgb.count(key) == 0 ? false : isSrgb[key];
|
||||
@ -681,6 +716,39 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
}
|
||||
}
|
||||
|
||||
// patch materials/textures
|
||||
for ( auto& name : graph.materials ) {
|
||||
auto& material = uf::graph::storage.materials[name];
|
||||
auto tag = ::findTag( name, graph );
|
||||
if ( ext::json::isObject( tag ) ) {
|
||||
material.colorBase = uf::vector::decode( tag["material"]["base"], material.colorBase);
|
||||
material.colorEmissive = uf::vector::decode( tag["material"]["emissive"], material.colorEmissive);
|
||||
material.factorMetallic = tag["material"]["fMetallic"].as(material.factorMetallic);
|
||||
material.factorRoughness = tag["material"]["fRoughness"].as(material.factorRoughness);
|
||||
material.factorOcclusion = tag["material"]["fOcclusion"].as(material.factorOcclusion);
|
||||
material.factorAlphaCutoff = tag["material"]["fAlphaCutoff"].as(material.factorAlphaCutoff);
|
||||
material.indexAlbedo = tag["material"]["iAlbedo"].as(material.indexAlbedo);
|
||||
material.indexNormal = tag["material"]["iNormal"].as(material.indexNormal);
|
||||
material.indexEmissive = tag["material"]["iEmissive"].as(material.indexEmissive);
|
||||
material.indexOcclusion = tag["material"]["iOcclusion"].as(material.indexOcclusion);
|
||||
material.indexMetallicRoughness = tag["material"]["iMetallicRoughness"].as(material.indexMetallicRoughness);
|
||||
|
||||
if ( tag["material"]["modeAlpha"].is<uf::stl::string>() ) {
|
||||
const auto mode = uf::string::lowercase( tag["material"]["modeAlpha"].as<uf::stl::string>() );
|
||||
if ( mode == "opaque" ) material.modeAlpha = 0;
|
||||
else if ( mode == "blend" ) material.modeAlpha = 1;
|
||||
else if ( mode == "mask" ) material.modeAlpha = 2;
|
||||
else UF_MSG_WARNING("Invalid AlphaMode enum string specified: {}", mode);
|
||||
} else {
|
||||
material.modeAlpha = tag["material"]["modeAlpha"].as(material.modeAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( graph.metadata["debug"]["print"]["meshes"].as<bool>() ) for ( auto& name : graph.meshes ) UF_MSG_DEBUG("Mesh: {}", name);
|
||||
if ( graph.metadata["debug"]["print"]["materials"].as<bool>() ) for ( auto& name : graph.materials ) UF_MSG_DEBUG("Material: {}", name);
|
||||
if ( graph.metadata["debug"]["print"]["textures"].as<bool>() ) for ( auto& name : graph.textures ) UF_MSG_DEBUG("Texture: {}", name);
|
||||
|
||||
uf::graph::reload();
|
||||
|
||||
// setup combined mesh if requested
|
||||
@ -756,7 +824,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
// ignore pesky light_Orientation nodes
|
||||
if ( uf::string::split( node.name, "_" ).back() == "Orientation" ) return;
|
||||
// for dreamcast, ignore lights if we're baked
|
||||
if ( graph.metadata["lightmapped"].as<bool>() && graph.metadata["lights"]["disable if lightmapped"].as<bool>(true) ) if ( graph.lights.count(node.name) > 0 ) return;
|
||||
if ( graph.metadata["lights"]["lightmapped"].as<bool>() && graph.metadata["lights"]["disable if lightmapped"].as<bool>(true) ) if ( graph.lights.count(node.name) > 0 ) return;
|
||||
|
||||
|
||||
// create child if requested
|
||||
@ -775,18 +843,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
// on systems where frametime is very, very important, we can set all static nodes to not tick
|
||||
|
||||
// tie to tag
|
||||
ext::json::Value tag = ext::json::null();
|
||||
/*
|
||||
if ( ext::json::isObject( graph.metadata["tags"][node.name] ) ) {
|
||||
tag = graph.metadata["tags"][node.name];
|
||||
}
|
||||
*/
|
||||
ext::json::forEach( graph.metadata["tags"], [&]( const uf::stl::string& key, ext::json::Value& value ) {
|
||||
if ( uf::string::isRegex( key ) ) {
|
||||
if ( !uf::string::matched( node.name, key ) ) return;
|
||||
} else if ( node.name != key ) return;
|
||||
tag = value;
|
||||
});
|
||||
ext::json::Value tag = ::findTag( node.name, graph );
|
||||
if ( ext::json::isObject( tag ) ) {
|
||||
if ( tag["ignore"].as<bool>() ) return;
|
||||
if ( graph.metadata["baking"]["enabled"].as<bool>(false) && !tag["bake"].as<bool>(true) ) return;
|
||||
@ -843,8 +900,13 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
metadataLight[key] = value;
|
||||
});
|
||||
#if !UF_USE_OPENGL
|
||||
if ( !(graph.metadata["lightmapped"].as<bool>() && !(metadataLight["shadows"].as<bool>() || metadataLight["dynamic"].as<bool>())) ) {
|
||||
// {
|
||||
bool should = false;
|
||||
if ( !graph.metadata["lights"]["lightmapped"].as<bool>() ) {
|
||||
should = true;
|
||||
} else if ( metadataLight["shadows"].as<bool>() || metadataLight["dynamic"].as<bool>() ) {
|
||||
should = true;
|
||||
}
|
||||
if ( should ) {
|
||||
auto& metadataJson = entity.getComponent<uf::Serializer>();
|
||||
entity.load("/light.json");
|
||||
// copy
|
||||
@ -931,8 +993,8 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
|
||||
{
|
||||
auto phyziks = tag["physics"];
|
||||
if ( !ext::json::isObject( phyziks ) ) phyziks = metadataJson["system"]["physics"];
|
||||
else metadataJson["system"]["physics"] = phyziks;
|
||||
if ( !ext::json::isObject( phyziks ) ) phyziks = metadataJson["physics"];
|
||||
else metadataJson["physics"] = phyziks;
|
||||
|
||||
if ( ext::json::isObject( phyziks ) ) {
|
||||
uf::stl::string type = phyziks["type"].as<uf::stl::string>();
|
||||
@ -953,8 +1015,8 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
pod::Vector3f center = (max + min) * 0.5f;
|
||||
pod::Vector3f corner = uf::vector::abs(max - min) * 0.5f;
|
||||
|
||||
metadataJson["system"]["physics"]["center"] = uf::vector::encode( center );
|
||||
metadataJson["system"]["physics"]["corner"] = uf::vector::encode( corner );
|
||||
metadataJson["physics"]["center"] = uf::vector::encode( center );
|
||||
metadataJson["physics"]["corner"] = uf::vector::encode( corner );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1130,20 +1192,12 @@ void uf::graph::update( pod::Graph& graph, pod::Node& node ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uf::graph::destroy( pod::Graph& graph ) {
|
||||
#if 0
|
||||
for ( auto& t : graph.textures ) t.texture.destroy();
|
||||
for ( auto& m : graph.meshes ) m.destroy();
|
||||
#endif
|
||||
|
||||
uf::graph::storage.buffers.camera.destroy();
|
||||
uf::graph::storage.buffers.drawCommands.destroy();
|
||||
uf::graph::storage.buffers.instance.destroy();
|
||||
uf::graph::storage.buffers.instanceAddresses.destroy();
|
||||
uf::graph::storage.buffers.joint.destroy();
|
||||
uf::graph::storage.buffers.material.destroy();
|
||||
uf::graph::storage.buffers.texture.destroy();
|
||||
uf::graph::storage.buffers.light.destroy();
|
||||
}
|
||||
|
||||
void uf::graph::initialize() {
|
||||
@ -1237,6 +1291,7 @@ void uf::graph::render() {
|
||||
uf::graph::storage.buffers.camera.update( (const void*) &camera.data().viewport, sizeof(pod::Camera::Viewports) );
|
||||
}
|
||||
void uf::graph::destroy() {
|
||||
// cleanup graphic handles
|
||||
for ( auto pair : uf::graph::storage.texture2Ds.map ) pair.second.destroy();
|
||||
for ( auto& t : uf::graph::storage.shadow2Ds ) t.destroy();
|
||||
for ( auto& t : uf::graph::storage.shadowCubes ) t.destroy();
|
||||
@ -1244,6 +1299,34 @@ void uf::graph::destroy() {
|
||||
for ( auto pair : uf::graph::storage.atlases.map ) pair.second.clear();
|
||||
for ( auto pair : uf::graph::storage.images.map ) pair.second.clear();
|
||||
for ( auto pair : uf::graph::storage.meshes.map ) pair.second.destroy();
|
||||
// cleanup storage buffers
|
||||
uf::graph::storage.buffers.camera.destroy();
|
||||
uf::graph::storage.buffers.drawCommands.destroy();
|
||||
uf::graph::storage.buffers.instance.destroy();
|
||||
uf::graph::storage.buffers.instanceAddresses.destroy();
|
||||
uf::graph::storage.buffers.joint.destroy();
|
||||
uf::graph::storage.buffers.material.destroy();
|
||||
uf::graph::storage.buffers.texture.destroy();
|
||||
uf::graph::storage.buffers.light.destroy();
|
||||
|
||||
// cleanup storage cache
|
||||
uf::graph::storage.instances.clear();
|
||||
uf::graph::storage.instanceAddresses.clear();
|
||||
uf::graph::storage.primitives.clear();
|
||||
uf::graph::storage.drawCommands.clear();
|
||||
uf::graph::storage.meshes.clear();
|
||||
uf::graph::storage.images.clear();
|
||||
uf::graph::storage.materials.clear();
|
||||
uf::graph::storage.textures.clear();
|
||||
uf::graph::storage.samplers.clear();
|
||||
uf::graph::storage.skins.clear();
|
||||
uf::graph::storage.animations.clear();
|
||||
uf::graph::storage.atlases.clear();
|
||||
uf::graph::storage.joints.clear();
|
||||
uf::graph::storage.texture2Ds.clear();
|
||||
uf::graph::storage.entities.clear();
|
||||
uf::graph::storage.shadow2Ds.clear();
|
||||
uf::graph::storage.shadowCubes.clear();
|
||||
}
|
||||
void uf::graph::reload() {
|
||||
::newGraphAdded = true;
|
||||
|
@ -101,25 +101,25 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
|
||||
metadata.deserialize(self, metadataJson);
|
||||
|
||||
if ( ext::json::isObject(metadataJson["system"]["physics"]) ) {
|
||||
if ( ext::json::isObject(metadataJson["physics"]) ) {
|
||||
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||
collider.stats.flags = metadataJson["system"]["physics"]["flags"].as(collider.stats.flags);
|
||||
collider.stats.mass = metadataJson["system"]["physics"]["mass"].as(collider.stats.mass);
|
||||
collider.stats.restitution = metadataJson["system"]["physics"]["restitution"].as(collider.stats.restitution);
|
||||
collider.stats.friction = metadataJson["system"]["physics"]["friction"].as(collider.stats.friction);
|
||||
collider.stats.inertia = uf::vector::decode( metadataJson["system"]["physics"]["inertia"], collider.stats.inertia );
|
||||
collider.stats.gravity = uf::vector::decode( metadataJson["system"]["physics"]["gravity"], collider.stats.gravity );
|
||||
collider.stats.flags = metadataJson["physics"]["flags"].as(collider.stats.flags);
|
||||
collider.stats.mass = metadataJson["physics"]["mass"].as(collider.stats.mass);
|
||||
collider.stats.restitution = metadataJson["physics"]["restitution"].as(collider.stats.restitution);
|
||||
collider.stats.friction = metadataJson["physics"]["friction"].as(collider.stats.friction);
|
||||
collider.stats.inertia = uf::vector::decode( metadataJson["physics"]["inertia"], collider.stats.inertia );
|
||||
collider.stats.gravity = uf::vector::decode( metadataJson["physics"]["gravity"], collider.stats.gravity );
|
||||
|
||||
if ( metadataJson["system"]["physics"]["type"].as<uf::stl::string>() == "bounding box" ) {
|
||||
pod::Vector3f center = uf::vector::decode( metadataJson["system"]["physics"]["center"], pod::Vector3f{} );
|
||||
pod::Vector3f corner = uf::vector::decode( metadataJson["system"]["physics"]["corner"], pod::Vector3f{0.5, 0.5, 0.5} );
|
||||
if ( metadataJson["physics"]["type"].as<uf::stl::string>() == "bounding box" ) {
|
||||
pod::Vector3f center = uf::vector::decode( metadataJson["physics"]["center"], pod::Vector3f{} );
|
||||
pod::Vector3f corner = uf::vector::decode( metadataJson["physics"]["corner"], pod::Vector3f{0.5, 0.5, 0.5} );
|
||||
|
||||
if ( metadataJson["system"]["physics"]["recenter"].as<bool>(true) ) collider.transform.position = (center - transform.position);
|
||||
if ( metadataJson["physics"]["recenter"].as<bool>(true) ) collider.transform.position = (center - transform.position);
|
||||
|
||||
uf::physics::impl::create( *this, corner );
|
||||
} else if ( metadataJson["system"]["physics"]["type"].as<uf::stl::string>() == "capsule" ) {
|
||||
float radius = metadataJson["system"]["physics"]["radius"].as<float>();
|
||||
float height = metadataJson["system"]["physics"]["height"].as<float>();
|
||||
} else if ( metadataJson["physics"]["type"].as<uf::stl::string>() == "capsule" ) {
|
||||
float radius = metadataJson["physics"]["radius"].as<float>();
|
||||
float height = metadataJson["physics"]["height"].as<float>();
|
||||
|
||||
uf::physics::impl::create( *this, radius, height );
|
||||
}
|
||||
@ -128,7 +128,9 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
void uf::ObjectBehavior::destroy( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
|
||||
for ( auto pair : metadata.hooks.bound ) {
|
||||
for ( auto id : pair.second ) uf::hooks.removeHook(pair.first, id);
|
||||
for ( auto id : pair.second ) {
|
||||
uf::hooks.removeHook(pair.first, id);
|
||||
}
|
||||
}
|
||||
|
||||
if ( this->hasComponent<uf::Audio>() ) {
|
||||
|
@ -224,22 +224,6 @@ bool uf::Object::load( const uf::Serializer& _json ) {
|
||||
physics.linear.acceleration = uf::vector::decode( json["physics"]["linear"]["acceleration"], physics.linear.acceleration );
|
||||
physics.rotational.velocity = uf::vector::decode( json["physics"]["rotational"]["velocity"], physics.rotational.velocity );
|
||||
physics.rotational.acceleration = uf::vector::decode( json["physics"]["rotational"]["acceleration"], physics.rotational.acceleration );
|
||||
|
||||
/*
|
||||
if ( ext::json::isArray( json["physics"]["linear"]["velocity"] ) )
|
||||
for ( size_t j = 0; j < 3; ++j )
|
||||
physics.linear.velocity[j] = json["physics"]["linear"]["velocity"][j].as<float>();
|
||||
if ( ext::json::isArray( json["physics"]["linear"]["acceleration"] ) )
|
||||
for ( size_t j = 0; j < 3; ++j )
|
||||
physics.linear.acceleration[j] = json["physics"]["linear"]["acceleration"][j].as<float>();
|
||||
|
||||
if ( ext::json::isArray( json["physics"]["rotational"]["velocity"] ) )
|
||||
for ( size_t j = 0; j < 4; ++j )
|
||||
physics.rotational.velocity[j] = json["physics"]["rotational"]["velocity"][j].as<float>();
|
||||
if ( ext::json::isArray( json["physics"]["rotational"]["acceleration"] ) )
|
||||
for ( size_t j = 0; j < 4; ++j )
|
||||
physics.rotational.acceleration[j] = json["physics"]["rotational"]["acceleration"][j].as<float>();
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
auto imageID = graph.images.size();
|
||||
auto keyName = graph.images.emplace_back(/*filename + "/" +*/ i.name);
|
||||
auto& image = /*graph.storage*/uf::graph::storage.images[keyName];
|
||||
if ( graph.metadata["exporter"]["image"]["print"].as<bool>() ) {
|
||||
if ( graph.metadata["debug"]["print"]["image"].as<bool>() ) {
|
||||
UF_MSG_DEBUG("Image: {}", i.name );
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
auto samplerID = graph.samplers.size();
|
||||
auto keyName = graph.samplers.emplace_back(/*filename + "/" +*/ s.name);
|
||||
auto& sampler = /*graph.storage*/uf::graph::storage.samplers[keyName];
|
||||
if ( graph.metadata["exporter"]["sampler"]["print"].as<bool>() ) {
|
||||
if ( graph.metadata["debug"]["print"]["sampler"].as<bool>() ) {
|
||||
UF_MSG_DEBUG("Sampler: {}", s.name );
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
auto textureID = graph.textures.size();
|
||||
auto keyName = graph.textures.emplace_back((t.name == "" ? graph.images[t.source] : (/*filename + "/" +*/ t.name)));
|
||||
auto& texture = /*graph.storage*/uf::graph::storage.textures[keyName];
|
||||
if ( graph.metadata["exporter"]["texture"]["print"].as<bool>() ) {
|
||||
if ( graph.metadata["debug"]["print"]["texture"].as<bool>() ) {
|
||||
UF_MSG_DEBUG("Texture: {}", t.name );
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
auto materialID = graph.materials.size();
|
||||
auto keyName = graph.materials.emplace_back(/*filename + "/" +*/ m.name);
|
||||
auto& material = /*graph.storage*/uf::graph::storage.materials[keyName];
|
||||
if ( graph.metadata["exporter"]["material"]["print"].as<bool>() ) {
|
||||
if ( graph.metadata["debug"]["print"]["material"].as<bool>() ) {
|
||||
UF_MSG_DEBUG("Material: {}", m.name );
|
||||
}
|
||||
|
||||
@ -233,14 +233,14 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
material.factorOcclusion = m.occlusionTexture.strength;
|
||||
material.factorAlphaCutoff = m.alphaCutoff;
|
||||
|
||||
const uf::stl::string mode = graph.metadata["alpha mode"].as<uf::stl::string>(m.alphaMode);
|
||||
if ( mode == "OPAQUE" ) material.modeAlpha = 0;
|
||||
else if ( mode == "BLEND" ) material.modeAlpha = 1;
|
||||
else if ( mode == "MASK" ) material.modeAlpha = 2;
|
||||
else UF_MSG_WARNING("Unhandled alpha mode: {}", mode);
|
||||
const auto mode = uf::string::lowercase( graph.metadata["renderer"]["alpha mode"].as<uf::stl::string>(m.alphaMode) );
|
||||
if ( mode == "opaque" ) material.modeAlpha = 0;
|
||||
else if ( mode == "blend" ) material.modeAlpha = 1;
|
||||
else if ( mode == "mask" ) material.modeAlpha = 2;
|
||||
else UF_MSG_WARNING("Invalid AlphaMode enum string specified: {}", mode);
|
||||
|
||||
if ( m.doubleSided && graph.metadata["cull mode"].as<uf::stl::string>() == "auto" ) {
|
||||
graph.metadata["cull mode"] = "none";
|
||||
if ( m.doubleSided && graph.metadata["renderer"]["cull mode"].as<uf::stl::string>() == "auto" ) {
|
||||
graph.metadata["renderer"]["cull mode"] = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -253,7 +253,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
for ( auto& m : model.meshes ) {
|
||||
auto meshID = graph.meshes.size();
|
||||
auto keyName = graph.meshes.emplace_back(/*filename + "/" +*/ m.name);
|
||||
if ( graph.metadata["exporter"]["mesh"]["print"].as<bool>() ) {
|
||||
if ( graph.metadata["debug"]["print"]["mesh"].as<bool>() ) {
|
||||
UF_MSG_DEBUG("Mesh: {}", m.name );
|
||||
}
|
||||
|
||||
@ -299,13 +299,13 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
#define UF_GRAPH_MESH_FORMAT uf::graph::mesh::Skinned, uint32_t
|
||||
#define UF_GRAPH_PROCESS_PRIMITIVES_FULL 1
|
||||
#define UF_GRAPH_GRID 1
|
||||
#include "processPrimitives2.inl"
|
||||
#include "processPrimitives.inl"
|
||||
#undef UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
#undef UF_GRAPH_MESH_FORMAT
|
||||
} else {
|
||||
#define UF_GRAPH_MESH_FORMAT uf::graph::mesh::Base, uint32_t
|
||||
#define UF_GRAPH_PROCESS_PRIMITIVES_FULL 0
|
||||
#include "processPrimitives2.inl"
|
||||
#include "processPrimitives.inl"
|
||||
#undef UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
#undef UF_GRAPH_MESH_FORMAT
|
||||
}
|
||||
@ -320,7 +320,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
auto skinID = graph.skins.size();
|
||||
auto keyName = graph.skins.emplace_back(/*filename + "/" +*/ s.name);
|
||||
auto& skin = /*graph.storage*/uf::graph::storage.skins[keyName];
|
||||
if ( graph.metadata["exporter"]["skin"]["print"].as<bool>() ) {
|
||||
if ( graph.metadata["debug"]["print"]["skin"].as<bool>() ) {
|
||||
UF_MSG_DEBUG("Skin: {}", s.name );
|
||||
}
|
||||
|
||||
@ -357,7 +357,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
auto animationID = graph.animations.size();
|
||||
auto keyName = graph.animations.emplace_back(/*filename + "/" +*/ a.name);
|
||||
auto& animation = /*graph.storage*/uf::graph::storage.animations[keyName];
|
||||
if ( graph.metadata["exporter"]["animation"]["print"].as<bool>() ) {
|
||||
if ( graph.metadata["debug"]["print"]["animation"].as<bool>() ) {
|
||||
UF_MSG_DEBUG("Animation: {}", a.name );
|
||||
}
|
||||
|
||||
@ -417,7 +417,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
{
|
||||
for ( auto& l : model.lights ) {
|
||||
auto& light = graph.lights[l.name];
|
||||
if ( graph.metadata["exporter"]["light"]["print"].as<bool>() ) {
|
||||
if ( graph.metadata["debug"]["print"]["light"].as<bool>() ) {
|
||||
UF_MSG_DEBUG("Light: {}", l.name );
|
||||
}
|
||||
|
||||
@ -524,7 +524,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
// graph.metadata["baking"]["enabled"] = false;
|
||||
|
||||
// disable lightmap loading, 99.999% of the time a previously baked lightmap will not work due to changing STs
|
||||
graph.metadata["lightmap"] = false;
|
||||
graph.metadata["lights"]["lightmapped"] = false;
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
@ -1,7 +1,20 @@
|
||||
struct {
|
||||
struct {
|
||||
bool should = true;
|
||||
size_t corrected{};
|
||||
size_t total{};
|
||||
} windingOrder;
|
||||
} sanitizer;
|
||||
|
||||
if ( graph.metadata["sanitizer"]["winding order"].as<bool>(true) ) {
|
||||
sanitizer.windingOrder.should = true;
|
||||
}
|
||||
|
||||
uf::stl::vector<uf::Meshlet_T<UF_GRAPH_MESH_FORMAT>> meshlets;
|
||||
|
||||
for ( auto& p : m.primitives ) {
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
auto& primitive = primitives.emplace_back();
|
||||
size_t primitiveID = meshlets.size();
|
||||
auto& meshlet = meshlets.emplace_back();
|
||||
|
||||
struct Attribute {
|
||||
uf::stl::string name = "";
|
||||
@ -38,13 +51,13 @@ for ( auto& p : m.primitives ) {
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
|
||||
if ( attribute.name == "POSITION" ) {
|
||||
vertices.resize(accessor.count);
|
||||
primitive.instance.bounds.min = pod::Vector3f{ accessor.minValues[0], accessor.minValues[1], accessor.minValues[2] };
|
||||
primitive.instance.bounds.max = pod::Vector3f{ accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2] };
|
||||
meshlet.vertices.resize(accessor.count);
|
||||
meshlet.primitive.instance.bounds.min = pod::Vector3f{ accessor.minValues[0], accessor.minValues[1], accessor.minValues[2] };
|
||||
meshlet.primitive.instance.bounds.max = pod::Vector3f{ accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2] };
|
||||
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
primitive.instance.bounds.min.x = -primitive.instance.bounds.min.x;
|
||||
primitive.instance.bounds.max.x = -primitive.instance.bounds.max.x;
|
||||
meshlet.primitive.instance.bounds.min.x = -meshlet.primitive.instance.bounds.min.x;
|
||||
meshlet.primitive.instance.bounds.max.x = -meshlet.primitive.instance.bounds.max.x;
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +93,7 @@ for ( auto& p : m.primitives ) {
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < vertices.size(); ++i ) {
|
||||
for ( size_t i = 0; i < meshlet.vertices.size(); ++i ) {
|
||||
#if 0
|
||||
#define ITERATE_ATTRIBUTE( name, member )\
|
||||
memcpy( &vertex.member[0], &attributes[name].buffer[i * attributes[name].components], attributes[name].stride );
|
||||
@ -101,7 +114,7 @@ for ( auto& p : m.primitives ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
auto& vertex = vertices[i];
|
||||
auto& vertex = meshlet.vertices[i];
|
||||
ITERATE_ATTRIBUTE("POSITION", position, 1);
|
||||
ITERATE_ATTRIBUTE("TEXCOORD_0", uv, 1);
|
||||
ITERATE_ATTRIBUTE("COLOR_0", color, 255.0f);
|
||||
@ -123,6 +136,9 @@ for ( auto& p : m.primitives ) {
|
||||
vertex.tangent.x = -vertex.tangent.x;
|
||||
#endif
|
||||
}
|
||||
|
||||
vertex.id.x = primitiveID;
|
||||
vertex.id.y = meshID;
|
||||
}
|
||||
|
||||
if ( p.indices > -1 ) {
|
||||
@ -130,9 +146,9 @@ for ( auto& p : m.primitives ) {
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
auto& buffer = model.buffers[view.buffer];
|
||||
|
||||
indices.reserve( static_cast<uint32_t>(accessor.count) );
|
||||
meshlet.indices.reserve( static_cast<uint32_t>(accessor.count) );
|
||||
|
||||
#define COPY_INDICES() for (size_t index = 0; index < accessor.count; index++) indices.emplace_back(buf[index]);
|
||||
#define COPY_INDICES() for (size_t index = 0; index < accessor.count; index++) meshlet.indices.emplace_back(buf[index]);
|
||||
|
||||
const void* pointer = &(buffer.data[accessor.byteOffset + view.byteOffset]);
|
||||
switch (accessor.componentType) {
|
||||
@ -155,29 +171,113 @@ for ( auto& p : m.primitives ) {
|
||||
#undef COPY_INDICES
|
||||
}
|
||||
|
||||
primitive.instance.materialID = p.material;
|
||||
primitive.instance.primitiveID = primitives.size() - 1;
|
||||
primitive.instance.meshID = meshID;
|
||||
primitive.instance.objectID = 0;
|
||||
meshlet.primitive.instance.materialID = p.material;
|
||||
meshlet.primitive.instance.primitiveID = primitiveID;
|
||||
meshlet.primitive.instance.meshID = meshID;
|
||||
meshlet.primitive.instance.objectID = 0;
|
||||
|
||||
primitive.drawCommand.indices = indices.size();
|
||||
primitive.drawCommand.instances = 1;
|
||||
primitive.drawCommand.indexID = 0;
|
||||
primitive.drawCommand.vertexID = 0;
|
||||
primitive.drawCommand.instanceID = 0;
|
||||
primitive.drawCommand.vertices = vertices.size();
|
||||
meshlet.primitive.drawCommand.indices = meshlet.indices.size();
|
||||
meshlet.primitive.drawCommand.instances = 1;
|
||||
meshlet.primitive.drawCommand.indexID = 0;
|
||||
meshlet.primitive.drawCommand.vertexID = 0;
|
||||
meshlet.primitive.drawCommand.instanceID = 0;
|
||||
meshlet.primitive.drawCommand.vertices = meshlet.vertices.size();
|
||||
|
||||
auto& drawCommand = drawCommands.emplace_back(pod::DrawCommand{
|
||||
.indices = indices.size(),
|
||||
.instances = 1,
|
||||
.indexID = mesh.index.count,
|
||||
.vertexID = mesh.vertex.count,
|
||||
.instanceID = 0,
|
||||
/* detect winding order */ if ( sanitizer.windingOrder.should ) {
|
||||
if ( !meshlet.indices.empty() ) {
|
||||
for ( size_t i = 0; i < meshlet.indices.size() / 3; ++i ) {
|
||||
size_t indices[3] = {
|
||||
meshlet.indices[i * 3 + 0],
|
||||
meshlet.indices[i * 3 + 1],
|
||||
meshlet.indices[i * 3 + 2],
|
||||
};
|
||||
pod::Vector3f triPosition[3] = {
|
||||
meshlet.vertices[indices[0]].position,
|
||||
meshlet.vertices[indices[1]].position,
|
||||
meshlet.vertices[indices[2]].position,
|
||||
};
|
||||
pod::Vector3f normal = meshlet.vertices[indices[0]].normal;
|
||||
pod::Vector3f geomNormal = uf::vector::normalize( uf::vector::cross((triPosition[0] - triPosition[1]), (triPosition[1] - triPosition[2])));
|
||||
|
||||
// negative dot = mismatched winding order
|
||||
if ( uf::vector::dot( normal, geomNormal ) < 0.0f ) {
|
||||
meshlet.indices[i * 3 + 0] = indices[2];
|
||||
meshlet.indices[i * 3 + 2] = indices[0];
|
||||
++sanitizer.windingOrder.corrected;
|
||||
}
|
||||
++sanitizer.windingOrder.total;
|
||||
}
|
||||
} else {
|
||||
for ( size_t i = 0; i < meshlet.vertices.size() / 3; ++i ) {
|
||||
size_t indices[3] = {
|
||||
i * 3 + 0,
|
||||
i * 3 + 1,
|
||||
i * 3 + 2,
|
||||
};
|
||||
pod::Vector3f triPosition[3] = {
|
||||
meshlet.vertices[indices[0]].position,
|
||||
meshlet.vertices[indices[1]].position,
|
||||
meshlet.vertices[indices[2]].position,
|
||||
};
|
||||
pod::Vector3f normal = meshlet.vertices[indices[0]].normal;
|
||||
pod::Vector3f geomNormal = uf::vector::normalize( uf::vector::cross((triPosition[0] - triPosition[1]), (triPosition[1] - triPosition[2])));
|
||||
|
||||
// negative dot = mismatched winding order
|
||||
if ( uf::vector::dot( normal, geomNormal ) < 0.0f ) {
|
||||
meshlet.indices[i * 3 + 0] = indices[2];
|
||||
meshlet.indices[i * 3 + 2] = indices[0];
|
||||
++sanitizer.windingOrder.corrected;
|
||||
}
|
||||
++sanitizer.windingOrder.total;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( sanitizer.windingOrder.should ) {
|
||||
UF_MSG_DEBUG("Winding order correction: {:.3f}%", ( (float) sanitizer.windingOrder.corrected / (float) sanitizer.windingOrder.total ) * 100.0f );
|
||||
if ( sanitizer.windingOrder.corrected * 2 > sanitizer.windingOrder.total ) {
|
||||
UF_MSG_DEBUG("Consider inverting the front face settings for mesh: {}", m.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.vertices = vertices.size(),
|
||||
});
|
||||
if ( meshgrid.grid.divisions.x > 1 || meshgrid.grid.divisions.y > 1 || meshgrid.grid.divisions.z > 1 ) {
|
||||
auto partitioned = uf::meshgrid::partition( meshgrid.grid, meshlets, meshgrid.eps );
|
||||
if ( meshgrid.print ) UF_MSG_DEBUG( "Draw commands: {}: {} -> {} | Partitions: {} -> {}", m.name, meshlets.size(), partitioned.size(),
|
||||
(meshgrid.grid.divisions.x * meshgrid.grid.divisions.y * meshgrid.grid.divisions.z), meshgrid.grid.nodes.size()
|
||||
);
|
||||
meshlets = std::move( partitioned );
|
||||
}
|
||||
|
||||
{
|
||||
size_t indexID = 0;
|
||||
size_t vertexID = 0;
|
||||
|
||||
mesh.bindIndirect<pod::DrawCommand>();
|
||||
mesh.bind<UF_GRAPH_MESH_FORMAT>(false); // default to de-interleaved regardless of requirement (makes things easier)
|
||||
|
||||
mesh.insertVertices(vertices);
|
||||
mesh.insertIndices(indices);
|
||||
for ( auto& meshlet : meshlets ) {
|
||||
auto& drawCommand = drawCommands.emplace_back(pod::DrawCommand{
|
||||
.indices = meshlet.indices.size(),
|
||||
.instances = 1,
|
||||
.indexID = indexID,
|
||||
.vertexID = vertexID,
|
||||
.instanceID = 0,
|
||||
.auxID = meshlet.primitive.drawCommand.auxID,
|
||||
.materialID = meshlet.primitive.drawCommand.materialID,
|
||||
.vertices = meshlet.vertices.size(),
|
||||
});
|
||||
|
||||
primitives.emplace_back( meshlet.primitive );
|
||||
|
||||
indexID += meshlet.indices.size();
|
||||
vertexID += meshlet.vertices.size();
|
||||
|
||||
mesh.insertVertices(meshlet.vertices);
|
||||
mesh.insertIndices(meshlet.indices);
|
||||
}
|
||||
|
||||
mesh.insertIndirects(drawCommands);
|
||||
mesh.updateDescriptor();
|
||||
}
|
@ -1,214 +0,0 @@
|
||||
uf::stl::vector<uf::Meshlet_T<UF_GRAPH_MESH_FORMAT>> meshlets;
|
||||
|
||||
for ( auto& p : m.primitives ) {
|
||||
size_t primitiveID = meshlets.size();
|
||||
auto& meshlet = meshlets.emplace_back();
|
||||
|
||||
struct Attribute {
|
||||
uf::stl::string name = "";
|
||||
size_t components = 0;
|
||||
size_t length = 0;
|
||||
size_t stride = 0;
|
||||
uint8_t* buffer = NULL;
|
||||
|
||||
uf::stl::vector<float> floats;
|
||||
uf::stl::vector<uint8_t> int8s;
|
||||
uf::stl::vector<uint16_t> int16s;
|
||||
uf::stl::vector<uint32_t> int32s;
|
||||
};
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, Attribute> attributes = {
|
||||
{"POSITION", {}},
|
||||
{"TEXCOORD_0", {}},
|
||||
{"COLOR_0", {}},
|
||||
{"NORMAL", {}},
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
{"TANGENT", {}},
|
||||
{"JOINTS_0", {}},
|
||||
{"WEIGHTS_0", {}},
|
||||
#endif
|
||||
};
|
||||
|
||||
for ( auto& kv : attributes ) {
|
||||
auto& attribute = kv.second;
|
||||
attribute.name = kv.first;
|
||||
auto it = p.attributes.find(attribute.name);
|
||||
if ( it == p.attributes.end() ) continue;
|
||||
|
||||
auto& accessor = model.accessors[it->second];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
|
||||
if ( attribute.name == "POSITION" ) {
|
||||
meshlet.vertices.resize(accessor.count);
|
||||
meshlet.primitive.instance.bounds.min = pod::Vector3f{ accessor.minValues[0], accessor.minValues[1], accessor.minValues[2] };
|
||||
meshlet.primitive.instance.bounds.max = pod::Vector3f{ accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2] };
|
||||
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
meshlet.primitive.instance.bounds.min.x = -meshlet.primitive.instance.bounds.min.x;
|
||||
meshlet.primitive.instance.bounds.max.x = -meshlet.primitive.instance.bounds.max.x;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( accessor.componentType ) {
|
||||
case TINYGLTF_COMPONENT_TYPE_BYTE:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buffer = reinterpret_cast<const uint8_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint8_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int8s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_SHORT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buffer = reinterpret_cast<const uint16_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint16_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int16s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_INT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: {
|
||||
auto* buffer = reinterpret_cast<const uint32_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint32_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int32s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_FLOAT: {
|
||||
auto* buffer = reinterpret_cast<const float*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(float);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.floats.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
default: UF_MSG_ERROR("Unsupported component type");
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < meshlet.vertices.size(); ++i ) {
|
||||
#if 0
|
||||
#define ITERATE_ATTRIBUTE( name, member )\
|
||||
memcpy( &vertex.member[0], &attributes[name].buffer[i * attributes[name].components], attributes[name].stride );
|
||||
#else
|
||||
#define ITERATE_ATTRIBUTE( name, member, floatScale )\
|
||||
if ( !attributes[name].int8s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int8s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int16s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int16s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int32s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int32s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].floats.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].floats[i * attributes[name].components + j] * floatScale;\
|
||||
}
|
||||
#endif
|
||||
|
||||
auto& vertex = meshlet.vertices[i];
|
||||
ITERATE_ATTRIBUTE("POSITION", position, 1);
|
||||
ITERATE_ATTRIBUTE("TEXCOORD_0", uv, 1);
|
||||
ITERATE_ATTRIBUTE("COLOR_0", color, 255.0f);
|
||||
ITERATE_ATTRIBUTE("NORMAL", normal, 1);
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
ITERATE_ATTRIBUTE("TANGENT", tangent, 1);
|
||||
ITERATE_ATTRIBUTE("JOINTS_0", joints, 1);
|
||||
ITERATE_ATTRIBUTE("WEIGHTS_0", weights, 1);
|
||||
#endif
|
||||
|
||||
#undef ITERATE_ATTRIBUTE
|
||||
|
||||
// required due to reverse-Z projection matrix flipping the X axis as well
|
||||
// default is to proceed with this
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
vertex.position.x = -vertex.position.x;
|
||||
vertex.normal.x = -vertex.normal.x;
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
vertex.tangent.x = -vertex.tangent.x;
|
||||
#endif
|
||||
}
|
||||
|
||||
vertex.id.x = primitiveID;
|
||||
vertex.id.y = meshID;
|
||||
}
|
||||
|
||||
if ( p.indices > -1 ) {
|
||||
auto& accessor = model.accessors[p.indices];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
auto& buffer = model.buffers[view.buffer];
|
||||
|
||||
meshlet.indices.reserve( static_cast<uint32_t>(accessor.count) );
|
||||
|
||||
#define COPY_INDICES() for (size_t index = 0; index < accessor.count; index++) meshlet.indices.emplace_back(buf[index]);
|
||||
|
||||
const void* pointer = &(buffer.data[accessor.byteOffset + view.byteOffset]);
|
||||
switch (accessor.componentType) {
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT: {
|
||||
auto* buf = static_cast<const uint32_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buf = static_cast<const uint16_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buf = static_cast<const uint8_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef COPY_INDICES
|
||||
}
|
||||
|
||||
meshlet.primitive.instance.materialID = p.material;
|
||||
meshlet.primitive.instance.primitiveID = primitiveID;
|
||||
meshlet.primitive.instance.meshID = meshID;
|
||||
meshlet.primitive.instance.objectID = 0;
|
||||
|
||||
meshlet.primitive.drawCommand.indices = meshlet.indices.size();
|
||||
meshlet.primitive.drawCommand.instances = 1;
|
||||
meshlet.primitive.drawCommand.indexID = 0;
|
||||
meshlet.primitive.drawCommand.vertexID = 0;
|
||||
meshlet.primitive.drawCommand.instanceID = 0;
|
||||
meshlet.primitive.drawCommand.vertices = meshlet.vertices.size();
|
||||
}
|
||||
|
||||
|
||||
if ( meshgrid.grid.divisions.x > 1 || meshgrid.grid.divisions.y > 1 || meshgrid.grid.divisions.z > 1 ) {
|
||||
auto partitioned = uf::meshgrid::partition( meshgrid.grid, meshlets, meshgrid.eps );
|
||||
if ( meshgrid.print ) UF_MSG_DEBUG( "Draw commands: {}: {} -> {} | Partitions: {} -> {}", m.name, meshlets.size(), partitioned.size(),
|
||||
(meshgrid.grid.divisions.x * meshgrid.grid.divisions.y * meshgrid.grid.divisions.z), meshgrid.grid.nodes.size()
|
||||
);
|
||||
meshlets = std::move( partitioned );
|
||||
}
|
||||
|
||||
{
|
||||
size_t indexID = 0;
|
||||
size_t vertexID = 0;
|
||||
|
||||
mesh.bindIndirect<pod::DrawCommand>();
|
||||
mesh.bind<UF_GRAPH_MESH_FORMAT>(false); // default to de-interleaved regardless of requirement (makes things easier)
|
||||
|
||||
for ( auto& meshlet : meshlets ) {
|
||||
auto& drawCommand = drawCommands.emplace_back(pod::DrawCommand{
|
||||
.indices = meshlet.indices.size(),
|
||||
.instances = 1,
|
||||
.indexID = indexID,
|
||||
.vertexID = vertexID,
|
||||
.instanceID = 0,
|
||||
.auxID = meshlet.primitive.drawCommand.auxID,
|
||||
.materialID = meshlet.primitive.drawCommand.materialID,
|
||||
.vertices = meshlet.vertices.size(),
|
||||
});
|
||||
|
||||
primitives.emplace_back( meshlet.primitive );
|
||||
|
||||
indexID += meshlet.indices.size();
|
||||
vertexID += meshlet.vertices.size();
|
||||
|
||||
mesh.insertVertices(meshlet.vertices);
|
||||
mesh.insertIndices(meshlet.indices);
|
||||
}
|
||||
|
||||
mesh.insertIndirects(drawCommands);
|
||||
mesh.updateDescriptor();
|
||||
}
|
@ -91,7 +91,7 @@ namespace {
|
||||
Items.clear();
|
||||
}
|
||||
|
||||
void AddLog(const uf::stl::string &str) { AddLog(str.c_str()); }
|
||||
void AddLog(const uf::stl::string &str) { AddLog("%s", str.c_str()); }
|
||||
void AddLog(const char *fmt, ...) IM_FMTARGS(2) {
|
||||
// FIXME-OPT
|
||||
char buf[1024];
|
||||
|
@ -59,7 +59,7 @@ void ext::lua::onInitialization( const std::function<void()>& function ) {
|
||||
|
||||
namespace binds {
|
||||
namespace hook {
|
||||
void add( const uf::stl::string& name, const sol::function& function ) {
|
||||
void add( const uf::stl::string& name, sol::function function ) {
|
||||
uf::hooks.addHook( name, [function](ext::json::Value& json){
|
||||
sol::table table = ext::lua::state["json"]["decode"]( json.dump() );
|
||||
auto result = function( table );
|
||||
|
@ -87,7 +87,7 @@ namespace binds {
|
||||
self.generateGraph();
|
||||
return true;
|
||||
}
|
||||
uf::Object& findByUid( uf::Object& self, const size_t& index ) {
|
||||
uf::Object& findByUid( uf::Object& self, size_t index ) {
|
||||
auto* pointer = self.findByUid( index );
|
||||
if ( pointer ) return pointer->as<uf::Object>();
|
||||
static uf::Object null;
|
||||
@ -123,7 +123,7 @@ namespace binds {
|
||||
uf::Object& getParent( uf::Object& self ){
|
||||
return self.getParent().as<uf::Object>();
|
||||
}
|
||||
void addHook( uf::Object& self, const uf::stl::string& name, const sol::function& function ) {
|
||||
void addHook( uf::Object& self, const uf::stl::string& name, sol::function function ) {
|
||||
self.addHook( name, [function](ext::json::Value& json){
|
||||
uf::stl::string payload = json.dump();
|
||||
auto decoded = ext::lua::decode( payload );
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <uf/utils/math/quaternion.h>
|
||||
|
||||
namespace binds {
|
||||
float index( const pod::Quaternion<>& self, const size_t& index ) {
|
||||
float index( const pod::Quaternion<>& self, size_t index ) {
|
||||
return self[index];
|
||||
}
|
||||
pod::Quaternion<> lookAt( const pod::Vector3f& at, const pod::Vector3f& up ) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
namespace binds {
|
||||
namespace v3f {
|
||||
float index( const pod::Vector3f& self, const size_t& index ) {
|
||||
float index( const pod::Vector3f& self, size_t index ) {
|
||||
return self[index];
|
||||
}
|
||||
float distance( pod::Vector3f& self, const pod::Vector3f& other ) {
|
||||
@ -45,7 +45,7 @@ namespace binds {
|
||||
}
|
||||
}
|
||||
namespace v4f {
|
||||
float index( const pod::Vector4f& self, const size_t& index ) {
|
||||
float index( const pod::Vector4f& self, size_t index ) {
|
||||
return self[index];
|
||||
}
|
||||
float distance( pod::Vector4f& self, const pod::Vector4f& other ) {
|
||||
|
@ -300,7 +300,7 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
GL_ERROR_CHECK(glEnable(drawInfo.textures.primary.viewType));
|
||||
GL_ERROR_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
GL_ERROR_CHECK(glBindTexture(drawInfo.textures.primary.viewType, drawInfo.textures.primary.image));
|
||||
GL_ERROR_CHECK(glTexCoordPointer(2, GL_FLOAT, drawInfo.attributes.uv.stride, (drawInfo.attributes.uv.pointer + drawInfo.attributes.uv.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
GL_ERROR_CHECK(glTexCoordPointer(2, GL_FLOAT, drawInfo.attributes.uv.stride, (static_cast<uint8_t*>(drawInfo.attributes.uv.pointer) + drawInfo.attributes.uv.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
|
||||
if ( !(drawInfo.textures.secondary.image && drawInfo.attributes.st.pointer) ) {
|
||||
GL_ERROR_CHECK(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
|
||||
@ -314,23 +314,23 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
GL_ERROR_CHECK(glBindTexture(drawInfo.textures.secondary.viewType, drawInfo.textures.secondary.image));
|
||||
GL_ERROR_CHECK(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
|
||||
|
||||
GL_ERROR_CHECK(glTexCoordPointer(2, GL_FLOAT, drawInfo.attributes.st.stride, (drawInfo.attributes.st.pointer + drawInfo.attributes.st.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
GL_ERROR_CHECK(glTexCoordPointer(2, GL_FLOAT, drawInfo.attributes.st.stride, (static_cast<uint8_t*>(drawInfo.attributes.st.pointer) + drawInfo.attributes.st.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
}
|
||||
}
|
||||
|
||||
if ( drawInfo.attributes.normal.pointer ) GL_ERROR_CHECK(glNormalPointer(GL_FLOAT, drawInfo.attributes.normal.stride, (drawInfo.attributes.normal.pointer + drawInfo.attributes.normal.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
if ( drawInfo.attributes.normal.pointer ) GL_ERROR_CHECK(glNormalPointer(GL_FLOAT, drawInfo.attributes.normal.stride, (static_cast<uint8_t*>(drawInfo.attributes.normal.pointer) + drawInfo.attributes.normal.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
if ( drawInfo.attributes.color.pointer ) {
|
||||
GLenum format = GL_UNSIGNED_BYTE;
|
||||
switch ( drawInfo.attributes.color.descriptor.size / drawInfo.attributes.color.descriptor.components ) {
|
||||
case sizeof(uint8_t): format = GL_UNSIGNED_BYTE; break;
|
||||
case sizeof(float): format = GL_FLOAT; break;
|
||||
}
|
||||
GL_ERROR_CHECK(glColorPointer(drawInfo.attributes.color.descriptor.components, format, drawInfo.attributes.color.stride, (drawInfo.attributes.color.pointer + drawInfo.attributes.color.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
GL_ERROR_CHECK(glColorPointer(drawInfo.attributes.color.descriptor.components, format, drawInfo.attributes.color.stride, (static_cast<uint8_t*>(drawInfo.attributes.color.pointer) + drawInfo.attributes.color.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
}
|
||||
GL_ERROR_CHECK(glVertexPointer(3, GL_FLOAT, drawInfo.attributes.position.stride, (drawInfo.attributes.position.pointer + drawInfo.attributes.position.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
GL_ERROR_CHECK(glVertexPointer(3, GL_FLOAT, drawInfo.attributes.position.stride, (static_cast<uint8_t*>(drawInfo.attributes.position.pointer) + drawInfo.attributes.position.stride * drawInfo.descriptor.inputs.vertex.first)));
|
||||
|
||||
if ( drawInfo.descriptor.inputs.index.count ) {
|
||||
GL_ERROR_CHECK(glDrawElements(GL_TRIANGLES, drawInfo.descriptor.inputs.index.count, indicesType, (drawInfo.attributes.index.pointer + drawInfo.attributes.index.stride * drawInfo.descriptor.inputs.index.first)));
|
||||
GL_ERROR_CHECK(glDrawElements(GL_TRIANGLES, drawInfo.descriptor.inputs.index.count, indicesType, (static_cast<uint8_t*>(drawInfo.attributes.index.pointer) + drawInfo.attributes.index.stride * drawInfo.descriptor.inputs.index.first)));
|
||||
} else {
|
||||
GL_ERROR_CHECK(glDrawArrays(GL_TRIANGLES, drawInfo.descriptor.inputs.vertex.first, drawInfo.descriptor.inputs.vertex.count));
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ bool ext::opengl::settings::invariant::individualPipelines = true;
|
||||
bool ext::opengl::settings::invariant::multithreadedRecording = true;
|
||||
|
||||
uf::stl::string ext::opengl::settings::invariant::deferredMode = "";
|
||||
bool ext::opengl::settings::invariant::deferredReconstructPosition = false;
|
||||
bool ext::opengl::settings::invariant::deferredAliasOutputToSwapchain = false;
|
||||
bool ext::opengl::settings::invariant::deferredSampling = false;
|
||||
|
||||
|
@ -20,16 +20,21 @@ namespace {
|
||||
class RaycastCallback : public rp3d::RaycastCallback {
|
||||
public:
|
||||
bool isHit = false;
|
||||
uf::Object* source = NULL;
|
||||
rp3d::RaycastInfo raycastInfo;
|
||||
|
||||
virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& info) override {
|
||||
if ( !isHit || raycastInfo.hitFraction > info.hitFraction ) {
|
||||
raycastInfo.body = info.body;
|
||||
raycastInfo.hitFraction = info.hitFraction;
|
||||
raycastInfo.collider = info.collider;
|
||||
raycastInfo.worldNormal = info.worldNormal;
|
||||
raycastInfo.worldPoint = info.worldPoint;
|
||||
isHit = true;
|
||||
if ( info.body->getUserData() == source ) {
|
||||
|
||||
} else {
|
||||
raycastInfo.body = info.body;
|
||||
raycastInfo.hitFraction = info.hitFraction;
|
||||
raycastInfo.collider = info.collider;
|
||||
raycastInfo.worldNormal = info.worldNormal;
|
||||
raycastInfo.worldPoint = info.worldPoint;
|
||||
isHit = true;
|
||||
}
|
||||
}
|
||||
// return rp3d::decimal(1.0);
|
||||
return raycastInfo.hitFraction;
|
||||
@ -295,6 +300,9 @@ void ext::reactphysics::attach( pod::PhysicsState& state ) {
|
||||
state.body->enableGravity(false);
|
||||
}
|
||||
|
||||
// affects air speed, bad
|
||||
// state.body->setLinearDamping(state.stats.friction);
|
||||
|
||||
auto& material = collider->getMaterial();
|
||||
material.setBounciness(0);
|
||||
|
||||
@ -316,13 +324,18 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const uf::Mesh
|
||||
uf::Mesh::Input indexInput = mesh.index;
|
||||
|
||||
uf::Mesh::Attribute vertexAttribute = mesh.vertex.attributes.front();
|
||||
uf::Mesh::Attribute normalAttribute = 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; }
|
||||
for ( auto& attribute : mesh.vertex.attributes ) {
|
||||
if ( attribute.descriptor.name == "position" ) vertexAttribute = attribute;
|
||||
if ( attribute.descriptor.name == "normal" ) normalAttribute = attribute;
|
||||
}
|
||||
UF_ASSERT( vertexAttribute.descriptor.name == "position" );
|
||||
|
||||
rp3d::TriangleVertexArray::IndexDataType indexType = rp3d::TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE;
|
||||
rp3d::TriangleVertexArray::VertexDataType vertexType = rp3d::TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE;
|
||||
rp3d::TriangleVertexArray::NormalDataType normalType = rp3d::TriangleVertexArray::NormalDataType::NORMAL_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;
|
||||
@ -334,6 +347,57 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const uf::Mesh
|
||||
vertexInput = mesh.remapVertexInput( i );
|
||||
indexInput = mesh.remapIndexInput( i );
|
||||
|
||||
if ( normalAttribute.descriptor.name == "normal" ) {
|
||||
rMesh->addSubpart(new rp3d::TriangleVertexArray(
|
||||
vertexInput.count,
|
||||
(const uint8_t*) (vertexAttribute.pointer) + vertexAttribute.stride * vertexInput.first,
|
||||
vertexAttribute.stride,
|
||||
|
||||
(const uint8_t*) (normalAttribute.pointer) + normalAttribute.stride * vertexInput.first,
|
||||
normalAttribute.stride,
|
||||
|
||||
indexInput.count / 3,
|
||||
(const uint8_t*) (indexAttribute.pointer) + indexAttribute.stride * indexInput.first,
|
||||
indexAttribute.stride * 3,
|
||||
|
||||
vertexType,
|
||||
normalType,
|
||||
indexType
|
||||
));
|
||||
} else {
|
||||
rMesh->addSubpart(new rp3d::TriangleVertexArray(
|
||||
vertexInput.count,
|
||||
(const uint8_t*) (vertexAttribute.pointer) + vertexAttribute.stride * vertexInput.first,
|
||||
vertexAttribute.stride,
|
||||
|
||||
indexInput.count / 3,
|
||||
(const uint8_t*) (indexAttribute.pointer) + indexAttribute.stride * indexInput.first,
|
||||
indexAttribute.stride * 3,
|
||||
|
||||
vertexType,
|
||||
indexType
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( normalAttribute.descriptor.name == "normal" ) {
|
||||
rMesh->addSubpart(new rp3d::TriangleVertexArray(
|
||||
vertexInput.count,
|
||||
(const uint8_t*) (vertexAttribute.pointer) + vertexAttribute.stride * vertexInput.first,
|
||||
vertexAttribute.stride,
|
||||
|
||||
(const uint8_t*) (normalAttribute.pointer) + normalAttribute.stride * vertexInput.first,
|
||||
normalAttribute.stride,
|
||||
|
||||
indexInput.count / 3,
|
||||
(const uint8_t*) (indexAttribute.pointer) + indexAttribute.stride * indexInput.first,
|
||||
indexAttribute.stride * 3,
|
||||
|
||||
vertexType,
|
||||
normalType,
|
||||
indexType
|
||||
));
|
||||
} else {
|
||||
rMesh->addSubpart(new rp3d::TriangleVertexArray(
|
||||
vertexInput.count,
|
||||
(const uint8_t*) (vertexAttribute.pointer) + vertexAttribute.stride * vertexInput.first,
|
||||
@ -347,19 +411,6 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const uf::Mesh
|
||||
indexType
|
||||
));
|
||||
}
|
||||
} else {
|
||||
rMesh->addSubpart(new rp3d::TriangleVertexArray(
|
||||
vertexInput.count,
|
||||
(const uint8_t*) (vertexAttribute.pointer) + vertexAttribute.stride * vertexInput.first,
|
||||
vertexAttribute.stride,
|
||||
|
||||
indexInput.count / 3,
|
||||
(const uint8_t*) (indexAttribute.pointer) + indexAttribute.stride * indexInput.first,
|
||||
indexAttribute.stride * 3,
|
||||
|
||||
vertexType,
|
||||
indexType
|
||||
));
|
||||
}
|
||||
|
||||
auto& state = ext::reactphysics::create( object );
|
||||
@ -512,30 +563,17 @@ float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector
|
||||
return -1;
|
||||
|
||||
::RaycastCallback callback;
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( direction ) ), &callback );
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( center + direction ) ), &callback );
|
||||
if ( !callback.isHit ) return -1;
|
||||
return callback.raycastInfo.hitFraction;
|
||||
}
|
||||
float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction, size_t& uid ) {
|
||||
float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction, uf::Object* source, uf::Object*& object ) {
|
||||
if ( !::world )
|
||||
return -1;
|
||||
|
||||
::RaycastCallback callback;
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( direction ) ), &callback );
|
||||
uid = 0;
|
||||
if ( !callback.isHit ) {
|
||||
return -1;
|
||||
}
|
||||
auto* object = (uf::Object*) callback.raycastInfo.body->getUserData();
|
||||
uid = object->getUid();
|
||||
return callback.raycastInfo.hitFraction;
|
||||
}
|
||||
float ext::reactphysics::rayCast( const pod::Vector3f& center, const pod::Vector3f& direction, uf::Object*& object ) {
|
||||
if ( !::world )
|
||||
return -1;
|
||||
|
||||
::RaycastCallback callback;
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( direction ) ), &callback );
|
||||
callback.source = source;
|
||||
::world->raycast( rp3d::Ray( ::convert( center ), ::convert( center + direction ) ), &callback );
|
||||
object = NULL;
|
||||
if ( !callback.isHit ) {
|
||||
return -1;
|
||||
|
@ -1042,8 +1042,7 @@ void ext::vulkan::Graphic::initializeMesh( uf::Mesh& mesh, bool buffer ) {
|
||||
}
|
||||
}
|
||||
bool ext::vulkan::Graphic::updateMesh( uf::Mesh& mesh ) {
|
||||
UF_MSG_ERROR("need to fix");
|
||||
return false;
|
||||
// UF_MSG_ERROR("need to fix"); return false;
|
||||
|
||||
// generate indices if not found
|
||||
// if ( mesh.index.count == 0 ) mesh.generateIndices();
|
||||
|
@ -46,8 +46,7 @@ bool ext::vulkan::settings::invariant::individualPipelines = true;
|
||||
bool ext::vulkan::settings::invariant::multithreadedRecording = true;
|
||||
|
||||
uf::stl::string ext::vulkan::settings::invariant::deferredMode = "";
|
||||
bool ext::vulkan::settings::invariant::deferredReconstructPosition = false;
|
||||
bool ext::vulkan::settings::invariant::deferredAliasOutputToSwapchain = true;
|
||||
bool ext::vulkan::settings::invariant::deferredAliasOutputToSwapchain = false;
|
||||
bool ext::vulkan::settings::invariant::deferredSampling = true;
|
||||
|
||||
bool ext::vulkan::settings::invariant::multiview = true;
|
||||
|
@ -16,7 +16,7 @@ void uf::Hooks::removeHook( const uf::Hooks::name_t& name, size_t uid ) {
|
||||
auto& container = this->m_container[name];
|
||||
for ( auto it = container.begin(); it != container.end(); ++it ) {
|
||||
if ( it->uid == uid ) {
|
||||
this->m_container[name].erase(it);
|
||||
it = container.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
uf::Http UF_API uf::http::get( const uf::stl::string& url ) {
|
||||
uf::Http uf::http::get( const uf::stl::string& url ) {
|
||||
uf::Http http;
|
||||
|
||||
#if UF_USE_CURL
|
||||
|
@ -160,18 +160,9 @@ void uf::Serializer::merge( const uf::Serializer& other, bool priority ) {
|
||||
|
||||
update(*this, other);
|
||||
}
|
||||
void uf::Serializer::import( const uf::Serializer& other ) {
|
||||
/*
|
||||
uf::Serializer diff = nlohmann::json::diff(*this, other);
|
||||
uf::Serializer filtered;
|
||||
for ( size_t i = 0; i < diff.size(); ++i ) {
|
||||
if ( diff[i]["op"].as<uf::stl::string>() != "remove" )
|
||||
filtered.emplace_back(diff[i]);
|
||||
}
|
||||
patch( filtered );
|
||||
std::cout << this->dump(1, '\t') << std::endl;
|
||||
*/
|
||||
|
||||
// only updates if this[key] == null
|
||||
void uf::Serializer::import( const uf::Serializer& other ) {
|
||||
if ( !ext::json::isObject( *this ) || !ext::json::isObject( other ) ) return;
|
||||
std::function<void(ext::json::Value&, const ext::json::Value&)> update = [&]( ext::json::Value& a, const ext::json::Value& b ) {
|
||||
// doesn't exist, just copy it
|
||||
|
@ -203,17 +203,26 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
stats.noclipped = metadata.system.noclipped;
|
||||
stats.floored = stats.noclipped;
|
||||
auto& collider = this->getComponent<pod::PhysicsState>();
|
||||
if ( !stats.floored && collider.body && uf::physics::impl::rayCast( transform.position, transform.position - pod::Vector3f{0,1,0} ) >= 0.0f ) stats.floored = true;
|
||||
else stats.floored |= fabs(physics.linear.velocity.y) < 0.01f;
|
||||
// if ( !stats.floored && collider.body && uf::physics::impl::rayCast( transform.position, transform.position - pod::Vector3f{0,1,0} ) >= 0.0f ) stats.floored = true;
|
||||
{
|
||||
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 ( metadata.movement.floored.print ) UF_MSG_DEBUG("Floored: {} | {}", hit->getName(), t);
|
||||
stats.floored = true;
|
||||
}
|
||||
}
|
||||
|
||||
TIMER(0.125, keys.use && ) {
|
||||
TIMER(0.25, keys.use && ) {
|
||||
size_t uid = 0;
|
||||
uf::Object* pointer = NULL;
|
||||
float length = 4.0f;
|
||||
pod::Vector3f pos = transform.position + cameraTransform.position;
|
||||
pod::Vector3f dir = uf::vector::normalize( transform.forward + pod::Vector3f{ 0, cameraTransform.forward.y, 0 } ) * length;
|
||||
pod::Vector3f center = transform.position + cameraTransform.position;
|
||||
pod::Vector3f direction = uf::vector::normalize( transform.forward + pod::Vector3f{ 0, cameraTransform.forward.y, 0 } ) * length;
|
||||
|
||||
float depth = uf::physics::impl::rayCast( pos, pos + dir, pointer );
|
||||
float depth = uf::physics::impl::rayCast( center, direction, this, pointer );
|
||||
if ( pointer ) {
|
||||
ext::json::Value payload;
|
||||
payload["uid"] = this->getUid();
|
||||
@ -363,7 +372,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
if ( stats.noclipped ) {
|
||||
physics.linear.velocity += target * speed.move;
|
||||
} else {
|
||||
float delta = collider.body ? uf::physics::impl::timescale : uf::physics::time::delta;
|
||||
// float delta = collider.body ? uf::physics::impl::timescale : uf::physics::time::delta;
|
||||
float delta = uf::physics::time::delta;
|
||||
|
||||
physics.linear.velocity += target * std::clamp( speed.move * factor - uf::vector::dot( physics.linear.velocity, target ), 0.0f, speed.move * 10 * delta );
|
||||
}
|
||||
@ -511,8 +521,8 @@ void ext::PlayerBehavior::render( uf::Object& self ){}
|
||||
void ext::PlayerBehavior::destroy( uf::Object& self ){}
|
||||
void ext::PlayerBehavior::Metadata::serialize( uf::Object& self, uf::Serializer& serializer ){
|
||||
auto& serializerSystem = serializer["system"];
|
||||
auto& serializerSystemPhysics = serializerSystem["physics"];
|
||||
auto& serializerSystemPhysicsMovement = serializerSystemPhysics["movement"];
|
||||
auto& serializerPhysics = serializer["physics"];
|
||||
auto& serializerMovement = serializer["movement"];
|
||||
auto& serializerAudioFootstep = serializer["audio"]["footstep"];
|
||||
auto& serializerCamera = serializer["camera"];
|
||||
auto& serializerCameraLimit = serializerCamera["limit"];
|
||||
@ -521,15 +531,18 @@ void ext::PlayerBehavior::Metadata::serialize( uf::Object& self, uf::Serializer&
|
||||
serializerSystem["control"] = /*this->*/system.control;
|
||||
serializerSystem["crouching"] = /*this->*/system.crouching;
|
||||
serializerSystem["noclipped"] = /*this->*/system.noclipped;
|
||||
serializerSystemPhysics["friction"] = /*this->*/movement.friction;
|
||||
serializerSystemPhysicsMovement["rotate"] = /*this->*/movement.rotate;
|
||||
serializerSystemPhysicsMovement["move"] = /*this->*/movement.move;
|
||||
serializerSystemPhysicsMovement["run"] = /*this->*/movement.run;
|
||||
serializerSystemPhysicsMovement["walk"] = /*this->*/movement.walk;
|
||||
serializerSystemPhysicsMovement["air"] = /*this->*/movement.air;
|
||||
serializerSystemPhysicsMovement["jump"] = uf::vector::encode(/*this->*/movement.jump);
|
||||
serializerSystemPhysicsMovement["crouch"] = /*this->*/movement.crouch;
|
||||
// serializerSystemPhysicsMovement["look"] = /*this->*/movement.look;
|
||||
serializerPhysics["friction"] = /*this->*/movement.friction;
|
||||
serializerMovement["rotate"] = /*this->*/movement.rotate;
|
||||
serializerMovement["move"] = /*this->*/movement.move;
|
||||
serializerMovement["run"] = /*this->*/movement.run;
|
||||
serializerMovement["walk"] = /*this->*/movement.walk;
|
||||
serializerMovement["air"] = /*this->*/movement.air;
|
||||
serializerMovement["jump"] = uf::vector::encode(/*this->*/movement.jump);
|
||||
serializerMovement["floored"]["feet"] = uf::vector::encode(/*this->*/movement.floored.feet);
|
||||
serializerMovement["floored"]["floor"] = uf::vector::encode(/*this->*/movement.floored.floor);
|
||||
serializerMovement["floored"]["print"] = /*this->*/movement.floored.print;
|
||||
serializerMovement["crouch"] = /*this->*/movement.crouch;
|
||||
// serializerMovement["look"] = /*this->*/movement.look;
|
||||
serializerAudioFootstep["list"] = /*this->*/audio.footstep.list;
|
||||
serializerAudioFootstep["volume"] = /*this->*/audio.footstep.volume;
|
||||
serializerCamera["invert"] = uf::vector::encode(/*this->*/camera.invert);
|
||||
@ -540,32 +553,35 @@ void ext::PlayerBehavior::Metadata::serialize( uf::Object& self, uf::Serializer&
|
||||
void ext::PlayerBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ){
|
||||
auto& serializerSystem = serializer["system"];
|
||||
auto& serializerAudioFootstep = serializer["audio"]["footstep"];
|
||||
auto& serializerSystemPhysics = serializerSystem["physics"];
|
||||
auto& serializerSystemPhysicsMovement = serializerSystemPhysics["movement"];
|
||||
auto& serializerPhysics = serializer["physics"];
|
||||
auto& serializerMovement = serializer["movement"];
|
||||
auto& serializerCamera = serializer["camera"];
|
||||
auto& serializerCameraLimit = serializerCamera["limit"];
|
||||
|
||||
/*this->*/system.menu = serializerSystem["menu"].as<uf::stl::string>();
|
||||
/*this->*/system.control = serializerSystem["control"].as<bool>(true);
|
||||
/*this->*/system.crouching = serializerSystem["crouching"].as<bool>();
|
||||
/*this->*/system.noclipped = serializerSystem["noclipped"].as<bool>();
|
||||
/*this->*/movement.friction = serializerSystemPhysics["friction"].as<float>();
|
||||
/*this->*/movement.rotate = serializerSystemPhysicsMovement["rotate"].as<float>();
|
||||
/*this->*/movement.move = serializerSystemPhysicsMovement["move"].as<float>();
|
||||
/*this->*/movement.run = serializerSystemPhysicsMovement["run"].as<float>();
|
||||
/*this->*/movement.walk = serializerSystemPhysicsMovement["walk"].as<float>();
|
||||
/*this->*/movement.air = serializerSystemPhysicsMovement["air"].as<float>();
|
||||
/*this->*/movement.jump = uf::vector::decode(serializerSystemPhysicsMovement["jump"], pod::Vector3f{});
|
||||
/*this->*/movement.crouch = serializerSystemPhysicsMovement["crouch"].as<float>();
|
||||
// /*this->*/movement.look = serializerSystemPhysicsMovement["look"].as<float>(1.0f);
|
||||
/*this->*/system.menu = serializerSystem["menu"].as(/*this->*/system.menu);
|
||||
/*this->*/system.control = serializerSystem["control"].as(/*this->*/system.control);
|
||||
/*this->*/system.crouching = serializerSystem["crouching"].as(/*this->*/system.crouching);
|
||||
/*this->*/system.noclipped = serializerSystem["noclipped"].as(/*this->*/system.noclipped);
|
||||
/*this->*/movement.friction = serializerPhysics["friction"].as(/*this->*/movement.friction);
|
||||
/*this->*/movement.rotate = serializerMovement["rotate"].as(/*this->*/movement.rotate);
|
||||
/*this->*/movement.move = serializerMovement["move"].as(/*this->*/movement.move);
|
||||
/*this->*/movement.run = serializerMovement["run"].as(/*this->*/movement.run);
|
||||
/*this->*/movement.walk = serializerMovement["walk"].as(/*this->*/movement.walk);
|
||||
/*this->*/movement.air = serializerMovement["air"].as(/*this->*/movement.air);
|
||||
/*this->*/movement.jump = uf::vector::decode(serializerMovement["jump"], /*this->*/movement.jump);
|
||||
/*this->*/movement.floored.feet = uf::vector::decode(serializerMovement["floored"]["feet"], /*this->*/movement.floored.feet);
|
||||
/*this->*/movement.floored.floor = uf::vector::decode(serializerMovement["floored"]["floor"], /*this->*/movement.floored.floor);
|
||||
/*this->*/movement.floored.print = serializerMovement["floored"]["print"].as(/*this->*/movement.floored.print);
|
||||
/*this->*/movement.crouch = serializerMovement["crouch"].as(/*this->*/movement.crouch);
|
||||
// /*this->*/movement.look = serializerMovement["look"].as<float>(1.0f);
|
||||
ext::json::forEach( serializerAudioFootstep["list"], [&]( const ext::json::Value& value ){
|
||||
/*this->*/audio.footstep.list.emplace_back(value);
|
||||
});
|
||||
/*this->*/audio.footstep.volume = serializerAudioFootstep["volume"].as<float>();
|
||||
|
||||
/*this->*/camera.invert = uf::vector::decode( serializerCamera["invert"], pod::Vector3t<bool>{false, false, false} );
|
||||
/*this->*/camera.limit.current = uf::vector::decode( serializerCameraLimit["current"], pod::Vector3f{NAN, NAN, NAN} );
|
||||
/*this->*/camera.limit.min = uf::vector::decode( serializerCameraLimit["minima"], pod::Vector3f{NAN, NAN, NAN} );
|
||||
/*this->*/camera.limit.max = uf::vector::decode( serializerCameraLimit["maxima"], pod::Vector3f{NAN, NAN, NAN} );
|
||||
/*this->*/camera.invert = uf::vector::decode( serializerCamera["invert"], /*this->*/camera.invert );
|
||||
/*this->*/camera.limit.current = uf::vector::decode( serializerCameraLimit["current"], /*this->*/camera.limit.current );
|
||||
/*this->*/camera.limit.min = uf::vector::decode( serializerCameraLimit["minima"], /*this->*/camera.limit.min );
|
||||
/*this->*/camera.limit.max = uf::vector::decode( serializerCameraLimit["maxima"], /*this->*/camera.limit.max );
|
||||
}
|
||||
#undef this
|
@ -27,6 +27,11 @@ namespace ext {
|
||||
float friction = 0.8f;
|
||||
float air = 1.0f;
|
||||
pod::Vector3f jump = {0,8,0};
|
||||
struct {
|
||||
pod::Vector3f feet = {0,-1.5,0};
|
||||
pod::Vector3f floor = {0,-1,0};
|
||||
bool print = false;
|
||||
} floored;
|
||||
} movement;
|
||||
struct {
|
||||
struct {
|
||||
|
@ -87,11 +87,17 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
||||
if ( graphic.material.hasShader("ray:gen", uf::renderer::settings::pipelines::names::rt) ) {
|
||||
auto& shader = graphic.material.getShader("ray:gen", uf::renderer::settings::pipelines::names::rt);
|
||||
//
|
||||
pod::Vector2ui size = metadata.renderer.size;
|
||||
UF_MSG_DEBUG("Size: {}", uf::vector::toString( size ));
|
||||
if ( size.x == 0 ) size.x = uf::renderer::settings::width * metadata.renderer.scale;
|
||||
if ( size.y == 0 ) size.y = uf::renderer::settings::height * metadata.renderer.scale;
|
||||
UF_MSG_DEBUG("Size: {}", uf::vector::toString( size ));
|
||||
|
||||
auto& image = shader.textures.emplace_back();
|
||||
image.fromBuffers(
|
||||
NULL, 0,
|
||||
uf::renderer::enums::Format::R8G8B8A8_UNORM,
|
||||
uf::renderer::settings::width * metadata.renderer.scale, uf::renderer::settings::height * metadata.renderer.scale, 1, 1,
|
||||
size.x, size.y, 1, 1,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL
|
||||
);
|
||||
|
||||
@ -161,8 +167,9 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
||||
if ( shader.textures.empty() ) {
|
||||
auto& tex = shader.textures.emplace_back();
|
||||
tex.aliasTexture( image );
|
||||
tex.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
tex.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
|
||||
tex.sampler.descriptor.filter.min = metadata.renderer.filter;
|
||||
tex.sampler.descriptor.filter.mag = metadata.renderer.filter;
|
||||
|
||||
renderMode.execute = true;
|
||||
renderMode.metadata.limiter.execute = true;
|
||||
@ -172,11 +179,14 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
|
||||
if ( uf::renderer::states::resized ) {
|
||||
pod::Vector2ui size = metadata.renderer.size;
|
||||
if ( size.x == 0 ) size.x = uf::renderer::settings::width * metadata.renderer.scale;
|
||||
if ( size.y == 0 ) size.y = uf::renderer::settings::height * metadata.renderer.scale;
|
||||
image.destroy();
|
||||
image.fromBuffers(
|
||||
NULL, 0,
|
||||
uf::renderer::enums::Format::R8G8B8A8_UNORM,
|
||||
uf::renderer::settings::width * metadata.renderer.scale, uf::renderer::settings::height * metadata.renderer.scale, 1, 1,
|
||||
size.x, size.y, 1, 1,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL
|
||||
);
|
||||
|
||||
@ -207,7 +217,6 @@ void ext::RayTraceSceneBehavior::Metadata::serialize( uf::Object& self, uf::Seri
|
||||
|
||||
}
|
||||
void ext::RayTraceSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ) {
|
||||
UF_MSG_DEBUG("Update");
|
||||
// merge vxgi settings with global settings
|
||||
{
|
||||
const auto& globalSettings = ext::config["engine"]["scenes"]["rt"];
|
||||
@ -217,8 +226,17 @@ void ext::RayTraceSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Se
|
||||
} );
|
||||
}
|
||||
|
||||
if ( serializer["size"].is<float>() ) {
|
||||
/*this->*/renderer.scale = serializer["size"].as(/*this->*/renderer.scale);
|
||||
if ( serializer["rt"]["filter"].is<uf::stl::string>() ) {
|
||||
const auto mode = uf::string::lowercase( serializer["rt"]["filter"].as<uf::stl::string>() );
|
||||
if ( mode == "nearest" ) /*this->*/renderer.filter = uf::renderer::enums::Filter::NEAREST;
|
||||
else if ( mode == "linear" ) /*this->*/renderer.filter = uf::renderer::enums::Filter::LINEAR;
|
||||
else UF_MSG_WARNING("Invalid Filter enum string specified: {}", mode);
|
||||
}
|
||||
|
||||
if ( serializer["rt"]["size"].is<float>() ) {
|
||||
/*this->*/renderer.scale = serializer["rt"]["size"].as(/*this->*/renderer.scale);
|
||||
} else if ( ext::json::isArray( serializer["rt"]["size"] ) ) {
|
||||
/*this->*/renderer.size = uf::vector::decode( serializer["rt"]["size"], /*this->*/renderer.size );
|
||||
} else if ( ext::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].is<float>() ) {
|
||||
/*this->*/renderer.scale = ext::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].as(/*this->*/renderer.scale);
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ namespace ext {
|
||||
struct {
|
||||
bool bound = false;
|
||||
float scale = 1;
|
||||
pod::Vector2ui size{};
|
||||
uf::renderer::enums::Filter::type_t filter = uf::renderer::enums::Filter::NEAREST;
|
||||
} renderer;
|
||||
|
||||
struct {
|
||||
|
@ -413,6 +413,16 @@ void ext::Gui::load( const uf::Image& image ) {
|
||||
}
|
||||
} else if ( ext::json::isArray(metadataJson["scaling"]) ) {
|
||||
raidou = uf::vector::decode( metadataJson["scaling"], raidou );
|
||||
#if 1
|
||||
float factor = 1;
|
||||
if ( raidou.x == 0 && raidou.y != 0 ) {
|
||||
factor = raidou.y;
|
||||
} else if ( raidou.y == 0 && raidou.x != 0 ) {
|
||||
factor = raidou.x;
|
||||
}
|
||||
raidou.x /= factor;
|
||||
raidou.y /= factor;
|
||||
#endif
|
||||
modified = true;
|
||||
}
|
||||
if ( modified ) {
|
||||
@ -531,7 +541,11 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
metadata.clicked = clicked;
|
||||
|
||||
if ( clicked ) this->callHook("gui:Clicked.%UID%", payload);
|
||||
|
||||
if ( clicked ) {
|
||||
UF_MSG_DEBUG("{} clicked", this->getName());
|
||||
this->callHook("gui:Clicked.%UID%", payload);
|
||||
}
|
||||
this->callHook("gui:Mouse.Clicked.%UID%", payload);
|
||||
} );
|
||||
|
||||
|
@ -38,7 +38,7 @@ ext::gui::Size ext::gui::size = {
|
||||
0,
|
||||
},
|
||||
#if UF_ENV_DREAMCAST
|
||||
.reference = { 960, 720 },
|
||||
.reference = { 640, 480 },
|
||||
#else
|
||||
.reference = { 1920, 1080 },
|
||||
#endif
|
||||
@ -67,7 +67,7 @@ void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
|
||||
ext::gui::size.current = uf::vector::decode( ext::config["window"]["size"], pod::Vector2f{} );
|
||||
this->addHook( "window:Resized", [&](pod::payloads::windowResized& payload){
|
||||
ext::gui::size.current = payload.window.size;
|
||||
// ext::gui::size.reference = payload.window.size;
|
||||
ext::gui::size.reference = payload.window.size;
|
||||
} );
|
||||
this->addHook( "window:Mouse.Moved", [&](pod::payloads::windowMouseMoved& payload){
|
||||
bool clicked = false;
|
||||
|
43
ext/main.cpp
43
ext/main.cpp
@ -416,7 +416,6 @@ void EXT_API ext::initialize() {
|
||||
uf::renderer::settings::invariant::waitOnRenderEnd = configRenderInvariantJson["wait on render end"].as( uf::renderer::settings::invariant::waitOnRenderEnd );
|
||||
uf::renderer::settings::invariant::individualPipelines = configRenderInvariantJson["individual pipelines"].as( uf::renderer::settings::invariant::individualPipelines );
|
||||
uf::renderer::settings::invariant::deferredMode = configRenderInvariantJson["deferred mode"].as( uf::renderer::settings::invariant::deferredMode );
|
||||
uf::renderer::settings::invariant::deferredReconstructPosition = configRenderInvariantJson["deferred reconstruct position"].as( uf::renderer::settings::invariant::deferredReconstructPosition );
|
||||
uf::renderer::settings::invariant::deferredAliasOutputToSwapchain = configRenderInvariantJson["deferred alias output to swapchain"].as( uf::renderer::settings::invariant::deferredAliasOutputToSwapchain );
|
||||
uf::renderer::settings::invariant::deferredSampling = configRenderInvariantJson["deferred sampling"].as( uf::renderer::settings::invariant::deferredSampling );
|
||||
|
||||
@ -606,11 +605,45 @@ void EXT_API ext::initialize() {
|
||||
});
|
||||
|
||||
uf::hooks.addHook( "game:Scene.Cleanup", [&](){
|
||||
UF_MSG_DEBUG("Cleanup");
|
||||
|
||||
uf::scene::unloadScene();
|
||||
uf::physics::terminate();
|
||||
uf::physics::initialize();
|
||||
|
||||
// reset physics world
|
||||
{
|
||||
uf::physics::terminate();
|
||||
uf::physics::initialize();
|
||||
}
|
||||
// reset graph state
|
||||
{
|
||||
// cleanup graphic handles
|
||||
for ( auto pair : uf::graph::storage.texture2Ds.map ) pair.second.destroy();
|
||||
for ( auto& t : uf::graph::storage.shadow2Ds ) t.destroy();
|
||||
for ( auto& t : uf::graph::storage.shadowCubes ) t.destroy();
|
||||
|
||||
for ( auto pair : uf::graph::storage.atlases.map ) pair.second.clear();
|
||||
for ( auto pair : uf::graph::storage.images.map ) pair.second.clear();
|
||||
for ( auto pair : uf::graph::storage.meshes.map ) pair.second.destroy();
|
||||
|
||||
// cleanup storage cache
|
||||
uf::graph::storage.instances.clear();
|
||||
uf::graph::storage.instanceAddresses.clear();
|
||||
uf::graph::storage.primitives.clear();
|
||||
uf::graph::storage.drawCommands.clear();
|
||||
uf::graph::storage.meshes.clear();
|
||||
uf::graph::storage.images.clear();
|
||||
uf::graph::storage.materials.clear();
|
||||
uf::graph::storage.textures.clear();
|
||||
uf::graph::storage.samplers.clear();
|
||||
uf::graph::storage.skins.clear();
|
||||
uf::graph::storage.animations.clear();
|
||||
uf::graph::storage.atlases.clear();
|
||||
uf::graph::storage.joints.clear();
|
||||
uf::graph::storage.texture2Ds.clear();
|
||||
uf::graph::storage.entities.clear();
|
||||
uf::graph::storage.shadow2Ds.clear();
|
||||
uf::graph::storage.shadowCubes.clear();
|
||||
}
|
||||
|
||||
uf::renderer::states::rebuild = true;
|
||||
});
|
||||
uf::hooks.addHook( "system:Quit", [&](ext::json::Value& json){
|
||||
if ( json["message"].is<uf::stl::string>() ) {
|
||||
|
@ -2,6 +2,7 @@ ARCH = win64
|
||||
CDIR =
|
||||
CC = clang
|
||||
CXX = clang++
|
||||
OPTIMIZATIONS = -O3 -fstrict-aliasing # -flto
|
||||
OPTIMIZATIONS = -O3 -fstrict-aliasing -flto
|
||||
WARNINGS = -g -Wall -Wno-pointer-arith -Wno-unused-function -Wno-unused-variable -Wno-switch -Wno-reorder-ctor -Wno-ignored-attributes -Wno-c++11-narrowing -Wno-unknown-pragmas -Wno-nullability-completeness -Wno-defaulted-function-deleted -Wno-mismatched-tags
|
||||
FLAGS += -std=c++17 $(OPTIMIZATIONS) $(WARNINGS) -fcolor-diagnostics -fansi-escape-codes
|
||||
SANITIZE = -fuse-ld=lld # -fsanitize=address -fno-omit-frame-pointer
|
||||
FLAGS += -std=c++17 $(OPTIMIZATIONS) $(WARNINGS) $(SANITIZE) -fcolor-diagnostics -fansi-escape-codes
|
@ -2,6 +2,6 @@ ARCH = win64
|
||||
CDIR =
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
OPTIMIZATIONS = -O3 -g -fstrict-aliasing -DUF_NO_EXCEPTIONS # -flto
|
||||
OPTIMIZATIONS = -O3 -g -fstrict-aliasing -DUF_NO_EXCEPTIONS -march=native # -flto
|
||||
WARNINGS = -Wall -Wno-unknown-pragmas -Wno-unused-function -Wno-unused-variable -Wno-switch -Wno-reorder -Wno-sign-compare -Wno-unused-but-set-variable -Wno-ignored-attributes -Wno-narrowing -Wno-misleading-indentation
|
||||
FLAGS += -std=c++20 $(OPTIMIZATIONS) $(WARNINGS) -fdiagnostics-color=always
|
8
makefiles/win64.zig.make
Normal file
8
makefiles/win64.zig.make
Normal file
@ -0,0 +1,8 @@
|
||||
ARCH = win64
|
||||
CDIR =
|
||||
CC = /opt/zig/zig cc
|
||||
CXX = /opt/zig/zig c++
|
||||
OPTIMIZATIONS = -O3 -fstrict-aliasing #-flto
|
||||
WARNINGS = -g -Wall -Wno-pointer-arith -Wno-unused-function -Wno-unused-variable -Wno-switch -Wno-reorder-ctor -Wno-ignored-attributes -Wno-c++11-narrowing -Wno-unknown-pragmas -Wno-nullability-completeness -Wno-defaulted-function-deleted -Wno-mismatched-tags
|
||||
SANITIZE = #-fuse-ld=lld -fsanitize=address -fno-omit-frame-pointer
|
||||
FLAGS += -std=c++17 $(OPTIMIZATIONS) $(WARNINGS) $(SANITIZE) -I./dep/zig/include/ -target x86_64-windows-gnu
|
@ -6,7 +6,9 @@ ARCH=$(cat ./exe/default/arch)
|
||||
CC=$(cat ./exe/default/cc)
|
||||
RENDERER=$(cat ./exe/default/renderer)
|
||||
|
||||
export PATH="$(pwd)/exe/lib/${ARCH}/:$(pwd)/exe/lib/${ARCH}/${CC}/${RENDERER}/:${PATH}"
|
||||
export PATH="$(pwd)/exe/lib/${ARCH}/:$(pwd)/exe/lib/${ARCH}/${CC}/:$(pwd)/exe/lib/${ARCH}/${CC}/${RENDERER}/:${PATH}"
|
||||
|
||||
echo PATH: ${PATH}
|
||||
echo Executing ./exe/program.${ARCH}.${CC}.${RENDERER}.exe $@
|
||||
./exe/program.${ARCH}.${CC}.${RENDERER}.exe $@
|
||||
tskill program
|
||||
|
Loading…
Reference in New Issue
Block a user