Commit for 2021.03.04.7z
This commit is contained in:
parent
ed4fb47ad9
commit
68e6b55daa
19
Makefile
19
Makefile
@ -35,10 +35,7 @@ ifneq (,$(findstring win64,$(ARCH)))
|
||||
FLAGS +=
|
||||
DEPS += -lgdi32
|
||||
else ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
REQ_DEPS += opengl gldc json:nlohmann png meshoptimizer bullet freetype # lua ogg openal draco luajit ultralight-ux ncurses curl openvr discord
|
||||
FLAGS += $(KOS_CPPFLAGS) -frtti -DUF_NO_EXCEPTIONS
|
||||
INCS += $(KOS_INC_PATHS) -I/opt/dreamcast/sh-elf/sh-elf/include
|
||||
LIBS += $(KOS_LIB_PATHS) -L/opt/dreamcast/sh-elf/sh-elf/lib
|
||||
REQ_DEPS += opengl gldc json:nlohmann bullet lua # freetype png meshoptimizer ogg openal draco luajit ultralight-ux ncurses curl openvr discord
|
||||
endif
|
||||
ifneq (,$(findstring vulkan,$(REQ_DEPS)))
|
||||
FLAGS += -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN
|
||||
@ -66,7 +63,7 @@ ifneq (,$(findstring json,$(REQ_DEPS)))
|
||||
endif
|
||||
ifneq (,$(findstring png,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_PNG
|
||||
DEPS += -lpng -lz -lbz2
|
||||
DEPS += -lpng -lz
|
||||
endif
|
||||
ifneq (,$(findstring openal,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_OPENAL
|
||||
@ -87,7 +84,7 @@ ifneq (,$(findstring ogg,$(REQ_DEPS)))
|
||||
endif
|
||||
ifneq (,$(findstring freetype,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_FREETYPE
|
||||
DEPS += -lfreetype
|
||||
DEPS += -lfreetype -lbz2
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
DEPS += -lbrotlicommon-static -lbrotlidec-static
|
||||
endif
|
||||
@ -185,8 +182,8 @@ SRCS_SHADERS += $(wildcard bin/data/shaders/*.glsl) $(wildcard bin/data/shade
|
||||
TARGET_SHADERS += $(patsubst %.glsl,%.spv,$(SRCS_SHADERS))
|
||||
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
$(ARCH): $(EX_DLL) $(EXT_EX_DLL) $(TARGET) ./bin/dreamcast/$(TARGET_NAME).cdi
|
||||
#$(ARCH): $(TARGET) ./bin/dreamcast/$(TARGET_NAME).cdi
|
||||
#$(ARCH): $(EX_DLL) $(EXT_EX_DLL) $(TARGET) ./bin/dreamcast/$(TARGET_NAME).cdi
|
||||
$(ARCH): $(TARGET) ./bin/dreamcast/$(TARGET_NAME).cdi
|
||||
OBJS = $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_DLL)) $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_EXT_DLL)) $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS))
|
||||
|
||||
DEPS += -lkallisti -lc -lm -lgcc -lstdc++ # -l$(LIB_NAME) -l$(EXT_LIB_NAME)
|
||||
@ -253,6 +250,9 @@ clean:
|
||||
@-rm ./bin/dreamcast/build/*
|
||||
@-rm ./bin/dreamcast/romdisk.*
|
||||
@-rm ./bin/dreamcast/$(TARGET_NAME).*
|
||||
|
||||
run:
|
||||
$(KOS_EMU) ./bin/dreamcast/$(TARGET_NAME).cdi
|
||||
else
|
||||
clean:
|
||||
@-rm $(EX_DLL)
|
||||
@ -262,6 +262,9 @@ clean:
|
||||
@-rm -f $(OBJS_DLL)
|
||||
@-rm -f $(OBJS_EXT_DLL)
|
||||
@-rm -f $(OBJS)
|
||||
|
||||
run:
|
||||
./program.sh
|
||||
endif
|
||||
clean-uf:
|
||||
@-rm $(EX_DLL)
|
||||
|
@ -1,87 +0,0 @@
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glkos.h>
|
||||
|
||||
/* A general OpenGL initialization function. Sets all of the initial parameters. */
|
||||
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
|
||||
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
|
||||
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
|
||||
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
|
||||
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex arrays
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // Reset The Projection Matrix
|
||||
|
||||
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
|
||||
void ReSizeGLScene(int Width, int Height)
|
||||
{
|
||||
if (Height == 0) // Prevent A Divide By Zero If The Window Is Too Small
|
||||
Height = 1;
|
||||
|
||||
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
||||
/* The main drawing function. */
|
||||
void DrawGLScene()
|
||||
{
|
||||
|
||||
const GLfloat triangle [] = {
|
||||
0.0f, 1.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f
|
||||
};
|
||||
|
||||
const GLfloat square [] = {
|
||||
-1.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f
|
||||
};
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
|
||||
glLoadIdentity(); // Reset The View
|
||||
|
||||
glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, triangle);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
glTranslatef(3.0f,0.0f,0.0f); // Move Right 3 Units
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, square);
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
|
||||
// swap buffers to display, since we're double buffered.
|
||||
glKosSwapBuffers();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
glKosInit();
|
||||
|
||||
InitGL(640, 480);
|
||||
ReSizeGLScene(640, 480);
|
||||
|
||||
while(1) {
|
||||
UF_DEBUG_PRINT_MARKER();
|
||||
DrawGLScene();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,82 +1,366 @@
|
||||
/*
|
||||
KallistiOS 2.0.0
|
||||
|
||||
nehe02.c
|
||||
(c)2014 Josh Pearson
|
||||
(c)2001 Benoit Miller
|
||||
(c)2000 Jeff Molofee
|
||||
/*
|
||||
** $Id: lua.c,v 1.222 2014/11/11 19:41:27 roberto Exp $
|
||||
** Lua stand-alone interpreter
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#include <kos.h>
|
||||
#define lua_c
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glut.h>
|
||||
#if 0
|
||||
#include "lprefix.h"
|
||||
|
||||
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
/* KOS-specific stuff. */
|
||||
#include <kos/dbgio.h>
|
||||
#include <dc/maple.h>
|
||||
#include <dc/maple/keyboard.h>
|
||||
#include <dc/maple/controller.h>
|
||||
|
||||
void cont_cb(uint8 addr, uint32 btns) {
|
||||
(void)addr;
|
||||
(void)btns;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int kbd_readline(char *buf, int len) {
|
||||
int ch = 0;
|
||||
maple_device_t *dev;
|
||||
int pos = 0;
|
||||
|
||||
if(!buf || !len)
|
||||
return 0;
|
||||
|
||||
/* Clear the buffer. */
|
||||
memset(buf, 0, len);
|
||||
|
||||
while(ch != '\n' && pos < len - 1) {
|
||||
/* Not really sensible, but just in case someone unplugs and replugs
|
||||
their keyboard, we'll probably work right... */
|
||||
if((dev = maple_enum_type(0, MAPLE_FUNC_KEYBOARD))) {
|
||||
ch = kbd_queue_pop(dev, 1);
|
||||
|
||||
/* Make sure we got an ASCII character. */
|
||||
if((ch & 0xFFFFFF00))
|
||||
continue;
|
||||
|
||||
/* Put the character into the buffer and print it out on the
|
||||
terminal. */
|
||||
buf[pos++] = (char)ch;
|
||||
printf("%c", (char)ch);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define lua_readline(L,b,p) \
|
||||
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
|
||||
kbd_readline(b, LUA_MAXINPUT) != 0) /* get line */
|
||||
#define lua_saveline(L,idx) { (void)L; (void)idx; }
|
||||
#define lua_freeline(L,b) { (void)L; (void)b; }
|
||||
|
||||
#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
|
||||
|
||||
/* End KOS-specific stuff. */
|
||||
|
||||
|
||||
#if !defined(LUA_PROMPT)
|
||||
#define LUA_PROMPT "> "
|
||||
#define LUA_PROMPT2 ">> "
|
||||
#endif
|
||||
|
||||
#if !defined(LUA_PROGNAME)
|
||||
#define LUA_PROGNAME "lua"
|
||||
#endif
|
||||
|
||||
#if !defined(LUA_MAXINPUT)
|
||||
#define LUA_MAXINPUT 512
|
||||
#endif
|
||||
|
||||
#if !defined(LUA_INIT_VAR)
|
||||
#define LUA_INIT_VAR "LUA_INIT"
|
||||
#endif
|
||||
|
||||
#define LUA_INITVARVERSION \
|
||||
LUA_INIT_VAR "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
|
||||
|
||||
|
||||
static lua_State *globalL = NULL;
|
||||
|
||||
static const char *progname = LUA_PROGNAME;
|
||||
|
||||
/*
|
||||
The simplest OpenGL example ever!
|
||||
|
||||
Essentially the same thing as NeHe's lesson02 code.
|
||||
To learn more, go to http://nehe.gamedev.net/.
|
||||
** Prints an error message, adding the program name in front of it
|
||||
** (if present)
|
||||
*/
|
||||
|
||||
void draw_gl(void) {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glLoadIdentity();
|
||||
glTranslatef(-1.5f, 0.0f, -6.0f);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, 0.0f);
|
||||
glEnd();
|
||||
|
||||
glTranslatef(3.0f, 0.0f, 0.0f);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(-1.0f, 1.0f, 0.0f);
|
||||
glVertex3f(1.0f, 1.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, 0.0f);
|
||||
glEnd();
|
||||
static void l_message (const char *pname, const char *msg) {
|
||||
if (pname) lua_writestringerror("%s: ", pname);
|
||||
lua_writestringerror("%s\n", msg);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
maple_device_t *cont;
|
||||
cont_state_t *state;
|
||||
|
||||
/* Get basic stuff initialized */
|
||||
printf("nehe02 beginning\n");
|
||||
/* Notice we do not init the PVR here, that is handled by OpenGL */
|
||||
glKosInit();
|
||||
/*
|
||||
** Check whether 'status' is not OK and, if so, prints the error
|
||||
** message on the top of the stack. It assumes that the error object
|
||||
** is a string, as it was either generated by Lua or by 'msghandler'.
|
||||
*/
|
||||
static int report (lua_State *L, int status) {
|
||||
if (status != LUA_OK) {
|
||||
const char *msg = lua_tostring(L, -1);
|
||||
l_message(progname, msg);
|
||||
lua_pop(L, 1); /* remove message */
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(45.0f, 640.0f / 480.0f, 0.1f, 100.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
while(1) {
|
||||
cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||
/*
|
||||
** Message handler used to run all chunks
|
||||
*/
|
||||
static int msghandler (lua_State *L) {
|
||||
const char *msg = lua_tostring(L, 1);
|
||||
if (msg == NULL) { /* is error object not a string? */
|
||||
if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
|
||||
lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */
|
||||
return 1; /* that is the message */
|
||||
else
|
||||
msg = lua_pushfstring(L, "(error object is a %s value)",
|
||||
luaL_typename(L, 1));
|
||||
}
|
||||
luaL_traceback(L, L, msg, 1); /* append a standard traceback */
|
||||
return 1; /* return the traceback */
|
||||
}
|
||||
|
||||
/* Check key status */
|
||||
state = (cont_state_t *)maple_dev_status(cont);
|
||||
|
||||
if(!state) {
|
||||
printf("Error reading controller\n");
|
||||
break;
|
||||
}
|
||||
/*
|
||||
** Interface to 'lua_pcall', which sets appropriate message function
|
||||
** and C-signal handler. Used to run all chunks.
|
||||
*/
|
||||
static int docall (lua_State *L, int narg, int nres) {
|
||||
int status;
|
||||
int base = lua_gettop(L) - narg; /* function index */
|
||||
lua_pushcfunction(L, msghandler); /* push message handler */
|
||||
lua_insert(L, base); /* put it under function and args */
|
||||
globalL = L; /* to be available to 'laction' */
|
||||
|
||||
if(state->buttons & CONT_START)
|
||||
break;
|
||||
status = lua_pcall(L, narg, nres, base);
|
||||
|
||||
/* Draw the "scene" */
|
||||
draw_gl();
|
||||
lua_remove(L, base); /* remove message handler from the stack */
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Finish the frame - Notice there is no glKosBegin/FinshFrame */
|
||||
glutSwapBuffers();
|
||||
|
||||
static void print_version (void) {
|
||||
lua_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT));
|
||||
lua_writeline();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Returns the string to be used as a prompt by the interpreter.
|
||||
*/
|
||||
static const char *get_prompt (lua_State *L, int firstline) {
|
||||
const char *p;
|
||||
lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
|
||||
p = lua_tostring(L, -1);
|
||||
if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* mark in error messages for incomplete statements */
|
||||
#define EOFMARK "<eof>"
|
||||
#define marklen (sizeof(EOFMARK)/sizeof(char) - 1)
|
||||
|
||||
|
||||
/*
|
||||
** Check whether 'status' signals a syntax error and the error
|
||||
** message at the top of the stack ends with the above mark for
|
||||
** incomplete statements.
|
||||
*/
|
||||
static int incomplete (lua_State *L, int status) {
|
||||
if (status == LUA_ERRSYNTAX) {
|
||||
size_t lmsg;
|
||||
const char *msg = lua_tolstring(L, -1, &lmsg);
|
||||
if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
|
||||
lua_pop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0; /* else... */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Prompt the user, read a line, and push it into the Lua stack.
|
||||
*/
|
||||
static int pushline (lua_State *L, int firstline) {
|
||||
char buffer[LUA_MAXINPUT];
|
||||
char *b = buffer;
|
||||
size_t l;
|
||||
const char *prmt = get_prompt(L, firstline);
|
||||
int readstatus = lua_readline(L, b, prmt);
|
||||
if (readstatus == 0)
|
||||
return 0; /* no input (prompt will be popped by caller) */
|
||||
lua_pop(L, 1); /* remove prompt */
|
||||
l = strlen(b);
|
||||
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
|
||||
b[l-1] = '\0'; /* remove it */
|
||||
if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */
|
||||
lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
|
||||
else
|
||||
lua_pushstring(L, b);
|
||||
lua_freeline(L, b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Try to compile line on the stack as 'return <line>'; on return, stack
|
||||
** has either compiled chunk or original line (if compilation failed).
|
||||
*/
|
||||
static int addreturn (lua_State *L) {
|
||||
int status;
|
||||
size_t len; const char *line;
|
||||
lua_pushliteral(L, "return ");
|
||||
lua_pushvalue(L, -2); /* duplicate line */
|
||||
lua_concat(L, 2); /* new line is "return ..." */
|
||||
line = lua_tolstring(L, -1, &len);
|
||||
if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK)
|
||||
lua_remove(L, -3); /* remove original line */
|
||||
else
|
||||
lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Read multiple lines until a complete Lua statement
|
||||
*/
|
||||
static int multiline (lua_State *L) {
|
||||
for (;;) { /* repeat until gets a complete statement */
|
||||
size_t len;
|
||||
const char *line = lua_tolstring(L, 1, &len); /* get what it has */
|
||||
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
|
||||
if (!incomplete(L, status) || !pushline(L, 0))
|
||||
return status; /* cannot or should not try to add continuation line */
|
||||
lua_pushliteral(L, "\n"); /* add newline... */
|
||||
lua_insert(L, -2); /* ...between the two lines */
|
||||
lua_concat(L, 3); /* join them */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Read a line and try to load (compile) it first as an expression (by
|
||||
** adding "return " in front of it) and second as a statement. Return
|
||||
** the final status of load/call with the resulting function (if any)
|
||||
** in the top of the stack.
|
||||
*/
|
||||
static int loadline (lua_State *L) {
|
||||
int status;
|
||||
lua_settop(L, 0);
|
||||
if (!pushline(L, 1))
|
||||
return -1; /* no input */
|
||||
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
|
||||
status = multiline(L); /* try as command, maybe with continuation lines */
|
||||
lua_saveline(L, 1); /* keep history */
|
||||
lua_remove(L, 1); /* remove line from the stack */
|
||||
lua_assert(lua_gettop(L) == 1);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Prints (calling the Lua 'print' function) any values on the stack
|
||||
*/
|
||||
static void l_print (lua_State *L) {
|
||||
int n = lua_gettop(L);
|
||||
if (n > 0) { /* any result to be printed? */
|
||||
luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
|
||||
lua_getglobal(L, "print");
|
||||
lua_insert(L, 1);
|
||||
if (lua_pcall(L, n, 0, 0) != LUA_OK)
|
||||
l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)",
|
||||
lua_tostring(L, -1)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Do the REPL: repeatedly read (load) a line, evaluate (call) it, and
|
||||
** print any results.
|
||||
*/
|
||||
static void doREPL (lua_State *L) {
|
||||
int status;
|
||||
const char *oldprogname = progname;
|
||||
progname = NULL; /* no 'progname' on errors in interactive mode */
|
||||
while ((status = loadline(L)) != -1) {
|
||||
if (status == LUA_OK)
|
||||
status = docall(L, 0, LUA_MULTRET);
|
||||
if (status == LUA_OK) l_print(L);
|
||||
else report(L, status);
|
||||
}
|
||||
lua_settop(L, 0); /* clear stack */
|
||||
lua_writeline();
|
||||
progname = oldprogname;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Main body of stand-alone interpreter (to be called in protected mode).
|
||||
** Reads the options and handles them all.
|
||||
*/
|
||||
static int pmain (lua_State *L) {
|
||||
luaL_checkversion(L); /* check that interpreter has correct version */
|
||||
|
||||
lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
|
||||
|
||||
luaL_openlibs(L); /* open standard libraries */
|
||||
|
||||
print_version();
|
||||
doREPL(L); /* do read-eval-print loop */
|
||||
|
||||
lua_pushboolean(L, 1); /* signal no errors */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int status, result;
|
||||
lua_State *L = luaL_newstate(); /* create state */
|
||||
|
||||
/* Make sure printf and friends go to the screen. */
|
||||
dbgio_dev_select("fb");
|
||||
|
||||
/* Set our "interrupt" callback to give us a way out of the interpreter. */
|
||||
cont_btn_callback(0, CONT_START, &cont_cb);
|
||||
|
||||
if (L == NULL) {
|
||||
l_message(argv[0], "cannot create state: not enough memory");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
|
||||
lua_pushinteger(L, argc); /* 1st argument */
|
||||
lua_pushlightuserdata(L, argv); /* 2nd argument */
|
||||
status = lua_pcall(L, 2, 1, 0); /* do the call */
|
||||
result = lua_toboolean(L, -1); /* get result */
|
||||
report(L, status);
|
||||
lua_close(L);
|
||||
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
@ -51,10 +51,10 @@ int main(int argc, char** argv){
|
||||
json["window"]["size"]["y"] = client::config["window"]["size"]["y"];
|
||||
uf::hooks.call(hook, json);
|
||||
}
|
||||
client::tick();
|
||||
ext::tick();
|
||||
client::render();
|
||||
ext::render();
|
||||
client::tick();
|
||||
ext::tick();
|
||||
#if HANDLE_EXCEPTIONS
|
||||
} catch ( std::runtime_error& e ) {
|
||||
uf::iostream << "RUNTIME ERROR: " << e.what() << "\n";
|
||||
|
@ -13,10 +13,11 @@ namespace uf {
|
||||
|
||||
namespace pod {
|
||||
struct UF_API Behavior {
|
||||
typedef std::type_index type_t;
|
||||
// typedef std::type_index type_t;
|
||||
typedef std::string type_t;
|
||||
typedef std::function<void(uf::Object&)> function_t;
|
||||
|
||||
type_t type = std::type_index(typeid(pod::Behavior));
|
||||
type_t type = ""; //std::type_index(typeid(pod::Behavior));
|
||||
function_t initialize = function_t();
|
||||
function_t tick = function_t();
|
||||
function_t render = function_t();
|
||||
@ -40,6 +41,10 @@ namespace uf {
|
||||
}
|
||||
|
||||
bool hasBehavior( const pod::Behavior& );
|
||||
void addBehavior( const pod::Behavior& );
|
||||
void removeBehavior( const pod::Behavior& );
|
||||
|
||||
#if 0
|
||||
template<typename T>
|
||||
bool hasBehavior() {
|
||||
for ( auto& behavior : this->m_behaviors ) {
|
||||
@ -47,13 +52,9 @@ namespace uf {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void addBehavior( const pod::Behavior& );
|
||||
void removeBehavior( const pod::Behavior& );
|
||||
|
||||
template<typename T>
|
||||
static pod::Behavior::type_t getType() {
|
||||
return std::type_index(typeid(T));
|
||||
return T::type; //std::type_index(typeid(T));
|
||||
}
|
||||
template<typename T>
|
||||
void addBehavior() {
|
||||
@ -71,6 +72,7 @@ namespace uf {
|
||||
.type = getType<T>()
|
||||
});
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,19 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_H( OBJ )\
|
||||
class UF_API OBJ ## Behavior {\
|
||||
public:\
|
||||
static void attach( uf::Entity& );\
|
||||
static void initialize( uf::Object& );\
|
||||
static void tick( uf::Object& );\
|
||||
static void render( uf::Object& );\
|
||||
static void destroy( uf::Object& );\
|
||||
#define UF_ENTITY_METADATA_USE_JSON 0
|
||||
#define UF_BEHAVIOR_DEFINE_TYPE static constexpr const char* type = __FILE__;
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_METADATA_H( OBJ, METADATA )\
|
||||
namespace OBJ ## Behavior {\
|
||||
UF_BEHAVIOR_DEFINE_TYPE;\
|
||||
void attach( uf::Entity& );\
|
||||
void initialize( uf::Object& );\
|
||||
void tick( uf::Object& );\
|
||||
void render( uf::Object& );\
|
||||
void destroy( uf::Object& );\
|
||||
METADATA;\
|
||||
};
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_H( OBJ ) UF_BEHAVIOR_ENTITY_METADATA_H( OBJ, struct Metadata{}; )
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_BEGIN( OBJ )\
|
||||
void OBJ ## Behavior::attach( uf::Entity& self ) {\
|
||||
self.addBehavior(pod::Behavior{\
|
||||
.type = uf::Behaviors::getType<OBJ ## Behavior>(),\
|
||||
.type = OBJ ## Behavior::type,\
|
||||
.initialize = OBJ ## Behavior::initialize,\
|
||||
.tick = OBJ ## Behavior::tick,\
|
||||
.render = OBJ ## Behavior::render,\
|
||||
@ -24,61 +30,4 @@
|
||||
OBJ ## Behavior::attach( *this );\
|
||||
}
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_END( OBJ )
|
||||
|
||||
/*
|
||||
#define UF_BEHAVIOR_VIRTUAL 0
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_H( OBJ )\
|
||||
class UF_API OBJ ## Behavior {\
|
||||
public:\
|
||||
static void attach( uf::Entity& );\
|
||||
static void initialize( uf::Object& );\
|
||||
static void tick( uf::Object& );\
|
||||
static void render( uf::Object& );\
|
||||
static void destroy( uf::Object& );\
|
||||
};
|
||||
#if UF_BEHAVIOR_VIRTUAL
|
||||
#define UF_BEHAVIOR_VIRTUAL_H() \
|
||||
virtual void initialize();\
|
||||
virtual void destroy();\
|
||||
virtual void tick();\
|
||||
virtual void render();
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_VIRTUAL_DEFINITIONS( OBJ )\
|
||||
void uf::OBJ::initialize(){ uf::Behaviors::initialize(); }\
|
||||
void uf::OBJ::tick(){ uf::Behaviors::tick(); }\
|
||||
void uf::OBJ::render(){ uf::Behaviors::render(); }\
|
||||
void uf::OBJ::destroy(){ uf::Behaviors::destroy(); }
|
||||
#else
|
||||
#define UF_BEHAVIOR_VIRTUAL_H()
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_VIRTUAL_DEFINITIONS( OBJ )
|
||||
#endif
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_BEGIN( OBJ )\
|
||||
uf::OBJ::OBJ() { \
|
||||
uf::OBJ ## Behavior::attach( *this );\
|
||||
}\
|
||||
UF_BEHAVIOR_ENTITY_CPP_VIRTUAL_DEFINITIONS( OBJ )\
|
||||
void uf::OBJ ## Behavior::attach( uf::Entity& self ) {\
|
||||
self.addBehavior(pod::Behavior{\
|
||||
.type = uf::Behaviors::getType<uf::OBJ ## Behavior>(),\
|
||||
.initialize = uf::OBJ ## Behavior::initialize,\
|
||||
.tick = uf::OBJ ## Behavior::tick,\
|
||||
.render = uf::OBJ ## Behavior::render,\
|
||||
.destroy = uf::OBJ ## Behavior::destroy,\
|
||||
});\
|
||||
}
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_END( OBJ )
|
||||
|
||||
#define EXT_BEHAVIOR_ENTITY_CPP_BEGIN( OBJ )\
|
||||
void ext::OBJ ## Behavior::attach( uf::Entity& self ) {\
|
||||
self.addBehavior(pod::Behavior{\
|
||||
.type = uf::Behaviors::getType<ext::OBJ ## Behavior>(),\
|
||||
.initialize = ext::OBJ ## Behavior::initialize,\
|
||||
.tick = ext::OBJ ## Behavior::tick,\
|
||||
.render = ext::OBJ ## Behavior::render,\
|
||||
.destroy = ext::OBJ ## Behavior::destroy,\
|
||||
});\
|
||||
}
|
||||
#define EXT_BEHAVIOR_ENTITY_CPP_END( OBJ )
|
||||
*/
|
||||
#define UF_BEHAVIOR_ENTITY_CPP_END( OBJ )
|
@ -1,5 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace uf {
|
||||
UF_BEHAVIOR_ENTITY_H(Entity)
|
||||
namespace EntityBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void UF_API attach( uf::Entity& );
|
||||
void UF_API initialize( uf::Object& );
|
||||
void UF_API tick( uf::Object& );
|
||||
void UF_API render( uf::Object& );
|
||||
void UF_API destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
namespace uf {
|
||||
class UF_API Object;
|
||||
class UF_API Entity : public uf::Behaviors {
|
||||
friend class EntityBehavior;
|
||||
//friend class EntityBehavior;
|
||||
public:
|
||||
typedef std::vector<uf::Entity*> container_t;
|
||||
static uf::Entity null;
|
||||
@ -45,6 +45,9 @@ namespace uf {
|
||||
template<typename T=uf::Entity> const T& getParent() const;
|
||||
template<typename T=uf::Entity> const T& getRootParent() const;
|
||||
|
||||
void setUid();
|
||||
void unsetUid();
|
||||
|
||||
void setParent();
|
||||
void setParent( uf::Entity& parent );
|
||||
uf::Entity& addChild( uf::Entity& child );
|
||||
|
@ -37,13 +37,16 @@ namespace pod {
|
||||
|
||||
C& get( const std::string& name );
|
||||
template<typename T> C& get();
|
||||
|
||||
C& operator[]( const std::string& name );
|
||||
};
|
||||
}
|
||||
|
||||
namespace uf {
|
||||
namespace instantiator {
|
||||
extern UF_API pod::NamedTypes<pod::Instantiator>* objects;
|
||||
extern UF_API pod::NamedTypes<pod::Behavior>* behaviors;
|
||||
// extern UF_API pod::NamedTypes<pod::Behavior>* behaviors;
|
||||
extern UF_API std::unordered_map<std::string, pod::Behavior>* behaviors;
|
||||
|
||||
uf::Entity* UF_API alloc( size_t );
|
||||
template<typename T> T* alloc();
|
||||
@ -54,8 +57,9 @@ namespace uf {
|
||||
size_t UF_API collect( uint8_t = 0 );
|
||||
|
||||
template<typename T> void registerObject( const std::string& name );
|
||||
template<typename T> void registerBehavior( const std::string& name );
|
||||
// template<typename T> void registerBehavior( const std::string& name );
|
||||
template<typename T> void registerBinding( const std::string& name );
|
||||
void UF_API registerBehavior( const std::string& name, const pod::Behavior& );
|
||||
void UF_API registerBinding( const std::string& object, const std::string& behavior );
|
||||
|
||||
uf::Entity& UF_API instantiate( const std::string& );
|
||||
@ -64,6 +68,7 @@ namespace uf {
|
||||
|
||||
void UF_API bind( const std::string&, uf::Entity& );
|
||||
template<typename T> void bind( uf::Entity& );
|
||||
|
||||
void UF_API unbind( const std::string&, uf::Entity& );
|
||||
template<typename T> void unbind( uf::Entity& );
|
||||
};
|
||||
|
@ -34,6 +34,10 @@ template<typename T>
|
||||
C& pod::NamedTypes<C>::get() {
|
||||
return map[getName<T>()];
|
||||
}
|
||||
template<typename C>
|
||||
C& pod::NamedTypes<C>::operator[]( const std::string& name ) {
|
||||
return get(name);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* uf::instantiator::alloc() {
|
||||
@ -48,8 +52,9 @@ template<typename T> void uf::instantiator::registerObject( const std::string& n
|
||||
.behaviors = {}
|
||||
});
|
||||
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) std::cout << "Registered instantiation for " << name << std::endl;
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) UF_DEBUG_MSG("Registered instantiation for " << name);
|
||||
}
|
||||
#if 0
|
||||
template<typename T> void uf::instantiator::registerBehavior( const std::string& name ) {
|
||||
if ( !behaviors ) behaviors = new pod::NamedTypes<pod::Behavior>;
|
||||
auto& container = *uf::instantiator::behaviors;
|
||||
@ -61,16 +66,16 @@ template<typename T> void uf::instantiator::registerBehavior( const std::string&
|
||||
.destroy = T::destroy,
|
||||
});
|
||||
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) std::cout << "Registered behavior for " << name << std::endl;
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) UF_DEBUG_MSG("Registered behavior for " << name);
|
||||
}
|
||||
|
||||
#endif
|
||||
template<typename T> void uf::instantiator::registerBinding( const std::string& name ) {
|
||||
if ( !objects ) objects = new pod::NamedTypes<pod::Instantiator>;
|
||||
auto& container = *uf::instantiator::objects;
|
||||
auto& instantiator = container.get<T>();
|
||||
instantiator.behaviors.emplace_back(name);
|
||||
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) std::cout << "Registered binding for " << name << std::endl;
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) UF_DEBUG_MSG("Registered binding for " << name);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -90,7 +95,7 @@ template<typename T>
|
||||
void uf::instantiator::bind( uf::Entity& entity ) {
|
||||
auto& instantiator = uf::instantiator::objects->get<T>();
|
||||
for ( auto& name : instantiator.behaviors ) {
|
||||
auto& behavior = uf::instantiator::behaviors->get( name );
|
||||
auto& behavior = (*uf::instantiator::behaviors)[name];
|
||||
entity.addBehavior(behavior);
|
||||
}
|
||||
}
|
||||
@ -99,88 +104,7 @@ template<typename T>
|
||||
void uf::instantiator::unbind( uf::Entity& entity ) {
|
||||
auto& instantiator = uf::instantiator::objects->get<T>();
|
||||
for ( auto& name : instantiator.behaviors ) {
|
||||
auto& behavior = uf::instantiator::behaviors->get( name );
|
||||
auto& behavior = (*uf::instantiator::behaviors)[name];
|
||||
entity.removeBehavior(behavior);
|
||||
}
|
||||
}
|
||||
/*
|
||||
template<typename T>
|
||||
T* uf::instantiator::alloc() {
|
||||
return (T*) alloc( sizeof(T) );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string uf::instantiator::getName() {
|
||||
auto type = getType<T>();
|
||||
auto& names = *uf::instantiator::names;
|
||||
return names[type];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
uf::instantiator::type_t uf::instantiator::getType() {
|
||||
return std::type_index(typeid(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& uf::instantiator::instantiate() {
|
||||
T* entity = alloc<T>();
|
||||
::new (entity) T();
|
||||
T& object = *entity;
|
||||
uf::instantiator::bind<T>( object );
|
||||
return object;
|
||||
}
|
||||
template<typename T>
|
||||
T* uf::instantiator::_instantiate() {
|
||||
return &instantiate<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void uf::instantiator::add( const std::string& name ) {
|
||||
if ( !map ) map = new std::unordered_map<std::string, pod::Instantiator>;
|
||||
if ( !names ) names = new std::unordered_map<uf::instantiator::type_t, std::string>;
|
||||
|
||||
auto& map = *uf::instantiator::map;
|
||||
auto& names = *uf::instantiator::names;
|
||||
|
||||
auto type = getType<T>();
|
||||
names[type] = name;
|
||||
map[name] = {
|
||||
.function = _instantiate<T>
|
||||
};
|
||||
|
||||
std::cout << "Registered instantiation for " << name << std::endl;
|
||||
}
|
||||
template<typename T>
|
||||
void uf::instantiator::add( const pod::Behavior& behavior ) {
|
||||
if ( !registered<T>() ) return;
|
||||
auto type = getType<T>();
|
||||
auto& map = *uf::instantiator::map;
|
||||
auto& instantiator = map[getName<T>()];
|
||||
instantiator.behaviors.emplace_back(behavior);
|
||||
}
|
||||
template<typename T, typename U>
|
||||
void uf::instantiator::add() {
|
||||
return uf::instantiator::add<T>(pod::Behavior{
|
||||
.type = uf::Behaviors::getType<U>(),
|
||||
.initialize = U::initialize,
|
||||
.tick = U::tick,
|
||||
.render = U::render,
|
||||
.destroy = U::destroy,
|
||||
});
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool uf::instantiator::registered() {
|
||||
return uf::instantiator::map->count(getName<T>()) > 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void uf::instantiator::bind( T& object ) {
|
||||
if ( !registered<T>() ) return;
|
||||
auto& map = *uf::instantiator::map;
|
||||
auto& instantiator = map[getName<T>()];
|
||||
for ( auto& behavior : instantiator.behaviors ) {
|
||||
object.addBehavior(behavior);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
@ -7,10 +7,17 @@ namespace {\
|
||||
});\
|
||||
}
|
||||
|
||||
// uf::instantiator::registerBehavior<BEHAVIOR>( UF_NS_GET_LAST(BEHAVIOR) );
|
||||
#define UF_BEHAVIOR_REGISTER_CPP( BEHAVIOR ) \
|
||||
namespace {\
|
||||
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\
|
||||
uf::instantiator::registerBehavior<BEHAVIOR>( UF_NS_GET_LAST(BEHAVIOR) );\
|
||||
uf::instantiator::registerBehavior(UF_NS_GET_LAST(BEHAVIOR), pod::Behavior{\
|
||||
.type = BEHAVIOR::type,\
|
||||
.initialize = BEHAVIOR::initialize,\
|
||||
.tick = BEHAVIOR::tick,\
|
||||
.render = BEHAVIOR::render,\
|
||||
.destroy = BEHAVIOR::destroy,\
|
||||
});\
|
||||
});\
|
||||
}
|
||||
|
||||
@ -30,8 +37,16 @@ namespace {\
|
||||
#define UF_OBJECT_BIND_BEHAVIOR( BEHAVIOR )\
|
||||
uf::instantiator::registerBinding( name, UF_NS_GET_LAST(BEHAVIOR) );
|
||||
|
||||
// uf::instantiator::registerBehavior<BEHAVIOR>( UF_NS_GET_LAST(BEHAVIOR) );
|
||||
#define UF_OBJECT_REGISTER_BEHAVIOR( BEHAVIOR )\
|
||||
uf::instantiator::registerBehavior<BEHAVIOR>( UF_NS_GET_LAST(BEHAVIOR) );\
|
||||
if ( !uf::instantiator::behaviors ) uf::instantiator::behaviors = new std::unordered_map<std::string, pod::Behavior>;\
|
||||
uf::instantiator::registerBehavior(UF_NS_GET_LAST(BEHAVIOR), pod::Behavior{\
|
||||
.type = BEHAVIOR::type,\
|
||||
.initialize = BEHAVIOR::initialize,\
|
||||
.tick = BEHAVIOR::tick,\
|
||||
.render = BEHAVIOR::render,\
|
||||
.destroy = BEHAVIOR::destroy,\
|
||||
});\
|
||||
UF_OBJECT_BIND_BEHAVIOR( BEHAVIOR )
|
||||
|
||||
#define UF_OBJECT_REGISTER_END()\
|
||||
|
@ -1,5 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/ext/json/json.h>
|
||||
#include <uf/engine/behavior/behavior.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace uf {
|
||||
UF_BEHAVIOR_ENTITY_H(Object)
|
||||
namespace ObjectBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void UF_API attach( uf::Entity& );
|
||||
void UF_API initialize( uf::Object& );
|
||||
void UF_API tick( uf::Object& );
|
||||
void UF_API render( uf::Object& );
|
||||
void UF_API destroy( uf::Object& );
|
||||
struct Metadata {
|
||||
struct Queued {
|
||||
std::string name;
|
||||
ext::json::Value payload;
|
||||
double timeout;
|
||||
};
|
||||
|
||||
struct {
|
||||
std::unordered_map<std::string, std::vector<size_t>> bound;
|
||||
std::vector<Queued> queue;
|
||||
} hooks;
|
||||
struct {
|
||||
bool ignoreGraph = false;
|
||||
} system;
|
||||
};
|
||||
}
|
||||
}
|
@ -5,12 +5,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace uf {
|
||||
class UF_API GltfBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace GltfBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void UF_API attach( uf::Object& );
|
||||
void UF_API initialize( uf::Object& );
|
||||
void UF_API tick( uf::Object& );
|
||||
void UF_API render( uf::Object& );
|
||||
void UF_API destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -5,12 +5,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace uf {
|
||||
class UF_API LoadingBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace LoadingBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void UF_API attach( uf::Object& );
|
||||
void UF_API initialize( uf::Object& );
|
||||
void UF_API tick( uf::Object& );
|
||||
void UF_API render( uf::Object& );
|
||||
void UF_API destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -5,12 +5,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace uf {
|
||||
class UF_API LuaBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace LuaBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void UF_API attach( uf::Object& );
|
||||
void UF_API initialize( uf::Object& );
|
||||
void UF_API tick( uf::Object& );
|
||||
void UF_API render( uf::Object& );
|
||||
void UF_API destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -5,12 +5,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace uf {
|
||||
class UF_API RenderBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace RenderBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void UF_API attach( uf::Object& );
|
||||
void UF_API initialize( uf::Object& );
|
||||
void UF_API tick( uf::Object& );
|
||||
void UF_API render( uf::Object& );
|
||||
void UF_API destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "behavior.h"
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/instantiator/instantiator.h>
|
||||
#include <uf/utils/hook/hook.h>
|
||||
@ -33,18 +34,13 @@ namespace uf {
|
||||
|
||||
std::string formatHookName( const std::string& name );
|
||||
static std::string formatHookName( const std::string& name, size_t uid, bool fetch = true );
|
||||
// void queueHook( const std::string&, const std::string& = "", double = 0 );
|
||||
// std::vector<std::string> callHook( const std::string&, const std::string& = "" );
|
||||
// std::size_t addHook( const std::string&, const uf::HookHandler::Readable::function_t& );
|
||||
|
||||
void queueHook( const std::string&, const ext::json::Value& = ext::json::null(), double = 0 );
|
||||
// std::vector<ext::json::Value> callHook( const std::string&, const ext::json::Value& = ext::json::null() );
|
||||
uf::Hooks::return_t callHook( const std::string& );
|
||||
uf::Hooks::return_t callHook( const std::string&, const ext::json::Value& );
|
||||
uf::Hooks::return_t callHook( const std::string&, const uf::Serializer& );
|
||||
|
||||
template<typename T> size_t addHook( const std::string& name, T function );
|
||||
// template<typename T> uf::Hooks::return_t queueHook( const std::string& name, const T& payload, double = 0 );
|
||||
template<typename T> uf::Hooks::return_t callHook( const std::string& name, const T& payload );
|
||||
|
||||
std::string grabURI( const std::string& filename, const std::string& root = "" );
|
||||
|
@ -20,8 +20,13 @@ template<typename T>
|
||||
size_t uf::Object::addHook( const std::string& name, T callback ) {
|
||||
std::string parsed = this->formatHookName( name );
|
||||
std::size_t id = uf::hooks.addHook( parsed, callback );
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
metadata["system"]["hooks"]["alloc"][parsed].emplace_back(id);
|
||||
#if UF_ENTITY_METADATA_USE_JSON
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
metadata["system"]["hooks"]["bound"][parsed].emplace_back(id);
|
||||
#else
|
||||
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
|
||||
metadata.hooks.bound[parsed].emplace_back(id);
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
template<typename T>
|
||||
|
@ -1,5 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace uf {
|
||||
UF_BEHAVIOR_ENTITY_H(Scene)
|
||||
namespace SceneBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void UF_API attach( uf::Entity& );
|
||||
void UF_API initialize( uf::Object& );
|
||||
void UF_API tick( uf::Object& );
|
||||
void UF_API render( uf::Object& );
|
||||
void UF_API destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <uf/engine/object/object.h>
|
||||
|
||||
#define UF_SCENE_USE_GRAPH 1
|
||||
|
||||
namespace uf {
|
||||
class UF_API Scene : public uf::Object {
|
||||
public:
|
||||
@ -19,6 +21,12 @@ namespace uf {
|
||||
|
||||
namespace scene {
|
||||
extern UF_API std::vector<uf::Scene*> scenes;
|
||||
extern UF_API std::vector<uf::Entity*> graph;
|
||||
extern UF_API bool queuedInvalidation;
|
||||
extern UF_API bool useGraph;
|
||||
void UF_API invalidateGraph();
|
||||
std::vector<uf::Entity*> UF_API generateGraph();
|
||||
|
||||
Scene& UF_API getCurrentScene();
|
||||
Scene& UF_API loadScene( const std::string& name, const std::string& filename = "" );
|
||||
Scene& UF_API loadScene( const std::string& name, const uf::Serializer& );
|
||||
|
@ -4,10 +4,16 @@
|
||||
#if UF_USE_LUA
|
||||
#if UF_USE_LUAJIT
|
||||
#define SOL_LUAJIT 1
|
||||
#define SOL_USING_CXX_LUA_JIT 1
|
||||
// #define SOL_USING_CXX_LUA_JIT 1
|
||||
#else
|
||||
// #define SOL_USING_CXX_LUA 1
|
||||
#endif
|
||||
#define SOL_NO_EXCEPTIONS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define SOL_NO_THREAD_LOCAL 1
|
||||
#else
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#endif
|
||||
|
||||
#include <sol/sol.hpp>
|
||||
#include <unordered_map>
|
||||
|
@ -29,28 +29,4 @@ namespace {\
|
||||
}
|
||||
|
||||
#define UF_LUA_REGISTER_USERTYPE_DEFINE(k, v) #k, v
|
||||
#define UF_LUA_REGISTER_USERTYPE_MEMBER(member) UF_NS_GET_LAST(member), &member
|
||||
|
||||
|
||||
/*
|
||||
#define UF_NS_LUA_REGISTER_USERTYPE_BEGIN(k, v) {\
|
||||
std::string name = #v;\
|
||||
sol::usertype<k::v> usertype = state.new_usertype<k::v>(name);
|
||||
|
||||
#define POD_LUA_REGISTER_USERTYPE_BEGIN(x) UF_NS_LUA_REGISTER_USERTYPE_BEGIN(pod, x)
|
||||
#define UF_LUA_REGISTER_USERTYPE_BEGIN(x) UF_NS_LUA_REGISTER_USERTYPE_BEGIN(uf, x)
|
||||
#define EXT_LUA_REGISTER_USERTYPE_BEGIN(x) UF_NS_LUA_REGISTER_USERTYPE_BEGIN(ext, x)
|
||||
|
||||
#define UF_LUA_REGISTER_USERTYPE_DEFINE(k, v) usertype[#k] = v;
|
||||
#define POD_LUA_REGISTER_USERTYPE_DEFINE(k, v) UF_LUA_REGISTER_USERTYPE_DEFINE(k, v)
|
||||
#define EXT_LUA_REGISTER_USERTYPE_DEFINE(k, v) UF_LUA_REGISTER_USERTYPE_DEFINE(k, v)
|
||||
|
||||
#define UF_NS_LUA_REGISTER_USERTYPE_MEMBER(ns, x, y) UF_LUA_REGISTER_USERTYPE_DEFINE(y, &ns::x::y)
|
||||
#define POD_LUA_REGISTER_USERTYPE_MEMBER(x, y) UF_NS_LUA_REGISTER_USERTYPE_MEMBER(pod, x, y)
|
||||
#define UF_LUA_REGISTER_USERTYPE_MEMBER(x, y) UF_NS_LUA_REGISTER_USERTYPE_MEMBER(uf, x, y)
|
||||
#define EXT_LUA_REGISTER_USERTYPE_MEMBER(x, y) UF_NS_LUA_REGISTER_USERTYPE_MEMBER(ext, x, y)
|
||||
|
||||
#define UF_LUA_REGISTER_USERTYPE_END() }
|
||||
#define POD_LUA_REGISTER_USERTYPE_END() UF_LUA_REGISTER_USERTYPE_END()
|
||||
#define EXT_LUA_REGISTER_USERTYPE_END() UF_LUA_REGISTER_USERTYPE_END()
|
||||
*/
|
||||
#define UF_LUA_REGISTER_USERTYPE_MEMBER(member) UF_NS_GET_LAST(member), &member
|
@ -22,10 +22,12 @@
|
||||
#include <GLdc/gl.h>
|
||||
#include <GLdc/glu.h>
|
||||
#include <GLdc/glkos.h>
|
||||
#include <GLdc/glext.h>
|
||||
#else
|
||||
#include <GLkos/gl.h>
|
||||
#include <GLkos/glu.h>
|
||||
#include <GLkos/glut.h>
|
||||
#include <GLkos/glext.h>
|
||||
|
||||
#define glIsTexture(x) ( x != 0 )
|
||||
#endif
|
||||
|
@ -51,6 +51,7 @@ namespace ext {
|
||||
enums::Image::type_t type = enums::Image::TYPE_2D;
|
||||
enums::Image::viewType_t viewType = enums::Image::VIEW_TYPE_2D;
|
||||
enums::Format::type_t format = enums::Format::R8G8B8A8_UNORM;
|
||||
size_t internalFormat = 0;
|
||||
|
||||
struct Descriptor {
|
||||
GLuint image = GL_NULL_HANDLE;
|
||||
|
@ -28,4 +28,17 @@
|
||||
#define UF_EXCEPTION(X) UF_ERROR_MSG(X)
|
||||
#else
|
||||
#define UF_EXCEPTION(X) throw std::runtime_error(X)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define UF_TIMER_TRACE_INIT() uf::Timer<long long> TIMER_TRACE;
|
||||
|
||||
#define UF_TIMER_TRACE(X) {\
|
||||
auto elapsed = TIMER_TRACE.elapsed().asMilliseconds();\
|
||||
if ( elapsed > 0 ) UF_DEBUG_MSG(X << " | " << TIMER_TRACE.elapsed().asMilliseconds() << "ms");\
|
||||
}
|
||||
|
||||
#define UF_TIMER_TRACE_RESET(X) {\
|
||||
auto elapsed = TIMER_TRACE.elapsed().asMilliseconds();\
|
||||
if ( elapsed > 0 ) UF_DEBUG_MSG(X << " | " << TIMER_TRACE.elapsed().asMilliseconds() << "ms");\
|
||||
TIMER_TRACE.reset();\
|
||||
}
|
||||
|
9
engine/inc/uf/spec/controller/controller.h
Normal file
9
engine/inc/uf/spec/controller/controller.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/spec/universal.h>
|
||||
|
||||
// include universal
|
||||
#include "universal.h"
|
||||
// defines which implementation to use
|
||||
#include UF_ENV_HEADER
|
23
engine/inc/uf/spec/controller/dreamcast.h
Normal file
23
engine/inc/uf/spec/controller/dreamcast.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include "universal.h"
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
|
||||
namespace spec {
|
||||
namespace dreamcast {
|
||||
namespace controller {
|
||||
void UF_API initialize();
|
||||
void UF_API tick();
|
||||
void UF_API terminate();
|
||||
|
||||
bool UF_API connected( size_t = 0 );
|
||||
bool UF_API pressed( const std::string&, size_t = 0 );
|
||||
float UF_API analog( const std::string&, size_t = 0 );
|
||||
}
|
||||
}
|
||||
namespace controller = dreamcast::controller;
|
||||
}
|
||||
|
||||
#endif
|
17
engine/inc/uf/spec/controller/universal.h
Normal file
17
engine/inc/uf/spec/controller/universal.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
|
||||
namespace spec {
|
||||
namespace uni {
|
||||
namespace controller {
|
||||
void UF_API initialize();
|
||||
void UF_API tick();
|
||||
void UF_API terminate();
|
||||
|
||||
bool UF_API connected( size_t = 0 );
|
||||
bool UF_API pressed( const std::string&, size_t = 0 );
|
||||
float UF_API analog( const std::string&, size_t = 0 );
|
||||
};
|
||||
};
|
||||
}
|
8
engine/inc/uf/spec/controller/unknown.h
Normal file
8
engine/inc/uf/spec/controller/unknown.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include "universal.h"
|
||||
|
||||
namespace spec {
|
||||
namespace controller = uni::controller;
|
||||
}
|
23
engine/inc/uf/spec/controller/windows.h
Normal file
23
engine/inc/uf/spec/controller/windows.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include "universal.h"
|
||||
|
||||
#if UF_ENV_WINDOWS
|
||||
|
||||
namespace spec {
|
||||
namespace win32 {
|
||||
namespace controller {
|
||||
void UF_API initialize();
|
||||
void UF_API tick();
|
||||
void UF_API terminate();
|
||||
|
||||
bool UF_API connected( size_t = 0 );
|
||||
bool UF_API pressed( const std::string&, size_t = 0 );
|
||||
float UF_API analog( const std::string&, size_t = 0 );
|
||||
}
|
||||
}
|
||||
namespace controller = win32::controller;
|
||||
}
|
||||
|
||||
#endif
|
@ -64,7 +64,6 @@ namespace spec {
|
||||
void UF_API setTracking(bool state);
|
||||
static pod::Vector2ui UF_API getResolution();
|
||||
void UF_API switchToFullscreen( bool borderless = false );
|
||||
static std::string UF_API getKey(/*WPARAM key, LPARAM flags*/);
|
||||
};
|
||||
}
|
||||
typedef spec::dreamcast::Window Window;
|
||||
|
@ -18,6 +18,7 @@ namespace uf {
|
||||
Image::vec2_t m_dimensions;
|
||||
std::size_t m_bpp;
|
||||
std::size_t m_channels;
|
||||
std::size_t m_format;
|
||||
public:
|
||||
// C-tor
|
||||
Image(); // Default
|
||||
@ -38,18 +39,27 @@ namespace uf {
|
||||
// Getters
|
||||
void loadFromBuffer( const Image::pixel_t::type_t* pointer, const pod::Vector2ui& size, std::size_t bpp, std::size_t channels, bool flip = false );
|
||||
void loadFromBuffer( const Image::container_t& container, const pod::Vector2ui& size, std::size_t bpp, std::size_t channels, bool flip = false );
|
||||
|
||||
std::string getFilename() const;
|
||||
|
||||
Image::container_t& getPixels();
|
||||
const Image::container_t& getPixels() const;
|
||||
|
||||
Image::pixel_t::type_t* getPixelsPtr();
|
||||
const Image::pixel_t::type_t* getPixelsPtr() const;
|
||||
|
||||
Image::vec2_t& getDimensions();
|
||||
const Image::vec2_t& getDimensions() const;
|
||||
|
||||
std::size_t& getBpp();
|
||||
std::size_t getBpp() const;
|
||||
|
||||
std::size_t& getChannels();
|
||||
std::size_t getChannels() const;
|
||||
|
||||
std::string getHash() const;
|
||||
size_t getFormat() const;
|
||||
|
||||
Image::pixel_t at( const Image::vec2_t& at );
|
||||
// Modifiers
|
||||
void flip();
|
||||
|
@ -3,6 +3,12 @@
|
||||
#include <uf/config.h>
|
||||
#include <cstdint>
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
#include "sh4.h"
|
||||
#include <dc/matrix.h>
|
||||
#define UF_EZ_VEC4(vec, size) vec[0], size > 1 ? vec[1] : 0, size > 2 ? vec[2] : 0, size > 3 ? vec[3] : 0
|
||||
#endif
|
||||
|
||||
namespace pod {
|
||||
namespace Math {
|
||||
typedef float num_t;
|
||||
@ -19,7 +25,7 @@ namespace uf {
|
||||
float UF_API unquantize( uint16_t );
|
||||
|
||||
template<typename T>
|
||||
T lerp( const T& a, const T& b, double f ) {
|
||||
inline T lerp( const T& a, const T& b, double f ) {
|
||||
return a + f * (b - a);
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ namespace uf {
|
||||
template<typename T> pod::Matrix<T,4,4> multiply( const pod::Matrix<T,4,4>& left, const pod::Matrix<T,4,4>& right ); // Multiplies two matrices of same type and size together
|
||||
template<typename T=pod::Matrix4> T /*UF_API*/ transpose( const T& matrix ); // Flip sign of all components
|
||||
template<typename T=pod::Matrix4> T /*UF_API*/ inverse( const T& matrix ); // Flip sign of all components
|
||||
template<typename T=pod::Math::num_t> pod::Vector3t<T> multiply( const pod::Matrix4t<T>& mat, const pod::Vector3t<T>& vector );
|
||||
template<typename T=pod::Math::num_t> pod::Vector3t<T> multiply( const pod::Matrix4t<T>& mat, const pod::Vector3t<T>& vector, T w = 1 );
|
||||
template<typename T=pod::Math::num_t> pod::Vector4t<T> multiply( const pod::Matrix4t<T>& mat, const pod::Vector4t<T>& vector );
|
||||
|
||||
template<typename T=pod::Matrix4> T /*UF_API*/ multiplyAll( const T& matrix, typename T::type_t scalar );
|
||||
|
@ -170,6 +170,16 @@ template<typename T> pod::Matrix<T,4,4> uf::matrix::multiply( const pod::Matrix<
|
||||
uf::simd::store(row, &res[4*i]);
|
||||
}
|
||||
return res;
|
||||
#elif UF_ENV_DREAMCAST
|
||||
// kallistios has dedicated SH4 asm for these or something
|
||||
mat_load( (matrix_t*) &left[0] );
|
||||
mat_apply( (matrix_t*) &right[0] );
|
||||
mat_store( (matrix_t*) &res[0]);
|
||||
|
||||
// gives very wrong output, not sure why
|
||||
// MATH_Load_Matrix_Product( (ALL_FLOATS_STRUCT*) &left[0], (ALL_FLOATS_STRUCT*) &right[0] );
|
||||
// MATH_Store_XMTRX( (ALL_FLOATS_STRUCT*) &res[0]);
|
||||
return res;
|
||||
#elif 1
|
||||
//
|
||||
float* dstPtr = &res[0];
|
||||
@ -400,15 +410,15 @@ template<typename T> T uf::matrix::inverse( const T& matrix ) {
|
||||
template<typename T> pod::Matrix<typename T::type_t, T::columns, T::columns> uf::matrix::multiply( T& left, const T& right ) {
|
||||
return left = uf::matrix::multiply((const T&) left, right);
|
||||
}
|
||||
template<typename T> pod::Vector3t<T> uf::matrix::multiply( const pod::Matrix4t<T>& mat, const pod::Vector3t<T>& vector ) {
|
||||
return {
|
||||
vector[0] * mat[0] + vector[1] * mat[4] + vector[2] * mat[8] + vector[3] * mat[12],
|
||||
vector[0] * mat[1] + vector[1] * mat[5] + vector[2] * mat[9] + vector[3] * mat[13],
|
||||
vector[0] * mat[2] + vector[1] * mat[6] + vector[2] * mat[10] + vector[3] * mat[14]
|
||||
// vector[0] * mat[3] + vector[1] * mat[7] + vector[2] * mat[11] + vector[3] * mat[15]
|
||||
};
|
||||
template<typename T> pod::Vector3t<T> uf::matrix::multiply( const pod::Matrix4t<T>& mat, const pod::Vector3t<T>& vector, T w ) {
|
||||
return uf::matrix::multiply( mat, pod::Vector4t<T>{ vector[0], vector[1], vector[2], w } );
|
||||
}
|
||||
template<typename T> pod::Vector4t<T> uf::matrix::multiply( const pod::Matrix4t<T>& mat, const pod::Vector4t<T>& vector ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
MATH_Load_XMTRX( (ALL_FLOATS_STRUCT*) &mat[0] );
|
||||
auto res = MATH_Matrix_Transform( vector[0], vector[1], vector[2], vector[3] );
|
||||
return *((pod::Vector4t<T>*) &res);
|
||||
#endif
|
||||
return {
|
||||
vector[0] * mat[0] + vector[1] * mat[4] + vector[2] * mat[8] + vector[3] * mat[12],
|
||||
vector[0] * mat[1] + vector[1] * mat[5] + vector[2] * mat[9] + vector[3] * mat[13],
|
||||
|
2194
engine/inc/uf/utils/math/sh4.h
Normal file
2194
engine/inc/uf/utils/math/sh4.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -71,19 +71,29 @@ template<typename T> // Divides two vectors of same type and size
|
||||
T /*UF_API*/ uf::vector::divide( const T& left, const T& right ) {
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::div( left, right );
|
||||
#endif
|
||||
#elif UF_ENV_DREAMCAST
|
||||
T res;
|
||||
for ( std::size_t i = 0; i < T::size; ++i ) res[i] = MATH_Fast_Divide(left[i], right[i]);
|
||||
return res;
|
||||
#else
|
||||
T res;
|
||||
for ( std::size_t i = 0; i < T::size; ++i ) res[i] = left[i] / right[i];
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
template<typename T> // Divides this vector by a scalar
|
||||
T /*UF_API*/ uf::vector::divide( const T& vector, const typename T::type_t& scalar ) {
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::div( vector, scalar );
|
||||
#endif
|
||||
#elif UF_ENV_DREAMCAST
|
||||
T res;
|
||||
for ( std::size_t i = 0; i < T::size; ++i ) res[i] = MATH_Fast_Divide(vector[i], scalar);
|
||||
return res;
|
||||
#else
|
||||
T res;
|
||||
for ( std::size_t i = 0; i < T::size; ++i ) res[i] = vector[i] / scalar;
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
template<typename T> // Compute the sum of all components
|
||||
typename T::type_t /*UF_API*/ uf::vector::sum( const T& vector ) {
|
||||
@ -172,7 +182,9 @@ T& /*UF_API*/ uf::vector::normalize( T& vector ) {
|
||||
// Complex arithmetic
|
||||
template<typename T> // Compute the dot product between two vectors
|
||||
typename T::type_t /*UF_API*/ uf::vector::dot( const T& left, const T& right ) {
|
||||
#if UF_USE_SIMD
|
||||
#if UF_ENV_DREAMCAST
|
||||
return MATH_fipr( UF_EZ_VEC4(left, T::size), UF_EZ_VEC4(right, T::size) );
|
||||
#elif UF_USE_SIMD
|
||||
return uf::simd::dot( left, right );
|
||||
#endif
|
||||
return uf::vector::sum(uf::vector::multiply(left, right));
|
||||
@ -185,7 +197,11 @@ template<typename T> // Linearly interpolate between two vectors
|
||||
T /*UF_API*/ uf::vector::lerp( const T& from, const T& to, double delta, bool clamp ) {
|
||||
delta = fmax( 0, fmin(1,delta) );
|
||||
// from + ( ( to - from ) * delta )
|
||||
#if UF_USE_SIMD
|
||||
#if UF_ENV_DREAMCAST
|
||||
T res;
|
||||
for ( auto i = 0; i < T::size; ++i ) res[i] = MATH_Lerp( from[i], to[i], delta );
|
||||
return res;
|
||||
#elif UF_USE_SIMD
|
||||
return uf::simd::add(from, uf::simd::mul( uf::simd::sub(to, from), (float) delta) );
|
||||
#endif
|
||||
return uf::vector::add(from, uf::vector::multiply( uf::vector::subtract(to, from), delta ) );
|
||||
@ -194,7 +210,11 @@ template<typename T> // Linearly interpolate between two vectors
|
||||
T /*UF_API*/ uf::vector::lerp( const T& from, const T& to, const T& delta, bool clamp ) {
|
||||
//delta = fmax( 0, fmin(1,delta) );
|
||||
// from + ( ( to - from ) * delta )
|
||||
#if UF_USE_SIMD
|
||||
#if UF_ENV_DREAMCAST
|
||||
T res;
|
||||
for ( auto i = 0; i < T::size; ++i ) res[i] = MATH_Lerp( from[i], to[i], delta[i] );
|
||||
return res;
|
||||
#elif UF_USE_SIMD
|
||||
return uf::simd::add(from, uf::simd::mul( uf::simd::sub(to, from), delta) );
|
||||
#endif
|
||||
return uf::vector::add(from, uf::vector::multiply( uf::vector::subtract(to, from), delta ) );
|
||||
@ -224,7 +244,10 @@ T /*UF_API*/ uf::vector::mix( const T& x, const T& y, double a, bool clamp ) {
|
||||
}
|
||||
template<typename T> // Compute the distance between two vectors (doesn't sqrt)
|
||||
typename T::type_t /*UF_API*/ uf::vector::distanceSquared( const T& a, const T& b ) {
|
||||
#if UF_USE_SIMD
|
||||
#if UF_ENV_DREAMCAST
|
||||
T delta = uf::vector::subtract(b, a);
|
||||
return MATH_Sum_of_Squares( UF_EZ_VEC4( delta, T::size ) );
|
||||
#elif UF_USE_SIMD
|
||||
uf::simd::value<typename T::type_t> delta = uf::simd::sub( b, a );
|
||||
return uf::vector::sum( uf::simd::vector( uf::simd::mul( delta, delta ) ) );
|
||||
#else
|
||||
@ -235,6 +258,9 @@ typename T::type_t /*UF_API*/ uf::vector::distanceSquared( const T& a, const T&
|
||||
}
|
||||
template<typename T> // Compute the distance between two vectors
|
||||
typename T::type_t /*UF_API*/ uf::vector::distance( const T& a, const T& b ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
return MATH_Fast_Sqrt(uf::vector::distanceSquared(a,b));
|
||||
#endif
|
||||
return sqrt(uf::vector::distanceSquared(a,b));
|
||||
}
|
||||
template<typename T> // Gets the magnitude of the vector
|
||||
@ -243,12 +269,18 @@ typename T::type_t /*UF_API*/ uf::vector::magnitude( const T& vector ) {
|
||||
}
|
||||
template<typename T> // Compute the norm of the vector
|
||||
typename T::type_t /*UF_API*/ uf::vector::norm( const T& vector ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
return MATH_Fast_Sqrt( uf::vector::magnitude(vector) );
|
||||
#endif
|
||||
return sqrt( uf::vector::magnitude(vector) );
|
||||
}
|
||||
template<typename T> // Normalizes a vector
|
||||
T /*UF_API*/ uf::vector::normalize( const T& vector ) {
|
||||
typename T::type_t norm = uf::vector::norm(vector);
|
||||
if ( norm == 0 ) return vector;
|
||||
#if UF_ENV_DREAMCAST
|
||||
return uf::vector::multiply(vector, MATH_fsrra(norm));
|
||||
#endif
|
||||
return uf::vector::divide(vector, norm);
|
||||
}
|
||||
template<typename T> // Normalizes a vector
|
||||
@ -284,6 +316,9 @@ T /*UF_API*/ uf::vector::cross( const T& a, const T& b ) {
|
||||
uf::simd::value<typename T::type_t> res = _mm_shuffle_ps(tmp2,tmp2,_MM_SHUFFLE(3,0,2,1));
|
||||
return res;
|
||||
#endif
|
||||
#elif UF_ENV_DREAMCAST
|
||||
auto res = MATH_Cross_Product( a.x, a.y, a.z, b.x, b.y, b.z );
|
||||
return *((T*) &res);
|
||||
#endif
|
||||
return T{
|
||||
a.y * b.z - b.y * a.z,
|
||||
|
@ -174,6 +174,8 @@ std::string uf::Asset::load( const std::string& uri, const std::string& hash, co
|
||||
#if UF_USE_OPENGL_FIXED_FUNCTION
|
||||
// force disable use of a texture atlas, for now
|
||||
metadata[uri]["flags"]["ATLAS"] = false;
|
||||
metadata[uri]["flags"]["SEPARATE"] = true;
|
||||
metadata[uri]["flags"]["NORMALS"] = true;
|
||||
#else
|
||||
metadata[uri]["flags"]["ATLAS"] = true;
|
||||
#endif
|
||||
|
@ -26,7 +26,7 @@ void uf::Behaviors::removeBehavior( const pod::Behavior& behavior ) {
|
||||
|
||||
#define FUNCTION_AS_VARIABLE(x) x
|
||||
|
||||
#define UF_BEHAVIOR_POLYFILL UF_BEHAVIOR_POLYFILL_SAFE
|
||||
#define UF_BEHAVIOR_POLYFILL UF_BEHAVIOR_POLYFILL_FAST
|
||||
/*
|
||||
// if ( this->hasComponent<uf::Serializer>() ) {\
|
||||
// auto& metadata = this->getComponent<uf::Serializer>();\
|
||||
@ -38,121 +38,46 @@ void uf::Behaviors::removeBehavior( const pod::Behavior& behavior ) {
|
||||
// multithreading = metadata["system"]["behavior"][#f]["multithreading"].as<bool>();\
|
||||
// }\
|
||||
*/
|
||||
|
||||
#define UF_BEHAVIOR_POLYFILL_SAFE(f)\
|
||||
bool headLoopChildren = true;\
|
||||
bool forwardIteration = true;\
|
||||
bool multithreading = false;\
|
||||
auto function = [&]() -> int {\
|
||||
if ( headLoopChildren ) {\
|
||||
if ( forwardIteration )\
|
||||
for ( auto& behavior : this->m_behaviors )\
|
||||
behavior.f(self);\
|
||||
else\
|
||||
for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it )\
|
||||
it->f(self);\
|
||||
} else {\
|
||||
if ( forwardIteration ) {\
|
||||
auto it = this->m_behaviors.begin();\
|
||||
for ( ++it; it != this->m_behaviors.end(); ++it )\
|
||||
it->f(self);\
|
||||
if ( (it = this->m_behaviors.begin()) != this->m_behaviors.end() ) {\
|
||||
it->f(self);\
|
||||
}\
|
||||
} else {\
|
||||
auto it = this->m_behaviors.rbegin();\
|
||||
for ( ++it; it != this->m_behaviors.rend(); ++it )\
|
||||
it->f(self);\
|
||||
if ( (it = this->m_behaviors.rbegin()) != this->m_behaviors.rend() ) {\
|
||||
it->f(self);\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
return 0;\
|
||||
};\
|
||||
if ( multithreading ) uf::thread::add( uf::thread::fetchWorker(), function, true ); else function();
|
||||
|
||||
#define UF_BEHAVIOR_POLYFILL_FAST(f)\
|
||||
if ( this->m_behaviors.empty() ) return;\
|
||||
uf::Object& self = *((uf::Object*) this);\
|
||||
bool headLoopChildren = true;\
|
||||
bool forwardIteration = true;\
|
||||
bool multithreading = false;\
|
||||
bool useWorkers = false;\
|
||||
std::vector<std::function<int()>> jobs;\
|
||||
if ( this->hasComponent<uf::Serializer>() ) {\
|
||||
auto& metadata = this->getComponent<uf::Serializer>();\
|
||||
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["head loop children"] ) )\
|
||||
headLoopChildren = metadata["system"]["behavior"][#f]["head loop children"].as<bool>();\
|
||||
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["forward iteration"] ) )\
|
||||
forwardIteration = metadata["system"]["behavior"][#f]["forward iteration"].as<bool>();\
|
||||
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["multithreading"] ) )\
|
||||
multithreading = metadata["system"]["behavior"][#f]["multithreading"].as<bool>();\
|
||||
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["use workers"] ) )\
|
||||
useWorkers = metadata["system"]["behavior"][#f]["use workers"].as<bool>();\
|
||||
}\
|
||||
if ( headLoopChildren ) {\
|
||||
if ( forwardIteration ) {\
|
||||
auto it = this->m_behaviors.begin();\
|
||||
if ( it != this->m_behaviors.end() ) {\
|
||||
if ( forwardIteration )\
|
||||
for ( auto& behavior : this->m_behaviors ){\
|
||||
behavior.f(self);\
|
||||
}\
|
||||
else\
|
||||
for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it )\
|
||||
it->f(self);\
|
||||
}\
|
||||
for ( ++it; it != this->m_behaviors.end(); ++it ) {\
|
||||
auto function = [&]() -> int {\
|
||||
it->f(self);\
|
||||
return 0;\
|
||||
};\
|
||||
if ( multithreading && useWorkers ) jobs.emplace_back(function);\
|
||||
else if ( multithreading ) uf::thread::add( uf::thread::fetchWorker(), function, true );\
|
||||
else function();\
|
||||
}\
|
||||
} else {\
|
||||
auto it = this->m_behaviors.rbegin();\
|
||||
if ( it != this->m_behaviors.rend() ) {\
|
||||
it->f(self);\
|
||||
}\
|
||||
for ( ++it; it != this->m_behaviors.rend(); ++it ) {\
|
||||
auto function = [&]() -> int {\
|
||||
it->f(self);\
|
||||
return 0;\
|
||||
};\
|
||||
if ( multithreading && useWorkers ) jobs.emplace_back(function);\
|
||||
else if ( multithreading ) uf::thread::add( uf::thread::fetchWorker(), function, true );\
|
||||
else function();\
|
||||
}\
|
||||
}\
|
||||
} else {\
|
||||
if ( forwardIteration ) {\
|
||||
auto it = this->m_behaviors.begin();\
|
||||
for ( ++it; it != this->m_behaviors.end(); ++it ) {\
|
||||
auto function = [&]() -> int {\
|
||||
it->f(self);\
|
||||
return 0;\
|
||||
};\
|
||||
if ( multithreading && useWorkers ) jobs.emplace_back(function);\
|
||||
else if ( multithreading ) uf::thread::add( uf::thread::fetchWorker(), function, true );\
|
||||
else function();\
|
||||
}\
|
||||
for ( ++it; it != this->m_behaviors.end(); ++it )\
|
||||
it->f(self);\
|
||||
if ( (it = this->m_behaviors.begin()) != this->m_behaviors.end() ) {\
|
||||
it->f(self);\
|
||||
}\
|
||||
} else {\
|
||||
auto it = this->m_behaviors.rbegin();\
|
||||
for ( ++it; it != this->m_behaviors.rend(); ++it ) {\
|
||||
auto function = [&]() -> int {\
|
||||
it->f(self);\
|
||||
return 0;\
|
||||
};\
|
||||
if ( multithreading && useWorkers ) jobs.emplace_back(function);\
|
||||
else if ( multithreading ) uf::thread::add( uf::thread::fetchWorker(), function, true );\
|
||||
else function();\
|
||||
}\
|
||||
for ( ++it; it != this->m_behaviors.rend(); ++it )\
|
||||
it->f(self);\
|
||||
if ( (it = this->m_behaviors.rbegin()) != this->m_behaviors.rend() ) {\
|
||||
it->f(self);\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
if ( !jobs.empty() ) uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
|
||||
#define UF_BEHAVIOR_POLYFILL_FAST(f)\
|
||||
for ( auto& behavior : this->m_behaviors ) behavior.f(self);
|
||||
/*
|
||||
#define UF_BEHAVIOR_POLYFILL_FAST(f)\
|
||||
for ( auto& behavior : this->m_behaviors ) {\
|
||||
UF_TIMER_TRACE_INIT();\
|
||||
behavior.f(self);\
|
||||
UF_TIMER_TRACE(self.getName() << ": " << self.getUid() << " | " << behavior.type.name() );\
|
||||
}
|
||||
*/
|
||||
|
||||
void uf::Behaviors::initialize() {
|
||||
uf::Object& self = *((uf::Object*) this);
|
||||
@ -162,12 +87,16 @@ void uf::Behaviors::initialize() {
|
||||
void uf::Behaviors::tick() {
|
||||
uf::Object& self = *((uf::Object*) this);
|
||||
if ( !self.isValid() ) return;
|
||||
// UF_TIMER_TRACE_INIT();
|
||||
UF_BEHAVIOR_POLYFILL(tick)
|
||||
// UF_TIMER_TRACE(self.getName() << ": " << self.getUid());
|
||||
}
|
||||
void uf::Behaviors::render() {
|
||||
uf::Object& self = *((uf::Object*) this);
|
||||
if ( !self.isValid() ) return;
|
||||
// UF_TIMER_TRACE_INIT();
|
||||
UF_BEHAVIOR_POLYFILL(render)
|
||||
// UF_TIMER_TRACE(self.getName() << ": " << self.getUid());
|
||||
}
|
||||
void uf::Behaviors::destroy() {
|
||||
uf::Object& self = *((uf::Object*) this);
|
||||
|
@ -1,47 +1,30 @@
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/engine/instantiator/instantiator.h>
|
||||
|
||||
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Entity)
|
||||
uf::Entity::Entity() UF_BEHAVIOR_ENTITY_CPP_ATTACH(uf::Entity)
|
||||
#define this ((uf::Entity*) &self)
|
||||
void uf::EntityBehavior::initialize( uf::Object& self ) {
|
||||
if ( !this->isValid() ) this->m_uid = ++uf::Entity::uids;
|
||||
// sanitize children
|
||||
/*
|
||||
for ( auto& kv : this->m_children ) {
|
||||
if ( !uf::instantiator::valid(kv) ) {
|
||||
std::cout << "FOUND INVALID CHILD IN " << this->getName() << ": " << this->getUid() << ": " << kv << std::endl;
|
||||
kv = NULL;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if ( !this->isValid() ) this->setUid();
|
||||
}
|
||||
|
||||
|
||||
void uf::EntityBehavior::tick( uf::Object& self ) {
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( !kv->isValid() ) continue;
|
||||
kv->tick();
|
||||
}
|
||||
if ( !uf::scene::useGraph ) for ( uf::Entity* kv : this->getChildren() ) if ( kv->isValid() ) kv->tick();
|
||||
}
|
||||
void uf::EntityBehavior::render( uf::Object& self ) {
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( !kv->isValid() ) continue;
|
||||
kv->render();
|
||||
}
|
||||
if ( !uf::scene::useGraph ) for ( uf::Entity* kv : this->getChildren() ) if ( kv->isValid() ) kv->render();
|
||||
}
|
||||
void uf::EntityBehavior::destroy( uf::Object& self ) {
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
for ( uf::Entity* kv : this->getChildren() ) {
|
||||
if ( !kv->isValid() ) continue;
|
||||
kv->destroy();
|
||||
if ( uf::Entity::deleteChildrenOnDestroy ) delete kv;
|
||||
}
|
||||
this->m_children.clear();
|
||||
this->m_uid = 0;
|
||||
if ( this->hasParent() )
|
||||
this->getParent().removeChild(*this);
|
||||
|
||||
this->getChildren().clear();
|
||||
this->unsetUid();
|
||||
if ( this->hasParent() ) this->getParent().removeChild(*this);
|
||||
if ( uf::Entity::deleteComponentsOnDestroy ) this->destroyComponents();
|
||||
}
|
||||
#undef this
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/engine/instantiator/instantiator.h>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
|
||||
@ -11,9 +12,16 @@ uf::Entity::~Entity(){
|
||||
this->destroy();
|
||||
}
|
||||
bool uf::Entity::isValid() const {
|
||||
// if ( uf::Entity::memoryPool.size() == 0 ) return false;
|
||||
if ( uf::Entity::memoryPool.size() > 0 && !uf::Entity::memoryPool.exists((void*) this) ) return false;
|
||||
return 0 < this->m_uid && this->m_uid <= uf::Entity::uids;
|
||||
return this && 0 < this->m_uid && this->m_uid <= uf::Entity::uids;
|
||||
}
|
||||
void uf::Entity::setUid() {
|
||||
uf::scene::invalidateGraph();
|
||||
this->m_uid = ++uf::Entity::uids;
|
||||
}
|
||||
void uf::Entity::unsetUid() {
|
||||
uf::scene::invalidateGraph();
|
||||
this->m_uid = 0;
|
||||
}
|
||||
bool uf::Entity::hasParent() const {
|
||||
return this->m_parent;
|
||||
|
@ -4,7 +4,8 @@
|
||||
#include <assert.h>
|
||||
|
||||
pod::NamedTypes<pod::Instantiator>* uf::instantiator::objects = NULL;
|
||||
pod::NamedTypes<pod::Behavior>* uf::instantiator::behaviors = NULL;
|
||||
//pod::NamedTypes<pod::Behavior>* uf::instantiator::behaviors = NULL;
|
||||
std::unordered_map<std::string, pod::Behavior>* uf::instantiator::behaviors = NULL;
|
||||
|
||||
uf::Entity* uf::instantiator::reuse( size_t size ) {
|
||||
uf::Entity* laxed = NULL;
|
||||
@ -93,17 +94,18 @@ bool uf::instantiator::valid( uf::Entity* pointer ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void uf::instantiator::registerBehavior( const std::string& name, const pod::Behavior& behavior ) {
|
||||
if ( !uf::instantiator::behaviors ) uf::instantiator::behaviors = new std::unordered_map<std::string, pod::Behavior>;\
|
||||
(*uf::instantiator::behaviors)[name] = behavior;
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) UF_DEBUG_MSG("Registered behavior for " << name << " | " << behavior.type);
|
||||
}
|
||||
void uf::instantiator::registerBinding( const std::string& object, const std::string& behavior ) {
|
||||
if ( !objects ) objects = new pod::NamedTypes<pod::Instantiator>;
|
||||
/*
|
||||
if ( !uf::instantiator::objects->has( object ) ) {
|
||||
// uf::instantiator::registerObject<uf::Object>( object );
|
||||
}
|
||||
*/
|
||||
if ( !behaviors ) behaviors = new std::unordered_map<std::string, pod::Behavior>;
|
||||
auto& instantiator = uf::instantiator::objects->get( object );
|
||||
instantiator.behaviors.emplace_back( behavior );
|
||||
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) std::cout << "Registered binding: " << object << " and " << behavior << ": " << instantiator.behaviors.size() << std::endl;
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) UF_DEBUG_MSG("Registered binding: " << object << " and " << behavior << ": " << instantiator.behaviors.size());
|
||||
}
|
||||
|
||||
uf::Entity& uf::instantiator::instantiate( const std::string& name ) {
|
||||
@ -120,14 +122,16 @@ uf::Entity& uf::instantiator::instantiate( const std::string& name ) {
|
||||
void uf::instantiator::bind( const std::string& name, uf::Entity& entity ) {
|
||||
// was actually a behavior name, single bind
|
||||
if ( !uf::instantiator::objects->has( name, false ) ) {
|
||||
if ( !uf::instantiator::behaviors->has( name, false ) ) return;
|
||||
auto& behavior = uf::instantiator::behaviors->get( name );
|
||||
if ( uf::instantiator::behaviors->count( name ) == 0 ) return;
|
||||
auto& behavior = (*uf::instantiator::behaviors)[name];
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) UF_DEBUG_MSG("Attaching " << name << " | " << behavior.type << " to " << entity.getName());
|
||||
entity.addBehavior(behavior);
|
||||
return;
|
||||
}
|
||||
auto& instantiator = uf::instantiator::objects->get( name );
|
||||
for ( auto& name : instantiator.behaviors ) {
|
||||
auto& behavior = uf::instantiator::behaviors->get( name );
|
||||
auto& behavior = (*uf::instantiator::behaviors)[name];
|
||||
if ( UF_INSTANTIATOR_ANNOUNCE ) UF_DEBUG_MSG("Attaching " << name << " | " << behavior.type << " to " << entity.getName());
|
||||
entity.addBehavior(behavior);
|
||||
}
|
||||
}
|
||||
@ -135,14 +139,14 @@ void uf::instantiator::bind( const std::string& name, uf::Entity& entity ) {
|
||||
void uf::instantiator::unbind( const std::string& name, uf::Entity& entity ) {
|
||||
// was actually a behavior name, single bind
|
||||
if ( !uf::instantiator::objects->has( name, false ) ) {
|
||||
if ( !uf::instantiator::behaviors->has( name, false ) ) return;
|
||||
auto& behavior = uf::instantiator::behaviors->get( name );
|
||||
if ( !uf::instantiator::behaviors->count( name ) == 0 ) return;
|
||||
auto& behavior = (*uf::instantiator::behaviors)[name];
|
||||
entity.removeBehavior(behavior);
|
||||
return;
|
||||
}
|
||||
auto& instantiator = uf::instantiator::objects->get( name );
|
||||
for ( auto& name : instantiator.behaviors ) {
|
||||
auto& behavior = uf::instantiator::behaviors->get( name );
|
||||
auto& behavior = (*uf::instantiator::behaviors)[name];
|
||||
entity.removeBehavior(behavior);
|
||||
}
|
||||
}
|
@ -130,14 +130,28 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
});
|
||||
}
|
||||
void uf::ObjectBehavior::destroy( uf::Object& self ) {
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
for( auto it = metadata["system"]["hooks"]["alloc"].begin() ; it != metadata["system"]["hooks"]["alloc"].end() ; ++it ) {
|
||||
#if UF_ENTITY_METADATA_USE_JSON
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
ext::json::forEach( metadata["system"]["hooks"]["bound"], [&]( const std::string& key, ext::json::Value& value ){
|
||||
ext::json::forEach( value, [&]( ext::json::Value& id ){
|
||||
uf::hooks.removeHook(key, id.as<size_t>());
|
||||
});
|
||||
});
|
||||
/*
|
||||
for( auto it = metadata["system"]["hooks"]["bound"].begin() ; it != metadata["system"]["hooks"]["bound"].end() ; ++it ) {
|
||||
std::string name = it.key();
|
||||
for ( size_t i = 0; i < metadata["system"]["hooks"]["alloc"][name].size(); ++i ) {
|
||||
size_t id = metadata["system"]["hooks"]["alloc"][name][(int) i].as<size_t>();
|
||||
for ( size_t i = 0; i < metadata["system"]["hooks"]["bound"][name].size(); ++i ) {
|
||||
size_t id = metadata["system"]["hooks"]["bound"][name][(int) i].as<size_t>();
|
||||
uf::hooks.removeHook(name, id);
|
||||
}
|
||||
}
|
||||
*/
|
||||
#else
|
||||
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
|
||||
for ( auto pair : metadata.hooks.bound ) {
|
||||
for ( auto id : pair.second ) uf::hooks.removeHook(pair.first, id);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( this->hasComponent<uf::Audio>() ) {
|
||||
auto& audio = this->getComponent<uf::Audio>();
|
||||
@ -155,37 +169,49 @@ void uf::ObjectBehavior::destroy( uf::Object& self ) {
|
||||
}
|
||||
void uf::ObjectBehavior::tick( uf::Object& self ) {
|
||||
// listen for metadata file changes
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
#if UF_ENTITY_METADATA_USE_JSON
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
#if !UF_ENV_DREAMCAST
|
||||
if ( metadata["system"]["hot reload"]["enabled"].as<bool>() ) {
|
||||
size_t mtime = uf::io::mtime( metadata["system"]["source"].as<std::string>() );
|
||||
if ( metadata["system"]["hot reload"]["mtime"].as<size_t>() < mtime ) {
|
||||
std::cout << "File reload detected: " << ": " << metadata["system"]["source"].as<std::string>() << ", " << metadata["system"]["hot reload"]["mtime"] << " -> " << mtime << std::endl;
|
||||
metadata["system"]["hot reload"]["mtime"] = mtime;
|
||||
this->reload();
|
||||
//this->queueHook("metadata:Reload.%UID%");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
// Call queued hooks
|
||||
{
|
||||
auto& queue = metadata["system"]["hooks"]["queue"];
|
||||
if ( !uf::Object::timer.running() ) uf::Object::timer.start();
|
||||
float curTime = uf::Object::timer.elapsed().asDouble();
|
||||
uf::Serializer newQueue = ext::json::array();
|
||||
if ( !ext::json::isNull( metadata["system"]["hooks"]["queue"] ) ) {
|
||||
ext::json::forEach(metadata["system"]["hooks"]["queue"], [&](ext::json::Value& member){
|
||||
if ( !ext::json::isNull( queue ) ) {
|
||||
ext::json::forEach(queue, [&](ext::json::Value& member){
|
||||
if ( !ext::json::isObject(member) ) return;
|
||||
uf::Serializer payload = member["payload"];
|
||||
std::string name = member["name"].as<std::string>();
|
||||
float timeout = member["timeout"].as<float>();
|
||||
if ( timeout < curTime ) {
|
||||
this->callHook( name, payload );
|
||||
} else {
|
||||
newQueue.emplace_back(member);
|
||||
}
|
||||
if ( timeout < curTime ) this->callHook( name, payload );
|
||||
else newQueue.emplace_back(member);
|
||||
});
|
||||
}
|
||||
if ( ext::json::isObject( metadata ) ) metadata["system"]["hooks"]["queue"] = newQueue;
|
||||
if ( ext::json::isObject( metadata ) ) queue = newQueue;
|
||||
}
|
||||
#else
|
||||
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
|
||||
{
|
||||
auto& queue = metadata.hooks.queue;
|
||||
if ( !uf::Object::timer.running() ) uf::Object::timer.start();
|
||||
float curTime = uf::Object::timer.elapsed().asDouble();
|
||||
for ( auto it = queue.begin(); it != queue.end(); ) {
|
||||
auto& q = *it;
|
||||
if ( q.timeout < curTime ) { this->callHook( q.name, q.payload ); it = queue.erase( it ); }
|
||||
else ++it;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void uf::ObjectBehavior::render( uf::Object& self ) {}
|
||||
#undef this
|
||||
|
@ -16,17 +16,7 @@
|
||||
UF_BEHAVIOR_REGISTER_CPP(uf::GltfBehavior)
|
||||
#define this (&self)
|
||||
void uf::GltfBehavior::initialize( uf::Object& self ) {
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
metadata["textures"]["additional"] = ext::json::array(); //Json::Value(Json::arrayValue);
|
||||
// Default load: GLTF model
|
||||
this->addHook( "asset:Load.%UID%", [&](ext::json::Value& json){
|
||||
std::string filename = json["filename"].as<std::string>();
|
||||
std::string category = json["category"].as<std::string>();
|
||||
if ( category != "" && category != "images" ) return;
|
||||
if ( category == "" && uf::io::extension(filename) != "png" ) return;
|
||||
auto& vector = metadata["textures"]["additional"];
|
||||
vector[vector.size()] = filename;
|
||||
});
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
this->addHook( "animation:Set.%UID%", [&](ext::json::Value& json){
|
||||
std::string name = json["name"].as<std::string>();
|
||||
|
||||
@ -55,7 +45,7 @@ void uf::GltfBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
auto& graph = this->getComponent<pod::Graph>();
|
||||
uf::Object* objectPointer = graph.root.entity;
|
||||
objectPointer->process([&]( uf::Entity* entity ) {
|
||||
graph.root.entity->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
auto& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !(graph.mode & ext::gltf::LoadMode::LOAD) ) {
|
||||
@ -97,21 +87,6 @@ void uf::GltfBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < metadata["textures"]["additional"].size(); ++i ) {
|
||||
std::string filename = metadata["textures"]["additional"][i].as<std::string>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& assetLoader = scene.getComponent<uf::Asset>();
|
||||
const uf::Image* imagePointer = NULL;
|
||||
if ( !assetLoader.has<uf::Image>(filename) ) return;
|
||||
imagePointer = &assetLoader.get<uf::Image>(filename);
|
||||
if ( !imagePointer ) continue;
|
||||
uf::Image image = *imagePointer;
|
||||
auto& texture = graphic.material.textures.emplace_back();
|
||||
texture.loadFromImage( image );
|
||||
}
|
||||
graphic.process = true;
|
||||
|
||||
#if UF_USE_VULKAN
|
||||
{
|
||||
auto& shader = graphic.material.getShader("vertex");
|
||||
@ -164,21 +139,19 @@ void uf::GltfBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
graphic.process = true;
|
||||
});
|
||||
this->addChild(objectPointer->as<uf::Entity>());
|
||||
this->addChild(graph.root.entity->as<uf::Entity>());
|
||||
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
objectPointer->getComponent<pod::Transform<>>().reference = &transform;
|
||||
graph.root.entity->getComponent<pod::Transform<>>().reference = &transform;
|
||||
|
||||
objectPointer->initialize();
|
||||
objectPointer->process([&]( uf::Entity* entity ) {
|
||||
graph.root.entity->initialize();
|
||||
graph.root.entity->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) {
|
||||
if ( entity->getUid() == 0 ) entity->initialize();
|
||||
return;
|
||||
}
|
||||
auto& eMetadata = entity->getComponent<uf::Serializer>();
|
||||
eMetadata["textures"]["map"] = metadata["textures"]["map"];
|
||||
// if ( graph.mode & ext::gltf::LoadMode::SEPARATE ) uf::instantiator::bind( "RenderBehavior", *entity );
|
||||
uf::instantiator::bind( "GltfBehavior", *entity );
|
||||
uf::instantiator::unbind( "RenderBehavior", *entity );
|
||||
if ( entity->getUid() == 0 ) entity->initialize();
|
||||
@ -189,9 +162,8 @@ void uf::GltfBehavior::initialize( uf::Object& self ) {
|
||||
uf::graph::animate( graph, metadata["model"]["animation"].as<std::string>() );
|
||||
}
|
||||
if ( metadata["model"]["print animations"].as<bool>() ) {
|
||||
uf::Serializer json = ext::json::array(); //Json::Value(Json::arrayValue);
|
||||
uf::Serializer json = ext::json::array();
|
||||
for ( auto pair : graph.animations ) json.emplace_back( pair.first );
|
||||
uf::iostream << "Animations found: " << json << "\n";
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -204,54 +176,9 @@ void uf::GltfBehavior::destroy( uf::Object& self ) {
|
||||
}
|
||||
void uf::GltfBehavior::tick( uf::Object& self ) {
|
||||
/* Animation change test */
|
||||
if ( this->hasComponent<pod::Graph>() ) {
|
||||
std::vector<std::string> animations = { "wank","walk","sit_wank","run","idle_wank","sit","idle" };
|
||||
bool anyNumber =
|
||||
uf::Window::isKeyPressed("1") ||
|
||||
uf::Window::isKeyPressed("2") ||
|
||||
uf::Window::isKeyPressed("3") ||
|
||||
uf::Window::isKeyPressed("4") ||
|
||||
uf::Window::isKeyPressed("5") ||
|
||||
uf::Window::isKeyPressed("6") ||
|
||||
uf::Window::isKeyPressed("7") ||
|
||||
uf::Window::isKeyPressed("8") ||
|
||||
uf::Window::isKeyPressed("9") ||
|
||||
uf::Window::isKeyPressed("0");
|
||||
TIMER(1, anyNumber && ) {
|
||||
auto& graph = this->getComponent<pod::Graph>();
|
||||
std::string target = "";
|
||||
if ( uf::Window::isKeyPressed("1") && animations.size() >= 1 ) target = animations[0];
|
||||
else if ( uf::Window::isKeyPressed("2") && animations.size() >= 2 ) target = animations[1];
|
||||
else if ( uf::Window::isKeyPressed("3") && animations.size() >= 3 ) target = animations[2];
|
||||
else if ( uf::Window::isKeyPressed("4") && animations.size() >= 4 ) target = animations[3];
|
||||
else if ( uf::Window::isKeyPressed("5") && animations.size() >= 5 ) target = animations[4];
|
||||
else if ( uf::Window::isKeyPressed("6") && animations.size() >= 6 ) target = animations[5];
|
||||
else if ( uf::Window::isKeyPressed("7") && animations.size() >= 7 ) target = animations[6];
|
||||
else if ( uf::Window::isKeyPressed("8") && animations.size() >= 8 ) target = animations[7];
|
||||
else if ( uf::Window::isKeyPressed("9") && animations.size() >= 9 ) target = animations[8];
|
||||
else if ( uf::Window::isKeyPressed("0") && animations.size() >= 10 ) target = animations[9];
|
||||
std::cout << "CHANGING ANIMATION TO " << target << std::endl;
|
||||
// graph.animationSettings.loop = false;
|
||||
uf::graph::animate( graph, target, 1 / 0.125f );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update animations */ if ( this->hasComponent<pod::Graph>() ) {
|
||||
auto& graph = this->getComponent<pod::Graph>();
|
||||
if ( graph.mode & ext::gltf::LoadMode::SKINNED ) {
|
||||
uf::graph::update( graph );
|
||||
}
|
||||
/*
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& node = graph.node->children.size() == 1 ? *graph.node->children[0] : *graph.node;
|
||||
pod::Matrix4f nodeMatrix = node.transform.model;
|
||||
pod::Node* currentParent = uf::graph::find(graph, node.parent);
|
||||
while ( currentParent ) {
|
||||
nodeMatrix = currentParent->transform.model * nodeMatrix;
|
||||
currentParent = uf::graph::find(graph, currentParent->parent);
|
||||
}
|
||||
transform.model = nodeMatrix;
|
||||
*/
|
||||
if ( graph.mode & ext::gltf::LoadMode::SKINNED ) uf::graph::update( graph );
|
||||
}
|
||||
#if UF_USE_OPENGL
|
||||
/* Update uniforms */ if ( this->hasComponent<uf::Graphic>() ) {
|
||||
@ -317,42 +244,6 @@ void uf::GltfBehavior::tick( uf::Object& self ) {
|
||||
auto& storageBuffer = *graphic.getStorageBuffer("Models");
|
||||
graphic.updateBuffer( (void*) instances.data(), instances.size() * sizeof(pod::Matrix4f), graph.instanceBufferIndex /*storageBuffer*/ );
|
||||
}
|
||||
/*
|
||||
if ( graph.materials.empty() && graphic.hasStorage("Materials") ) {
|
||||
auto& shader = graphic.material.getShader("fragment");
|
||||
std::vector<pod::Material::Storage> materials( graph.materials.size() );
|
||||
for ( size_t i = 0; i < graph.materials.size(); ++i ) {
|
||||
materials[i] = graph.materials[i].storage;
|
||||
materials[i].indexMappedTarget = graph.mode & ext::gltf::LoadMode::ATLAS ? 0 : i;
|
||||
materials[i].factorMappedBlend = graph.mode & ext::gltf::LoadMode::ATLAS ? 1.0f : 0.0f;
|
||||
}
|
||||
{
|
||||
size_t texturesLen = graphic.material.textures.size();
|
||||
ext::json::forEach(metadata["textures"]["map"], [&]( const std::string& key, const ext::json::Value& mapping ){
|
||||
uint32_t from = std::stoi(key);
|
||||
if ( mapping["alpha cutoff"].is<float>() ) {
|
||||
materials[from].factorAlphaCutoff = mapping["alpha cutoff"].as<float>();
|
||||
}
|
||||
if ( mapping["to"].is<size_t>() ) {
|
||||
uint32_t to = mapping["to"].as<size_t>();
|
||||
float blend = 1.0f;
|
||||
if ( mapping["factor"].as<std::string>() == "sin(time)" ) {
|
||||
blend = sin(uf::physics::time::current)*0.5f+0.5f;
|
||||
} else if ( mapping["factor"].as<std::string>() == "cos(time)" ) {
|
||||
blend = cos(uf::physics::time::current)*0.5f+0.5f;
|
||||
} else if ( mapping["factor"].is<float>() ) {
|
||||
blend = mapping["factor"].as<float>();
|
||||
}
|
||||
if ( from >= texturesLen || to >= texturesLen ) return;
|
||||
materials[from].indexMappedTarget = to;
|
||||
materials[from].factorMappedBlend = blend;
|
||||
}
|
||||
});
|
||||
}
|
||||
auto& storageBuffer = *graphic.getStorageBuffer("Materials");
|
||||
graphic.updateBuffer( (void*) materials.data(), materials.size() * sizeof(pod::Material::Storage), graph.root.materialBufferIndex /storageBuffer/ );
|
||||
}
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ void uf::LoadingBehavior::initialize( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
this->addHook( "system:Load.Finished.%UID%", [&](ext::json::Value& json){
|
||||
metadata["system"]["loaded"] = true;
|
||||
this->removeBehavior<uf::LoadingBehavior>();
|
||||
this->removeBehavior(pod::Behavior{.type = uf::LoadingBehavior::type});
|
||||
|
||||
auto& parent = this->getParent();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
@ -27,29 +27,23 @@ void uf::LoadingBehavior::initialize( uf::Object& self ) {
|
||||
uf::Serializer payload;
|
||||
payload["uid"] = parent.getUid();
|
||||
parent.getParent().removeChild(parent);
|
||||
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
parent.process([&]( uf::Entity* entity ) {
|
||||
if ( !entity || !entity->isValid() || !entity->hasComponent<pod::Transform<>>() ) return;
|
||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||
transform.scale = { 0, 0, 0 };
|
||||
entity->render();
|
||||
};
|
||||
parent.process(filter);
|
||||
|
||||
});
|
||||
scene.queueHook("system:Destroy", payload);
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
void uf::LoadingBehavior::destroy( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void uf::LoadingBehavior::tick( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
if ( metadata["system"]["loaded"].as<bool>() ) return;
|
||||
size_t loading = 0;
|
||||
size_t loaded = 1;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
this->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity || !entity->isValid() || !entity->hasComponent<uf::Serializer>() ) return;
|
||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||
if ( metadata["system"]["load"]["ignore"].is<bool>() ) return;
|
||||
@ -57,38 +51,12 @@ void uf::LoadingBehavior::tick( uf::Object& self ) {
|
||||
++loading;
|
||||
if ( metadata["system"]["load"]["progress"].as<int>() < metadata["system"]["load"]["total"].as<int>() ) return;
|
||||
++loaded;
|
||||
};
|
||||
this->process(filter);
|
||||
});
|
||||
if ( loading == loaded ) {
|
||||
metadata["system"]["loaded"] = true;
|
||||
this->callHook("system:Load.Finished.%UID%");
|
||||
}
|
||||
/*
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
if ( !metadata["system"]["loaded"].as<bool>() ) {
|
||||
size_t loading = 0;
|
||||
size_t loaded = 0;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity || !entity->isValid() || !entity->hasComponent<uf::Serializer>() ) return;
|
||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||
if ( ext::json::isNull( metadata["system"]["load"] ) ) return;
|
||||
++loading;
|
||||
if ( metadata["system"]["load"]["progress"].as<float>() < 1.0f ) return;
|
||||
++loaded;
|
||||
};
|
||||
this->process(filter);
|
||||
|
||||
if ( loading == loaded ) {
|
||||
this->callHook("system:Load.Finished.%UID%");
|
||||
}
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
if ( metadata["system"]["load"]["progress"].as<float>() >= 1.0f ) {
|
||||
this->callHook("system:Load.Finished.%UID%");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
void uf::LoadingBehavior::render( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void uf::LoadingBehavior::render( uf::Object& self ) {}
|
||||
void uf::LoadingBehavior::destroy( uf::Object& self ) {}
|
||||
#undef this
|
@ -28,21 +28,12 @@ void uf::LuaBehavior::initialize( uf::Object& self ) {
|
||||
assetPointer = &assetLoader.get<pod::LuaScript>(filename);
|
||||
if ( !assetPointer ) return;
|
||||
pod::LuaScript script = *assetPointer;
|
||||
// script.header = "local ent = entities.get("+ std::to_string((uint) this->getUid()) +")";
|
||||
script.env["ent"] = &this->as<uf::Object>();
|
||||
ext::lua::run( script );
|
||||
|
||||
return;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
void uf::LuaBehavior::destroy( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void uf::LuaBehavior::tick( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void uf::LuaBehavior::render( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void uf::LuaBehavior::destroy( uf::Object& self ) {}
|
||||
void uf::LuaBehavior::tick( uf::Object& self ) {}
|
||||
void uf::LuaBehavior::render( uf::Object& self ) {}
|
||||
#undef this
|
@ -16,7 +16,6 @@
|
||||
UF_BEHAVIOR_REGISTER_CPP(uf::RenderBehavior)
|
||||
#define this (&self)
|
||||
void uf::RenderBehavior::initialize( uf::Object& self ) {}
|
||||
void uf::RenderBehavior::destroy( uf::Object& self ) {}
|
||||
void uf::RenderBehavior::tick( uf::Object& self ) {}
|
||||
void uf::RenderBehavior::render( uf::Object& self ) {
|
||||
if ( !this->hasComponent<uf::Graphic>() ) return;
|
||||
@ -80,4 +79,5 @@ void uf::RenderBehavior::render( uf::Object& self ) {
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
void uf::RenderBehavior::destroy( uf::Object& self ) {}
|
||||
#undef this
|
@ -1,4 +1,5 @@
|
||||
#include <uf/engine/object/object.h>
|
||||
#include <uf/engine/object/behavior.h>
|
||||
#include <uf/engine/asset/asset.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/utils/time/time.h>
|
||||
@ -19,27 +20,24 @@ UF_OBJECT_REGISTER_BEGIN(uf::Object)
|
||||
UF_OBJECT_REGISTER_BEHAVIOR(uf::ObjectBehavior)
|
||||
UF_OBJECT_REGISTER_END()
|
||||
uf::Object::Object() UF_BEHAVIOR_ENTITY_CPP_ATTACH(uf::Object)
|
||||
/*
|
||||
void uf::Object::queueHook( const std::string& name, const std::string& payload, double timeout ) {
|
||||
if ( !uf::Object::timer.running() ) uf::Object::timer.start();
|
||||
float start = uf::Object::timer.elapsed().asDouble();
|
||||
uf::Serializer queue;
|
||||
queue["name"] = name;
|
||||
queue["payload"] = uf::Serializer{payload};
|
||||
queue["timeout"] = start + timeout;
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
metadata["system"]["hooks"]["queue"].emplace_back(queue);
|
||||
}
|
||||
*/
|
||||
void uf::Object::queueHook( const std::string& name, const ext::json::Value& payload, double timeout ) {
|
||||
if ( !uf::Object::timer.running() ) uf::Object::timer.start();
|
||||
float start = uf::Object::timer.elapsed().asDouble();
|
||||
double start = uf::Object::timer.elapsed().asDouble();
|
||||
#if UF_ENTITY_METADATA_USE_JSON
|
||||
uf::Serializer queue;
|
||||
queue["name"] = name;
|
||||
queue["payload"] = payload;
|
||||
queue["timeout"] = start + timeout;
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
metadata["system"]["hooks"]["queue"].emplace_back(queue);
|
||||
#else
|
||||
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
|
||||
auto& queue = metadata.hooks.queue.emplace_back(uf::ObjectBehavior::Metadata::Queued{
|
||||
.name = name,
|
||||
.payload = payload,
|
||||
.timeout = start + timeout,
|
||||
});
|
||||
#endif
|
||||
}
|
||||
std::string uf::Object::formatHookName( const std::string& n, size_t uid, bool fetch ) {
|
||||
if ( fetch ) {
|
||||
@ -81,39 +79,6 @@ uf::Hooks::return_t uf::Object::callHook( const std::string& name, const ext::js
|
||||
uf::Hooks::return_t uf::Object::callHook( const std::string& name, const uf::Serializer& serializer ) {
|
||||
return uf::hooks.call( this->formatHookName( name ), (const ext::json::Value&) serializer );
|
||||
}
|
||||
/*
|
||||
std::vector<ext::json::Value> uf::Object::callHook( const std::string& name, const ext::json::Value& payload ) {
|
||||
std::vector<ext::json::Value> jsons;
|
||||
auto results = uf::hooks.call( this->formatHookName( name ), payload );
|
||||
for ( auto& result : results ) {
|
||||
if ( result.is<std::string>() ) jsons.emplace_back( uf::Serializer(result.as<std::string>()) );
|
||||
else if ( result.is<ext::json::Value>() ) jsons.emplace_back( result.as<ext::json::Value>() );
|
||||
else if ( result.is<uf::Serializer>() ) jsons.emplace_back( result.as<uf::Serializer>() );
|
||||
}
|
||||
return jsons;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
std::vector<std::string> uf::Object::callHook( const std::string& name, const std::string& payload ) {
|
||||
std::vector<std::string> strings;
|
||||
auto results = uf::hooks.call( this->formatHookName( name ), payload );
|
||||
for ( auto& result : results ) {
|
||||
if ( result.is<std::string>() ) {
|
||||
strings.emplace_back( result.as<std::string>() );
|
||||
}
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
std::size_t uf::Object::addHook( const std::string& name, const uf::HookHandler::Readable::function_t& callback ) {
|
||||
std::string parsed = this->formatHookName( name );
|
||||
std::size_t id = uf::hooks.addHook( parsed, callback );
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
metadata["system"]["hooks"]["alloc"][parsed].emplace_back(id);
|
||||
return id;
|
||||
}
|
||||
*/
|
||||
bool uf::Object::load( const std::string& f, bool inheritRoot ) {
|
||||
uf::Serializer json;
|
||||
std::string root = "";
|
||||
@ -152,14 +117,8 @@ bool uf::Object::reload( bool hard ) {
|
||||
transform = uf::transform::decode( json["transform"], transform );
|
||||
transform.reference = reference;
|
||||
}
|
||||
/*
|
||||
for ( auto it = json["metadata"].begin(); it != json["metadata"].end(); ++it ) {
|
||||
metadata[it.key()] = json["metadata"][it.key()];
|
||||
}
|
||||
*/
|
||||
payload["new"] = metadata;
|
||||
uf::iostream << "Updated metadata for " << uf::string::toString( this ) << "\n";
|
||||
|
||||
UF_DEBUG_MSG("Updated metadata for " << uf::string::toString( this ));
|
||||
this->queueHook("object:Reload.%UID%", payload);
|
||||
return true;
|
||||
}
|
||||
@ -177,11 +136,8 @@ bool uf::Object::load( const uf::Serializer& _json ) {
|
||||
do {
|
||||
std::string filename = chain["import"].is<std::string>() ? chain["import"].as<std::string>() : chain["include"].as<std::string>();
|
||||
filename = grabURI( filename, root );
|
||||
// std::cout << "Importing: " << filename << std::endl;
|
||||
chain.readFromFile( filename );
|
||||
// set new root
|
||||
root = uf::io::directory( filename );
|
||||
// get real path for assets to merge separately
|
||||
ext::json::forEach(chain["assets"], [&](ext::json::Value& value){
|
||||
if ( ext::json::isObject( value ) ) value["filename"] = grabURI( value["filename"].as<std::string>(), root );
|
||||
else value = grabURI( value.as<std::string>(), root );
|
||||
|
@ -6,7 +6,6 @@
|
||||
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Scene)
|
||||
#define this ((uf::Scene*) &self)
|
||||
void uf::SceneBehavior::initialize( uf::Object& self ) {
|
||||
// uf::renderer::scenes.push_back(this);
|
||||
uf::renderer::states::rebuild = true;
|
||||
|
||||
this->addHook( "system:Renderer.QueueRebuild", [&](ext::json::Value& json){
|
||||
@ -23,10 +22,8 @@ void uf::SceneBehavior::initialize( uf::Object& self ) {
|
||||
this->queueHook("system:Renderer.QueueRebuild");
|
||||
});
|
||||
}
|
||||
void uf::SceneBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
void uf::SceneBehavior::render( uf::Object& self ) {
|
||||
}
|
||||
void uf::SceneBehavior::tick( uf::Object& self ) {}
|
||||
void uf::SceneBehavior::render( uf::Object& self ) {}
|
||||
void uf::SceneBehavior::destroy( uf::Object& self ) {
|
||||
uf::renderer::states::rebuild = true;
|
||||
}
|
||||
|
@ -37,21 +37,21 @@ const uf::Entity& uf::Scene::getController() const {
|
||||
uf::Scene& scene = *const_cast<uf::Scene*>(this);
|
||||
return scene.getController();
|
||||
}
|
||||
std::vector<uf::Scene*> uf::scene::scenes;
|
||||
uf::Scene& uf::scene::loadScene( const std::string& name, const std::string& filename ) {
|
||||
uf::Scene* scene = uf::instantiator::objects->has( name ) ? (uf::Scene*) &uf::instantiator::instantiate( name ) : new uf::Scene;
|
||||
|
||||
// uf::scene::scenes.insert(uf::scene::scenes.begin(), scene);
|
||||
uf::scene::scenes.emplace_back( scene );
|
||||
|
||||
std::vector<uf::Scene*> uf::scene::scenes;
|
||||
std::vector<uf::Entity*> uf::scene::graph;
|
||||
bool uf::scene::queuedInvalidation = false;
|
||||
bool uf::scene::useGraph = true;
|
||||
|
||||
uf::Scene& uf::scene::loadScene( const std::string& name, const std::string& filename ) {
|
||||
std::string target = name;
|
||||
|
||||
uf::Scene* scene = uf::instantiator::objects->has( name ) ? (uf::Scene*) &uf::instantiator::instantiate( name ) : new uf::Scene;
|
||||
uf::scene::scenes.emplace_back( scene );
|
||||
/*
|
||||
std::regex regex("^(TestScene_?)?(.+?)(_?Scene)?$");
|
||||
std::smatch match;
|
||||
|
||||
if ( std::regex_search( target, match, regex ) ) {
|
||||
target = match[2];
|
||||
}
|
||||
if ( std::regex_search( target, match, regex ) ) target = match[2];
|
||||
*/
|
||||
target = uf::string::lowercase( target );
|
||||
scene->load(filename != "" ? filename : "./scenes/" + target + "/scene.json");
|
||||
scene->initialize();
|
||||
@ -59,10 +59,7 @@ uf::Scene& uf::scene::loadScene( const std::string& name, const std::string& fil
|
||||
}
|
||||
uf::Scene& uf::scene::loadScene( const std::string& name, const uf::Serializer& data ) {
|
||||
uf::Scene* scene = uf::instantiator::objects->has( name ) ? (uf::Scene*) &uf::instantiator::instantiate( name ) : new uf::Scene;
|
||||
|
||||
// uf::scene::scenes.insert(uf::scene::scenes.begin(), scene);
|
||||
uf::scene::scenes.emplace_back( scene );
|
||||
|
||||
if ( data != "" ) scene->load(data);
|
||||
scene->initialize();
|
||||
return *scene;
|
||||
@ -71,33 +68,57 @@ void uf::scene::unloadScene() {
|
||||
uf::Scene* current = uf::scene::scenes.back();
|
||||
current->destroy();
|
||||
uf::scene::scenes.pop_back();
|
||||
//delete current;
|
||||
}
|
||||
uf::Scene& uf::scene::getCurrentScene() {
|
||||
return *uf::scene::scenes.back();
|
||||
}
|
||||
void uf::scene::invalidateGraph() {
|
||||
uf::scene::queuedInvalidation = true;
|
||||
}
|
||||
std::vector<uf::Entity*> uf::scene::generateGraph() {
|
||||
// invalidate it by clearing the graph
|
||||
if ( uf::scene::queuedInvalidation ) {
|
||||
uf::scene::graph.clear();
|
||||
uf::scene::queuedInvalidation = false;
|
||||
}
|
||||
|
||||
if ( !uf::scene::graph.empty() ) return uf::scene::graph;
|
||||
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
auto& metadata = entity->getComponent<uf::ObjectBehavior::Metadata>();
|
||||
if ( !metadata.system.ignoreGraph ) uf::scene::graph.emplace_back(entity);
|
||||
});
|
||||
}
|
||||
uf::renderer::states::rebuild = true;
|
||||
return uf::scene::graph;
|
||||
}
|
||||
|
||||
void uf::scene::tick() {
|
||||
// uf::scene::getCurrentScene().tick();
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
uf::Timer<long long> TIMER_TRACE;
|
||||
// UF_DEBUG_MSG("==== START TICK ====");
|
||||
for ( auto it = graph.rbegin(); it != graph.rend(); ++it ) {
|
||||
(*it)->tick();
|
||||
// UF_DEBUG_MSG(TIMER_TRACE.elapsed().asMicroseconds() << " us\t" << (*it)->getName() << ": " << (*it)->getUid());
|
||||
}
|
||||
// UF_DEBUG_MSG("==== END TICK ====");
|
||||
} else {
|
||||
for ( auto scene : scenes ) scene->tick();
|
||||
}
|
||||
}
|
||||
void uf::scene::render() {
|
||||
// uf::scene::getCurrentScene().render();
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto it = graph.rbegin(); it != graph.rend(); ++it ) {
|
||||
(*it)->render();
|
||||
}
|
||||
} else {
|
||||
for ( auto scene : scenes ) scene->render();
|
||||
}
|
||||
}
|
||||
void uf::scene::destroy() {
|
||||
while ( !scenes.empty() ) {
|
||||
unloadScene();
|
||||
}
|
||||
}
|
||||
/*
|
||||
uf::Camera& uf::Scene::getCamera() {
|
||||
if ( !::camera ) ::camera = this->getPlayer().getComponentPointer<uf::Camera>();
|
||||
return *::camera;
|
||||
}
|
||||
uf::Player& uf::Scene::getPlayer() {
|
||||
return *((uf::Player*) this->findByName("Player"));
|
||||
}
|
||||
const uf::Player& uf::Scene::getPlayer() const {
|
||||
return *((const uf::Player*) this->findByName("Player"));
|
||||
}
|
||||
*/
|
||||
while ( !scenes.empty() ) unloadScene();
|
||||
}
|
@ -2,8 +2,14 @@
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/utils/mesh/grid.h>
|
||||
#include <uf/utils/thread/thread.h>
|
||||
|
||||
#define UF_VK_TESTING 1
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 0
|
||||
#else
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 1
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
void initializeGraphics( pod::Graph& graph, uf::Object& entity ) {
|
||||
@ -33,6 +39,7 @@ namespace {
|
||||
auto& atlas = *graph.atlas;
|
||||
auto& texture = graphic.material.textures.emplace_back();
|
||||
texture.loadFromImage( atlas.getAtlas() );
|
||||
atlas.getAtlas().clear();
|
||||
} else {
|
||||
graphic.material.textures.emplace_back().aliasTexture(uf::renderer::Texture2D::empty);
|
||||
for ( auto& image : graph.images ) {
|
||||
@ -49,6 +56,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
texture.loadFromImage( image );
|
||||
image.clear();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -155,6 +163,7 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
}
|
||||
}
|
||||
texture.loadFromImage( image );
|
||||
image.clear();
|
||||
} else {
|
||||
for ( size_t i = 0; i < graph.textures.size() && i < graph.images.size(); ++i ) {
|
||||
auto& image = graph.images[i];
|
||||
@ -171,6 +180,7 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
}
|
||||
}
|
||||
texture.loadFromImage( image );
|
||||
image.clear();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -238,17 +248,18 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
auto& mesh = entity->getComponent<ext::gltf::mesh_t>();
|
||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||
std::string nodeName = metadata["system"]["graph"]["name"].as<std::string>();
|
||||
#if 0
|
||||
#if 1
|
||||
if ( graph.mode & ext::gltf::LoadMode::NORMALS ) {
|
||||
// bool invert = false;
|
||||
bool INVERTED = graph.mode & ext::gltf::LoadMode::INVERT;
|
||||
if ( !mesh.indices.empty() ) {
|
||||
if ( mesh.indices.empty() ) {
|
||||
for ( size_t i = 0; i < mesh.vertices.size(); i+=3 ) {
|
||||
auto& a = mesh.vertices[i+(INVERTED ? 0 : 0)].position;
|
||||
auto& b = mesh.vertices[i+(INVERTED ? 1 : 2)].position;
|
||||
auto& c = mesh.vertices[i+(INVERTED ? 2 : 1)].position;
|
||||
|
||||
pod::Vector3f normal = uf::vector::normalize( uf::vector::cross( b - a, c - a ) );
|
||||
|
||||
mesh.vertices[i+0].normal = normal;
|
||||
mesh.vertices[i+1].normal = normal;
|
||||
mesh.vertices[i+2].normal = normal;
|
||||
@ -367,6 +378,16 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
if ( !info["preserve position"].as<bool>() ) childTransform.position = flatten.position;
|
||||
if ( !info["preserve orientation"].as<bool>() ) childTransform.orientation = flatten.orientation;
|
||||
}
|
||||
if ( info["ignore"].as<bool>() ) {
|
||||
auto& metadata = entity.getComponent<uf::ObjectBehavior::Metadata>();
|
||||
metadata.system.ignoreGraph = true;
|
||||
}
|
||||
#if UF_ENV_DREAMCAST
|
||||
if ( info["superfluous"].as<bool>() ) {
|
||||
auto& metadata = entity.getComponent<uf::ObjectBehavior::Metadata>();
|
||||
metadata.system.ignoreGraph = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// create as light
|
||||
for ( auto& l : graph.lights ) {
|
||||
@ -890,7 +911,7 @@ namespace {
|
||||
|
||||
pod::Graph uf::graph::load( const std::string& filename, ext::gltf::load_mode_t mode, const uf::Serializer& metadata ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define UF_DEBUG_TRACE_MSG(X) UF_DEBUG_MSG(X); malloc_stats();
|
||||
#define UF_DEBUG_TRACE_MSG(X) UF_DEBUG_MSG(X); //malloc_stats();
|
||||
uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
#else
|
||||
@ -905,7 +926,120 @@ pod::Graph uf::graph::load( const std::string& filename, ext::gltf::load_mode_t
|
||||
graph.name = serializer["name"].as<std::string>();
|
||||
graph.mode = mode; // serializer["mode"].as<size_t>();
|
||||
graph.metadata = metadata; // serializer["metadata"];
|
||||
|
||||
#if UF_GRAPH_LOAD_MULTITHREAD
|
||||
std::vector<std::function<int()>> jobs;
|
||||
jobs.emplace_back([&]{
|
||||
// load mesh information
|
||||
UF_DEBUG_TRACE_MSG("Reading meshes...");
|
||||
graph.meshes.reserve( serializer["meshes"].size() );
|
||||
ext::json::forEach( serializer["meshes"], [&]( ext::json::Value& value ){
|
||||
auto& mesh = graph.meshes.emplace_back();
|
||||
if ( value.is<std::string>() ) {
|
||||
UF_DEBUG_TRACE_MSG(directory + "/" + value.as<std::string>());
|
||||
uf::Serializer json;
|
||||
json.readFromFile( directory + "/" + value.as<std::string>() );
|
||||
decode( json, mesh );
|
||||
|
||||
} else {
|
||||
decode( value, mesh );
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// load images
|
||||
UF_DEBUG_TRACE_MSG("Reading images...");
|
||||
graph.images.reserve( serializer["images"].size() );
|
||||
ext::json::forEach( serializer["images"], [&]( ext::json::Value& value ){
|
||||
auto& image = graph.images.emplace_back();
|
||||
if ( value.is<std::string>() ) {
|
||||
std::string filename = directory + "/" + value.as<std::string>();
|
||||
#if UF_ENV_DREAMCAST
|
||||
std::string dtex = uf::string::replace( filename, ".png", ".dtex" );
|
||||
if ( uf::io::exists(dtex) ) filename = dtex;
|
||||
#endif
|
||||
UF_DEBUG_TRACE_MSG("Reading image " << filename);
|
||||
image.open(filename, false);
|
||||
} else {
|
||||
decode( value, image );
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// load texture information
|
||||
UF_DEBUG_TRACE_MSG("Reading texture information...");
|
||||
graph.textures.reserve( serializer["textures"].size() );
|
||||
ext::json::forEach( serializer["textures"], [&]( ext::json::Value& value ){
|
||||
decode( value, graph.textures.emplace_back() );
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// load sampler information
|
||||
UF_DEBUG_TRACE_MSG("Reading sampler information...");
|
||||
graph.samplers.reserve( serializer["samplers"].size() );
|
||||
ext::json::forEach( serializer["samplers"], [&]( ext::json::Value& value ){
|
||||
decode( value, graph.samplers.emplace_back() );
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// load material information
|
||||
UF_DEBUG_TRACE_MSG("Reading material information...");
|
||||
graph.materials.reserve( serializer["materials"].size() );
|
||||
ext::json::forEach( serializer["materials"], [&]( ext::json::Value& value ){
|
||||
decode( value, graph.materials.emplace_back() );
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// load light information
|
||||
UF_DEBUG_TRACE_MSG("Reading lighting information...");
|
||||
graph.lights.reserve( serializer["lighting"].size() );
|
||||
ext::json::forEach( serializer["lighting"], [&]( ext::json::Value& value ){
|
||||
decode( value, graph.lights.emplace_back() );
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// load animation information
|
||||
UF_DEBUG_TRACE_MSG("Reading animation information...");
|
||||
graph.animations.reserve( serializer["animations"].size() );
|
||||
ext::json::forEach( serializer["animations"], [&]( ext::json::Value& value ){
|
||||
if ( value.is<std::string>() ) {
|
||||
uf::Serializer json;
|
||||
json.readFromFile( directory + "/" + value.as<std::string>() );
|
||||
std::string key = json["name"].as<std::string>();
|
||||
decode( json, graph.animations[key] );
|
||||
} else {
|
||||
std::string key = value["name"].as<std::string>();
|
||||
decode( value, graph.animations[key] );
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// load skin information
|
||||
UF_DEBUG_TRACE_MSG("Reading skinning information...");
|
||||
graph.skins.reserve( serializer["skins"].size() );
|
||||
ext::json::forEach( serializer["skins"], [&]( ext::json::Value& value ){
|
||||
decode( value, graph.skins.emplace_back() );
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// load node information
|
||||
UF_DEBUG_TRACE_MSG("Reading nodes...");
|
||||
graph.nodes.reserve( serializer["nodes"].size() );
|
||||
ext::json::forEach( serializer["nodes"], [&]( ext::json::Value& value ){
|
||||
decode( value, graph.nodes.emplace_back() );
|
||||
});
|
||||
decode(serializer["root"], graph.root);
|
||||
return 0;
|
||||
});
|
||||
if ( !jobs.empty() ) uf::thread::batchWorkers( jobs );
|
||||
#else
|
||||
// load mesh information
|
||||
UF_DEBUG_TRACE_MSG("Reading meshes...");
|
||||
graph.meshes.reserve( serializer["meshes"].size() );
|
||||
@ -927,8 +1061,13 @@ pod::Graph uf::graph::load( const std::string& filename, ext::gltf::load_mode_t
|
||||
ext::json::forEach( serializer["images"], [&]( ext::json::Value& value ){
|
||||
auto& image = graph.images.emplace_back();
|
||||
if ( value.is<std::string>() ) {
|
||||
UF_DEBUG_TRACE_MSG("Reading image " << directory << "/" << value.as<std::string>());
|
||||
image.open(directory + "/" + value.as<std::string>(), false);
|
||||
std::string filename = directory + "/" + value.as<std::string>();
|
||||
#if UF_ENV_DREAMCAST
|
||||
std::string dtex = uf::string::replace( filename, ".png", ".dtex" );
|
||||
if ( uf::io::exists(dtex) ) filename = dtex;
|
||||
#endif
|
||||
UF_DEBUG_TRACE_MSG("Reading image " << filename);
|
||||
image.open(filename, false);
|
||||
} else {
|
||||
decode( value, image );
|
||||
}
|
||||
@ -984,7 +1123,7 @@ pod::Graph uf::graph::load( const std::string& filename, ext::gltf::load_mode_t
|
||||
decode( value, graph.nodes.emplace_back() );
|
||||
});
|
||||
decode(serializer["root"], graph.root);
|
||||
|
||||
#endif
|
||||
// generate atlas
|
||||
if ( graph.mode & ext::gltf::LoadMode::ATLAS ) { if ( graph.atlas ) delete graph.atlas; graph.atlas = new uf::Atlas;
|
||||
UF_DEBUG_TRACE_MSG("Generating atlas...");
|
||||
@ -1161,16 +1300,99 @@ void uf::graph::save( const std::string& filename, const pod::Graph& graph ) {
|
||||
|
||||
uf::Serializer serializer;
|
||||
// store metadata
|
||||
/*
|
||||
serializer["name"] = graph.name;
|
||||
serializer["mode"] = graph.mode;
|
||||
serializer["metadata"] = graph.metadata;
|
||||
serializer["metadata"]["mesh optimization"] = 0;
|
||||
*/
|
||||
bool saveSeparately = graph.metadata["debug"]["export"]["split"].as<bool>();
|
||||
bool compression = graph.metadata["debug"]["export"]["compression"].as<bool>();
|
||||
// store images
|
||||
if ( saveSeparately ) {
|
||||
uf::io::mkdir(directory);
|
||||
}
|
||||
if ( saveSeparately ) uf::io::mkdir(directory);
|
||||
|
||||
#if UF_GRAPH_LOAD_MULTITHREAD
|
||||
std::vector<std::function<int()>> jobs;
|
||||
jobs.emplace_back([&]{
|
||||
ext::json::reserve( serializer["images"], graph.images.size() );
|
||||
if ( saveSeparately ) {
|
||||
for ( size_t i = 0; i < graph.images.size(); ++i ) {
|
||||
std::string f = "image."+std::to_string(i)+(compression?".jpg":".png");
|
||||
graph.images[i].save(directory + "/" + f);
|
||||
serializer["images"].emplace_back(f);
|
||||
}
|
||||
} else {
|
||||
for ( auto& image : graph.images ) serializer["images"].emplace_back( encode(image, compression) );
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// store texture information
|
||||
ext::json::reserve( serializer["textures"], graph.textures.size() );
|
||||
for ( auto& texture : graph.textures ) serializer["textures"].emplace_back( encode(texture, compression) );
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// store sampler information
|
||||
ext::json::reserve( serializer["samplers"], graph.samplers.size() );
|
||||
for ( auto& sampler : graph.samplers ) serializer["samplers"].emplace_back( encode(sampler, compression) );
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// store material information
|
||||
ext::json::reserve( serializer["materials"], graph.materials.size() );
|
||||
for ( auto& material : graph.materials ) serializer["materials"].emplace_back( encode(material, compression) );
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// store light information
|
||||
ext::json::reserve( serializer["lighting"], graph.lights.size() );
|
||||
for ( auto& light : graph.lights ) serializer["lighting"].emplace_back( encode(light, compression) );
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// store animation information
|
||||
ext::json::reserve( serializer["animations"], graph.animations.size() );
|
||||
if ( saveSeparately ) {
|
||||
for ( auto pair : graph.animations ) {
|
||||
std::string f = "animation."+pair.first+".json";
|
||||
encode(pair.second, compression).writeToFile(directory+"/" + f);
|
||||
serializer["animations"].emplace_back(f);
|
||||
}
|
||||
} else {
|
||||
for ( auto pair : graph.animations ) serializer["animations"][pair.first] = encode(pair.second, compression);
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// store skin information
|
||||
ext::json::reserve( serializer["skins"], graph.skins.size() );
|
||||
for ( auto& skin : graph.skins ) serializer["skins"].emplace_back( encode(skin, compression) );
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// store mesh information
|
||||
ext::json::reserve( serializer["meshes"], graph.meshes.size() );
|
||||
if ( saveSeparately ) {
|
||||
for ( size_t i = 0; i < graph.meshes.size(); ++i ) {
|
||||
std::string f = "mesh."+std::to_string(i)+".json";
|
||||
encode(graph.meshes[i], compression).writeToFile(directory+"/" + f);
|
||||
serializer["meshes"].emplace_back(f);
|
||||
}
|
||||
} else {
|
||||
for ( auto& mesh : graph.meshes ) serializer["meshes"].emplace_back( encode(mesh, compression) );
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
jobs.emplace_back([&]{
|
||||
// store node information
|
||||
ext::json::reserve( serializer["nodes"], graph.nodes.size() );
|
||||
for ( auto& node : graph.nodes ) serializer["nodes"].emplace_back( encode(node, compression) );
|
||||
serializer["root"] = encode(graph.root, compression);
|
||||
return 0;
|
||||
});
|
||||
if ( !jobs.empty() ) uf::thread::batchWorkers( jobs );
|
||||
#else
|
||||
ext::json::reserve( serializer["images"], graph.images.size() );
|
||||
if ( saveSeparately ) {
|
||||
for ( size_t i = 0; i < graph.images.size(); ++i ) {
|
||||
@ -1222,6 +1444,7 @@ void uf::graph::save( const std::string& filename, const pod::Graph& graph ) {
|
||||
ext::json::reserve( serializer["nodes"], graph.nodes.size() );
|
||||
for ( auto& node : graph.nodes ) serializer["nodes"].emplace_back( encode(node, compression) );
|
||||
serializer["root"] = encode(graph.root, compression);
|
||||
#endif
|
||||
|
||||
if ( saveSeparately ) target = directory + "/graph.json";
|
||||
if ( graph.metadata["debug"]["export"]["precision"].is<size_t>() ) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <uf/ext/lua/lua.h>
|
||||
#if UF_USE_LUA
|
||||
#include <uf/engine/asset/asset.h>
|
||||
|
||||
UF_LUA_REGISTER_USERTYPE(uf::Asset,
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( load, []( uf::Asset& asset, sol::variadic_args va ) {
|
||||
auto it = va.begin();
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <uf/ext/lua/lua.h>
|
||||
#if UF_USE_LUA
|
||||
#include <uf/utils/audio/audio.h>
|
||||
|
||||
UF_LUA_REGISTER_USERTYPE(uf::Audio,
|
||||
sol::call_constructor, sol::initializers( []( uf::Audio& self ){},
|
||||
[]( uf::Audio& self, const std::string& filename = "", double volume = 1 ){
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <uf/ext/lua/lua.h>
|
||||
#if UF_USE_LUA
|
||||
#include <uf/utils/camera/camera.h>
|
||||
|
||||
UF_LUA_REGISTER_USERTYPE(uf::Camera,
|
||||
UF_LUA_REGISTER_USERTYPE_DEFINE( getTransform, []( uf::Camera& self ) {
|
||||
return self.getTransform();
|
||||
|
@ -68,11 +68,11 @@ namespace {
|
||||
UF_LUA_UPDATE_COMPONENT(uf::Camera)
|
||||
},
|
||||
"bind", [](uf::Object& self, const std::string& type, sol::protected_function fun ) {
|
||||
if ( !self.hasBehavior<uf::LuaBehavior>() ) uf::instantiator::bind( "LuaBehavior", self );
|
||||
if ( !self.hasBehavior({.type = uf::LuaBehavior::type}) ) uf::instantiator::bind( "LuaBehavior", self );
|
||||
pod::Behavior* behaviorPointer = NULL;
|
||||
auto& behaviors = self.getBehaviors();
|
||||
for ( auto& b : behaviors ) {
|
||||
if ( b.type != self.getType<uf::LuaBehavior>() ) continue;
|
||||
if ( b.type != uf::LuaBehavior::type ) continue;
|
||||
behaviorPointer = &b;
|
||||
break;
|
||||
}
|
||||
|
@ -254,6 +254,7 @@ void ext::opengl::CommandBuffer::submit() {
|
||||
GL_ERROR_CHECK(glClearColor(info->color[0], info->color[1], info->color[2], info->color[3]));
|
||||
GL_ERROR_CHECK(glClearDepth(info->depth));
|
||||
GL_ERROR_CHECK(glClear(info->bits));
|
||||
GL_ERROR_CHECK(glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &info->color[0]));
|
||||
} break;
|
||||
case ext::opengl::enums::Command::VIEWPORT: {
|
||||
InfoViewport* info = (InfoViewport*) header;
|
||||
@ -330,6 +331,7 @@ void ext::opengl::CommandBuffer::submit() {
|
||||
vertexBufferInfo = NULL;
|
||||
indexBufferInfo = NULL;
|
||||
} break;
|
||||
/*
|
||||
case ext::opengl::enums::Command::GENERATE_TEXTURE: {
|
||||
InfoGenerateTexture* info = (InfoGenerateTexture*) header;
|
||||
if ( state == 2 && VERBOSE_SUBMIT ) std::cout << "["<<info<<"] GENERATING TEXTURE | " << info->descriptor.image << " | " << info->data << "\n";
|
||||
@ -353,6 +355,7 @@ void ext::opengl::CommandBuffer::submit() {
|
||||
}
|
||||
GL_ERROR_CHECK(glBindTexture(info->descriptor.viewType, 0));
|
||||
} break;
|
||||
*/
|
||||
default: {
|
||||
if ( state == 2 && VERBOSE_SUBMIT ) {
|
||||
std::cout << "["<<header<<"] UNKNOWN COMMAND TYPE: " << header->type << ": " << info.data().len << std::endl;;
|
||||
|
@ -138,6 +138,7 @@ void UF_API ext::opengl::removeRenderMode( ext::opengl::RenderMode* mode, bool f
|
||||
if ( free ) delete mode;
|
||||
ext::opengl::states::rebuild = true;
|
||||
}
|
||||
|
||||
void UF_API ext::opengl::initialize() {
|
||||
device.initialize();
|
||||
// swapchain.initialize( device );
|
||||
@ -168,13 +169,10 @@ void UF_API ext::opengl::initialize() {
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
if ( !jobs.empty() ) uf::thread::batchWorkers( jobs );
|
||||
// bind shaders
|
||||
#if !UF_ENV_DREAMCAST
|
||||
{
|
||||
ext::opengl::Shader::bind( "./data/shaders/gltf/instanced.vert.spv", [](const ext::opengl::Shader& shader, const ext::opengl::Graphic& graphic, void* userdata) {
|
||||
ext::opengl::Shader::bind( uf::io::root + "shaders/gltf/instanced.vert.spv", [](const ext::opengl::Shader& shader, const ext::opengl::Graphic& graphic, void* userdata) {
|
||||
if ( !userdata ) return;
|
||||
|
||||
ext::gltf::mesh_t::vertex_t* verticesSrc = (ext::gltf::mesh_t::vertex_t*) userdata;
|
||||
@ -195,10 +193,12 @@ void UF_API ext::opengl::initialize() {
|
||||
|
||||
uf::renderer::VertexDescriptor vertexAttributePosition,
|
||||
vertexAttributeUv,
|
||||
vertexAttributeNormal,
|
||||
vertexAttributeId;
|
||||
|
||||
for ( auto& attribute : graphic.descriptor.geometry.attributes.descriptor ) {
|
||||
if ( attribute.name == "position" ) vertexAttributePosition = attribute;
|
||||
else if ( attribute.name == "normal" ) vertexAttributeNormal = attribute;
|
||||
else if ( attribute.name == "uv" ) vertexAttributeUv = attribute;
|
||||
else if ( attribute.name == "id" ) vertexAttributeId = attribute;
|
||||
}
|
||||
@ -223,19 +223,22 @@ void UF_API ext::opengl::initialize() {
|
||||
|
||||
const pod::Vector3f& position = *((pod::Vector3f*) (vertexSrc + vertexAttributePosition.offset));
|
||||
const pod::Vector2ui& id = *((pod::Vector2ui*) (vertexSrc + vertexAttributeId.offset));
|
||||
const pod::Vector3f& normal = *((pod::Vector3f*) (vertexSrc + vertexAttributeNormal.offset));
|
||||
const pod::Vector2f& uv = *((pod::Vector2f*) (vertexSrc + vertexAttributeUv.offset));
|
||||
|
||||
pod::Vector3f& positionDst = *((pod::Vector3f*) (vertexDst + vertexAttributePosition.offset));
|
||||
pod::Vector3f& normalDst = *((pod::Vector3f*) (vertexDst + vertexAttributeNormal.offset));
|
||||
pod::Vector2f& uvDst = *((pod::Vector2f*) (vertexDst + vertexAttributeUv.offset));
|
||||
|
||||
auto& model = instances[id.x];
|
||||
auto& material = materials[id.y];
|
||||
auto& texture = textures[material.indexAlbedo];
|
||||
|
||||
positionDst = uf::matrix::multiply<float>( model, pod::Vector4f{ position[0], position[1], position[2], 1.0f } );
|
||||
positionDst = uf::matrix::multiply<float>( model, position, 1.0f );
|
||||
normalDst = uf::vector::normalize( uf::matrix::multiply<float>( model, normal, 0.0f ) );
|
||||
}
|
||||
});
|
||||
ext::opengl::Shader::bind( "./data/shaders/gltf/skinned.vert.spv", [](const ext::opengl::Shader& shader, const ext::opengl::Graphic& graphic, void* userdata) {
|
||||
ext::opengl::Shader::bind( uf::io::root + "shaders/gltf/skinned.vert.spv", [](const ext::opengl::Shader& shader, const ext::opengl::Graphic& graphic, void* userdata) {
|
||||
if ( !userdata ) return;
|
||||
|
||||
ext::gltf::mesh_t::vertex_t* verticesSrc = (ext::gltf::mesh_t::vertex_t*) userdata;
|
||||
@ -252,11 +255,13 @@ void UF_API ext::opengl::initialize() {
|
||||
size_t vertices = vertexBuffer.range / vertexStride;
|
||||
|
||||
uf::renderer::VertexDescriptor vertexAttributePosition,
|
||||
vertexAttributeNormal,
|
||||
vertexAttributeJoints,
|
||||
vertexAttributeWeights;
|
||||
|
||||
for ( auto& attribute : graphic.descriptor.geometry.attributes.descriptor ) {
|
||||
if ( attribute.name == "position" ) vertexAttributePosition = attribute;
|
||||
else if ( attribute.name == "normal" ) vertexAttributeNormal = attribute;
|
||||
else if ( attribute.name == "joints" ) vertexAttributeJoints = attribute;
|
||||
else if ( attribute.name == "weights" ) vertexAttributeWeights = attribute;
|
||||
}
|
||||
@ -275,34 +280,49 @@ void UF_API ext::opengl::initialize() {
|
||||
uint8_t* vertexDst = vertexDstPointer + (currentIndex * vertexStride);
|
||||
|
||||
const pod::Vector3f& position = *((pod::Vector3f*) (vertexSrc + vertexAttributePosition.offset));
|
||||
const pod::Vector3f& normal = *((pod::Vector3f*) (vertexSrc + vertexAttributeNormal.offset));
|
||||
const pod::Vector4ui& joints = *((pod::Vector4ui*) (vertexSrc + vertexAttributeJoints.offset));
|
||||
const pod::Vector4f& weights = *((pod::Vector4f*) (vertexSrc + vertexAttributeWeights.offset));
|
||||
|
||||
pod::Vector3f& positionDst = *((pod::Vector3f*) (vertexDst + vertexAttributePosition.offset));
|
||||
pod::Vector3f& normalDst = *((pod::Vector3f*) (vertexDst + vertexAttributeNormal.offset));
|
||||
pod::Matrix4f model = jointMatrices[joints[0]] * weights[0] + jointMatrices[joints[1]] * weights[1] + jointMatrices[joints[2]] * weights[2] + jointMatrices[joints[3]] * weights[3];
|
||||
positionDst = uf::matrix::multiply<float>( model, pod::Vector4f{ position[0], position[1], position[2], 1.0f } );
|
||||
|
||||
positionDst = uf::matrix::multiply<float>( model, position, 1.0f );
|
||||
normalDst = uf::vector::normalize( uf::matrix::multiply<float>( model, normal, 0.0f ) );
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void UF_API ext::opengl::tick(){
|
||||
uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
|
||||
ext::opengl::mutex.lock();
|
||||
if ( ext::opengl::states::resized || ext::opengl::settings::experimental::rebuildOnTickBegin ) {
|
||||
ext::opengl::states::rebuild = true;
|
||||
}
|
||||
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
ext::opengl::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( graphic.initialized || !graphic.process || graphic.initialized ) return;
|
||||
if ( graphic.initialized || !graphic.process || graphic.initialized ) continue;
|
||||
graphic.initializePipeline();
|
||||
ext::opengl::states::rebuild = true;
|
||||
};
|
||||
}
|
||||
} else {
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
ext::opengl::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( graphic.initialized || !graphic.process || graphic.initialized ) return;
|
||||
graphic.initializePipeline();
|
||||
ext::opengl::states::rebuild = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode->device ) {
|
||||
@ -311,39 +331,30 @@ void UF_API ext::opengl::tick(){
|
||||
}
|
||||
renderMode->tick();
|
||||
}
|
||||
|
||||
std::vector<std::function<int()>> jobs;
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( ext::opengl::states::rebuild || renderMode->rebuild ) {
|
||||
if ( settings::experimental::individualPipelines ) renderMode->bindPipelines();
|
||||
if ( settings::experimental::multithreadedCommandRecording ) {
|
||||
jobs.emplace_back([&]{
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
} else {
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
if ( settings::experimental::multithreadedCommandRecording ) jobs.emplace_back([&]{ renderMode->createCommandBuffers(); return 0; });
|
||||
else renderMode->createCommandBuffers();
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
|
||||
if ( !jobs.empty() ) uf::thread::batchWorkers( jobs );
|
||||
/*
|
||||
ext::opengl::device.activateContext();
|
||||
|
||||
ext::opengl::device.commandBuffer.end();
|
||||
ext::opengl::device.commandBuffer.submit();
|
||||
ext::opengl::device.commandBuffer.flush();
|
||||
ext::opengl::device.commandBuffer.start();
|
||||
|
||||
*/
|
||||
ext::opengl::states::rebuild = false;
|
||||
ext::opengl::states::resized = false;
|
||||
ext::opengl::mutex.unlock();
|
||||
}
|
||||
void UF_API ext::opengl::render(){
|
||||
ext::opengl::mutex.lock();
|
||||
#if !UF_ENV_DREAMCAST
|
||||
if ( hasRenderMode("Gui", true) ) {
|
||||
RenderMode& primary = getRenderMode("Gui", true);
|
||||
auto it = std::find( renderModes.begin(), renderModes.end(), &primary );
|
||||
@ -358,110 +369,19 @@ void UF_API ext::opengl::render(){
|
||||
auto it = std::find( renderModes.begin(), renderModes.end(), &primary );
|
||||
if ( it + 1 != renderModes.end() ) std::rotate( it, it + 1, renderModes.end() );
|
||||
}
|
||||
|
||||
#endif
|
||||
ext::opengl::device.activateContext();
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode->execute ) continue;
|
||||
ext::opengl::currentRenderMode = renderMode;
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) scene->render();
|
||||
uf::scene::render();
|
||||
renderMode->render();
|
||||
}
|
||||
/*
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
|
||||
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
|
||||
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // Reset The Projection Matrix
|
||||
|
||||
gluPerspective(45.0f, (GLfloat) settings::width / (GLfloat) settings::height, 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glLoadIdentity(); // Reset The View
|
||||
glTranslatef(-3.0f, 1.5f, -10.0f); // Move Left 1.5 Units And Into The Screen 6.0
|
||||
|
||||
// draw a triangle
|
||||
glBegin(GL_TRIANGLES); // start drawing a polygon
|
||||
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
|
||||
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
|
||||
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
|
||||
glEnd(); // we're done with the polygon
|
||||
|
||||
glTranslatef(3.0f, 0.0f, 0.0f); // Move Right 3 Units
|
||||
|
||||
// draw a square (quadrilateral)
|
||||
glBegin(GL_QUADS); // start drawing a polygon (4 sided)
|
||||
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
|
||||
glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right
|
||||
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
|
||||
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
|
||||
glEnd(); // done with the polygon
|
||||
|
||||
glTranslatef(3.0f, 0.0f, 0.0f);
|
||||
|
||||
glBegin(GL_POLYGON); // start drawing a polygon (4 sided)
|
||||
glVertex3f(-0.0f, 1.0f, 0.0f); // Top Left
|
||||
glVertex3f(-0.75f, 0.75f, 0.0f);
|
||||
glVertex3f(-1.0f, 0.0f, 0.0f); // Top Right
|
||||
glVertex3f(-0.75f,-0.75f, 0.0f); // Bottom Right
|
||||
glVertex3f(-0.0f,-1.0f, 0.0f); // Bottom Left
|
||||
glVertex3f( 0.75f,-0.75f, 0.0f); // Bottom Right
|
||||
glVertex3f( 1.0f, 0.0f, 0.0f); // Top Right
|
||||
glVertex3f( 0.75f, 0.75f, 0.0f);
|
||||
glEnd(); // done with the polygon
|
||||
|
||||
glTranslatef(-6.0f, -3.0f, 0.0f);
|
||||
|
||||
// draw a triangle
|
||||
glBegin(GL_POLYGON); // start drawing a polygon
|
||||
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
|
||||
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
|
||||
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
|
||||
glEnd(); // we're done with the polygon
|
||||
|
||||
glTranslatef(3.0f, 0.0f, 0.0f); // Move Right 3 Units
|
||||
|
||||
// draw a square (quadrilateral)
|
||||
glBegin(GL_POLYGON); // start drawing a polygon (4 sided)
|
||||
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
|
||||
glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right
|
||||
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
|
||||
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
|
||||
glEnd(); // done with the polygon
|
||||
|
||||
glTranslatef(3.0f, 0.0f, 0.0f);
|
||||
|
||||
glBegin(GL_POLYGON); // start drawing a polygon (4 sided)
|
||||
glVertex3f(-0.0f, 1.0f, 0.0f); // Top Left
|
||||
glVertex3f(-0.75f, 0.75f, 0.0f);
|
||||
glVertex3f(-1.0f, 0.0f, 0.0f); // Top Right
|
||||
glVertex3f(-0.75f,-0.75f, 0.0f); // Bottom Right
|
||||
glVertex3f(-0.0f,-1.0f, 0.0f); // Bottom Left
|
||||
glVertex3f( 0.75f,-0.75f, 0.0f); // Bottom Right
|
||||
glVertex3f( 1.0f, 0.0f, 0.0f); // Top Right
|
||||
glVertex3f( 0.75f, 0.75f, 0.0f);
|
||||
glEnd(); // done with the polygon
|
||||
#if UF_ENV_DREAMCAST
|
||||
glKosSwapBuffers();
|
||||
#else
|
||||
device.activateContext().display();
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
ext::opengl::currentRenderMode = NULL;
|
||||
if ( ext::opengl::settings::experimental::waitOnRenderEnd ) {
|
||||
synchronize();
|
||||
}
|
||||
if ( ext::opengl::settings::experimental::waitOnRenderEnd ) synchronize();
|
||||
#if UF_USE_OPENVR
|
||||
/*
|
||||
if ( ext::openvr::context ) {
|
||||
ext::openvr::postSubmit();
|
||||
}
|
||||
*/
|
||||
// if ( ext::openvr::context ) ext::openvr::postSubmit();
|
||||
#endif
|
||||
ext::opengl::mutex.unlock();
|
||||
}
|
||||
@ -470,17 +390,23 @@ void UF_API ext::opengl::destroy() {
|
||||
synchronize();
|
||||
|
||||
Texture2D::empty.destroy();
|
||||
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
uf::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
graphic.destroy();
|
||||
};
|
||||
}
|
||||
} else {
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
uf::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
graphic.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->destroy();
|
||||
|
@ -56,6 +56,15 @@ void ext::opengl::RenderMode::createCommandBuffers() {
|
||||
this->execute = true;
|
||||
|
||||
std::vector<ext::opengl::Graphic*> graphics;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
ext::opengl::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !graphic.initialized || !graphic.process ) continue;
|
||||
graphics.push_back(&graphic);
|
||||
}
|
||||
} else {
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
@ -65,6 +74,7 @@ void ext::opengl::RenderMode::createCommandBuffers() {
|
||||
graphics.push_back(&graphic);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this->synchronize();
|
||||
// bindPipelines( graphics );
|
||||
@ -90,6 +100,15 @@ void ext::opengl::RenderMode::bindPipelines() {
|
||||
this->execute = true;
|
||||
|
||||
std::vector<ext::opengl::Graphic*> graphics;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
ext::opengl::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !graphic.initialized || !graphic.process ) continue;
|
||||
graphics.push_back(&graphic);
|
||||
}
|
||||
} else {
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
@ -100,6 +119,7 @@ void ext::opengl::RenderMode::bindPipelines() {
|
||||
graphics.push_back(&graphic);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this->synchronize();
|
||||
this->bindPipelines( graphics );
|
||||
|
@ -65,11 +65,23 @@ void ext::opengl::BaseRenderMode::initialize( Device& device ) {
|
||||
GL_ERROR_CHECK(glDepthFunc(GL_LESS));
|
||||
}
|
||||
GL_ERROR_CHECK(glEnable(GL_DEPTH_TEST));
|
||||
GL_ERROR_CHECK(glShadeModel(GL_SMOOTH));
|
||||
GL_ERROR_CHECK(glEnable(GL_TEXTURE_2D));
|
||||
GL_ERROR_CHECK(glEnable(GL_BLEND));
|
||||
GL_ERROR_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
GL_ERROR_CHECK(glEnable(GL_LIGHTING));
|
||||
// GL_ERROR_CHECK(glEnable(GL_NORMALIZE));
|
||||
GL_ERROR_CHECK(glEnable(GL_COLOR_MATERIAL));
|
||||
GL_ERROR_CHECK(glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE));
|
||||
GL_ERROR_CHECK(glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR));
|
||||
#if UF_USE_DREAMCAST
|
||||
GL_ERROR_CHECK(glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0));
|
||||
GL_ERROR_CHECK(glShadeModel(GL_SMOOTH));
|
||||
#else
|
||||
GL_ERROR_CHECK(glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1));
|
||||
GL_ERROR_CHECK(glShadeModel(GL_SMOOTH));
|
||||
#endif
|
||||
|
||||
ext::opengl::RenderMode::initialize( device );
|
||||
}
|
||||
|
||||
|
@ -96,44 +96,61 @@ void ext::opengl::Texture::loadFromImage(
|
||||
Device& device,
|
||||
enums::Format::type_t format
|
||||
) {
|
||||
switch ( image.getChannels() ) {
|
||||
// R
|
||||
case 1:
|
||||
switch ( image.getBpp() ) {
|
||||
case 8:
|
||||
format = enums::Format::R8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported BPP of " + std::to_string(image.getBpp()));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RGB
|
||||
case 3:
|
||||
switch ( image.getBpp() ) {
|
||||
case 24:
|
||||
format = enums::Format::R8G8B8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported BPP of " + std::to_string(image.getBpp()));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RGBA
|
||||
case 4:
|
||||
switch ( image.getBpp() ) {
|
||||
case 32:
|
||||
format = enums::Format::R8G8B8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported BPP of " + std::to_string(image.getBpp()));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported channels of " + std::to_string(image.getChannels()));
|
||||
break;
|
||||
}
|
||||
if ( image.getFormat() > 0 ) {
|
||||
internalFormat = image.getFormat();
|
||||
} else
|
||||
switch ( image.getChannels() ) {
|
||||
// R
|
||||
case 1:
|
||||
switch ( image.getBpp() ) {
|
||||
case 8:
|
||||
format = enums::Format::R8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported BPP of " + std::to_string(image.getBpp()));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RB
|
||||
case 2:
|
||||
switch ( image.getBpp() ) {
|
||||
case 16:
|
||||
format = enums::Format::R8G8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported BPP of " + std::to_string(image.getBpp()));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RGB
|
||||
case 3:
|
||||
switch ( image.getBpp() ) {
|
||||
case 24:
|
||||
format = enums::Format::R8G8B8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported BPP of " + std::to_string(image.getBpp()));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RGBA
|
||||
case 4:
|
||||
switch ( image.getBpp() ) {
|
||||
case 16:
|
||||
format = enums::Format::R4G4B4A4_UNORM_PACK16;
|
||||
break;
|
||||
case 32:
|
||||
format = enums::Format::R8G8B8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported BPP of " + std::to_string(image.getBpp()));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported channels of " + std::to_string(image.getChannels()));
|
||||
break;
|
||||
}
|
||||
|
||||
// convert to power of two
|
||||
//image.padToPowerOfTwo();
|
||||
@ -225,15 +242,37 @@ void ext::opengl::Texture::update( uf::Image& image, uint32_t layer ) {
|
||||
return this->update( (void*) image.getPixelsPtr(), image.getPixels().size(), layer );
|
||||
}
|
||||
void ext::opengl::Texture::update( void* data, size_t bufferSize, uint32_t layer ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
if ( internalFormat > 0 ) {
|
||||
GL_ERROR_CHECK(glBindTexture(viewType, image));
|
||||
GL_ERROR_CHECK(glCompressedTexImage2DARB( viewType, 0, internalFormat, width, height, 0, bufferSize, data));
|
||||
GL_ERROR_CHECK(glBindTexture(viewType, 0));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
GLenum format = GL_RGBA;
|
||||
GLenum type = GL_UNSIGNED_BYTE;
|
||||
switch ( this->format ) {
|
||||
#if !UF_ENV_DREAMCAST
|
||||
case enums::Format::R8_UNORM: format = GL_RED;; break;
|
||||
case enums::Format::R8G8_UNORM: format = GL_RG;; break;
|
||||
case enums::Format::R8_UNORM:
|
||||
format = GL_RED;
|
||||
break;
|
||||
#endif
|
||||
case enums::Format::R8G8B8_UNORM: format = GL_RGB;; break;
|
||||
case enums::Format::R8G8B8A8_UNORM: format = GL_RGBA;; break;
|
||||
#if !UF_ENV_DREAMCAST
|
||||
case enums::Format::R8G8_UNORM:
|
||||
format = GL_RG;
|
||||
break;
|
||||
#endif
|
||||
case enums::Format::R8G8B8_UNORM:
|
||||
format = GL_RGB;
|
||||
break;
|
||||
case enums::Format::R4G4B4A4_UNORM_PACK16:
|
||||
format = GL_RGBA;
|
||||
type = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||
break;
|
||||
case enums::Format::R8G8B8A8_UNORM:
|
||||
format = GL_RGBA;
|
||||
break;
|
||||
}
|
||||
GL_ERROR_CHECK(glBindTexture(viewType, image));
|
||||
switch ( viewType ) {
|
||||
|
@ -72,16 +72,25 @@ void ext::vulkan::RenderMode::createCommandBuffers() {
|
||||
this->execute = true;
|
||||
|
||||
std::vector<ext::vulkan::Graphic*> graphics;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !graphic.initialized || !graphic.process ) return;
|
||||
if ( !graphic.initialized || !graphic.process ) continue;
|
||||
graphics.push_back(&graphic);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !graphic.initialized || !graphic.process ) return;
|
||||
graphics.push_back(&graphic);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this->synchronize();
|
||||
// bindPipelines( graphics );
|
||||
@ -115,18 +124,26 @@ void ext::vulkan::RenderMode::bindPipelines() {
|
||||
this->execute = true;
|
||||
|
||||
std::vector<ext::vulkan::Graphic*> graphics;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !graphic.initialized ) return;
|
||||
if ( !graphic.process ) return;
|
||||
if ( !graphic.initialized || !graphic.process ) continue;
|
||||
graphics.push_back(&graphic);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !graphic.initialized ) return;
|
||||
if ( !graphic.process ) return;
|
||||
graphics.push_back(&graphic);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
this->synchronize();
|
||||
this->bindPipelines( graphics );
|
||||
}
|
||||
|
@ -206,135 +206,101 @@ void ext::vulkan::removeRenderMode( ext::vulkan::RenderMode* mode, bool free ) {
|
||||
ext::vulkan::states::rebuild = true;
|
||||
}
|
||||
|
||||
void ext::vulkan::initialize( /*uint8_t stage*/ ) {
|
||||
/*
|
||||
switch ( stage ) {
|
||||
case 0: {
|
||||
*/
|
||||
device.initialize();
|
||||
swapchain.initialize( device );
|
||||
{
|
||||
std::vector<uint8_t> pixels = {
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
};
|
||||
Texture2D::empty.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
Texture2D::empty.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
Texture2D::empty.fromBuffers( (void*) &pixels[0], pixels.size(), ext::vulkan::enums::Format::R8G8B8A8_UNORM, 2, 2, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT );
|
||||
}
|
||||
{
|
||||
std::vector<uint8_t> pixels = {
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
};
|
||||
Texture3D::empty.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
Texture3D::empty.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
Texture3D::empty.fromBuffers( (void*) &pixels[0], pixels.size(), ext::vulkan::enums::Format::R8G8B8A8_UNORM, 2, 2, 2, 1, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT );
|
||||
}
|
||||
{
|
||||
std::vector<uint8_t> pixels = {
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
};
|
||||
TextureCube::empty.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
TextureCube::empty.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
TextureCube::empty.fromBuffers( (void*) &pixels[0], pixels.size(), ext::vulkan::enums::Format::R8G8B8A8_UNORM, 2, 2, 1, 6, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT );
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->initialize(device);
|
||||
}
|
||||
std::vector<std::function<int()>> jobs;
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( settings::experimental::individualPipelines ) renderMode->bindPipelines();
|
||||
if ( settings::experimental::multithreadedCommandRecording ) {
|
||||
jobs.emplace_back([&]{
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
} else {
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
/*
|
||||
} break;
|
||||
case 1: {
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( graphic.initialized ) return;
|
||||
|
||||
graphic.initializePipeline();
|
||||
ext::vulkan::states::rebuild = true;
|
||||
};
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
}
|
||||
}
|
||||
case 2: {
|
||||
std::vector<std::function<int()>> jobs;
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( settings::experimental::individualPipelines ) renderMode->bindPipelines();
|
||||
if ( settings::experimental::multithreadedCommandRecording ) {
|
||||
jobs.emplace_back([&]{
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
} else {
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
UF_EXCEPTION("invalid stage id");
|
||||
} break;
|
||||
void ext::vulkan::initialize() {
|
||||
device.initialize();
|
||||
swapchain.initialize( device );
|
||||
{
|
||||
std::vector<uint8_t> pixels = {
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
};
|
||||
Texture2D::empty.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
Texture2D::empty.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
Texture2D::empty.fromBuffers( (void*) &pixels[0], pixels.size(), ext::vulkan::enums::Format::R8G8B8A8_UNORM, 2, 2, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT );
|
||||
}
|
||||
{
|
||||
std::vector<uint8_t> pixels = {
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
};
|
||||
Texture3D::empty.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
Texture3D::empty.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
Texture3D::empty.fromBuffers( (void*) &pixels[0], pixels.size(), ext::vulkan::enums::Format::R8G8B8A8_UNORM, 2, 2, 2, 1, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT );
|
||||
}
|
||||
{
|
||||
std::vector<uint8_t> pixels = {
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
};
|
||||
TextureCube::empty.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
TextureCube::empty.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
TextureCube::empty.fromBuffers( (void*) &pixels[0], pixels.size(), ext::vulkan::enums::Format::R8G8B8A8_UNORM, 2, 2, 1, 6, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT );
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->initialize(device);
|
||||
}
|
||||
std::vector<std::function<int()>> jobs;
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( settings::experimental::individualPipelines ) renderMode->bindPipelines();
|
||||
if ( settings::experimental::multithreadedCommandRecording ) {
|
||||
jobs.emplace_back([&]{
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
} else {
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
*/
|
||||
}
|
||||
void ext::vulkan::tick() {
|
||||
ext::vulkan::mutex.lock();
|
||||
if ( ext::vulkan::states::resized || ext::vulkan::settings::experimental::rebuildOnTickBegin ) {
|
||||
ext::vulkan::states::rebuild = true;
|
||||
}
|
||||
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( graphic.initialized || !graphic.process || graphic.initialized ) return;
|
||||
if ( graphic.initialized || !graphic.process || graphic.initialized ) continue;
|
||||
graphic.initializePipeline();
|
||||
ext::vulkan::states::rebuild = true;
|
||||
};
|
||||
}
|
||||
} else {
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( graphic.initialized || !graphic.process || graphic.initialized ) return;
|
||||
graphic.initializePipeline();
|
||||
ext::vulkan::states::rebuild = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode->device ) {
|
||||
@ -388,7 +354,7 @@ void ext::vulkan::render() {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode->execute ) continue;
|
||||
ext::vulkan::currentRenderMode = renderMode;
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) scene->render();
|
||||
uf::scene::render();
|
||||
renderMode->render();
|
||||
}
|
||||
|
||||
@ -410,17 +376,23 @@ void ext::vulkan::destroy() {
|
||||
Texture2D::empty.destroy();
|
||||
Texture3D::empty.destroy();
|
||||
TextureCube::empty.destroy();
|
||||
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) continue;
|
||||
uf::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
graphic.destroy();
|
||||
};
|
||||
}
|
||||
} else {
|
||||
for ( uf::Scene* scene : uf::scene::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
scene->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
uf::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
graphic.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->destroy();
|
||||
|
114
engine/src/spec/controller/dreamcast.cpp
Normal file
114
engine/src/spec/controller/dreamcast.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
#include <uf/spec/controller/controller.h>
|
||||
#ifdef UF_ENV_DREAMCAST
|
||||
|
||||
#include <kos.h>
|
||||
#include <limits>
|
||||
#include <uf/utils/string/ext.h>
|
||||
#include <uf/utils/math/vector.h>
|
||||
namespace {
|
||||
struct {
|
||||
maple_device_t* device = NULL;
|
||||
cont_state_t* state = NULL;
|
||||
} controller;
|
||||
|
||||
std::string GetKeyName( uint32_t code ) {
|
||||
switch ( code ) {
|
||||
case CONT_C: return "C";
|
||||
case CONT_B: return "B";
|
||||
case CONT_A: return "A";
|
||||
case CONT_START: return "START";
|
||||
case CONT_DPAD_UP: return "L_DPAD_UP";
|
||||
case CONT_DPAD_DOWN: return "L_DPAD_DOWN";
|
||||
case CONT_DPAD_LEFT: return "L_DPAD_LEFT";
|
||||
case CONT_DPAD_RIGHT: return "L_DPAD_RIGHT";
|
||||
case CONT_Z: return "Z";
|
||||
case CONT_Y: return "Y";
|
||||
case CONT_X: return "X";
|
||||
case CONT_D: return "D";
|
||||
case CONT_DPAD2_UP: return "R_DPAD_UP";
|
||||
case CONT_DPAD2_DOWN: return "R_DPAD_DOWN";
|
||||
case CONT_DPAD2_LEFT: return "R_DPAD_LEFT";
|
||||
case CONT_DPAD2_RIGHT: return "R_DPAD_RIGHT";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
uint32_t GetKeyCode( const std::string& _name ) {
|
||||
std::string name = uf::string::uppercase( _name );
|
||||
if ( name == "C" ) return CONT_C;
|
||||
else if ( name == "B" ) return CONT_B;
|
||||
else if ( name == "A" ) return CONT_A;
|
||||
else if ( name == "START" ) return CONT_START;
|
||||
else if ( name == "L_DPAD_UP" ) return CONT_DPAD_UP;
|
||||
else if ( name == "L_DPAD_DOWN" ) return CONT_DPAD_DOWN;
|
||||
else if ( name == "L_DPAD_LEFT" ) return CONT_DPAD_LEFT;
|
||||
else if ( name == "L_DPAD_RIGHT" ) return CONT_DPAD_RIGHT;
|
||||
else if ( name == "Z" ) return CONT_Z;
|
||||
else if ( name == "Y" ) return CONT_Y;
|
||||
else if ( name == "X" ) return CONT_X;
|
||||
else if ( name == "D" ) return CONT_D;
|
||||
else if ( name == "R_DPAD_UP" ) return CONT_DPAD2_UP;
|
||||
else if ( name == "R_DPAD_DOWN" ) return CONT_DPAD2_DOWN;
|
||||
else if ( name == "R_DPAD_LEFT" ) return CONT_DPAD2_LEFT;
|
||||
else if ( name == "R_DPAD_RIGHT" ) return CONT_DPAD2_RIGHT;
|
||||
else if ( name == "DPAD_UP" ) return CONT_DPAD_UP;
|
||||
else if ( name == "DPAD_DOWN" ) return CONT_DPAD_DOWN;
|
||||
else if ( name == "DPAD_LEFT" ) return CONT_DPAD_LEFT;
|
||||
else if ( name == "DPAD_RIGHT" ) return CONT_DPAD_RIGHT;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void spec::dreamcast::controller::initialize() {
|
||||
::controller.device = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||
}
|
||||
void spec::dreamcast::controller::tick() {
|
||||
if ( !::controller.device ) ::controller.device = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||
if ( ::controller.device ) ::controller.state = (cont_state_t*) maple_dev_status(::controller.device);
|
||||
#if 0
|
||||
std::vector<std::string> str;
|
||||
pod::Vector2f joystick = { analog("L_JOYSTICK_X"), analog("L_JOYSTICK_Y") };
|
||||
if ( joystick ) str.emplace_back("Joystick: " + uf::vector::toString(joystick));
|
||||
if ( pressed("C") ) str.emplace_back("C");
|
||||
if ( pressed("B") ) str.emplace_back("B");
|
||||
if ( pressed("A") ) str.emplace_back("A");
|
||||
if ( pressed("START") ) str.emplace_back("START");
|
||||
if ( pressed("L_DPAD_UP") ) str.emplace_back("L_DPAD_UP");
|
||||
if ( pressed("L_DPAD_DOWN") ) str.emplace_back("L_DPAD_DOWN");
|
||||
if ( pressed("L_DPAD_LEFT") ) str.emplace_back("L_DPAD_LEFT");
|
||||
if ( pressed("L_DPAD_RIGHT") ) str.emplace_back("L_DPAD_RIGHT");
|
||||
if ( pressed("Z") ) str.emplace_back("Z");
|
||||
if ( pressed("Y") ) str.emplace_back("Y");
|
||||
if ( pressed("X") ) str.emplace_back("X");
|
||||
if ( pressed("D") ) str.emplace_back("D");
|
||||
if ( pressed("R_DPAD_UP") ) str.emplace_back("R_DPAD_UP");
|
||||
if ( pressed("R_DPAD_DOWN") ) str.emplace_back("R_DPAD_DOWN");
|
||||
if ( pressed("R_DPAD_LEFT") ) str.emplace_back("R_DPAD_LEFT");
|
||||
if ( pressed("R_DPAD_RIGHT") ) str.emplace_back("R_DPAD_RIGHT");
|
||||
if ( !str.empty() ) UF_DEBUG_MSG(uf::string::join( str, " | " ));
|
||||
#endif
|
||||
}
|
||||
void spec::dreamcast::controller::terminate() {
|
||||
}
|
||||
bool spec::dreamcast::controller::connected( size_t i ) {
|
||||
return ::controller.state;
|
||||
}
|
||||
bool spec::dreamcast::controller::pressed( const std::string& str, size_t i ) {
|
||||
if ( !::controller.state ) return false;
|
||||
return ::controller.state->buttons & GetKeyCode( str );
|
||||
}
|
||||
float spec::dreamcast::controller::analog( const std::string& str, size_t i ) {
|
||||
#define NORMALIZE(X) ((float) (X) / (float) std::numeric_limits<decltype(X)>::max())
|
||||
if ( !::controller.state ) return false;
|
||||
|
||||
if ( str == "L_TRIGGER" ) return NORMALIZE(::controller.state->ltrig);
|
||||
else if ( str == "R_TRIGGER" ) return NORMALIZE(::controller.state->rtrig);
|
||||
else if ( str == "JOYSTICK_X" ) return NORMALIZE(::controller.state->joyx);
|
||||
else if ( str == "JOYSTICK_Y" ) return NORMALIZE(::controller.state->joyy);
|
||||
else if ( str == "L_JOYSTICK_X" ) return NORMALIZE(::controller.state->joyx);
|
||||
else if ( str == "L_JOYSTICK_Y" ) return NORMALIZE(::controller.state->joyy);
|
||||
else if ( str == "R_JOYSTICK_X" ) return NORMALIZE(::controller.state->joy2x);
|
||||
else if ( str == "R_JOYSTICK_Y" ) return NORMALIZE(::controller.state->joy2y);
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#endif
|
8
engine/src/spec/controller/universal.cpp
Normal file
8
engine/src/spec/controller/universal.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include <uf/spec/controller/controller.h>
|
||||
|
||||
void spec::uni::controller::initialize() {}
|
||||
void spec::uni::controller::tick() {}
|
||||
void spec::uni::controller::terminate() {}
|
||||
bool spec::uni::controller::connected( size_t ) { return false; }
|
||||
bool spec::uni::controller::pressed( const std::string&, size_t ) { return false; }
|
||||
float spec::uni::controller::analog( const std::string&, size_t ) { return 0; }
|
5
engine/src/spec/controller/unknown.cpp
Normal file
5
engine/src/spec/controller/unknown.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include <uf/spec/controller/controller.h>
|
||||
|
||||
#ifdef UF_ENV_UNKNOWN
|
||||
|
||||
#endif
|
79
engine/src/spec/controller/windows.cpp
Normal file
79
engine/src/spec/controller/windows.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include <uf/spec/controller/controller.h>
|
||||
#include <uf/utils/string/ext.h>
|
||||
|
||||
#ifdef UF_ENV_WINDOWS
|
||||
#if UF_USE_OPENVR
|
||||
#include <uf/ext/openvr/openvr.h>
|
||||
#endif
|
||||
|
||||
void spec::win32::controller::initialize() {}
|
||||
void spec::win32::controller::tick() {}
|
||||
void spec::win32::controller::terminate() {}
|
||||
bool spec::win32::controller::connected( size_t i ) {
|
||||
#if UF_USE_OPENVR
|
||||
if ( ext::openvr::controllerActive( i ) ) return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
bool spec::win32::controller::pressed( const std::string& _name, size_t i ) {
|
||||
std::string name = uf::string::uppercase(_name);
|
||||
#if UF_USE_OPENVR
|
||||
if ( ext::openvr::context ) {
|
||||
std::string key = "";
|
||||
if ( name == "R_DPAD_UP" ) { i = vr::Controller_Hand::Hand_Right; key = "dpadUp"; }
|
||||
else if ( name == "R_DPAD_DOWN" ) { i = vr::Controller_Hand::Hand_Right; key = "dpadDown"; }
|
||||
else if ( name == "R_DPAD_LEFT" ) { i = vr::Controller_Hand::Hand_Right; key = "dpadLeft"; }
|
||||
else if ( name == "R_DPAD_RIGHT" ) { i = vr::Controller_Hand::Hand_Right; key = "dpadRight"; }
|
||||
else if ( name == "R_JOYSTICK" ) { i = vr::Controller_Hand::Hand_Right; key = "thumbclick"; }
|
||||
else if ( name == "R_A" ) { i = vr::Controller_Hand::Hand_Right; key = "a"; }
|
||||
else if ( name == "R_B" ) { i = vr::Controller_Hand::Hand_Right; key = "b"; }
|
||||
else if ( name == "DPAD_UP" && i == vr::Controller_Hand::Hand_Right ) key = "dpadUp";
|
||||
else if ( name == "DPAD_DOWN" && i == vr::Controller_Hand::Hand_Right ) key = "dpadDown";
|
||||
else if ( name == "DPAD_LEFT" && i == vr::Controller_Hand::Hand_Right ) key = "dpadLeft";
|
||||
else if ( name == "DPAD_RIGHT" && i == vr::Controller_Hand::Hand_Right ) key = "dpadRight";
|
||||
else if ( name == "JOYSTICK" && i == vr::Controller_Hand::Hand_Right ) key = "thumbclick";
|
||||
else if ( name == "A" && i == vr::Controller_Hand::Hand_Right ) key = "a";
|
||||
else if ( name == "B" && i == vr::Controller_Hand::Hand_Right ) key = "b";
|
||||
|
||||
else if ( name == "L_DPAD_UP" ) { i = vr::Controller_Hand::Hand_Left; key = "dpadUp"; }
|
||||
else if ( name == "L_DPAD_DOWN" ) { i = vr::Controller_Hand::Hand_Left; key = "dpadDown"; }
|
||||
else if ( name == "L_DPAD_LEFT" ) { i = vr::Controller_Hand::Hand_Left; key = "dpadLeft"; }
|
||||
else if ( name == "L_DPAD_RIGHT" ) { i = vr::Controller_Hand::Hand_Left; key = "dpadRight"; }
|
||||
else if ( name == "L_JOYSTICK" ) { i = vr::Controller_Hand::Hand_Left; key = "thumbclick"; }
|
||||
else if ( name == "L_A" ) { i = vr::Controller_Hand::Hand_Left; key = "a"; }
|
||||
else if ( name == "L_B" ) { i = vr::Controller_Hand::Hand_Left; key = "b"; }
|
||||
else if ( name == "DPAD_UP" && i == vr::Controller_Hand::Hand_Left ) key = "dpadUp";
|
||||
else if ( name == "DPAD_DOWN" && i == vr::Controller_Hand::Hand_Left ) key = "dpadDown";
|
||||
else if ( name == "DPAD_LEFT" && i == vr::Controller_Hand::Hand_Left ) key = "dpadLeft";
|
||||
else if ( name == "DPAD_RIGHT" && i == vr::Controller_Hand::Hand_Left ) key = "dpadRight";
|
||||
else if ( name == "JOYSTICK" && i == vr::Controller_Hand::Hand_Left ) key = "thumbclick";
|
||||
else if ( name == "A" && i == vr::Controller_Hand::Hand_Left ) key = "a";
|
||||
else if ( name == "B" && i == vr::Controller_Hand::Hand_Left ) key = "b";
|
||||
|
||||
if ( name != "" ) return ext::openvr::controllerState( i, key )["state"].as<bool>();
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
float spec::win32::controller::analog( const std::string&, size_t i ) {
|
||||
#if UF_USE_OPENVR
|
||||
if ( ext::openvr::context ) {
|
||||
size_t offset = 0;
|
||||
std::string key = "";
|
||||
if ( name == "R_JOYSTICK_X" ) { i = vr::Controller_Hand::Hand_Right; key = "thumbstick"; offset = 0; }
|
||||
else if ( name == "JOYSTICK_X" && i == vr::Controller_Hand::Hand_Right ) { key = "thumbstick"; offset = 0;}
|
||||
else if ( name == "R_JOYSTICK_Y" ) { i = vr::Controller_Hand::Hand_Right; key = "thumbstick"; offset = 1; }
|
||||
else if ( name == "JOYSTICK_Y" && i == vr::Controller_Hand::Hand_Right ) { key = "thumbstick"; offset = 1; }
|
||||
|
||||
else if ( name == "L_JOYSTICK_X" ) { i = vr::Controller_Hand::Hand_Left; key = "thumbstick"; offset = 0; }
|
||||
else if ( name == "JOYSTICK_X" && i == vr::Controller_Hand::Hand_Left ) { key = "thumbstick"; offset = 0;}
|
||||
else if ( name == "L_JOYSTICK_Y" ) { i = vr::Controller_Hand::Hand_Left; key = "thumbstick"; offset = 1; }
|
||||
else if ( name == "JOYSTICK_Y" && i == vr::Controller_Hand::Hand_Left ) { key = "thumbstick"; offset = 1; }
|
||||
|
||||
if ( name != "" ) return ext::openvr::controllerState( i, key )["analog"]["position"][offset].as<float>();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
#include <uf/spec/window/window.h>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/string/utf.h>
|
||||
#include <uf/utils/string/ext.h>
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
|
||||
@ -14,6 +15,8 @@ INIT_MALLOCSTATS -- Enable a call to malloc_stats() right before shutdown
|
||||
|
||||
*/
|
||||
|
||||
#include <kos.h>
|
||||
|
||||
extern uint8 romdisk[];
|
||||
KOS_INIT_FLAGS(INIT_DEFAULT | INIT_MALLOCSTATS);
|
||||
KOS_INIT_ROMDISK(romdisk);
|
||||
@ -21,8 +24,237 @@ KOS_INIT_ROMDISK(romdisk);
|
||||
namespace {
|
||||
struct {
|
||||
maple_device_t* device = NULL;
|
||||
cont_state_t* state = NULL;
|
||||
} controller, keyboard;
|
||||
kbd_state_t* state = NULL;
|
||||
} keyboard;
|
||||
struct {
|
||||
maple_device_t* device = NULL;
|
||||
mouse_state_t* state = NULL;
|
||||
} mouse;
|
||||
|
||||
bool GetModifier( uint8_t modifier ) {
|
||||
if ( !::keyboard.state ) return false;
|
||||
return ::keyboard.state->cond.modifiers & modifier;
|
||||
}
|
||||
std::vector<uint8_t> GetKeys() {
|
||||
std::vector<uint8_t> keys;
|
||||
keys.reserve(6);
|
||||
for ( size_t i = 0; i < MAX_PRESSED_KEYS && ::keyboard.state; ++i ) keys.emplace_back(::keyboard.state->cond.keys[i]);
|
||||
return keys;
|
||||
}
|
||||
uint8_t GetKeyState( uint8_t key ) {
|
||||
if ( !::keyboard.state || key < MAX_KBD_KEYS ) return 0;
|
||||
return ::keyboard.state->matrix[key];
|
||||
}
|
||||
std::string GetKeyName( uint8_t key ) {
|
||||
switch ( key ) {
|
||||
case KBD_KEY_A: return "A";
|
||||
case KBD_KEY_B: return "B";
|
||||
case KBD_KEY_C: return "C";
|
||||
case KBD_KEY_D: return "D";
|
||||
case KBD_KEY_E: return "E";
|
||||
case KBD_KEY_F: return "F";
|
||||
case KBD_KEY_G: return "G";
|
||||
case KBD_KEY_H: return "H";
|
||||
case KBD_KEY_I: return "I";
|
||||
case KBD_KEY_J: return "J";
|
||||
case KBD_KEY_K: return "K";
|
||||
case KBD_KEY_L: return "L";
|
||||
case KBD_KEY_M: return "M";
|
||||
case KBD_KEY_N: return "N";
|
||||
case KBD_KEY_O: return "O";
|
||||
case KBD_KEY_P: return "P";
|
||||
case KBD_KEY_Q: return "Q";
|
||||
case KBD_KEY_R: return "R";
|
||||
case KBD_KEY_S: return "S";
|
||||
case KBD_KEY_T: return "T";
|
||||
case KBD_KEY_U: return "U";
|
||||
case KBD_KEY_V: return "V";
|
||||
case KBD_KEY_W: return "W";
|
||||
case KBD_KEY_X: return "X";
|
||||
case KBD_KEY_Y: return "Y";
|
||||
case KBD_KEY_Z: return "Z";
|
||||
case KBD_KEY_1: return "1";
|
||||
case KBD_KEY_2: return "2";
|
||||
case KBD_KEY_3: return "3";
|
||||
case KBD_KEY_4: return "4";
|
||||
case KBD_KEY_5: return "5";
|
||||
case KBD_KEY_6: return "6";
|
||||
case KBD_KEY_7: return "7";
|
||||
case KBD_KEY_8: return "8";
|
||||
case KBD_KEY_9: return "9";
|
||||
case KBD_KEY_0: return "0";
|
||||
case KBD_KEY_NONE: return "NONE";
|
||||
case KBD_KEY_ERROR: return "ERROR";
|
||||
case KBD_KEY_ERR2: return "ERR2";
|
||||
case KBD_KEY_ERR3: return "ERR3";
|
||||
case KBD_KEY_ENTER: return "ENTER";
|
||||
case KBD_KEY_ESCAPE: return "ESCAPE";
|
||||
case KBD_KEY_BACKSPACE: return "BACKSPACE";
|
||||
case KBD_KEY_TAB: return "TAB";
|
||||
case KBD_KEY_SPACE: return "SPACE";
|
||||
case KBD_KEY_MINUS: return "MINUS";
|
||||
case KBD_KEY_PLUS: return "PLUS";
|
||||
case KBD_KEY_LBRACKET: return "LBRACKET";
|
||||
case KBD_KEY_RBRACKET: return "RBRACKET";
|
||||
case KBD_KEY_BACKSLASH: return "BACKSLASH";
|
||||
case KBD_KEY_SEMICOLON: return "SEMICOLON";
|
||||
case KBD_KEY_QUOTE: return "QUOTE";
|
||||
case KBD_KEY_TILDE: return "TILDE";
|
||||
case KBD_KEY_COMMA: return "COMMA";
|
||||
case KBD_KEY_PERIOD: return "PERIOD";
|
||||
case KBD_KEY_SLASH: return "SLASH";
|
||||
case KBD_KEY_CAPSLOCK: return "CAPSLOCK";
|
||||
case KBD_KEY_F1: return "F1";
|
||||
case KBD_KEY_F2: return "F2";
|
||||
case KBD_KEY_F3: return "F3";
|
||||
case KBD_KEY_F4: return "F4";
|
||||
case KBD_KEY_F5: return "F5";
|
||||
case KBD_KEY_F6: return "F6";
|
||||
case KBD_KEY_F7: return "F7";
|
||||
case KBD_KEY_F8: return "F8";
|
||||
case KBD_KEY_F9: return "F9";
|
||||
case KBD_KEY_F10: return "F10";
|
||||
case KBD_KEY_F11: return "F11";
|
||||
case KBD_KEY_F12: return "F12";
|
||||
case KBD_KEY_PRINT: return "PRINT";
|
||||
case KBD_KEY_SCRLOCK: return "SCRLOCK";
|
||||
case KBD_KEY_PAUSE: return "PAUSE";
|
||||
case KBD_KEY_INSERT: return "INSERT";
|
||||
case KBD_KEY_HOME: return "HOME";
|
||||
case KBD_KEY_PGUP: return "PGUP";
|
||||
case KBD_KEY_DEL: return "DEL";
|
||||
case KBD_KEY_END: return "END";
|
||||
case KBD_KEY_PGDOWN: return "PGDOWN";
|
||||
case KBD_KEY_RIGHT: return "RIGHT";
|
||||
case KBD_KEY_LEFT: return "LEFT";
|
||||
case KBD_KEY_DOWN: return "DOWN";
|
||||
case KBD_KEY_UP: return "UP";
|
||||
case KBD_KEY_PAD_NUMLOCK: return "PAD_NUMLOCK";
|
||||
case KBD_KEY_PAD_DIVIDE: return "PAD_DIVIDE";
|
||||
case KBD_KEY_PAD_MULTIPLY: return "PAD_MULTIPLY";
|
||||
case KBD_KEY_PAD_MINUS: return "PAD_MINUS";
|
||||
case KBD_KEY_PAD_PLUS: return "PAD_PLUS";
|
||||
case KBD_KEY_PAD_ENTER: return "PAD_ENTER";
|
||||
case KBD_KEY_PAD_1: return "PAD_1";
|
||||
case KBD_KEY_PAD_2: return "PAD_2";
|
||||
case KBD_KEY_PAD_3: return "PAD_3";
|
||||
case KBD_KEY_PAD_4: return "PAD_4";
|
||||
case KBD_KEY_PAD_5: return "PAD_5";
|
||||
case KBD_KEY_PAD_6: return "PAD_6";
|
||||
case KBD_KEY_PAD_7: return "PAD_7";
|
||||
case KBD_KEY_PAD_8: return "PAD_8";
|
||||
case KBD_KEY_PAD_9: return "PAD_9";
|
||||
case KBD_KEY_PAD_0: return "PAD_0";
|
||||
case KBD_KEY_PAD_PERIOD: return "PAD_PERIOD";
|
||||
case KBD_KEY_S3: return "S3";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
uint8_t GetKeyCode( const std::string& _key ) {
|
||||
std::string key = uf::string::uppercase(_key);
|
||||
|
||||
if ( key == "A" ) return KBD_KEY_A;
|
||||
else if ( key == "B" ) return KBD_KEY_B;
|
||||
else if ( key == "C" ) return KBD_KEY_C;
|
||||
else if ( key == "D" ) return KBD_KEY_D;
|
||||
else if ( key == "E" ) return KBD_KEY_E;
|
||||
else if ( key == "F" ) return KBD_KEY_F;
|
||||
else if ( key == "G" ) return KBD_KEY_G;
|
||||
else if ( key == "H" ) return KBD_KEY_H;
|
||||
else if ( key == "I" ) return KBD_KEY_I;
|
||||
else if ( key == "J" ) return KBD_KEY_J;
|
||||
else if ( key == "K" ) return KBD_KEY_K;
|
||||
else if ( key == "L" ) return KBD_KEY_L;
|
||||
else if ( key == "M" ) return KBD_KEY_M;
|
||||
else if ( key == "N" ) return KBD_KEY_N;
|
||||
else if ( key == "O" ) return KBD_KEY_O;
|
||||
else if ( key == "P" ) return KBD_KEY_P;
|
||||
else if ( key == "Q" ) return KBD_KEY_Q;
|
||||
else if ( key == "R" ) return KBD_KEY_R;
|
||||
else if ( key == "S" ) return KBD_KEY_S;
|
||||
else if ( key == "T" ) return KBD_KEY_T;
|
||||
else if ( key == "U" ) return KBD_KEY_U;
|
||||
else if ( key == "V" ) return KBD_KEY_V;
|
||||
else if ( key == "W" ) return KBD_KEY_W;
|
||||
else if ( key == "X" ) return KBD_KEY_X;
|
||||
else if ( key == "Y" ) return KBD_KEY_Y;
|
||||
else if ( key == "Z" ) return KBD_KEY_Z;
|
||||
else if ( key == "1" ) return KBD_KEY_1;
|
||||
else if ( key == "2" ) return KBD_KEY_2;
|
||||
else if ( key == "3" ) return KBD_KEY_3;
|
||||
else if ( key == "4" ) return KBD_KEY_4;
|
||||
else if ( key == "5" ) return KBD_KEY_5;
|
||||
else if ( key == "6" ) return KBD_KEY_6;
|
||||
else if ( key == "7" ) return KBD_KEY_7;
|
||||
else if ( key == "8" ) return KBD_KEY_8;
|
||||
else if ( key == "9" ) return KBD_KEY_9;
|
||||
else if ( key == "0" ) return KBD_KEY_0;
|
||||
else if ( key == "NONE" ) return KBD_KEY_NONE;
|
||||
else if ( key == "ERROR" ) return KBD_KEY_ERROR;
|
||||
else if ( key == "ERR2" ) return KBD_KEY_ERR2;
|
||||
else if ( key == "ERR3" ) return KBD_KEY_ERR3;
|
||||
else if ( key == "ENTER" ) return KBD_KEY_ENTER;
|
||||
else if ( key == "ESCAPE" ) return KBD_KEY_ESCAPE;
|
||||
else if ( key == "BACKSPACE" ) return KBD_KEY_BACKSPACE;
|
||||
else if ( key == "TAB" ) return KBD_KEY_TAB;
|
||||
else if ( key == "SPACE" ) return KBD_KEY_SPACE;
|
||||
else if ( key == "MINUS" ) return KBD_KEY_MINUS;
|
||||
else if ( key == "PLUS" ) return KBD_KEY_PLUS;
|
||||
else if ( key == "LBRACKET" ) return KBD_KEY_LBRACKET;
|
||||
else if ( key == "RBRACKET" ) return KBD_KEY_RBRACKET;
|
||||
else if ( key == "BACKSLASH" ) return KBD_KEY_BACKSLASH;
|
||||
else if ( key == "SEMICOLON" ) return KBD_KEY_SEMICOLON;
|
||||
else if ( key == "QUOTE" ) return KBD_KEY_QUOTE;
|
||||
else if ( key == "TILDE" ) return KBD_KEY_TILDE;
|
||||
else if ( key == "COMMA" ) return KBD_KEY_COMMA;
|
||||
else if ( key == "PERIOD" ) return KBD_KEY_PERIOD;
|
||||
else if ( key == "SLASH" ) return KBD_KEY_SLASH;
|
||||
else if ( key == "CAPSLOCK" ) return KBD_KEY_CAPSLOCK;
|
||||
else if ( key == "F1" ) return KBD_KEY_F1;
|
||||
else if ( key == "F2" ) return KBD_KEY_F2;
|
||||
else if ( key == "F3" ) return KBD_KEY_F3;
|
||||
else if ( key == "F4" ) return KBD_KEY_F4;
|
||||
else if ( key == "F5" ) return KBD_KEY_F5;
|
||||
else if ( key == "F6" ) return KBD_KEY_F6;
|
||||
else if ( key == "F7" ) return KBD_KEY_F7;
|
||||
else if ( key == "F8" ) return KBD_KEY_F8;
|
||||
else if ( key == "F9" ) return KBD_KEY_F9;
|
||||
else if ( key == "F10" ) return KBD_KEY_F10;
|
||||
else if ( key == "F11" ) return KBD_KEY_F11;
|
||||
else if ( key == "F12" ) return KBD_KEY_F12;
|
||||
else if ( key == "PRINT" ) return KBD_KEY_PRINT;
|
||||
else if ( key == "SCRLOCK" ) return KBD_KEY_SCRLOCK;
|
||||
else if ( key == "PAUSE" ) return KBD_KEY_PAUSE;
|
||||
else if ( key == "INSERT" ) return KBD_KEY_INSERT;
|
||||
else if ( key == "HOME" ) return KBD_KEY_HOME;
|
||||
else if ( key == "PGUP" ) return KBD_KEY_PGUP;
|
||||
else if ( key == "DEL" ) return KBD_KEY_DEL;
|
||||
else if ( key == "END" ) return KBD_KEY_END;
|
||||
else if ( key == "PGDOWN" ) return KBD_KEY_PGDOWN;
|
||||
else if ( key == "RIGHT" ) return KBD_KEY_RIGHT;
|
||||
else if ( key == "LEFT" ) return KBD_KEY_LEFT;
|
||||
else if ( key == "DOWN" ) return KBD_KEY_DOWN;
|
||||
else if ( key == "UP" ) return KBD_KEY_UP;
|
||||
else if ( key == "PAD_NUMLOCK" ) return KBD_KEY_PAD_NUMLOCK;
|
||||
else if ( key == "PAD_DIVIDE" ) return KBD_KEY_PAD_DIVIDE;
|
||||
else if ( key == "PAD_MULTIPLY" ) return KBD_KEY_PAD_MULTIPLY;
|
||||
else if ( key == "PAD_MINUS" ) return KBD_KEY_PAD_MINUS;
|
||||
else if ( key == "PAD_PLUS" ) return KBD_KEY_PAD_PLUS;
|
||||
else if ( key == "PAD_ENTER" ) return KBD_KEY_PAD_ENTER;
|
||||
else if ( key == "PAD_1" ) return KBD_KEY_PAD_1;
|
||||
else if ( key == "PAD_2" ) return KBD_KEY_PAD_2;
|
||||
else if ( key == "PAD_3" ) return KBD_KEY_PAD_3;
|
||||
else if ( key == "PAD_4" ) return KBD_KEY_PAD_4;
|
||||
else if ( key == "PAD_5" ) return KBD_KEY_PAD_5;
|
||||
else if ( key == "PAD_6" ) return KBD_KEY_PAD_6;
|
||||
else if ( key == "PAD_7" ) return KBD_KEY_PAD_7;
|
||||
else if ( key == "PAD_8" ) return KBD_KEY_PAD_8;
|
||||
else if ( key == "PAD_9" ) return KBD_KEY_PAD_9;
|
||||
else if ( key == "PAD_0" ) return KBD_KEY_PAD_0;
|
||||
else if ( key == "PAD_PERIOD" ) return KBD_KEY_PAD_PERIOD;
|
||||
else if ( key == "S3" ) return KBD_KEY_S3;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
UF_API_CALL spec::dreamcast::Window::Window() :
|
||||
@ -69,9 +301,7 @@ UF_API_CALL spec::dreamcast::Window::Window( const spec::dreamcast::Window::vect
|
||||
this->create(size, title);
|
||||
}
|
||||
void UF_API_CALL spec::dreamcast::Window::create( const spec::dreamcast::Window::vector_t& _size, const spec::dreamcast::Window::title_t& title ) {
|
||||
//dbglog_set_level(DBG_WARNING);
|
||||
::controller.device = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||
::keyboard.device = maple_enum_type(0, MAPLE_FUNC_KEYBOARD);
|
||||
::keyboard.device = maple_enum_type(1, MAPLE_FUNC_KEYBOARD);
|
||||
}
|
||||
|
||||
spec::dreamcast::Window::~Window() {
|
||||
@ -124,16 +354,73 @@ bool UF_API_CALL spec::dreamcast::Window::hasFocus() const {
|
||||
|
||||
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
void UF_API_CALL spec::dreamcast::Window::processEvents() {
|
||||
if ( !::controller.device ) ::controller.device = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||
void UF_API_CALL spec::dreamcast::Window::processEvents() {
|
||||
if ( !::keyboard.device ) ::keyboard.device = maple_enum_type(0, MAPLE_FUNC_KEYBOARD);
|
||||
if ( ::keyboard.device ) ::keyboard.state = (kbd_state_t*) maple_dev_status(::keyboard.device);
|
||||
|
||||
if ( !::mouse.device ) ::mouse.device = maple_enum_type(0, MAPLE_FUNC_MOUSE);
|
||||
if ( ::mouse.device ) ::mouse.state = (mouse_state_t*) maple_dev_status(::mouse.device);
|
||||
|
||||
if ( ::controller.device ) ::controller.state = (cont_state_t*) maple_dev_status(::controller.device);
|
||||
if ( ::keyboard.device ) ::keyboard.state = (cont_state_t*) maple_dev_status(::keyboard.device);
|
||||
/* Key inputs */ if ( this->m_asyncParse ) {
|
||||
std::vector<uint8_t> keys = GetKeys();
|
||||
|
||||
if ( ::controller.state ) {
|
||||
if ( ::controller.state->buttons & CONT_START ) {
|
||||
struct Event {
|
||||
std::string type = "unknown";
|
||||
std::string invoker = "???";
|
||||
|
||||
struct {
|
||||
int state;
|
||||
std::string code;
|
||||
uint32_t raw;
|
||||
bool async;
|
||||
|
||||
struct {
|
||||
bool alt;
|
||||
bool ctrl;
|
||||
bool shift;
|
||||
bool sys;
|
||||
} modifier;
|
||||
} key;
|
||||
};
|
||||
Event event; {
|
||||
event.type = "window:Key";
|
||||
event.invoker = "window";
|
||||
event.key.state = -1;
|
||||
event.key.code = "NULL";
|
||||
event.key.raw = 0;
|
||||
event.key.async = true;
|
||||
event.key.modifier = {
|
||||
.alt = GetModifier(KBD_MOD_LALT) || GetModifier(KBD_MOD_RALT),
|
||||
.ctrl = GetModifier(KBD_MOD_LCTRL) || GetModifier(KBD_MOD_RCTRL),
|
||||
.shift = GetModifier(KBD_MOD_LSHIFT) || GetModifier(KBD_MOD_RSHIFT),
|
||||
.sys = GetModifier(KBD_MOD_S1) || GetModifier(KBD_MOD_S2),
|
||||
};
|
||||
}
|
||||
/* Readable (JSON) + Optimal (Userdata) event */ {
|
||||
uf::Serializer json;
|
||||
/* Set up JSON data*/ {
|
||||
json["type"] = event.type + "." + ((event.key.state == -1)?"Pressed":"Released");
|
||||
json["invoker"] = event.invoker;
|
||||
json["key"]["state"] = (event.key.state == -1) ? "Down" : "Up";
|
||||
json["key"]["async"] = event.key.async;
|
||||
json["key"]["modifier"]["alt"] = event.key.modifier.alt;
|
||||
json["key"]["modifier"]["control"] = event.key.modifier.ctrl;
|
||||
json["key"]["modifier"]["shift"] = event.key.modifier.shift;
|
||||
json["key"]["modifier"]["system"] = event.key.modifier.sys;
|
||||
}
|
||||
/* Loop through key inputs */ {
|
||||
for ( auto& key : keys ) {
|
||||
auto code = GetKeyName(key);
|
||||
event.key.code = code;
|
||||
event.key.raw = key;
|
||||
event.key.state = GetKeyState(key);
|
||||
|
||||
json["key"]["code"] = code;
|
||||
json["key"]["raw"] = key;
|
||||
this->pushEvent(event.type, json);
|
||||
this->pushEvent(event.type + "." + code, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,31 +486,9 @@ void UF_API_CALL spec::dreamcast::Window::switchToFullscreen( bool borderless )
|
||||
}
|
||||
|
||||
bool UF_API_CALL spec::dreamcast::Window::isKeyPressed(const std::string& key) {
|
||||
if ( !::controller.state ) return false;
|
||||
|
||||
if ( (key == "Up") && (::controller.state->buttons & CONT_DPAD_UP) ) return true;
|
||||
if ( (key == "Down") && (::controller.state->buttons & CONT_DPAD_DOWN) ) return true;
|
||||
if ( (key == "Left") && (::controller.state->buttons & CONT_DPAD_LEFT) ) return true;
|
||||
if ( (key == "Right") && (::controller.state->buttons & CONT_DPAD_RIGHT) ) return true;
|
||||
|
||||
if ( (key == "Up2") && (::controller.state->buttons & CONT_DPAD2_UP) ) return true;
|
||||
if ( (key == "Down2") && (::controller.state->buttons & CONT_DPAD2_DOWN) ) return true;
|
||||
if ( (key == "Left2") && (::controller.state->buttons & CONT_DPAD2_LEFT) ) return true;
|
||||
if ( (key == "Right2") && (::controller.state->buttons & CONT_DPAD2_RIGHT) ) return true;
|
||||
|
||||
if ( (key == "Start") && (::controller.state->buttons & CONT_START) ) return true;
|
||||
|
||||
if ( (key == "A") && (::controller.state->buttons & CONT_A) ) return true;
|
||||
if ( (key == "B") && (::controller.state->buttons & CONT_B) ) return true;
|
||||
if ( (key == "C") && (::controller.state->buttons & CONT_C) ) return true;
|
||||
if ( (key == "D") && (::controller.state->buttons & CONT_D) ) return true;
|
||||
if ( (key == "X") && (::controller.state->buttons & CONT_X) ) return true;
|
||||
if ( (key == "Y") && (::controller.state->buttons & CONT_Y) ) return true;
|
||||
if ( (key == "Z") && (::controller.state->buttons & CONT_Z) ) return true;
|
||||
|
||||
auto code = GetKeyCode(key);
|
||||
auto keys = GetKeys();
|
||||
for ( auto key : keys ) if ( key == code ) return true;
|
||||
return false;
|
||||
}
|
||||
std::string UF_API_CALL spec::dreamcast::Window::getKey(/*WPARAM key, LPARAM flags*/) {
|
||||
return "";
|
||||
}
|
||||
#endif
|
@ -1,10 +1,11 @@
|
||||
#include <uf/spec/window/window.h>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/string/utf.h>
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
|
||||
#define USE_OPTIMAL 0
|
||||
|
||||
#if defined(UF_ENV_WINDOWS) && (!defined(UF_USE_SFML) || (defined(UF_USE_SFML) && UF_USE_SFML == 0))
|
||||
#if UF_ENV_WINDOWS && (!UF_USE_SFML || (UF_USE_SFML && UF_USE_SFML == 0))
|
||||
namespace {
|
||||
int windowCount = 0;
|
||||
std::wstring className = L"uf::Window::Class";
|
||||
@ -55,6 +56,467 @@ namespace {
|
||||
if ((message == WM_SYSCOMMAND) && (wParam == SC_KEYMENU)) return 0;
|
||||
return DefWindowProcW(handle, message, wParam, lParam);
|
||||
}
|
||||
|
||||
std::vector<WPARAM> GetKeys() {
|
||||
std::vector<WPARAM> keys;
|
||||
keys.reserve(8);
|
||||
|
||||
if ( GetAsyncKeyState('A') & 0x8000 ) keys.push_back('A');
|
||||
if ( GetAsyncKeyState('B') & 0x8000 ) keys.push_back('B');
|
||||
if ( GetAsyncKeyState('C') & 0x8000 ) keys.push_back('C');
|
||||
if ( GetAsyncKeyState('D') & 0x8000 ) keys.push_back('D');
|
||||
if ( GetAsyncKeyState('E') & 0x8000 ) keys.push_back('E');
|
||||
if ( GetAsyncKeyState('F') & 0x8000 ) keys.push_back('F');
|
||||
if ( GetAsyncKeyState('G') & 0x8000 ) keys.push_back('G');
|
||||
if ( GetAsyncKeyState('H') & 0x8000 ) keys.push_back('H');
|
||||
if ( GetAsyncKeyState('I') & 0x8000 ) keys.push_back('I');
|
||||
if ( GetAsyncKeyState('J') & 0x8000 ) keys.push_back('J');
|
||||
if ( GetAsyncKeyState('K') & 0x8000 ) keys.push_back('K');
|
||||
if ( GetAsyncKeyState('L') & 0x8000 ) keys.push_back('L');
|
||||
if ( GetAsyncKeyState('M') & 0x8000 ) keys.push_back('M');
|
||||
if ( GetAsyncKeyState('N') & 0x8000 ) keys.push_back('N');
|
||||
if ( GetAsyncKeyState('O') & 0x8000 ) keys.push_back('O');
|
||||
if ( GetAsyncKeyState('P') & 0x8000 ) keys.push_back('P');
|
||||
if ( GetAsyncKeyState('Q') & 0x8000 ) keys.push_back('Q');
|
||||
if ( GetAsyncKeyState('R') & 0x8000 ) keys.push_back('R');
|
||||
if ( GetAsyncKeyState('S') & 0x8000 ) keys.push_back('S');
|
||||
if ( GetAsyncKeyState('T') & 0x8000 ) keys.push_back('T');
|
||||
if ( GetAsyncKeyState('U') & 0x8000 ) keys.push_back('U');
|
||||
if ( GetAsyncKeyState('V') & 0x8000 ) keys.push_back('V');
|
||||
if ( GetAsyncKeyState('W') & 0x8000 ) keys.push_back('W');
|
||||
if ( GetAsyncKeyState('X') & 0x8000 ) keys.push_back('X');
|
||||
if ( GetAsyncKeyState('Y') & 0x8000 ) keys.push_back('Y');
|
||||
if ( GetAsyncKeyState('Z') & 0x8000 ) keys.push_back('Z');
|
||||
if ( GetAsyncKeyState('0') & 0x8000 ) keys.push_back('0');
|
||||
if ( GetAsyncKeyState('1') & 0x8000 ) keys.push_back('1');
|
||||
if ( GetAsyncKeyState('2') & 0x8000 ) keys.push_back('2');
|
||||
if ( GetAsyncKeyState('3') & 0x8000 ) keys.push_back('3');
|
||||
if ( GetAsyncKeyState('4') & 0x8000 ) keys.push_back('4');
|
||||
if ( GetAsyncKeyState('5') & 0x8000 ) keys.push_back('5');
|
||||
if ( GetAsyncKeyState('6') & 0x8000 ) keys.push_back('6');
|
||||
if ( GetAsyncKeyState('7') & 0x8000 ) keys.push_back('7');
|
||||
if ( GetAsyncKeyState('8') & 0x8000 ) keys.push_back('8');
|
||||
if ( GetAsyncKeyState('9') & 0x8000 ) keys.push_back('9');
|
||||
if ( GetAsyncKeyState(VK_ESCAPE) & 0x8000 ) keys.push_back(VK_ESCAPE);
|
||||
if ( GetAsyncKeyState(VK_LCONTROL) & 0x8000 ) keys.push_back(VK_LCONTROL);
|
||||
if ( GetAsyncKeyState(VK_LSHIFT) & 0x8000 ) keys.push_back(VK_LSHIFT);
|
||||
if ( GetAsyncKeyState(VK_LMENU) & 0x8000 ) keys.push_back(VK_LMENU);
|
||||
if ( GetAsyncKeyState(VK_LWIN) & 0x8000 ) keys.push_back(VK_LWIN);
|
||||
if ( GetAsyncKeyState(VK_RCONTROL) & 0x8000 ) keys.push_back(VK_RCONTROL);
|
||||
if ( GetAsyncKeyState(VK_RSHIFT) & 0x8000 ) keys.push_back(VK_RSHIFT);
|
||||
if ( GetAsyncKeyState(VK_RMENU) & 0x8000 ) keys.push_back(VK_RMENU);
|
||||
if ( GetAsyncKeyState(VK_RWIN) & 0x8000 ) keys.push_back(VK_RWIN);
|
||||
if ( GetAsyncKeyState(VK_APPS) & 0x8000 ) keys.push_back(VK_APPS);
|
||||
if ( GetAsyncKeyState(VK_OEM_4) & 0x8000 ) keys.push_back(VK_OEM_4);
|
||||
if ( GetAsyncKeyState(VK_OEM_6) & 0x8000 ) keys.push_back(VK_OEM_6);
|
||||
if ( GetAsyncKeyState(VK_OEM_1) & 0x8000 ) keys.push_back(VK_OEM_1);
|
||||
if ( GetAsyncKeyState(VK_OEM_COMMA) & 0x8000 ) keys.push_back(VK_OEM_COMMA);
|
||||
if ( GetAsyncKeyState(VK_OEM_PERIOD) & 0x8000 ) keys.push_back(VK_OEM_PERIOD);
|
||||
if ( GetAsyncKeyState(VK_OEM_7) & 0x8000 ) keys.push_back(VK_OEM_7);
|
||||
if ( GetAsyncKeyState(VK_OEM_2) & 0x8000 ) keys.push_back(VK_OEM_2);
|
||||
if ( GetAsyncKeyState(VK_OEM_5) & 0x8000 ) keys.push_back(VK_OEM_5);
|
||||
if ( GetAsyncKeyState(VK_OEM_3) & 0x8000 ) keys.push_back(VK_OEM_3);
|
||||
if ( GetAsyncKeyState(VK_OEM_PLUS) & 0x8000 ) keys.push_back(VK_OEM_PLUS);
|
||||
if ( GetAsyncKeyState(VK_OEM_MINUS) & 0x8000 ) keys.push_back(VK_OEM_MINUS);
|
||||
if ( GetAsyncKeyState(VK_SPACE) & 0x8000 ) keys.push_back(VK_SPACE);
|
||||
if ( GetAsyncKeyState(VK_RETURN) & 0x8000 ) keys.push_back(VK_RETURN);
|
||||
if ( GetAsyncKeyState(VK_BACK) & 0x8000 ) keys.push_back(VK_BACK);
|
||||
if ( GetAsyncKeyState(VK_TAB) & 0x8000 ) keys.push_back(VK_TAB);
|
||||
if ( GetAsyncKeyState(VK_PRIOR) & 0x8000 ) keys.push_back(VK_PRIOR);
|
||||
if ( GetAsyncKeyState(VK_NEXT) & 0x8000 ) keys.push_back(VK_NEXT);
|
||||
if ( GetAsyncKeyState(VK_END) & 0x8000 ) keys.push_back(VK_END);
|
||||
if ( GetAsyncKeyState(VK_HOME) & 0x8000 ) keys.push_back(VK_HOME);
|
||||
if ( GetAsyncKeyState(VK_INSERT) & 0x8000 ) keys.push_back(VK_INSERT);
|
||||
if ( GetAsyncKeyState(VK_DELETE) & 0x8000 ) keys.push_back(VK_DELETE);
|
||||
if ( GetAsyncKeyState(VK_ADD) & 0x8000 ) keys.push_back(VK_ADD);
|
||||
if ( GetAsyncKeyState(VK_SUBTRACT) & 0x8000 ) keys.push_back(VK_SUBTRACT);
|
||||
if ( GetAsyncKeyState(VK_MULTIPLY) & 0x8000 ) keys.push_back(VK_MULTIPLY);
|
||||
if ( GetAsyncKeyState(VK_DIVIDE) & 0x8000 ) keys.push_back(VK_DIVIDE);
|
||||
if ( GetAsyncKeyState(VK_LEFT) & 0x8000 ) keys.push_back(VK_LEFT);
|
||||
if ( GetAsyncKeyState(VK_RIGHT) & 0x8000 ) keys.push_back(VK_RIGHT);
|
||||
if ( GetAsyncKeyState(VK_UP) & 0x8000 ) keys.push_back(VK_UP);
|
||||
if ( GetAsyncKeyState(VK_DOWN) & 0x8000 ) keys.push_back(VK_DOWN);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD0) & 0x8000 ) keys.push_back(VK_NUMPAD0);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD1) & 0x8000 ) keys.push_back(VK_NUMPAD1);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD2) & 0x8000 ) keys.push_back(VK_NUMPAD2);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD3) & 0x8000 ) keys.push_back(VK_NUMPAD3);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD4) & 0x8000 ) keys.push_back(VK_NUMPAD4);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD5) & 0x8000 ) keys.push_back(VK_NUMPAD5);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD6) & 0x8000 ) keys.push_back(VK_NUMPAD6);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD7) & 0x8000 ) keys.push_back(VK_NUMPAD7);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD8) & 0x8000 ) keys.push_back(VK_NUMPAD8);
|
||||
if ( GetAsyncKeyState(VK_NUMPAD9) & 0x8000 ) keys.push_back(VK_NUMPAD9);
|
||||
if ( GetAsyncKeyState(VK_F1) & 0x8000 ) keys.push_back(VK_F1);
|
||||
if ( GetAsyncKeyState(VK_F2) & 0x8000 ) keys.push_back(VK_F2);
|
||||
if ( GetAsyncKeyState(VK_F3) & 0x8000 ) keys.push_back(VK_F3);
|
||||
if ( GetAsyncKeyState(VK_F4) & 0x8000 ) keys.push_back(VK_F4);
|
||||
if ( GetAsyncKeyState(VK_F5) & 0x8000 ) keys.push_back(VK_F5);
|
||||
if ( GetAsyncKeyState(VK_F6) & 0x8000 ) keys.push_back(VK_F6);
|
||||
if ( GetAsyncKeyState(VK_F7) & 0x8000 ) keys.push_back(VK_F7);
|
||||
if ( GetAsyncKeyState(VK_F8) & 0x8000 ) keys.push_back(VK_F8);
|
||||
if ( GetAsyncKeyState(VK_F9) & 0x8000 ) keys.push_back(VK_F9);
|
||||
if ( GetAsyncKeyState(VK_F10) & 0x8000 ) keys.push_back(VK_F10);
|
||||
if ( GetAsyncKeyState(VK_F11) & 0x8000 ) keys.push_back(VK_F11);
|
||||
if ( GetAsyncKeyState(VK_F12) & 0x8000 ) keys.push_back(VK_F12);
|
||||
if ( GetAsyncKeyState(VK_F13) & 0x8000 ) keys.push_back(VK_F13);
|
||||
if ( GetAsyncKeyState(VK_F14) & 0x8000 ) keys.push_back(VK_F14);
|
||||
if ( GetAsyncKeyState(VK_F15) & 0x8000 ) keys.push_back(VK_F15);
|
||||
if ( GetAsyncKeyState(VK_PAUSE) & 0x8000 ) keys.push_back(VK_PAUSE);
|
||||
|
||||
if ( GetAsyncKeyState(VK_LBUTTON) & 0x8000 ) keys.push_back(VK_LBUTTON);
|
||||
if ( GetAsyncKeyState(VK_RBUTTON) & 0x8000 ) keys.push_back(VK_RBUTTON);
|
||||
if ( GetAsyncKeyState(VK_MBUTTON) & 0x8000 ) keys.push_back(VK_MBUTTON);
|
||||
if ( GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ) keys.push_back(VK_XBUTTON1);
|
||||
if ( GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ) keys.push_back(VK_XBUTTON2);
|
||||
return keys;
|
||||
}
|
||||
std::string _GetKeyName( WPARAM key, LPARAM flags = 0 ) {
|
||||
#if 1
|
||||
switch ( key ) {
|
||||
// Check the scancode to distinguish between left and right shift
|
||||
case VK_SHIFT: {
|
||||
static UINT lShift = MapVirtualKeyW(VK_LSHIFT, MAPVK_VK_TO_VSC);
|
||||
UINT scancode = static_cast<UINT>((flags & (0xFF << 16)) >> 16);
|
||||
return scancode == lShift ? "LShift" : "RShift";
|
||||
}
|
||||
// Check the "extended" flag to distinguish between left and right alt
|
||||
case VK_MENU : return (HIWORD(flags) & KF_EXTENDED) ? "RAlt" : "LAlt";
|
||||
// Check the "extended" flag to distinguish between left and right control
|
||||
case VK_CONTROL : return (HIWORD(flags) & KF_EXTENDED) ? "RControl" : "LControl";
|
||||
|
||||
// Other keys are reported properly
|
||||
case VK_LWIN: return "LSystem";
|
||||
case VK_RWIN: return "RSystem";
|
||||
case VK_APPS: return "Menu";
|
||||
case VK_OEM_1: return "SemiColon";
|
||||
case VK_OEM_2: return "Slash";
|
||||
case VK_OEM_PLUS: return "Equal";
|
||||
case VK_OEM_MINUS: return "Dash";
|
||||
case VK_OEM_4: return "LBracket";
|
||||
case VK_OEM_6: return "RBracket";
|
||||
case VK_OEM_COMMA: return "Comma";
|
||||
case VK_OEM_PERIOD: return "Period";
|
||||
case VK_OEM_7: return "Quote";
|
||||
case VK_OEM_5: return "BackSlash";
|
||||
case VK_OEM_3: return "Tilde";
|
||||
|
||||
case VK_ESCAPE: return "Escape";
|
||||
case VK_SPACE: return "Space";
|
||||
case VK_RETURN: return "Enter";
|
||||
case VK_BACK: return "BackSpace";
|
||||
case VK_TAB: return "Tab";
|
||||
case VK_PRIOR: return "PageUp";
|
||||
case VK_NEXT: return "PageDown";
|
||||
case VK_END: return "End";
|
||||
case VK_HOME: return "Home";
|
||||
case VK_INSERT: return "Insert";
|
||||
case VK_DELETE: return "Delete";
|
||||
case VK_ADD: return "Add";
|
||||
case VK_SUBTRACT: return "Subtract";
|
||||
case VK_MULTIPLY: return "Multiply";
|
||||
case VK_DIVIDE: return "Divide";
|
||||
case VK_PAUSE: return "Pause";
|
||||
|
||||
case VK_F1: return "F1";
|
||||
case VK_F2: return "F2";
|
||||
case VK_F3: return "F3";
|
||||
case VK_F4: return "F4";
|
||||
case VK_F5: return "F5";
|
||||
case VK_F6: return "F6";
|
||||
case VK_F7: return "F7";
|
||||
case VK_F8: return "F8";
|
||||
case VK_F9: return "F9";
|
||||
case VK_F10: return "F10";
|
||||
case VK_F11: return "F11";
|
||||
case VK_F12: return "F12";
|
||||
case VK_F13: return "F13";
|
||||
case VK_F14: return "F14";
|
||||
case VK_F15: return "F15";
|
||||
|
||||
case VK_LEFT: return "Left";
|
||||
case VK_RIGHT: return "Right";
|
||||
case VK_UP: return "Up";
|
||||
case VK_DOWN: return "Down";
|
||||
|
||||
case VK_NUMPAD0: return "Numpad0";
|
||||
case VK_NUMPAD1: return "Numpad1";
|
||||
case VK_NUMPAD2: return "Numpad2";
|
||||
case VK_NUMPAD3: return "Numpad3";
|
||||
case VK_NUMPAD4: return "Numpad4";
|
||||
case VK_NUMPAD5: return "Numpad5";
|
||||
case VK_NUMPAD6: return "Numpad6";
|
||||
case VK_NUMPAD7: return "Numpad7";
|
||||
case VK_NUMPAD8: return "Numpad8";
|
||||
case VK_NUMPAD9: return "Numpad9";
|
||||
|
||||
case 'Q': return "Q";
|
||||
case 'W': return "W";
|
||||
case 'E': return "E";
|
||||
case 'R': return "R";
|
||||
case 'T': return "T";
|
||||
case 'Y': return "Y";
|
||||
case 'U': return "U";
|
||||
case 'I': return "I";
|
||||
case 'O': return "O";
|
||||
case 'P': return "P";
|
||||
|
||||
case 'A': return "A";
|
||||
case 'S': return "S";
|
||||
case 'D': return "D";
|
||||
case 'F': return "F";
|
||||
case 'G': return "G";
|
||||
case 'H': return "H";
|
||||
case 'J': return "J";
|
||||
case 'K': return "K";
|
||||
case 'L': return "L";
|
||||
|
||||
case 'Z': return "Z";
|
||||
case 'X': return "X";
|
||||
case 'C': return "C";
|
||||
case 'V': return "V";
|
||||
case 'B': return "B";
|
||||
case 'N': return "N";
|
||||
case 'M': return "M";
|
||||
|
||||
case '1': return "Num1";
|
||||
case '2': return "Num2";
|
||||
case '3': return "Num3";
|
||||
case '4': return "Num4";
|
||||
case '5': return "Num5";
|
||||
case '6': return "Num6";
|
||||
case '7': return "Num7";
|
||||
case '8': return "Num8";
|
||||
case '9': return "Num9";
|
||||
case '0': return "Num0";
|
||||
}
|
||||
#else
|
||||
switch ( key ) {
|
||||
case 'A': return "A";
|
||||
case 'B': return "B";
|
||||
case 'C': return "C";
|
||||
case 'D': return "D";
|
||||
case 'E': return "E";
|
||||
case 'F': return "F";
|
||||
case 'G': return "G";
|
||||
case 'H': return "H";
|
||||
case 'I': return "I";
|
||||
case 'J': return "J";
|
||||
case 'K': return "K";
|
||||
case 'L': return "L";
|
||||
case 'M': return "M";
|
||||
case 'N': return "N";
|
||||
case 'O': return "O";
|
||||
case 'P': return "P";
|
||||
case 'Q': return "Q";
|
||||
case 'R': return "R";
|
||||
case 'S': return "S";
|
||||
case 'T': return "T";
|
||||
case 'U': return "U";
|
||||
case 'V': return "V";
|
||||
case 'W': return "W";
|
||||
case 'X': return "X";
|
||||
case 'Y': return "Y";
|
||||
case 'Z': return "Z";
|
||||
case '0': return "0";
|
||||
case '1': return "1";
|
||||
case '2': return "2";
|
||||
case '3': return "3";
|
||||
case '4': return "4";
|
||||
case '5': return "5";
|
||||
case '6': return "6";
|
||||
case '7': return "7";
|
||||
case '8': return "8";
|
||||
case '9': return "9";
|
||||
case VK_ESCAPE: return "Escape";
|
||||
case VK_LCONTROL: return "LControl";
|
||||
case VK_LSHIFT: return "LShift";
|
||||
case VK_LMENU: return "LAlt";
|
||||
case VK_LWIN: return "LSystem";
|
||||
case VK_RCONTROL: return "RControl";
|
||||
case VK_RSHIFT: return "RShift";
|
||||
case VK_RMENU: return "RAlt";
|
||||
case VK_RWIN: return "RSystem";
|
||||
case VK_APPS: return "Apps";
|
||||
case VK_OEM_4: return "OEM4";
|
||||
case VK_OEM_6: return "OEM6";
|
||||
case VK_OEM_1: return "OEM1";
|
||||
case VK_OEM_COMMA: return "OEMComma";
|
||||
case VK_OEM_PERIOD: return "OEMPeriod";
|
||||
case VK_OEM_7: return "OEM7";
|
||||
case VK_OEM_2: return "OEM2";
|
||||
case VK_OEM_5: return "OEM5";
|
||||
case VK_OEM_3: return "OEM3";
|
||||
case VK_OEM_PLUS: return "OEM+";
|
||||
case VK_OEM_MINUS: return "OEM-";
|
||||
case VK_SPACE: return " ";
|
||||
case VK_RETURN: return "Enter";
|
||||
case VK_BACK: return "Back";
|
||||
case VK_TAB: return "Tab";
|
||||
case VK_PRIOR: return "Prior";
|
||||
case VK_NEXT: return "Next";
|
||||
case VK_END: return "End";
|
||||
case VK_HOME: return "Home";
|
||||
case VK_INSERT: return "Insert";
|
||||
case VK_DELETE: return "Delete";
|
||||
case VK_ADD: return "+";
|
||||
case VK_SUBTRACT: return "-";
|
||||
case VK_MULTIPLY: return "*";
|
||||
case VK_DIVIDE: return "/";
|
||||
case VK_LEFT: return "Left";
|
||||
case VK_RIGHT: return "Right";
|
||||
case VK_UP: return "Up";
|
||||
case VK_DOWN: return "Down";
|
||||
case VK_NUMPAD0: return "Num0";
|
||||
case VK_NUMPAD1: return "Num1";
|
||||
case VK_NUMPAD2: return "Num2";
|
||||
case VK_NUMPAD3: return "Num3";
|
||||
case VK_NUMPAD4: return "Num4";
|
||||
case VK_NUMPAD5: return "Num5";
|
||||
case VK_NUMPAD6: return "Num6";
|
||||
case VK_NUMPAD7: return "Num7";
|
||||
case VK_NUMPAD8: return "Num8";
|
||||
case VK_NUMPAD9: return "Num9";
|
||||
case VK_F1: return "F1";
|
||||
case VK_F2: return "F2";
|
||||
case VK_F3: return "F3";
|
||||
case VK_F4: return "F4";
|
||||
case VK_F5: return "F5";
|
||||
case VK_F6: return "F6";
|
||||
case VK_F7: return "F7";
|
||||
case VK_F8: return "F8";
|
||||
case VK_F9: return "F9";
|
||||
case VK_F10: return "F10";
|
||||
case VK_F11: return "F11";
|
||||
case VK_F12: return "F12";
|
||||
case VK_F13: return "F13";
|
||||
case VK_F14: return "F14";
|
||||
case VK_F15: return "F15";
|
||||
case VK_PAUSE: return "Pause";
|
||||
|
||||
case VK_LBUTTON: return "LeftMouse";
|
||||
case VK_RBUTTON: return "RightMouse";
|
||||
case VK_MBUTTON: return "MiddleMouse";
|
||||
case VK_XBUTTON1: return "XButton1";
|
||||
case VK_XBUTTON2: return "XButton2";
|
||||
}
|
||||
#endif
|
||||
return std::to_string((int) key);
|
||||
}
|
||||
std::string GetKeyName( WPARAM key, LPARAM flags = 0 ) {
|
||||
return uf::string::uppercase( _GetKeyName( key, flags ) );
|
||||
}
|
||||
|
||||
WPARAM GetKeyCode( const std::string& _name ) {
|
||||
std::string name = uf::string::uppercase(_name);
|
||||
if ( name == "A" ) return 'A';
|
||||
else if ( name == "B" ) return 'B';
|
||||
else if ( name == "C" ) return 'C';
|
||||
else if ( name == "D" ) return 'D';
|
||||
else if ( name == "E" ) return 'E';
|
||||
else if ( name == "F" ) return 'F';
|
||||
else if ( name == "G" ) return 'G';
|
||||
else if ( name == "H" ) return 'H';
|
||||
else if ( name == "I" ) return 'I';
|
||||
else if ( name == "J" ) return 'J';
|
||||
else if ( name == "K" ) return 'K';
|
||||
else if ( name == "L" ) return 'L';
|
||||
else if ( name == "M" ) return 'M';
|
||||
else if ( name == "N" ) return 'N';
|
||||
else if ( name == "O" ) return 'O';
|
||||
else if ( name == "P" ) return 'P';
|
||||
else if ( name == "Q" ) return 'Q';
|
||||
else if ( name == "R" ) return 'R';
|
||||
else if ( name == "S" ) return 'S';
|
||||
else if ( name == "T" ) return 'T';
|
||||
else if ( name == "U" ) return 'U';
|
||||
else if ( name == "V" ) return 'V';
|
||||
else if ( name == "W" ) return 'W';
|
||||
else if ( name == "X" ) return 'X';
|
||||
else if ( name == "Y" ) return 'Y';
|
||||
else if ( name == "Z" ) return 'Z';
|
||||
else if ( name == "0" ) return '0';
|
||||
else if ( name == "1" ) return '1';
|
||||
else if ( name == "2" ) return '2';
|
||||
else if ( name == "3" ) return '3';
|
||||
else if ( name == "4" ) return '4';
|
||||
else if ( name == "5" ) return '5';
|
||||
else if ( name == "6" ) return '6';
|
||||
else if ( name == "7" ) return '7';
|
||||
else if ( name == "8" ) return '8';
|
||||
else if ( name == "9" ) return '9';
|
||||
else if ( name == "ESCAPE" ) return VK_ESCAPE;
|
||||
else if ( name == "LCONTROL" ) return VK_LCONTROL;
|
||||
else if ( name == "LSHIFT" ) return VK_LSHIFT;
|
||||
else if ( name == "LALT" ) return VK_LMENU;
|
||||
else if ( name == "LSYSTEM" ) return VK_LWIN;
|
||||
else if ( name == "RCONTROL" ) return VK_RCONTROL;
|
||||
else if ( name == "RSHIFT" ) return VK_RSHIFT;
|
||||
else if ( name == "RALT" ) return VK_RMENU;
|
||||
else if ( name == "RSYSTEM" ) return VK_RWIN;
|
||||
else if ( name == "APPS" ) return VK_APPS;
|
||||
else if ( name == "OEM4" ) return VK_OEM_4;
|
||||
else if ( name == "OEM6" ) return VK_OEM_6;
|
||||
else if ( name == "OEM1" ) return VK_OEM_1;
|
||||
else if ( name == "OEMCOMMA" ) return VK_OEM_COMMA;
|
||||
else if ( name == "OEMPERIOD" ) return VK_OEM_PERIOD;
|
||||
else if ( name == "OEM7" ) return VK_OEM_7;
|
||||
else if ( name == "OEM2" ) return VK_OEM_2;
|
||||
else if ( name == "OEM5" ) return VK_OEM_5;
|
||||
else if ( name == "OEM3" ) return VK_OEM_3;
|
||||
else if ( name == "OEM+" ) return VK_OEM_PLUS;
|
||||
else if ( name == "OEM-" ) return VK_OEM_MINUS;
|
||||
else if ( name == " " ) return VK_SPACE;
|
||||
else if ( name == "ENTER" ) return VK_RETURN;
|
||||
else if ( name == "BACK" ) return VK_BACK;
|
||||
else if ( name == "TAB" ) return VK_TAB;
|
||||
else if ( name == "PRIOR" ) return VK_PRIOR;
|
||||
else if ( name == "NEXT" ) return VK_NEXT;
|
||||
else if ( name == "END" ) return VK_END;
|
||||
else if ( name == "HOME" ) return VK_HOME;
|
||||
else if ( name == "INSERT" ) return VK_INSERT;
|
||||
else if ( name == "DELETE" ) return VK_DELETE;
|
||||
else if ( name == "+" ) return VK_ADD;
|
||||
else if ( name == "-" ) return VK_SUBTRACT;
|
||||
else if ( name == "*" ) return VK_MULTIPLY;
|
||||
else if ( name == "/" ) return VK_DIVIDE;
|
||||
else if ( name == "LEFT" ) return VK_LEFT;
|
||||
else if ( name == "RIGHT" ) return VK_RIGHT;
|
||||
else if ( name == "UP" ) return VK_UP;
|
||||
else if ( name == "DOWN" ) return VK_DOWN;
|
||||
else if ( name == "NUM0" ) return VK_NUMPAD0;
|
||||
else if ( name == "NUM1" ) return VK_NUMPAD1;
|
||||
else if ( name == "NUM2" ) return VK_NUMPAD2;
|
||||
else if ( name == "NUM3" ) return VK_NUMPAD3;
|
||||
else if ( name == "NUM4" ) return VK_NUMPAD4;
|
||||
else if ( name == "NUM5" ) return VK_NUMPAD5;
|
||||
else if ( name == "NUM6" ) return VK_NUMPAD6;
|
||||
else if ( name == "NUM7" ) return VK_NUMPAD7;
|
||||
else if ( name == "NUM8" ) return VK_NUMPAD8;
|
||||
else if ( name == "NUM9" ) return VK_NUMPAD9;
|
||||
else if ( name == "F1" ) return VK_F1;
|
||||
else if ( name == "F2" ) return VK_F2;
|
||||
else if ( name == "F3" ) return VK_F3;
|
||||
else if ( name == "F4" ) return VK_F4;
|
||||
else if ( name == "F5" ) return VK_F5;
|
||||
else if ( name == "F6" ) return VK_F6;
|
||||
else if ( name == "F7" ) return VK_F7;
|
||||
else if ( name == "F8" ) return VK_F8;
|
||||
else if ( name == "F9" ) return VK_F9;
|
||||
else if ( name == "F10" ) return VK_F10;
|
||||
else if ( name == "F11" ) return VK_F11;
|
||||
else if ( name == "F12" ) return VK_F12;
|
||||
else if ( name == "F13" ) return VK_F13;
|
||||
else if ( name == "F14" ) return VK_F14;
|
||||
else if ( name == "F15" ) return VK_F15;
|
||||
else if ( name == "PAUSE" ) return VK_PAUSE;
|
||||
|
||||
else if ( name == "LEFTMOUSE" ) return VK_LBUTTON;
|
||||
else if ( name == "RIGHTMOUSE" ) return VK_RBUTTON;
|
||||
else if ( name == "MIDDLEMOUSE" ) return VK_MBUTTON;
|
||||
else if ( name == "XBUTTON1" ) return VK_XBUTTON1;
|
||||
else if ( name == "XBUTTON2" ) return VK_XBUTTON2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
UF_API_CALL spec::win32::Window::Window() :
|
||||
@ -300,8 +762,6 @@ bool UF_API_CALL spec::win32::Window::hasFocus() const {
|
||||
return this->m_handle == GetForegroundWindow();
|
||||
}
|
||||
|
||||
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
void UF_API_CALL spec::win32::Window::processEvents() {
|
||||
if ( !this->m_callback ) {
|
||||
MSG message;
|
||||
@ -311,114 +771,7 @@ void UF_API_CALL spec::win32::Window::processEvents() {
|
||||
}
|
||||
}
|
||||
/* Key inputs */ if ( this->m_asyncParse ) {
|
||||
std::vector<WPARAM> keys;
|
||||
if ( GetAsyncKeyState('A') & 0x8000 ) keys.push_back('A'); // keys.push_back(this->getKey('A', 0));
|
||||
if ( GetAsyncKeyState('B') & 0x8000 ) keys.push_back('B'); // keys.push_back(this->getKey('B', 0));
|
||||
if ( GetAsyncKeyState('C') & 0x8000 ) keys.push_back('C'); // keys.push_back(this->getKey('C', 0));
|
||||
if ( GetAsyncKeyState('D') & 0x8000 ) keys.push_back('D'); // keys.push_back(this->getKey('D', 0));
|
||||
if ( GetAsyncKeyState('E') & 0x8000 ) keys.push_back('E'); // keys.push_back(this->getKey('E', 0));
|
||||
if ( GetAsyncKeyState('F') & 0x8000 ) keys.push_back('F'); // keys.push_back(this->getKey('F', 0));
|
||||
if ( GetAsyncKeyState('G') & 0x8000 ) keys.push_back('G'); // keys.push_back(this->getKey('G', 0));
|
||||
if ( GetAsyncKeyState('H') & 0x8000 ) keys.push_back('H'); // keys.push_back(this->getKey('H', 0));
|
||||
if ( GetAsyncKeyState('I') & 0x8000 ) keys.push_back('I'); // keys.push_back(this->getKey('I', 0));
|
||||
if ( GetAsyncKeyState('J') & 0x8000 ) keys.push_back('J'); // keys.push_back(this->getKey('J', 0));
|
||||
if ( GetAsyncKeyState('K') & 0x8000 ) keys.push_back('K'); // keys.push_back(this->getKey('K', 0));
|
||||
if ( GetAsyncKeyState('L') & 0x8000 ) keys.push_back('L'); // keys.push_back(this->getKey('L', 0));
|
||||
if ( GetAsyncKeyState('M') & 0x8000 ) keys.push_back('M'); // keys.push_back(this->getKey('M', 0));
|
||||
if ( GetAsyncKeyState('N') & 0x8000 ) keys.push_back('N'); // keys.push_back(this->getKey('N', 0));
|
||||
if ( GetAsyncKeyState('O') & 0x8000 ) keys.push_back('O'); // keys.push_back(this->getKey('O', 0));
|
||||
if ( GetAsyncKeyState('P') & 0x8000 ) keys.push_back('P'); // keys.push_back(this->getKey('P', 0));
|
||||
if ( GetAsyncKeyState('Q') & 0x8000 ) keys.push_back('Q'); // keys.push_back(this->getKey('Q', 0));
|
||||
if ( GetAsyncKeyState('R') & 0x8000 ) keys.push_back('R'); // keys.push_back(this->getKey('R', 0));
|
||||
if ( GetAsyncKeyState('S') & 0x8000 ) keys.push_back('S'); // keys.push_back(this->getKey('S', 0));
|
||||
if ( GetAsyncKeyState('T') & 0x8000 ) keys.push_back('T'); // keys.push_back(this->getKey('T', 0));
|
||||
if ( GetAsyncKeyState('U') & 0x8000 ) keys.push_back('U'); // keys.push_back(this->getKey('U', 0));
|
||||
if ( GetAsyncKeyState('V') & 0x8000 ) keys.push_back('V'); // keys.push_back(this->getKey('V', 0));
|
||||
if ( GetAsyncKeyState('W') & 0x8000 ) keys.push_back('W'); // keys.push_back(this->getKey('W', 0));
|
||||
if ( GetAsyncKeyState('X') & 0x8000 ) keys.push_back('X'); // keys.push_back(this->getKey('X', 0));
|
||||
if ( GetAsyncKeyState('Y') & 0x8000 ) keys.push_back('Y'); // keys.push_back(this->getKey('Y', 0));
|
||||
if ( GetAsyncKeyState('Z') & 0x8000 ) keys.push_back('Z'); // keys.push_back(this->getKey('Z', 0));
|
||||
if ( GetAsyncKeyState('0') & 0x8000 ) keys.push_back('0'); // keys.push_back(this->getKey('0', 0));
|
||||
if ( GetAsyncKeyState('1') & 0x8000 ) keys.push_back('1'); // keys.push_back(this->getKey('1', 0));
|
||||
if ( GetAsyncKeyState('2') & 0x8000 ) keys.push_back('2'); // keys.push_back(this->getKey('2', 0));
|
||||
if ( GetAsyncKeyState('3') & 0x8000 ) keys.push_back('3'); // keys.push_back(this->getKey('3', 0));
|
||||
if ( GetAsyncKeyState('4') & 0x8000 ) keys.push_back('4'); // keys.push_back(this->getKey('4', 0));
|
||||
if ( GetAsyncKeyState('5') & 0x8000 ) keys.push_back('5'); // keys.push_back(this->getKey('5', 0));
|
||||
if ( GetAsyncKeyState('6') & 0x8000 ) keys.push_back('6'); // keys.push_back(this->getKey('6', 0));
|
||||
if ( GetAsyncKeyState('7') & 0x8000 ) keys.push_back('7'); // keys.push_back(this->getKey('7', 0));
|
||||
if ( GetAsyncKeyState('8') & 0x8000 ) keys.push_back('8'); // keys.push_back(this->getKey('8', 0));
|
||||
if ( GetAsyncKeyState('9') & 0x8000 ) keys.push_back('9'); // keys.push_back(this->getKey('9', 0));
|
||||
if ( GetAsyncKeyState(VK_ESCAPE) & 0x8000 ) keys.push_back(VK_ESCAPE); // keys.push_back(this->getKey(VK_ESCAPE, 0));
|
||||
if ( GetAsyncKeyState(VK_LCONTROL) & 0x8000 ) keys.push_back(VK_LCONTROL); // keys.push_back(this->getKey(VK_LCONTROL, 0));
|
||||
if ( GetAsyncKeyState(VK_LSHIFT) & 0x8000 ) keys.push_back(VK_LSHIFT); // keys.push_back(this->getKey(VK_LSHIFT, 0));
|
||||
if ( GetAsyncKeyState(VK_LMENU) & 0x8000 ) keys.push_back(VK_LMENU); // keys.push_back(this->getKey(VK_LMENU, 0));
|
||||
if ( GetAsyncKeyState(VK_LWIN) & 0x8000 ) keys.push_back(VK_LWIN); // keys.push_back(this->getKey(VK_LWIN, 0));
|
||||
if ( GetAsyncKeyState(VK_RCONTROL) & 0x8000 ) keys.push_back(VK_RCONTROL); // keys.push_back(this->getKey(VK_RCONTROL, 0));
|
||||
if ( GetAsyncKeyState(VK_RSHIFT) & 0x8000 ) keys.push_back(VK_RSHIFT); // keys.push_back(this->getKey(VK_RSHIFT, 0));
|
||||
if ( GetAsyncKeyState(VK_RMENU) & 0x8000 ) keys.push_back(VK_RMENU); // keys.push_back(this->getKey(VK_RMENU, 0));
|
||||
if ( GetAsyncKeyState(VK_RWIN) & 0x8000 ) keys.push_back(VK_RWIN); // keys.push_back(this->getKey(VK_RWIN, 0));
|
||||
if ( GetAsyncKeyState(VK_APPS) & 0x8000 ) keys.push_back(VK_APPS); // keys.push_back(this->getKey(VK_APPS, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_4) & 0x8000 ) keys.push_back(VK_OEM_4); // keys.push_back(this->getKey(VK_OEM_4, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_6) & 0x8000 ) keys.push_back(VK_OEM_6); // keys.push_back(this->getKey(VK_OEM_6, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_1) & 0x8000 ) keys.push_back(VK_OEM_1); // keys.push_back(this->getKey(VK_OEM_1, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_COMMA) & 0x8000 ) keys.push_back(VK_OEM_COMMA); // keys.push_back(this->getKey(VK_OEM_COMMA, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_PERIOD) & 0x8000 ) keys.push_back(VK_OEM_PERIOD); // keys.push_back(this->getKey(VK_OEM_PERIOD, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_7) & 0x8000 ) keys.push_back(VK_OEM_7); // keys.push_back(this->getKey(VK_OEM_7, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_2) & 0x8000 ) keys.push_back(VK_OEM_2); // keys.push_back(this->getKey(VK_OEM_2, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_5) & 0x8000 ) keys.push_back(VK_OEM_5); // keys.push_back(this->getKey(VK_OEM_5, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_3) & 0x8000 ) keys.push_back(VK_OEM_3); // keys.push_back(this->getKey(VK_OEM_3, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_PLUS) & 0x8000 ) keys.push_back(VK_OEM_PLUS); // keys.push_back(this->getKey(VK_OEM_PLUS, 0));
|
||||
if ( GetAsyncKeyState(VK_OEM_MINUS) & 0x8000 ) keys.push_back(VK_OEM_MINUS); // keys.push_back(this->getKey(VK_OEM_MINUS, 0));
|
||||
if ( GetAsyncKeyState(VK_SPACE) & 0x8000 ) keys.push_back(VK_SPACE); // keys.push_back(this->getKey(VK_SPACE, 0));
|
||||
if ( GetAsyncKeyState(VK_RETURN) & 0x8000 ) keys.push_back(VK_RETURN); // keys.push_back(this->getKey(VK_RETURN, 0));
|
||||
if ( GetAsyncKeyState(VK_BACK) & 0x8000 ) keys.push_back(VK_BACK); // keys.push_back(this->getKey(VK_BACK, 0));
|
||||
if ( GetAsyncKeyState(VK_TAB) & 0x8000 ) keys.push_back(VK_TAB); // keys.push_back(this->getKey(VK_TAB, 0));
|
||||
if ( GetAsyncKeyState(VK_PRIOR) & 0x8000 ) keys.push_back(VK_PRIOR); // keys.push_back(this->getKey(VK_PRIOR, 0));
|
||||
if ( GetAsyncKeyState(VK_NEXT) & 0x8000 ) keys.push_back(VK_NEXT); // keys.push_back(this->getKey(VK_NEXT, 0));
|
||||
if ( GetAsyncKeyState(VK_END) & 0x8000 ) keys.push_back(VK_END); // keys.push_back(this->getKey(VK_END, 0));
|
||||
if ( GetAsyncKeyState(VK_HOME) & 0x8000 ) keys.push_back(VK_HOME); // keys.push_back(this->getKey(VK_HOME, 0));
|
||||
if ( GetAsyncKeyState(VK_INSERT) & 0x8000 ) keys.push_back(VK_INSERT); // keys.push_back(this->getKey(VK_INSERT, 0));
|
||||
if ( GetAsyncKeyState(VK_DELETE) & 0x8000 ) keys.push_back(VK_DELETE); // keys.push_back(this->getKey(VK_DELETE, 0));
|
||||
if ( GetAsyncKeyState(VK_ADD) & 0x8000 ) keys.push_back(VK_ADD); // keys.push_back(this->getKey(VK_ADD, 0));
|
||||
if ( GetAsyncKeyState(VK_SUBTRACT) & 0x8000 ) keys.push_back(VK_SUBTRACT); // keys.push_back(this->getKey(VK_SUBTRACT, 0));
|
||||
if ( GetAsyncKeyState(VK_MULTIPLY) & 0x8000 ) keys.push_back(VK_MULTIPLY); // keys.push_back(this->getKey(VK_MULTIPLY, 0));
|
||||
if ( GetAsyncKeyState(VK_DIVIDE) & 0x8000 ) keys.push_back(VK_DIVIDE); // keys.push_back(this->getKey(VK_DIVIDE, 0));
|
||||
if ( GetAsyncKeyState(VK_LEFT) & 0x8000 ) keys.push_back(VK_LEFT); // keys.push_back(this->getKey(VK_LEFT, 0));
|
||||
if ( GetAsyncKeyState(VK_RIGHT) & 0x8000 ) keys.push_back(VK_RIGHT); // keys.push_back(this->getKey(VK_RIGHT, 0));
|
||||
if ( GetAsyncKeyState(VK_UP) & 0x8000 ) keys.push_back(VK_UP); // keys.push_back(this->getKey(VK_UP, 0));
|
||||
if ( GetAsyncKeyState(VK_DOWN) & 0x8000 ) keys.push_back(VK_DOWN); // keys.push_back(this->getKey(VK_DOWN, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD0) & 0x8000 ) keys.push_back(VK_NUMPAD0); // keys.push_back(this->getKey(VK_NUMPAD0, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD1) & 0x8000 ) keys.push_back(VK_NUMPAD1); // keys.push_back(this->getKey(VK_NUMPAD1, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD2) & 0x8000 ) keys.push_back(VK_NUMPAD2); // keys.push_back(this->getKey(VK_NUMPAD2, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD3) & 0x8000 ) keys.push_back(VK_NUMPAD3); // keys.push_back(this->getKey(VK_NUMPAD3, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD4) & 0x8000 ) keys.push_back(VK_NUMPAD4); // keys.push_back(this->getKey(VK_NUMPAD4, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD5) & 0x8000 ) keys.push_back(VK_NUMPAD5); // keys.push_back(this->getKey(VK_NUMPAD5, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD6) & 0x8000 ) keys.push_back(VK_NUMPAD6); // keys.push_back(this->getKey(VK_NUMPAD6, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD7) & 0x8000 ) keys.push_back(VK_NUMPAD7); // keys.push_back(this->getKey(VK_NUMPAD7, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD8) & 0x8000 ) keys.push_back(VK_NUMPAD8); // keys.push_back(this->getKey(VK_NUMPAD8, 0));
|
||||
if ( GetAsyncKeyState(VK_NUMPAD9) & 0x8000 ) keys.push_back(VK_NUMPAD9); // keys.push_back(this->getKey(VK_NUMPAD9, 0));
|
||||
if ( GetAsyncKeyState(VK_F1) & 0x8000 ) keys.push_back(VK_F1); // keys.push_back(this->getKey(VK_F1, 0));
|
||||
if ( GetAsyncKeyState(VK_F2) & 0x8000 ) keys.push_back(VK_F2); // keys.push_back(this->getKey(VK_F2, 0));
|
||||
if ( GetAsyncKeyState(VK_F3) & 0x8000 ) keys.push_back(VK_F3); // keys.push_back(this->getKey(VK_F3, 0));
|
||||
if ( GetAsyncKeyState(VK_F4) & 0x8000 ) keys.push_back(VK_F4); // keys.push_back(this->getKey(VK_F4, 0));
|
||||
if ( GetAsyncKeyState(VK_F5) & 0x8000 ) keys.push_back(VK_F5); // keys.push_back(this->getKey(VK_F5, 0));
|
||||
if ( GetAsyncKeyState(VK_F6) & 0x8000 ) keys.push_back(VK_F6); // keys.push_back(this->getKey(VK_F6, 0));
|
||||
if ( GetAsyncKeyState(VK_F7) & 0x8000 ) keys.push_back(VK_F7); // keys.push_back(this->getKey(VK_F7, 0));
|
||||
if ( GetAsyncKeyState(VK_F8) & 0x8000 ) keys.push_back(VK_F8); // keys.push_back(this->getKey(VK_F8, 0));
|
||||
if ( GetAsyncKeyState(VK_F9) & 0x8000 ) keys.push_back(VK_F9); // keys.push_back(this->getKey(VK_F9, 0));
|
||||
if ( GetAsyncKeyState(VK_F10) & 0x8000 ) keys.push_back(VK_F10); // keys.push_back(this->getKey(VK_F10, 0));
|
||||
if ( GetAsyncKeyState(VK_F11) & 0x8000 ) keys.push_back(VK_F11); // keys.push_back(this->getKey(VK_F11, 0));
|
||||
if ( GetAsyncKeyState(VK_F12) & 0x8000 ) keys.push_back(VK_F12); // keys.push_back(this->getKey(VK_F12, 0));
|
||||
if ( GetAsyncKeyState(VK_F13) & 0x8000 ) keys.push_back(VK_F13); // keys.push_back(this->getKey(VK_F13, 0));
|
||||
if ( GetAsyncKeyState(VK_F14) & 0x8000 ) keys.push_back(VK_F14); // keys.push_back(this->getKey(VK_F14, 0));
|
||||
if ( GetAsyncKeyState(VK_F15) & 0x8000 ) keys.push_back(VK_F15); // keys.push_back(this->getKey(VK_F15, 0));
|
||||
if ( GetAsyncKeyState(VK_PAUSE) & 0x8000 ) keys.push_back(VK_PAUSE); // keys.push_back(this->getKey(VK_PAUSE, 0));
|
||||
|
||||
if ( GetAsyncKeyState(VK_LBUTTON) & 0x8000 ) keys.push_back(VK_LBUTTON); // keys.push_back( this->getKey(VK_LBUTTON, 0) );
|
||||
if ( GetAsyncKeyState(VK_RBUTTON) & 0x8000 ) keys.push_back(VK_RBUTTON); // keys.push_back( this->getKey(VK_RBUTTON, 0) );
|
||||
if ( GetAsyncKeyState(VK_MBUTTON) & 0x8000 ) keys.push_back(VK_MBUTTON); // keys.push_back( this->getKey(VK_MBUTTON, 0) );
|
||||
if ( GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ) keys.push_back(VK_XBUTTON1); // keys.push_back( this->getKey(VK_XBUTTON1, 0) );
|
||||
if ( GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ) keys.push_back(VK_XBUTTON2); // keys.push_back( this->getKey(VK_XBUTTON2, 0) );
|
||||
std::vector<WPARAM> keys = GetKeys();
|
||||
|
||||
struct Event {
|
||||
std::string type = "unknown";
|
||||
@ -466,11 +819,9 @@ void UF_API_CALL spec::win32::Window::processEvents() {
|
||||
}
|
||||
/* Loop through key inputs */ {
|
||||
for ( auto& key : keys ) {
|
||||
auto code = this->getKey(key, 0);
|
||||
auto code = GetKeyName(key);
|
||||
event.key.code = code;
|
||||
event.key.raw = key;
|
||||
// if ( USE_OPTIMAL ) this->pushEvent(event.type + "." + code, uf::Userdata(uf::userdata::create(event)));
|
||||
// if ( USE_OPTIMAL ) this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
|
||||
|
||||
json["key"]["code"] = code;
|
||||
json["key"]["raw"] = key;
|
||||
@ -1127,235 +1478,10 @@ void UF_API_CALL spec::win32::Window::switchToFullscreen( bool borderless ) {
|
||||
}
|
||||
|
||||
bool UF_API_CALL spec::win32::Window::isKeyPressed(const std::string& key) {
|
||||
if ( (key == "A") && (GetAsyncKeyState('A') & 0x8000) ) return true;
|
||||
if ( (key == "B") && (GetAsyncKeyState('B') & 0x8000) ) return true;
|
||||
if ( (key == "C") && (GetAsyncKeyState('C') & 0x8000) ) return true;
|
||||
if ( (key == "D") && (GetAsyncKeyState('D') & 0x8000) ) return true;
|
||||
if ( (key == "E") && (GetAsyncKeyState('E') & 0x8000) ) return true;
|
||||
if ( (key == "F") && (GetAsyncKeyState('F') & 0x8000) ) return true;
|
||||
if ( (key == "G") && (GetAsyncKeyState('G') & 0x8000) ) return true;
|
||||
if ( (key == "H") && (GetAsyncKeyState('H') & 0x8000) ) return true;
|
||||
if ( (key == "I") && (GetAsyncKeyState('I') & 0x8000) ) return true;
|
||||
if ( (key == "J") && (GetAsyncKeyState('J') & 0x8000) ) return true;
|
||||
if ( (key == "K") && (GetAsyncKeyState('K') & 0x8000) ) return true;
|
||||
if ( (key == "L") && (GetAsyncKeyState('L') & 0x8000) ) return true;
|
||||
if ( (key == "M") && (GetAsyncKeyState('M') & 0x8000) ) return true;
|
||||
if ( (key == "N") && (GetAsyncKeyState('N') & 0x8000) ) return true;
|
||||
if ( (key == "O") && (GetAsyncKeyState('O') & 0x8000) ) return true;
|
||||
if ( (key == "P") && (GetAsyncKeyState('P') & 0x8000) ) return true;
|
||||
if ( (key == "Q") && (GetAsyncKeyState('Q') & 0x8000) ) return true;
|
||||
if ( (key == "R") && (GetAsyncKeyState('R') & 0x8000) ) return true;
|
||||
if ( (key == "S") && (GetAsyncKeyState('S') & 0x8000) ) return true;
|
||||
if ( (key == "T") && (GetAsyncKeyState('T') & 0x8000) ) return true;
|
||||
if ( (key == "U") && (GetAsyncKeyState('U') & 0x8000) ) return true;
|
||||
if ( (key == "V") && (GetAsyncKeyState('V') & 0x8000) ) return true;
|
||||
if ( (key == "W") && (GetAsyncKeyState('W') & 0x8000) ) return true;
|
||||
if ( (key == "X") && (GetAsyncKeyState('X') & 0x8000) ) return true;
|
||||
if ( (key == "Y") && (GetAsyncKeyState('Y') & 0x8000) ) return true;
|
||||
if ( (key == "Z") && (GetAsyncKeyState('Z') & 0x8000) ) return true;
|
||||
if ( (key == "0") && (GetAsyncKeyState('0') & 0x8000) ) return true;
|
||||
if ( (key == "1") && (GetAsyncKeyState('1') & 0x8000) ) return true;
|
||||
if ( (key == "2") && (GetAsyncKeyState('2') & 0x8000) ) return true;
|
||||
if ( (key == "3") && (GetAsyncKeyState('3') & 0x8000) ) return true;
|
||||
if ( (key == "4") && (GetAsyncKeyState('4') & 0x8000) ) return true;
|
||||
if ( (key == "5") && (GetAsyncKeyState('5') & 0x8000) ) return true;
|
||||
if ( (key == "6") && (GetAsyncKeyState('6') & 0x8000) ) return true;
|
||||
if ( (key == "7") && (GetAsyncKeyState('7') & 0x8000) ) return true;
|
||||
if ( (key == "8") && (GetAsyncKeyState('8') & 0x8000) ) return true;
|
||||
if ( (key == "9") && (GetAsyncKeyState('9') & 0x8000) ) return true;
|
||||
if ( (key == "Escape") && (GetAsyncKeyState(VK_ESCAPE) & 0x8000) ) return true;
|
||||
if ( (key == "LControl") && (GetAsyncKeyState(VK_LCONTROL) & 0x8000) ) return true;
|
||||
if ( (key == "LShift") && (GetAsyncKeyState(VK_LSHIFT) & 0x8000) ) return true;
|
||||
if ( (key == "LAlt") && (GetAsyncKeyState(VK_LMENU) & 0x8000) ) return true;
|
||||
if ( (key == "LSystem") && (GetAsyncKeyState(VK_LWIN) & 0x8000) ) return true;
|
||||
if ( (key == "RControl") && (GetAsyncKeyState(VK_RCONTROL) & 0x8000) ) return true;
|
||||
if ( (key == "RShift") && (GetAsyncKeyState(VK_RSHIFT) & 0x8000) ) return true;
|
||||
if ( (key == "RAlt") && (GetAsyncKeyState(VK_RMENU) & 0x8000) ) return true;
|
||||
if ( (key == "RSystem") && (GetAsyncKeyState(VK_RWIN) & 0x8000) ) return true;
|
||||
if ( (key == "Apps") && (GetAsyncKeyState(VK_APPS) & 0x8000) ) return true;
|
||||
if ( (key == "OEM4") && (GetAsyncKeyState(VK_OEM_4) & 0x8000) ) return true;
|
||||
if ( (key == "OEM6") && (GetAsyncKeyState(VK_OEM_6) & 0x8000) ) return true;
|
||||
if ( (key == "OEM1") && (GetAsyncKeyState(VK_OEM_1) & 0x8000) ) return true;
|
||||
if ( (key == "OEMComma") && (GetAsyncKeyState(VK_OEM_COMMA) & 0x8000) ) return true;
|
||||
if ( (key == "OEMPeriod") && (GetAsyncKeyState(VK_OEM_PERIOD) & 0x8000) ) return true;
|
||||
if ( (key == "OEM7") && (GetAsyncKeyState(VK_OEM_7) & 0x8000) ) return true;
|
||||
if ( (key == "OEM2") && (GetAsyncKeyState(VK_OEM_2) & 0x8000) ) return true;
|
||||
if ( (key == "OEM5") && (GetAsyncKeyState(VK_OEM_5) & 0x8000) ) return true;
|
||||
if ( (key == "OEM3") && (GetAsyncKeyState(VK_OEM_3) & 0x8000) ) return true;
|
||||
if ( (key == "OEM+") && (GetAsyncKeyState(VK_OEM_PLUS) & 0x8000) ) return true;
|
||||
if ( (key == "OEM-") && (GetAsyncKeyState(VK_OEM_MINUS) & 0x8000) ) return true;
|
||||
if ( (key == " ") && (GetAsyncKeyState(VK_SPACE) & 0x8000) ) return true;
|
||||
if ( (key == "Enter") && (GetAsyncKeyState(VK_RETURN) & 0x8000) ) return true;
|
||||
if ( (key == "Back") && (GetAsyncKeyState(VK_BACK) & 0x8000) ) return true;
|
||||
if ( (key == "Tab") && (GetAsyncKeyState(VK_TAB) & 0x8000) ) return true;
|
||||
if ( (key == "Prior") && (GetAsyncKeyState(VK_PRIOR) & 0x8000) ) return true;
|
||||
if ( (key == "Next") && (GetAsyncKeyState(VK_NEXT) & 0x8000) ) return true;
|
||||
if ( (key == "End") && (GetAsyncKeyState(VK_END) & 0x8000) ) return true;
|
||||
if ( (key == "Home") && (GetAsyncKeyState(VK_HOME) & 0x8000) ) return true;
|
||||
if ( (key == "Insert") && (GetAsyncKeyState(VK_INSERT) & 0x8000) ) return true;
|
||||
if ( (key == "Delete") && (GetAsyncKeyState(VK_DELETE) & 0x8000) ) return true;
|
||||
if ( (key == "+") && (GetAsyncKeyState(VK_ADD) & 0x8000) ) return true;
|
||||
if ( (key == "-") && (GetAsyncKeyState(VK_SUBTRACT) & 0x8000) ) return true;
|
||||
if ( (key == "*") && (GetAsyncKeyState(VK_MULTIPLY) & 0x8000) ) return true;
|
||||
if ( (key == "/") && (GetAsyncKeyState(VK_DIVIDE) & 0x8000) ) return true;
|
||||
if ( (key == "Left") && (GetAsyncKeyState(VK_LEFT) & 0x8000) ) return true;
|
||||
if ( (key == "Right") && (GetAsyncKeyState(VK_RIGHT) & 0x8000) ) return true;
|
||||
if ( (key == "Up") && (GetAsyncKeyState(VK_UP) & 0x8000) ) return true;
|
||||
if ( (key == "Down") && (GetAsyncKeyState(VK_DOWN) & 0x8000) ) return true;
|
||||
if ( (key == "Num0") && (GetAsyncKeyState(VK_NUMPAD0) & 0x8000) ) return true;
|
||||
if ( (key == "Num1") && (GetAsyncKeyState(VK_NUMPAD1) & 0x8000) ) return true;
|
||||
if ( (key == "Num2") && (GetAsyncKeyState(VK_NUMPAD2) & 0x8000) ) return true;
|
||||
if ( (key == "Num3") && (GetAsyncKeyState(VK_NUMPAD3) & 0x8000) ) return true;
|
||||
if ( (key == "Num4") && (GetAsyncKeyState(VK_NUMPAD4) & 0x8000) ) return true;
|
||||
if ( (key == "Num5") && (GetAsyncKeyState(VK_NUMPAD5) & 0x8000) ) return true;
|
||||
if ( (key == "Num6") && (GetAsyncKeyState(VK_NUMPAD6) & 0x8000) ) return true;
|
||||
if ( (key == "Num7") && (GetAsyncKeyState(VK_NUMPAD7) & 0x8000) ) return true;
|
||||
if ( (key == "Num8") && (GetAsyncKeyState(VK_NUMPAD8) & 0x8000) ) return true;
|
||||
if ( (key == "Num9") && (GetAsyncKeyState(VK_NUMPAD9) & 0x8000) ) return true;
|
||||
if ( (key == "F1") && (GetAsyncKeyState(VK_F1) & 0x8000) ) return true;
|
||||
if ( (key == "F2") && (GetAsyncKeyState(VK_F2) & 0x8000) ) return true;
|
||||
if ( (key == "F3") && (GetAsyncKeyState(VK_F3) & 0x8000) ) return true;
|
||||
if ( (key == "F4") && (GetAsyncKeyState(VK_F4) & 0x8000) ) return true;
|
||||
if ( (key == "F5") && (GetAsyncKeyState(VK_F5) & 0x8000) ) return true;
|
||||
if ( (key == "F6") && (GetAsyncKeyState(VK_F6) & 0x8000) ) return true;
|
||||
if ( (key == "F7") && (GetAsyncKeyState(VK_F7) & 0x8000) ) return true;
|
||||
if ( (key == "F8") && (GetAsyncKeyState(VK_F8) & 0x8000) ) return true;
|
||||
if ( (key == "F9") && (GetAsyncKeyState(VK_F9) & 0x8000) ) return true;
|
||||
if ( (key == "F10") && (GetAsyncKeyState(VK_F10) & 0x8000) ) return true;
|
||||
if ( (key == "F11") && (GetAsyncKeyState(VK_F11) & 0x8000) ) return true;
|
||||
if ( (key == "F12") && (GetAsyncKeyState(VK_F12) & 0x8000) ) return true;
|
||||
if ( (key == "F13") && (GetAsyncKeyState(VK_F13) & 0x8000) ) return true;
|
||||
if ( (key == "F14") && (GetAsyncKeyState(VK_F14) & 0x8000) ) return true;
|
||||
if ( (key == "F15") && (GetAsyncKeyState(VK_F15) & 0x8000) ) return true;
|
||||
if ( (key == "Pause") && (GetAsyncKeyState(VK_PAUSE) & 0x8000) ) return true;
|
||||
|
||||
if ( (key == "LeftMouse") && (GetAsyncKeyState(VK_LBUTTON) & 0x8000) ) return true;
|
||||
if ( (key == "RightMouse") && (GetAsyncKeyState(VK_RBUTTON) & 0x8000) ) return true;
|
||||
if ( (key == "MiddleMouse") && (GetAsyncKeyState(VK_MBUTTON) & 0x8000) ) return true;
|
||||
if ( (key == "XButton1") && (GetAsyncKeyState(VK_XBUTTON1) & 0x8000) ) return true;
|
||||
if ( (key == "XButton2") && (GetAsyncKeyState(VK_XBUTTON2) & 0x8000) ) return true;
|
||||
return false;
|
||||
return GetAsyncKeyState( GetKeyCode( key ) ) & 0x8000;
|
||||
}
|
||||
std::string UF_API_CALL spec::win32::Window::getKey(WPARAM key, LPARAM flags) {
|
||||
switch (key) {
|
||||
// Check the scancode to distinguish between left and right shift
|
||||
case VK_SHIFT: {
|
||||
static UINT lShift = MapVirtualKeyW(VK_LSHIFT, MAPVK_VK_TO_VSC);
|
||||
UINT scancode = static_cast<UINT>((flags & (0xFF << 16)) >> 16);
|
||||
return scancode == lShift ? "LShift" : "RShift";
|
||||
}
|
||||
// Check the "extended" flag to distinguish between left and right alt
|
||||
case VK_MENU : return (HIWORD(flags) & KF_EXTENDED) ? "RAlt" : "LAlt";
|
||||
// Check the "extended" flag to distinguish between left and right control
|
||||
case VK_CONTROL : return (HIWORD(flags) & KF_EXTENDED) ? "RControl" : "LControl";
|
||||
|
||||
// Other keys are reported properly
|
||||
case VK_LWIN: return "LSystem";
|
||||
case VK_RWIN: return "RSystem";
|
||||
case VK_APPS: return "Menu";
|
||||
case VK_OEM_1: return "SemiColon";
|
||||
case VK_OEM_2: return "Slash";
|
||||
case VK_OEM_PLUS: return "Equal";
|
||||
case VK_OEM_MINUS: return "Dash";
|
||||
case VK_OEM_4: return "LBracket";
|
||||
case VK_OEM_6: return "RBracket";
|
||||
case VK_OEM_COMMA: return "Comma";
|
||||
case VK_OEM_PERIOD: return "Period";
|
||||
case VK_OEM_7: return "Quote";
|
||||
case VK_OEM_5: return "BackSlash";
|
||||
case VK_OEM_3: return "Tilde";
|
||||
|
||||
case VK_ESCAPE: return "Escape";
|
||||
case VK_SPACE: return "Space";
|
||||
case VK_RETURN: return "Enter";
|
||||
case VK_BACK: return "BackSpace";
|
||||
case VK_TAB: return "Tab";
|
||||
case VK_PRIOR: return "PageUp";
|
||||
case VK_NEXT: return "PageDown";
|
||||
case VK_END: return "End";
|
||||
case VK_HOME: return "Home";
|
||||
case VK_INSERT: return "Insert";
|
||||
case VK_DELETE: return "Delete";
|
||||
case VK_ADD: return "Add";
|
||||
case VK_SUBTRACT: return "Subtract";
|
||||
case VK_MULTIPLY: return "Multiply";
|
||||
case VK_DIVIDE: return "Divide";
|
||||
case VK_PAUSE: return "Pause";
|
||||
|
||||
case VK_F1: return "F1";
|
||||
case VK_F2: return "F2";
|
||||
case VK_F3: return "F3";
|
||||
case VK_F4: return "F4";
|
||||
case VK_F5: return "F5";
|
||||
case VK_F6: return "F6";
|
||||
case VK_F7: return "F7";
|
||||
case VK_F8: return "F8";
|
||||
case VK_F9: return "F9";
|
||||
case VK_F10: return "F10";
|
||||
case VK_F11: return "F11";
|
||||
case VK_F12: return "F12";
|
||||
case VK_F13: return "F13";
|
||||
case VK_F14: return "F14";
|
||||
case VK_F15: return "F15";
|
||||
|
||||
case VK_LEFT: return "Left";
|
||||
case VK_RIGHT: return "Right";
|
||||
case VK_UP: return "Up";
|
||||
case VK_DOWN: return "Down";
|
||||
|
||||
case VK_NUMPAD0: return "Numpad0";
|
||||
case VK_NUMPAD1: return "Numpad1";
|
||||
case VK_NUMPAD2: return "Numpad2";
|
||||
case VK_NUMPAD3: return "Numpad3";
|
||||
case VK_NUMPAD4: return "Numpad4";
|
||||
case VK_NUMPAD5: return "Numpad5";
|
||||
case VK_NUMPAD6: return "Numpad6";
|
||||
case VK_NUMPAD7: return "Numpad7";
|
||||
case VK_NUMPAD8: return "Numpad8";
|
||||
case VK_NUMPAD9: return "Numpad9";
|
||||
|
||||
case 'Q': return "Q";
|
||||
case 'W': return "W";
|
||||
case 'E': return "E";
|
||||
case 'R': return "R";
|
||||
case 'T': return "T";
|
||||
case 'Y': return "Y";
|
||||
case 'U': return "U";
|
||||
case 'I': return "I";
|
||||
case 'O': return "O";
|
||||
case 'P': return "P";
|
||||
|
||||
case 'A': return "A";
|
||||
case 'S': return "S";
|
||||
case 'D': return "D";
|
||||
case 'F': return "F";
|
||||
case 'G': return "G";
|
||||
case 'H': return "H";
|
||||
case 'J': return "J";
|
||||
case 'K': return "K";
|
||||
case 'L': return "L";
|
||||
|
||||
case 'Z': return "Z";
|
||||
case 'X': return "X";
|
||||
case 'C': return "C";
|
||||
case 'V': return "V";
|
||||
case 'B': return "B";
|
||||
case 'N': return "N";
|
||||
case 'M': return "M";
|
||||
|
||||
case '1': return "Num1";
|
||||
case '2': return "Num2";
|
||||
case '3': return "Num3";
|
||||
case '4': return "Num4";
|
||||
case '5': return "Num5";
|
||||
case '6': return "Num6";
|
||||
case '7': return "Num7";
|
||||
case '8': return "Num8";
|
||||
case '9': return "Num9";
|
||||
case '0': return "Num0";
|
||||
}
|
||||
// return "Unknown";
|
||||
return std::to_string((int) key);
|
||||
return GetKeyName( key, flags );
|
||||
}
|
||||
#if defined(UF_USE_VULKAN) && UF_USE_VULKAN == 1
|
||||
std::vector<std::string> UF_API_CALL spec::win32::Window::getExtensions( bool validationEnabled ) {
|
||||
|
@ -10,19 +10,22 @@
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <gltf/stb_image.h>
|
||||
#include <gltf/stb_image_write.h>
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
|
||||
// C-tor
|
||||
// Default
|
||||
uf::Image::Image() :
|
||||
m_bpp(8),
|
||||
m_channels(4) {
|
||||
m_channels(4),
|
||||
m_format(0) {
|
||||
|
||||
}
|
||||
// Just Size
|
||||
uf::Image::Image( const Image::vec2_t& size ) :
|
||||
m_dimensions(size),
|
||||
m_bpp(8),
|
||||
m_channels(4)
|
||||
m_channels(4),
|
||||
m_format(0)
|
||||
{
|
||||
this->m_pixels.reserve(size.x*size.y*this->m_channels);
|
||||
}
|
||||
@ -32,7 +35,8 @@ uf::Image::Image( Image&& move ) :
|
||||
m_dimensions(std::move(move.m_dimensions)),
|
||||
m_bpp(move.m_bpp),
|
||||
m_channels(move.m_channels),
|
||||
m_filename(move.m_filename)
|
||||
m_filename(move.m_filename),
|
||||
m_format(move.m_format)
|
||||
{
|
||||
|
||||
}
|
||||
@ -42,7 +46,8 @@ uf::Image::Image( const Image& copy ) :
|
||||
m_dimensions(copy.m_dimensions),
|
||||
m_bpp(copy.m_bpp),
|
||||
m_channels(copy.m_channels),
|
||||
m_filename(copy.m_filename)
|
||||
m_filename(copy.m_filename),
|
||||
m_format(copy.m_format)
|
||||
{
|
||||
|
||||
}
|
||||
@ -51,7 +56,8 @@ uf::Image::Image( Image::container_t&& move, const Image::vec2_t& size ) :
|
||||
m_pixels(std::move(move)),
|
||||
m_dimensions(size),
|
||||
m_bpp(8),
|
||||
m_channels(4)
|
||||
m_channels(4),
|
||||
m_format(0)
|
||||
{
|
||||
|
||||
}
|
||||
@ -60,7 +66,8 @@ uf::Image::Image( const Image::container_t& copy, const Image::vec2_t& size ) :
|
||||
m_pixels(copy),
|
||||
m_dimensions(size),
|
||||
m_bpp(8),
|
||||
m_channels(4)
|
||||
m_channels(4),
|
||||
m_format(0)
|
||||
{
|
||||
|
||||
}
|
||||
@ -69,25 +76,81 @@ std::string uf::Image::getFilename() const {
|
||||
return this->m_filename;
|
||||
}
|
||||
|
||||
#define _PACK4(v) ((v * 0xF) / 0xFF)
|
||||
#define PACK_ARGB4444(a,r,g,b) (_PACK4(a) << 12) | (_PACK4(r) << 8) | (_PACK4(g) << 4) | (_PACK4(b))
|
||||
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
|
||||
#define PACK_ARGB1555(a,r,g,b) \
|
||||
(((uint16_t)(a > 0) << 15) | (((uint16_t) r >> 3) << 10) | (((uint16_t)g >> 3) << 5) | ((uint16_t)b >> 3))
|
||||
|
||||
#define PACK_RGB565(r,g,b) \
|
||||
((((uint16_t)r & 0xf8) << 8) | (((uint16_t) g & 0xfc) << 3) | ((uint16_t) b >> 3))
|
||||
|
||||
// from file
|
||||
bool uf::Image::open( const std::string& filename, bool flip ) {
|
||||
if ( !uf::io::exists(filename) ) UF_EXCEPTION("does not exist: " + filename);
|
||||
std::string extension = uf::io::extension(filename);
|
||||
this->m_filename = filename;
|
||||
this->m_pixels.clear();
|
||||
int width, height, channels, bit_depth;
|
||||
bit_depth = 8;
|
||||
stbi_set_flip_vertically_on_load(flip);
|
||||
uint8_t* buffer = stbi_load( filename.c_str(), &width, &height, &channels, STBI_rgb_alpha );
|
||||
|
||||
channels = 4;
|
||||
uint len = width * height * channels;
|
||||
int width = 0, height = 0, channelsDud = 0, bit_depth = 8, channels = 4;
|
||||
#if UF_ENV_DREAMCAST
|
||||
if ( extension == "dtex" ) {
|
||||
struct {
|
||||
char id[4]; // 'DTEX'
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
} header;
|
||||
|
||||
FILE* file = NULL;
|
||||
file = fopen(filename.c_str(), "rb");
|
||||
fread(&header, sizeof(header), 1, file);
|
||||
this->m_pixels.resize(header.size);
|
||||
fread(this->m_pixels.data(), header.size, 1, file);
|
||||
fclose(file);
|
||||
|
||||
bool twiddled = (header.type & (1 << 26)) < 1;
|
||||
bool compressed = (header.type & (1 << 30)) > 0;
|
||||
bool mipmapped = (header.type & (1 << 31)) > 0;
|
||||
bool strided = (header.type & (1 << 25)) > 0;
|
||||
uint32_t format = (header.type >> 27) & 0b111;
|
||||
width = header.width;
|
||||
height = header.height;
|
||||
|
||||
uint32_t expected = 2 * header.width * header.height;
|
||||
uint32_t ratio = (uint32_t) (((float) expected) / ((float) header.size));
|
||||
bit_depth = 4;
|
||||
if ( compressed ) {
|
||||
if ( twiddled ) {
|
||||
switch ( format ) {
|
||||
case 0: this->m_format = mipmapped ? GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_TWID_KOS : GL_COMPRESSED_ARGB_1555_VQ_TWID_KOS; break;
|
||||
case 1: this->m_format = mipmapped ? GL_COMPRESSED_RGB_565_VQ_MIPMAP_TWID_KOS : GL_COMPRESSED_RGB_565_VQ_TWID_KOS; channels = 3; break;
|
||||
case 2: this->m_format = mipmapped ? GL_COMPRESSED_ARGB_4444_VQ_MIPMAP_TWID_KOS : GL_COMPRESSED_ARGB_4444_VQ_TWID_KOS; break;
|
||||
default: UF_EXCEPTION(filename << ": invalid texture format"); return false;
|
||||
}
|
||||
} else {
|
||||
switch ( format ) {
|
||||
case 0: this->m_format = mipmapped ? GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_KOS : GL_COMPRESSED_ARGB_1555_VQ_KOS; break;
|
||||
case 1: this->m_format = mipmapped ? GL_COMPRESSED_RGB_565_VQ_MIPMAP_KOS : GL_COMPRESSED_RGB_565_VQ_KOS; channels = 3; break;
|
||||
case 2: this->m_format = mipmapped ? GL_COMPRESSED_ARGB_4444_VQ_MIPMAP_KOS : GL_COMPRESSED_ARGB_4444_VQ_KOS; break;
|
||||
default: UF_EXCEPTION(filename << ": invalid texture format"); return false;
|
||||
}
|
||||
}
|
||||
} else { UF_EXCEPTION(filename << ": not a compressed texture"); return false; }
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
stbi_set_flip_vertically_on_load(flip);
|
||||
uint8_t* buffer = stbi_load( filename.c_str(), &width, &height, &channelsDud, STBI_rgb_alpha );
|
||||
size_t len = width * height * channels;
|
||||
this->m_pixels.insert( this->m_pixels.end(), (uint8_t*) buffer, buffer + len );
|
||||
stbi_image_free(buffer);
|
||||
}
|
||||
|
||||
this->m_dimensions.x = width;
|
||||
this->m_dimensions.y = height;
|
||||
this->m_bpp = bit_depth * channels;
|
||||
this->m_channels = channels;
|
||||
this->m_pixels.insert( this->m_pixels.end(), (uint8_t*) buffer, buffer + len );
|
||||
stbi_image_free(buffer);
|
||||
return true;
|
||||
}
|
||||
void uf::Image::loadFromBuffer( const Image::pixel_t::type_t* pointer, const pod::Vector2ui& size, std::size_t bit_depth, std::size_t channels, bool flip ) {
|
||||
@ -232,6 +295,9 @@ std::size_t& uf::Image::getChannels() {
|
||||
std::size_t uf::Image::getChannels() const {
|
||||
return this->m_channels;
|
||||
}
|
||||
std::size_t uf::Image::getFormat() const {
|
||||
return this->m_format;
|
||||
}
|
||||
std::string uf::Image::getHash() const {
|
||||
return uf::string::sha256( this->m_pixels );
|
||||
}
|
||||
@ -253,60 +319,6 @@ bool uf::Image::save( const std::string& filename, bool flip ) const {
|
||||
std::string extension = uf::io::extension(filename);
|
||||
stbi_flip_vertically_on_write(flip);
|
||||
if ( extension == "png" ) {
|
||||
#if 0
|
||||
if ( flip )
|
||||
for (uint j = 0; j * 2 < h; ++j) {
|
||||
uint x = j * w * this->m_bpp/8;
|
||||
uint y = (h - 1 - j) * w * this->m_bpp/8;
|
||||
for (uint i = w * this->m_bpp/8; i > 0; --i) {
|
||||
std::swap( pixels[x], pixels[y] );
|
||||
++x, ++y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png)
|
||||
return false;
|
||||
|
||||
png_infop info = png_create_info_struct(png);
|
||||
if (!info) {
|
||||
png_destroy_write_struct(&png, &info);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(filename.c_str(), "wb");
|
||||
if (!fp) {
|
||||
png_destroy_write_struct(&png, &info);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_init_io(png, fp);
|
||||
png_set_IHDR(png, info, w, h, 8 /* depth */, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
if ( this->m_channels == 4 ) png_set_IHDR(png, info, w, h, 8 /* depth */, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
if ( this->m_channels == 3 ) png_set_IHDR(png, info, w, h, 8 /* depth */, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
png_colorp palette = (png_colorp)png_malloc(png, PNG_MAX_PALETTE_LENGTH * sizeof(png_color));
|
||||
if (!palette) {
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png, &info);
|
||||
return false;
|
||||
}
|
||||
png_set_PLTE(png, info, palette, PNG_MAX_PALETTE_LENGTH);
|
||||
png_write_info(png, info);
|
||||
png_set_packing(png);
|
||||
|
||||
png_bytepp rows = (png_bytepp)png_malloc(png, h * sizeof(png_bytep));
|
||||
for (uint i = 0; i < h; ++i)
|
||||
rows[i] = (png_bytep)(pixels + (h - i - 1) * w * this->m_bpp/8);
|
||||
|
||||
png_write_image(png, rows);
|
||||
png_write_end(png, info);
|
||||
png_free(png, palette);
|
||||
png_destroy_write_struct(&png, &info);
|
||||
|
||||
fclose(fp);
|
||||
delete[] rows;
|
||||
#endif
|
||||
stbi_write_png(filename.c_str(), w, h, this->m_channels, &pixels[0], w * this->m_channels);
|
||||
} else if ( extension == "jpg" || extension == "jpeg" ) {
|
||||
stbi_write_jpg(filename.c_str(), w, h, this->m_channels, &pixels[0], w * this->m_channels);
|
||||
|
@ -53,20 +53,17 @@ pod::Thread& UF_API uf::thread::fetchWorker( const std::string& name ) {
|
||||
static int current = 0;
|
||||
static int limit = uf::thread::workers;
|
||||
static uint threads = std::thread::hardware_concurrency();
|
||||
if ( ++current >= limit ) current = 0;
|
||||
std::string thread = name;
|
||||
if ( current > 0 ) thread += " " + std::to_string(current);
|
||||
bool exists = uf::thread::has(thread);
|
||||
auto& pod = exists ? uf::thread::get(thread) : uf::thread::create( thread, true );
|
||||
if ( !exists ) {
|
||||
/*
|
||||
pod.affinity = (current + 1) % threads;
|
||||
std::cout << "Create: " << thread << ": " << pod.affinity << std::endl;
|
||||
BOOL res = SetThreadAffinityMask((HANDLE) pod.thread.native_handle(), 1u << pod.affinity );
|
||||
if ( res ) if ( UF_THREAD_ANNOUNCE ) uf::iostream << "Bound worker thread #" << current << " to ID " << pod.affinity << "\n";
|
||||
else if ( UF_THREAD_ANNOUNCE ) uf::iostream << "Failed to bind worker thread #" << current << " to ID " << pod.affinity << "\n";
|
||||
*/
|
||||
int tries = 8;
|
||||
while ( --tries >= 0 ) {
|
||||
if ( ++current >= limit ) current = 0;
|
||||
std::string thread = name;
|
||||
if ( current > 0 ) thread += " " + std::to_string(current);
|
||||
bool exists = uf::thread::has(thread);
|
||||
auto& pod = exists ? uf::thread::get(thread) : uf::thread::create( thread, true );
|
||||
if ( std::this_thread::get_id() != pod.thread.get_id() ) return pod;
|
||||
}
|
||||
bool exists = uf::thread::has( "Main" );
|
||||
auto& pod = exists ? uf::thread::get( "Main" ) : uf::thread::create( "Main" , true );
|
||||
return pod;
|
||||
}
|
||||
void UF_API uf::thread::batchWorkers( const std::vector<pod::Thread::function_t>& functions, bool wait, const std::string& name ) {
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "behavior.h"
|
||||
|
||||
#include <uf/utils/hook/hook.h>
|
||||
@ -58,12 +59,7 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
#endif
|
||||
// Hooks
|
||||
/*
|
||||
struct {
|
||||
uf::Timer<long long> flash = uf::Timer<long long>(false);
|
||||
uf::Timer<long long> sound = uf::Timer<long long>(false);
|
||||
} timers;
|
||||
*/
|
||||
#if 0
|
||||
static uf::Timer<long long> timer(true);
|
||||
this->addHook( "world:Collision.%UID%", [&](ext::json::Value& json){
|
||||
size_t uid = json["uid"].as<size_t>();
|
||||
@ -88,6 +84,7 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
|
||||
if ( normal.z == 1 || normal.z == -1 ) physics.linear.velocity.z = 0;
|
||||
#endif
|
||||
});
|
||||
#endif
|
||||
this->addHook( "asset:Cache.Sound.%UID%", [&](ext::json::Value& json){
|
||||
uf::Scene& world = uf::scene::getCurrentScene();
|
||||
uf::Serializer& masterdata = world.getComponent<uf::Serializer>();
|
||||
@ -103,6 +100,7 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
|
||||
sfx.setPosition( transform.position );
|
||||
sfx.play();
|
||||
});
|
||||
#if 0
|
||||
this->addHook( "world:Craeture.OnHit.%UID%", [&](ext::json::Value& json){
|
||||
uint64_t phase = json["phase"].as<size_t>();
|
||||
// start color
|
||||
@ -142,14 +140,15 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
void ext::CraetureBehavior::tick( uf::Object& self ) {
|
||||
#if 0
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
uf::Serializer& sMetadata = scene.getComponent<uf::Serializer>();
|
||||
uf::Serializer& pMetadata = scene.getController().getComponent<uf::Serializer>();
|
||||
|
||||
#if 0
|
||||
if ( !pMetadata["system"]["control"].as<bool>() ) return;
|
||||
if ( !sMetadata["system"]["physics"]["optimizations"]["entity-local update"].as<bool>() ) return;
|
||||
|
||||
@ -173,4 +172,5 @@ void ext::CraetureBehavior::tick( uf::Object& self ) {
|
||||
|
||||
void ext::CraetureBehavior::render( uf::Object& self ){}
|
||||
void ext::CraetureBehavior::destroy( uf::Object& self ){}
|
||||
#undef this
|
||||
#undef this
|
||||
#endif
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API CraetureBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace CraetureBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#if UF_USE_OPENVR
|
||||
#include "behavior.h"
|
||||
|
||||
#include <uf/utils/hook/hook.h>
|
||||
@ -484,4 +485,5 @@ void ext::PlayerHandBehavior::render( uf::Object& self ){
|
||||
void ext::PlayerHandBehavior::destroy( uf::Object& self ){
|
||||
|
||||
}
|
||||
#undef this
|
||||
#undef this
|
||||
#endif
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API PlayerHandBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace PlayerHandBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ namespace {
|
||||
UF_BEHAVIOR_REGISTER_CPP(ext::LightBehavior)
|
||||
#define this (&self)
|
||||
void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
@ -30,31 +30,31 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
});
|
||||
}
|
||||
|
||||
if ( !metadata["light"]["bias"]["constant"].is<float>() ) {
|
||||
metadata["light"]["bias"]["constant"] = 0.00005f;
|
||||
if ( !metadataJson["light"]["bias"]["constant"].is<float>() ) {
|
||||
metadataJson["light"]["bias"]["constant"] = 0.00005f;
|
||||
}
|
||||
if ( !ext::json::isArray( metadata["light"]["color"] ) ) {
|
||||
metadata["light"]["color"][0] = 1; //metadata["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
|
||||
metadata["light"]["color"][1] = 1; //metadata["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
|
||||
metadata["light"]["color"][2] = 1; //metadata["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
|
||||
if ( !ext::json::isArray( metadataJson["light"]["color"] ) ) {
|
||||
metadataJson["light"]["color"][0] = 1; //metadataJson["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
|
||||
metadataJson["light"]["color"][1] = 1; //metadataJson["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
|
||||
metadataJson["light"]["color"][2] = 1; //metadataJson["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
|
||||
}
|
||||
#if UF_USE_OPENGL
|
||||
metadata["light"]["shadows"] = false;
|
||||
metadataJson["light"]["shadows"] = false;
|
||||
#endif
|
||||
if ( metadata["light"]["shadows"].as<bool>() ) {
|
||||
if ( metadataJson["light"]["shadows"].as<bool>() ) {
|
||||
auto& cameraTransform = camera.getTransform();
|
||||
cameraTransform.reference = &transform;
|
||||
camera.setStereoscopic(false);
|
||||
if ( ext::json::isArray( metadata["light"]["radius"] ) ) {
|
||||
if ( ext::json::isArray( metadataJson["light"]["radius"] ) ) {
|
||||
auto bounds = camera.getBounds();
|
||||
bounds.x = metadata["light"]["radius"][0].as<float>();
|
||||
bounds.y = metadata["light"]["radius"][1].as<float>();
|
||||
bounds.x = metadataJson["light"]["radius"][0].as<float>();
|
||||
bounds.y = metadataJson["light"]["radius"][1].as<float>();
|
||||
camera.setBounds(bounds);
|
||||
}
|
||||
if ( ext::json::isArray( metadata["light"]["resolution"] ) ) {
|
||||
camera.setSize( uf::vector::decode( metadata["light"]["resolution"], pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height } ) );
|
||||
} else if ( metadata["light"]["resolution"].is<float>() ) {
|
||||
size_t size = metadata["light"]["resolution"].as<size_t>();
|
||||
if ( ext::json::isArray( metadataJson["light"]["resolution"] ) ) {
|
||||
camera.setSize( uf::vector::decode( metadataJson["light"]["resolution"], pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height } ) );
|
||||
} else if ( metadataJson["light"]["resolution"].is<float>() ) {
|
||||
size_t size = metadataJson["light"]["resolution"].as<size_t>();
|
||||
camera.setSize( {size, size} );
|
||||
} else {
|
||||
camera.setSize( pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height } );
|
||||
@ -64,16 +64,16 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
renderMode.metadata["type"] = "depth";
|
||||
renderMode.metadata["depth bias"] = metadata["light"]["bias"];
|
||||
renderMode.metadata["renderMode"] = metadata["renderMode"];
|
||||
renderMode.metadata["depth bias"] = metadataJson["light"]["bias"];
|
||||
renderMode.metadata["renderMode"] = metadataJson["renderMode"];
|
||||
// std::cout << this->getName() << ": " << renderMode.metadata["renderMode"] << std::endl;
|
||||
|
||||
if ( metadata["light"]["type"].as<std::string>() == "point" ) {
|
||||
metadata["light"]["fov"] = 90.0f;
|
||||
if ( metadataJson["light"]["type"].as<std::string>() == "point" ) {
|
||||
metadataJson["light"]["fov"] = 90.0f;
|
||||
renderMode.metadata["subpasses"] = 6;
|
||||
}
|
||||
if ( metadata["light"]["fov"].is<float>() ) {
|
||||
camera.setFov( metadata["light"]["fov"].as<float>() );
|
||||
if ( metadataJson["light"]["fov"].is<float>() ) {
|
||||
camera.setFov( metadataJson["light"]["fov"].as<float>() );
|
||||
}
|
||||
camera.updateView();
|
||||
camera.updateProjection();
|
||||
@ -87,149 +87,147 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
}
|
||||
|
||||
auto updateMetadata = [&](){
|
||||
auto& metadata = this->getComponent<ext::LightBehavior::Metadata>();
|
||||
metadata.color = uf::vector::decode( metadataJson["light"]["color"], pod::Vector3f{1,1,1} );
|
||||
metadata.power = metadataJson["light"]["power"].as<float>();
|
||||
metadata.bias = metadataJson["light"]["bias"]["shader"].as<float>();
|
||||
metadata.shadows = metadataJson["light"]["shadows"].as<bool>();
|
||||
metadata.renderer.mode = metadataJson["system"]["renderer"]["mode"].as<std::string>();
|
||||
metadata.renderer.rendered = false;
|
||||
metadata.renderer.external = metadataJson["light"]["external update"].as<bool>();
|
||||
metadata.renderer.limiter = metadataJson["system"]["renderer"]["timer"].as<float>();
|
||||
if ( metadataJson["light"]["type"].is<size_t>() ) {
|
||||
metadata.type = metadataJson["light"]["type"].as<size_t>();
|
||||
} else if ( metadataJson["light"]["type"].is<std::string>() ) {
|
||||
std::string lightType = metadataJson["light"]["type"].as<std::string>();
|
||||
if ( lightType == "point" ) metadata.type = 1;
|
||||
else if ( lightType == "spot" ) metadata.type = 2;
|
||||
}
|
||||
};
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", updateMetadata);
|
||||
updateMetadata();
|
||||
}
|
||||
void ext::LightBehavior::tick( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
#if !UF_ENV_DREAMCAST
|
||||
auto& metadata = this->getComponent<ext::LightBehavior::Metadata>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
if ( this->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
renderMode.setTarget("");
|
||||
}
|
||||
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& parent = this->getParent();
|
||||
auto& parentMetadata = parent.getComponent<uf::Serializer>();
|
||||
auto& parentTransform = parent.getComponent<pod::Transform<>>();
|
||||
// copy from our parent
|
||||
// if ( parentMetadata["system"]["name"] == "Light" ) {
|
||||
if ( metadata["light"]["bound"].as<bool>() ) {
|
||||
metadata["light"] = parentMetadata["light"];
|
||||
metadata["light"]["bound"] = true;
|
||||
if ( metadata["light"]["static"].as<bool>() ) {
|
||||
auto flatten = uf::transform::flatten( parentTransform );
|
||||
transform.position = flatten.position;
|
||||
#if 0
|
||||
// light fade action
|
||||
if ( ext::json::isObject( metadataJson["light"]["fade"] ) ) {
|
||||
if ( ext::json::isNull( metadataJson["light"]["backup"]["power"] ) ) {
|
||||
metadataJson["light"]["backup"]["power"] = metadataJson["light"]["power"];
|
||||
}
|
||||
} else {
|
||||
// light fade action
|
||||
if ( ext::json::isObject( metadata["light"]["fade"] ) ) {
|
||||
if ( ext::json::isNull( metadata["light"]["backup"]["power"] ) ) {
|
||||
metadata["light"]["backup"]["power"] = metadata["light"]["power"];
|
||||
}
|
||||
if ( ext::json::isNull( metadata["light"]["backup"]["color"] ) ) {
|
||||
metadata["light"]["backup"]["color"] = metadata["light"]["color"];
|
||||
}
|
||||
// fade towards
|
||||
int direction = metadata["light"]["fade"]["increment"].as<bool>() ? 1 : -1;
|
||||
metadata["light"]["fade"]["timer"] = metadata["light"]["fade"]["timer"].as<float>() + metadata["light"]["fade"]["rate"].as<float>() * uf::physics::time::delta * direction;
|
||||
|
||||
// 0 .. delta .. 1 .. (1 + timeout * 0.5)
|
||||
if ( direction == 1 && metadata["light"]["fade"]["timer"].as<float>() >= 0.5f * metadata["light"]["fade"]["timeout"].as<float>() + 1.0f ) {
|
||||
metadata["light"]["fade"]["increment"] = false;
|
||||
} else if ( direction == -1 && metadata["light"]["fade"]["timer"].as<float>() <= -0.5f * metadata["light"]["fade"]["timeout"].as<float>() ) {
|
||||
metadata["light"]["fade"]["increment"] = true;
|
||||
}
|
||||
{
|
||||
float delta = metadata["light"]["fade"]["timer"].as<float>();
|
||||
delta = std::clamp( delta, 0.f, 1.f );
|
||||
if ( metadata["light"]["fade"]["power"].is<double>() ) {
|
||||
metadata["light"]["power"] = uf::math::lerp( metadata["light"]["backup"]["power"].as<float>(), metadata["light"]["fade"]["power"].as<float>(), delta );
|
||||
}
|
||||
if ( ext::json::isArray( metadata["light"]["fade"]["color"] ) ) {
|
||||
pod::Vector3f fadeColor; {
|
||||
fadeColor.x = metadata["light"]["fade"]["color"][0].as<float>();
|
||||
fadeColor.y = metadata["light"]["fade"]["color"][1].as<float>();
|
||||
fadeColor.z = metadata["light"]["fade"]["color"][2].as<float>();
|
||||
}
|
||||
pod::Vector3f origColor; {
|
||||
origColor.x = metadata["light"]["backup"]["color"][0].as<float>();
|
||||
origColor.y = metadata["light"]["backup"]["color"][1].as<float>();
|
||||
origColor.z = metadata["light"]["backup"]["color"][2].as<float>();
|
||||
}
|
||||
pod::Vector3f color = uf::vector::lerp( origColor, fadeColor, delta );
|
||||
|
||||
metadata["light"]["color"][0] = color[0];
|
||||
metadata["light"]["color"][1] = color[1];
|
||||
metadata["light"]["color"][2] = color[2];
|
||||
}
|
||||
}
|
||||
if ( ext::json::isNull( metadataJson["light"]["backup"]["color"] ) ) {
|
||||
metadataJson["light"]["backup"]["color"] = metadataJson["light"]["color"];
|
||||
}
|
||||
// light flicker action
|
||||
if ( ext::json::isObject( metadata["light"]["flicker"] ) ) {
|
||||
float r = (rand() % 100) / 100.0;
|
||||
float rate = metadata["light"]["flicker"]["rate"].as<float>();
|
||||
if ( ext::json::isNull( metadata["light"]["backup"]["power"] ) ) {
|
||||
metadata["light"]["backup"]["power"] = metadata["light"]["power"];
|
||||
// fade towards
|
||||
int direction = metadataJson["light"]["fade"]["increment"].as<bool>() ? 1 : -1;
|
||||
metadataJson["light"]["fade"]["timer"] = metadataJson["light"]["fade"]["timer"].as<float>() + metadataJson["light"]["fade"]["rate"].as<float>() * uf::physics::time::delta * direction;
|
||||
|
||||
// 0 .. delta .. 1 .. (1 + timeout * 0.5)
|
||||
if ( direction == 1 && metadataJson["light"]["fade"]["timer"].as<float>() >= 0.5f * metadataJson["light"]["fade"]["timeout"].as<float>() + 1.0f ) {
|
||||
metadataJson["light"]["fade"]["increment"] = false;
|
||||
} else if ( direction == -1 && metadataJson["light"]["fade"]["timer"].as<float>() <= -0.5f * metadataJson["light"]["fade"]["timeout"].as<float>() ) {
|
||||
metadataJson["light"]["fade"]["increment"] = true;
|
||||
}
|
||||
{
|
||||
float delta = metadataJson["light"]["fade"]["timer"].as<float>();
|
||||
delta = std::clamp( delta, 0.f, 1.f );
|
||||
if ( metadataJson["light"]["fade"]["power"].is<double>() ) {
|
||||
metadataJson["light"]["power"] = uf::math::lerp( metadataJson["light"]["backup"]["power"].as<float>(), metadataJson["light"]["fade"]["power"].as<float>(), delta );
|
||||
}
|
||||
metadata["light"]["flicker"]["timer"] = metadata["light"]["flicker"]["timer"].as<float>() + uf::physics::time::delta;
|
||||
if ( metadata["light"]["flicker"]["timer"].as<float>() >= metadata["light"]["flicker"]["timeout"].as<float>() ) {
|
||||
metadata["light"]["flicker"]["timer"] = 0;
|
||||
metadata["light"]["power"] = (r > rate) ? metadata["light"]["flicker"]["power"].as<float>() : metadata["light"]["backup"]["power"].as<float>();
|
||||
if ( ext::json::isArray( metadataJson["light"]["fade"]["color"] ) ) {
|
||||
pod::Vector3f fadeColor; {
|
||||
fadeColor.x = metadataJson["light"]["fade"]["color"][0].as<float>();
|
||||
fadeColor.y = metadataJson["light"]["fade"]["color"][1].as<float>();
|
||||
fadeColor.z = metadataJson["light"]["fade"]["color"][2].as<float>();
|
||||
}
|
||||
pod::Vector3f origColor; {
|
||||
origColor.x = metadataJson["light"]["backup"]["color"][0].as<float>();
|
||||
origColor.y = metadataJson["light"]["backup"]["color"][1].as<float>();
|
||||
origColor.z = metadataJson["light"]["backup"]["color"][2].as<float>();
|
||||
}
|
||||
pod::Vector3f color = uf::vector::lerp( origColor, fadeColor, delta );
|
||||
|
||||
metadataJson["light"]["color"][0] = color[0];
|
||||
metadataJson["light"]["color"][1] = color[1];
|
||||
metadataJson["light"]["color"][2] = color[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// skip if we're handling the camera view matrix position ourselves
|
||||
if ( !metadata["light"]["external update"].as<bool>() ) {
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
// omni light
|
||||
if ( metadata["light"]["shadows"].as<bool>() && metadata["light"]["type"].as<std::string>() == "point" ) {
|
||||
auto transform = camera.getTransform();
|
||||
std::vector<pod::Quaternion<>> rotations = {
|
||||
/*
|
||||
{0, 0, 0, 1},
|
||||
{0, 0.707107, 0, -0.707107},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0.707107, 0, 0.707107},
|
||||
{-0.707107, 0, 0, -0.707107},
|
||||
{0.707107, 0, 0, -0.707107},
|
||||
*/
|
||||
uf::quaternion::axisAngle( { 0, 1, 0 }, 0 * 1.57079633 ),
|
||||
uf::quaternion::axisAngle( { 0, 1, 0 }, 1 * 1.57079633 ),
|
||||
uf::quaternion::axisAngle( { 0, 1, 0 }, 2 * 1.57079633 ),
|
||||
uf::quaternion::axisAngle( { 0, 1, 0 }, 3 * 1.57079633 ),
|
||||
|
||||
uf::quaternion::axisAngle( { 1, 0, 0 }, 1 * 1.57079633 ),
|
||||
uf::quaternion::axisAngle( { 1, 0, 0 }, 3 * 1.57079633 ),
|
||||
};
|
||||
for ( size_t i = 0; i < rotations.size(); ++i ) {
|
||||
auto transform = camera.getTransform();
|
||||
transform.orientation = rotations[i];
|
||||
camera.setView( uf::matrix::inverse( uf::transform::model( transform, false ) ), i );
|
||||
}
|
||||
} else {
|
||||
camera.updateView();
|
||||
// light flicker action
|
||||
if ( ext::json::isObject( metadataJson["light"]["flicker"] ) ) {
|
||||
float r = (rand() % 100) / 100.0;
|
||||
float rate = metadataJson["light"]["flicker"]["rate"].as<float>();
|
||||
if ( ext::json::isNull( metadataJson["light"]["backup"]["power"] ) ) {
|
||||
metadataJson["light"]["backup"]["power"] = metadataJson["light"]["power"];
|
||||
}
|
||||
metadataJson["light"]["flicker"]["timer"] = metadataJson["light"]["flicker"]["timer"].as<float>() + uf::physics::time::delta;
|
||||
if ( metadataJson["light"]["flicker"]["timer"].as<float>() >= metadataJson["light"]["flicker"]["timeout"].as<float>() ) {
|
||||
metadataJson["light"]["flicker"]["timer"] = 0;
|
||||
metadataJson["light"]["power"] = (r > rate) ? metadataJson["light"]["flicker"]["power"].as<float>() : metadataJson["light"]["backup"]["power"].as<float>();
|
||||
}
|
||||
// for ( std::size_t i = 0; i < 2; ++i ) camera.setView( uf::matrix::inverse( uf::transform::model( transform ) ), i );
|
||||
}
|
||||
|
||||
#endif
|
||||
// limit updating our shadow map
|
||||
if ( this->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
// skip if we're handling the camera view matrix position ourselves
|
||||
if ( !metadata.renderer.external ) {
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
// omni light
|
||||
if ( metadata.shadows && metadata.type == 1 ) {
|
||||
auto transform = camera.getTransform();
|
||||
std::vector<pod::Quaternion<>> rotations = {
|
||||
uf::quaternion::axisAngle( { 0, 1, 0 }, 0 * 1.57079633 ),
|
||||
uf::quaternion::axisAngle( { 0, 1, 0 }, 1 * 1.57079633 ),
|
||||
uf::quaternion::axisAngle( { 0, 1, 0 }, 2 * 1.57079633 ),
|
||||
uf::quaternion::axisAngle( { 0, 1, 0 }, 3 * 1.57079633 ),
|
||||
|
||||
uf::quaternion::axisAngle( { 1, 0, 0 }, 1 * 1.57079633 ),
|
||||
uf::quaternion::axisAngle( { 1, 0, 0 }, 3 * 1.57079633 ),
|
||||
};
|
||||
for ( size_t i = 0; i < rotations.size(); ++i ) {
|
||||
auto transform = camera.getTransform();
|
||||
transform.orientation = rotations[i];
|
||||
camera.setView( uf::matrix::inverse( uf::transform::model( transform, false ) ), i );
|
||||
}
|
||||
} else {
|
||||
camera.updateView();
|
||||
}
|
||||
}
|
||||
bool execute = true;
|
||||
// enable renderer every X seconds
|
||||
if ( metadata["system"]["renderer"]["limiter"].is<float>() ) {
|
||||
if ( metadata["system"]["renderer"]["timer"].as<float>() > metadata["system"]["renderer"]["limiter"].as<float>() ) {
|
||||
metadata["system"]["renderer"]["timer"] = 0;
|
||||
if ( metadata.renderer.limiter > 0 ) {
|
||||
if ( metadata.renderer.timer > metadata.renderer.limiter ) {
|
||||
metadata.renderer.timer = 0;
|
||||
execute = true;
|
||||
} else {
|
||||
metadata["system"]["renderer"]["timer"] = metadata["system"]["renderer"]["timer"].as<float>() + uf::physics::time::delta;
|
||||
metadata.renderer.timer = metadata.renderer.timer + uf::physics::time::delta;
|
||||
execute = false;
|
||||
}
|
||||
} else if ( metadata["system"]["renderer"]["mode"].is<std::string>() ) {
|
||||
std::string mode = metadata["system"]["renderer"]["mode"].as<std::string>();
|
||||
} else {
|
||||
// round robin, enable if it's the light's current turn
|
||||
if ( mode == "round robin" ) {
|
||||
if ( metadata.renderer.mode == "round robin" ) {
|
||||
if ( ::roundRobin.current < ::roundRobin.lights.size() ) execute = ::roundRobin.lights[::roundRobin.current] == this;
|
||||
// render only if the light is used
|
||||
} else if ( mode == "occlusion" ) {
|
||||
execute = metadata["system"]["renderer"]["rendered"].as<bool>();
|
||||
} else if ( metadata.renderer.mode == "occlusion" ) {
|
||||
execute = metadata.renderer.rendered;
|
||||
// light baking, but sadly re-bakes every time the command buffer is recorded
|
||||
} else if ( mode == "once" ) {
|
||||
execute = !metadata["system"]["renderer"]["rendered"].as<bool>();
|
||||
metadata["system"]["renderer"]["rendered"] = true;
|
||||
} else if ( metadata.renderer.mode == "once" ) {
|
||||
execute = !metadata.renderer.rendered;
|
||||
metadata.renderer.rendered = true;
|
||||
}
|
||||
}
|
||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
renderMode.execute = execute;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void ext::LightBehavior::render( uf::Object& self ){
|
||||
|
||||
|
@ -4,14 +4,29 @@
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/utils/math/vector.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API LightBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace LightBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
struct Metadata {
|
||||
pod::Vector3f color = {1,1,1};
|
||||
float power = 0.0f;
|
||||
float bias = 0.0f;
|
||||
bool shadows = false;
|
||||
size_t type = 0;
|
||||
struct {
|
||||
std::string mode = "in-range";
|
||||
float limiter = 0.0f;
|
||||
float timer = 0.0f;
|
||||
bool rendered = false;
|
||||
bool external = false;
|
||||
} renderer;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "behavior.h"
|
||||
|
||||
#include <uf/utils/graphic/mesh.h>
|
||||
@ -120,4 +121,5 @@ void ext::NoiseBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
void ext::NoiseBehavior::render( uf::Object& self ) {}
|
||||
void ext::NoiseBehavior::destroy( uf::Object& self ) {}
|
||||
#undef this
|
||||
#undef this
|
||||
#endif
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API NoiseBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace NoiseBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -11,29 +11,18 @@
|
||||
#include <uf/ext/gltf/graph.h>
|
||||
#include <uf/ext/bullet/bullet.h>
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/spec/controller/controller.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#if 0
|
||||
namespace {
|
||||
uf::Serializer masterTableGet( const std::string& table ) {
|
||||
uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
uf::Serializer& mastertable = scene.getComponent<uf::Serializer>();
|
||||
return mastertable["system"]["mastertable"][table];
|
||||
}
|
||||
uf::Serializer masterDataGet( const std::string& table, const std::string& key ) {
|
||||
uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
uf::Serializer& mastertable = scene.getComponent<uf::Serializer>();
|
||||
return mastertable["system"]["mastertable"][table][key];
|
||||
}
|
||||
inline int64_t parseInt( const std::string& str ) {
|
||||
return atoi(str.c_str());
|
||||
}
|
||||
|
||||
inline std::string colorString( const std::string& hex ) {
|
||||
return "%#" + hex + "%";
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
UF_BEHAVIOR_REGISTER_CPP(ext::PlayerBehavior)
|
||||
#define this (&self)
|
||||
void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
@ -114,13 +103,10 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
metadata["system"]["control"] = true;
|
||||
|
||||
this->addHook( "window:Mouse.CursorVisibility", [&](ext::json::Value& json){
|
||||
metadata["system"]["control"] = !json["state"].as<bool>();
|
||||
});
|
||||
|
||||
// Rotate Camera
|
||||
this->addHook( "window:Mouse.Moved", [&](ext::json::Value& json){
|
||||
// discard events sent by os, only trust client now
|
||||
@ -181,7 +167,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
camera.updateView();
|
||||
}
|
||||
});
|
||||
|
||||
#if 0
|
||||
this->addHook( ":Update.%UID%", [&](ext::json::Value& json){
|
||||
// for ( auto& member : json[""]["transients"] ) {
|
||||
ext::json::forEach(metadata[""]["transients"], [&](ext::json::Value& member){
|
||||
@ -257,7 +243,9 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
metadata["system"]["menu"] = "";
|
||||
metadata["system"]["cooldown"] = uf::physics::time::current + 1;
|
||||
});
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
#if UF_USE_DISCORD
|
||||
// Discord Integration
|
||||
this->addHook( "discord.Activity.Update.%UID%", [&](ext::json::Value& json){
|
||||
std::string leaderId = metadata[""]["party"][0].as<std::string>();
|
||||
@ -270,13 +258,38 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
uf::hooks.call( "discord:Activity.Update", payload );
|
||||
});
|
||||
this->queueHook("discord.Activity.Update.%UID%", ext::json::null(), 1.0);
|
||||
#endif
|
||||
#endif
|
||||
#if !UF_ENTITY_METADATA_USE_JSON
|
||||
{
|
||||
auto& metadataBehavior = this->getComponent<ext::PlayerBehavior::Metadata>();
|
||||
auto& metadataSystem = metadata["system"];
|
||||
metadataBehavior.system.menu = metadataSystem["menu"].as<std::string>();
|
||||
metadataBehavior.system.control = metadataSystem["control"].as<bool>();
|
||||
metadataBehavior.system.crouching = metadataSystem["crouching"].as<bool>();
|
||||
metadataBehavior.system.noclipped = metadataSystem["noclipped"].as<bool>();
|
||||
auto& metadataSystemPhysics = metadataSystem["physics"];
|
||||
metadataBehavior.system.physics.impulse = metadataSystemPhysics["impulse"].as<bool>();
|
||||
metadataBehavior.system.physics.rotate = metadataSystemPhysics["rotate"].as<float>();
|
||||
metadataBehavior.system.physics.move = metadataSystemPhysics["move"].as<float>();
|
||||
metadataBehavior.system.physics.run = metadataSystemPhysics["run"].as<float>();
|
||||
metadataBehavior.system.physics.walk = metadataSystemPhysics["walk"].as<float>();
|
||||
metadataBehavior.system.physics.collision = metadataSystemPhysics["collision"].as<bool>();
|
||||
metadataBehavior.system.physics.jump = uf::vector::decode(metadataSystemPhysics["jump"], pod::Vector3f{});
|
||||
metadataBehavior.system.physics.crouch = metadataSystemPhysics["crouch"].as<float>();
|
||||
auto& metadataAudioFootstep = metadata["audio"]["footstep"];
|
||||
ext::json::forEach( metadataAudioFootstep["list"], [&]( const ext::json::Value& value ){
|
||||
metadataBehavior.audio.footstep.list.emplace_back(value);
|
||||
});
|
||||
metadataBehavior.audio.footstep.volume = metadataAudioFootstep["volume"].as<float>();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
uf::Camera& camera = this->getComponent<uf::Camera>();
|
||||
pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
|
||||
pod::Physics& physics = this->getComponent<pod::Physics>();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& physics = this->getComponent<pod::Physics>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
|
||||
struct {
|
||||
bool forward;
|
||||
@ -293,20 +306,6 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
bool paused;
|
||||
bool vee;
|
||||
} keys = {
|
||||
#if UF_ENV_DREAMCAST
|
||||
.forward = uf::Window::isKeyPressed("Up"),
|
||||
.backwards = uf::Window::isKeyPressed("Down"),
|
||||
.left = uf::Window::isKeyPressed("Left"),
|
||||
.right = uf::Window::isKeyPressed("Right"),
|
||||
.lookLeft = uf::Window::isKeyPressed("C"),
|
||||
.lookRight = uf::Window::isKeyPressed("X"),
|
||||
.running = uf::Window::isKeyPressed("Y"),
|
||||
.walk = uf::Window::isKeyPressed("_"),
|
||||
.jump = uf::Window::isKeyPressed("A"),
|
||||
.crouch = uf::Window::isKeyPressed("X"),
|
||||
.paused = uf::Window::isKeyPressed("Start"),
|
||||
.vee = uf::Window::isKeyPressed("B"),
|
||||
#else
|
||||
.forward = uf::Window::isKeyPressed("W"),
|
||||
.backwards = uf::Window::isKeyPressed("S"),
|
||||
.left = uf::Window::isKeyPressed("A"),
|
||||
@ -319,26 +318,38 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
.crouch = uf::Window::isKeyPressed("LControl"),
|
||||
.paused = uf::Window::isKeyPressed("Escape"),
|
||||
.vee = uf::Window::isKeyPressed("V"),
|
||||
#endif
|
||||
};
|
||||
|
||||
#if UF_USE_OPENVR
|
||||
if ( ext::openvr::context ) {
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadUp" )["state"].as<bool>() ) keys.forward = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadDown" )["state"].as<bool>() ) keys.backwards = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadLeft" )["state"].as<bool>() ) keys.lookLeft = true; // keys.left = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadRight" )["state"].as<bool>() ) keys.lookRight = true; // keys.right = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "thumbclick" )["state"].as<bool>() ) keys.running = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "a" )["state"].as<bool>() ) keys.jump = true;
|
||||
if ( spec::controller::connected() ) {
|
||||
#if UF_USE_OPENVR
|
||||
if ( spec::controller::pressed( "R_DPAD_UP" ) ) keys.forward = true;
|
||||
if ( spec::controller::pressed( "R_DPAD_DOWN" ) ) keys.backwards = true;
|
||||
if ( spec::controller::pressed( "R_DPAD_LEFT" ) ) keys.lookLeft = true; // keys.left = true;
|
||||
if ( spec::controller::pressed( "R_DPAD_RIGHT" ) ) keys.lookRight = true; // keys.right = true;
|
||||
if ( spec::controller::pressed( "R_JOYSTICK" ) ) keys.running = true;
|
||||
if ( spec::controller::pressed( "R_A" ) ) keys.jump = true;
|
||||
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadUp" )["state"].as<bool>() ) keys.forward = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadDown" )["state"].as<bool>() ) keys.backwards = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadLeft" )["state"].as<bool>() ) keys.lookLeft = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadRight" )["state"].as<bool>() ) keys.lookRight = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "thumbclick" )["state"].as<bool>() ) keys.crouch = true, keys.walk = true;
|
||||
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "a" )["state"].as<bool>() ) keys.paused = true;
|
||||
if ( spec::controller::pressed( "L_DPAD_UP" ) ) keys.forward = true;
|
||||
if ( spec::controller::pressed( "L_DPAD_DOWN" ) ) keys.backwards = true;
|
||||
if ( spec::controller::pressed( "L_DPAD_LEFT" ) ) keys.lookLeft = true;
|
||||
if ( spec::controller::pressed( "L_DPAD_RIGHT" ) ) keys.lookRight = true;
|
||||
if ( spec::controller::pressed( "L_JOYSTICK" ) ) keys.crouch = true, keys.walk = true;
|
||||
if ( spec::controller::pressed( "L_A" ) ) keys.paused = true;
|
||||
#else
|
||||
if ( spec::controller::pressed( "DPAD_UP" ) ) keys.forward = true;
|
||||
if ( spec::controller::pressed( "DPAD_DOWN" ) ) keys.backwards = true;
|
||||
if ( spec::controller::pressed( "DPAD_LEFT" ) ) keys.lookLeft = true;
|
||||
if ( spec::controller::pressed( "DPAD_RIGHT" ) ) keys.lookRight = true;
|
||||
if ( spec::controller::pressed( "A" ) ) keys.jump = true;
|
||||
if ( spec::controller::pressed( "B" ) ) keys.running = true;
|
||||
if ( spec::controller::pressed( "X" ) ) keys.crouch = true, keys.walk = true;
|
||||
if ( spec::controller::pressed( "Y" ) ) keys.vee = true;
|
||||
if ( spec::controller::pressed( "L_TRIGGER" ) ) keys.left = true;
|
||||
if ( spec::controller::pressed( "R_TRIGGER" ) ) keys.right = true;
|
||||
if ( spec::controller::pressed( "START" ) ) keys.paused = true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
struct {
|
||||
bool updateCamera = true;
|
||||
bool deltaCrouch = false;
|
||||
@ -350,10 +361,33 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
std::string targetAnimation = "";
|
||||
} stats;
|
||||
|
||||
auto& metadata = this->getComponent<ext::PlayerBehavior::Metadata>();
|
||||
#if UF_ENTITY_METADATA_USE_JSON
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
auto& metadataSystem = metadataJson["system"];
|
||||
metadata.system.menu = metadataSystem["menu"].as<std::string>();
|
||||
metadata.system.control = metadataSystem["control"].as<bool>();
|
||||
metadata.system.crouching = metadataSystem["crouching"].as<bool>();
|
||||
metadata.system.noclipped = metadataSystem["noclipped"].as<bool>();
|
||||
auto& metadataSystemPhysics = metadataSystem["physics"];
|
||||
metadata.system.physics.impulse = metadataSystemPhysics["impulse"].as<bool>();
|
||||
metadata.system.physics.rotate = metadataSystemPhysics["rotate"].as<float>();
|
||||
metadata.system.physics.move = metadataSystemPhysics["move"].as<float>();
|
||||
metadata.system.physics.run = metadataSystemPhysics["run"].as<float>();
|
||||
metadata.system.physics.walk = metadataSystemPhysics["walk"].as<float>();
|
||||
metadata.system.physics.collision = metadataSystemPhysics["collision"].as<bool>();
|
||||
metadata.system.physics.jump = uf::vector::decode(metadataSystemPhysics["jump"], pod::Vector3f{});
|
||||
metadata.system.physics.crouch = metadataSystemPhysics["crouch"].as<float>();
|
||||
auto& metadataAudioFootstep = metadataJson["audio"]["footstep"];
|
||||
ext::json::forEach( metadataAudioFootstep["list"], [&]( const ext::json::Value& value ){
|
||||
metadata.audio.footstep.list.emplace_back(value);
|
||||
});
|
||||
metadata.audio.footstep.volume = metadataAudioFootstep["volume"].as<float>();
|
||||
#endif
|
||||
stats.floored = fabs(physics.linear.velocity.y) < 0.01f;
|
||||
stats.menu = metadata["system"]["menu"].as<std::string>();
|
||||
stats.impulse = metadata["system"]["physics"]["impulse"].as<bool>();
|
||||
stats.noclipped = metadata["system"]["noclipped"].as<bool>();
|
||||
stats.menu = metadata.system.menu;
|
||||
stats.impulse = metadata.system.physics.impulse;
|
||||
stats.noclipped = metadata.system.noclipped;
|
||||
struct {
|
||||
float move = 4;
|
||||
float walk = 1;
|
||||
@ -361,12 +395,12 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
float rotate = uf::physics::time::delta;
|
||||
float limitSquared = 4*4;
|
||||
} speed; {
|
||||
speed.rotate *= metadata["system"]["physics"]["rotate"].as<float>();
|
||||
speed.move = metadata["system"]["physics"]["move"].as<float>();
|
||||
speed.run = metadata["system"]["physics"]["run"].as<float>() / metadata["system"]["physics"]["move"].as<float>();
|
||||
speed.walk = metadata["system"]["physics"]["walk"].as<float>() / metadata["system"]["physics"]["move"].as<float>();
|
||||
speed.rotate *= metadata.system.physics.rotate;
|
||||
speed.move = metadata.system.physics.move;
|
||||
speed.run = metadata.system.physics.run / speed.move;
|
||||
speed.walk = metadata.system.physics.walk / speed.move;
|
||||
}
|
||||
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
|
||||
if ( !metadata.system.physics.collision ) {
|
||||
stats.impulse = true;
|
||||
}
|
||||
if ( keys.running ) speed.move *= speed.run;
|
||||
@ -378,27 +412,26 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
// make assumptions
|
||||
if ( stats.menu == "" && keys.paused ) {
|
||||
stats.menu = "paused";
|
||||
metadata["system"]["control"] = false;
|
||||
metadata.system.control = false;
|
||||
uf::hooks.call("menu:Pause");
|
||||
}
|
||||
else if ( !metadata["system"]["control"].as<bool>() ) {
|
||||
else if ( !metadata.system.control ) {
|
||||
stats.menu = "menu";
|
||||
} else if ( stats.menu == "" ) {
|
||||
metadata["system"]["control"] = true;
|
||||
metadata.system.control = true;
|
||||
} else {
|
||||
metadata["system"]["control"] = false;
|
||||
metadata.system.control = false;
|
||||
}
|
||||
metadata["system"]["menu"] = stats.menu;
|
||||
metadata.system.menu = stats.menu;
|
||||
auto& collider = this->getComponent<pod::Bullet>();
|
||||
if ( metadata["system"]["control"].as<bool>() ) {
|
||||
if ( metadata.system.control ) {
|
||||
{
|
||||
TIMER(0.25, keys.vee && ) {
|
||||
bool state = !metadata["system"]["noclipped"].as<bool>();
|
||||
metadata["system"]["noclipped"] = state;
|
||||
bool state = !stats.noclipped;
|
||||
metadata.system.noclipped = state;
|
||||
|
||||
std::cout << "Toggling noclip: " << transform.position.x << ", " << transform.position.y << ", " << transform.position.z << std::endl;
|
||||
UF_DEBUG_MSG( (state ? "En" : "Dis") << "abled noclip: " << uf::vector::toString(transform.position));
|
||||
if ( state ) {
|
||||
std::cout << "Enabled noclip" << std::endl;
|
||||
#if UF_USE_BULLET
|
||||
if ( collider.body ) {
|
||||
collider.body->setGravity(btVector3(0,0.0,0));
|
||||
@ -407,7 +440,6 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
std::cout << "Disabled noclip" << std::endl;
|
||||
#if UF_USE_BULLET
|
||||
if ( collider.body ) {
|
||||
collider.body->setGravity(btVector3(0,-9.81,0));
|
||||
@ -440,16 +472,11 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
int polarity = keys.forward ? 1 : -1;
|
||||
float mag = uf::vector::magnitude(physics.linear.velocity * pod::Vector3{1, 0, 1});
|
||||
if ( mag < speed.limitSquared ) {
|
||||
// physics.linear.velocity += translator.forward * speed.move * polarity;
|
||||
// mag = uf::vector::magnitude(physics.linear.velocity);
|
||||
mag = uf::vector::magnitude(physics.linear.velocity + translator.forward * speed.move * polarity);
|
||||
} else mag = speed.limitSquared;
|
||||
pod::Vector3 correction = translator.forward * sqrt(mag) * polarity;
|
||||
pod::Vector3 correction = translator.forward * ::sqrt(mag) * polarity;
|
||||
|
||||
if ( collider.body && !collider.shared ) {
|
||||
// physics.linear.velocity.x += correction.x;
|
||||
// physics.linear.velocity.z += correction.z;
|
||||
// ext::bullet::move( collider, physics.linear.velocity );
|
||||
queued += correction;
|
||||
} else {
|
||||
if ( stats.impulse && stats.noclipped ) {
|
||||
@ -467,16 +494,11 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
int polarity = keys.right ? 1 : -1;
|
||||
float mag = uf::vector::magnitude(physics.linear.velocity * pod::Vector3{1, 0, 1});
|
||||
if ( mag < speed.limitSquared ) {
|
||||
// physics.linear.velocity += translator.right * speed.move * polarity;
|
||||
// mag = uf::vector::magnitude(physics.linear.velocity);
|
||||
mag = uf::vector::magnitude(physics.linear.velocity + translator.right * speed.move * polarity);
|
||||
} else mag = speed.limitSquared;
|
||||
pod::Vector3 correction = translator.right * sqrt(mag) * polarity;
|
||||
pod::Vector3 correction = translator.right * ::sqrt(mag) * polarity;
|
||||
|
||||
if ( collider.body && !collider.shared ) {
|
||||
// physics.linear.velocity.x += correction.x;
|
||||
// physics.linear.velocity.z += correction.z;
|
||||
// ext::bullet::move( collider, physics.linear.velocity );
|
||||
queued += correction;
|
||||
} else {
|
||||
if ( stats.impulse && stats.noclipped ) {
|
||||
@ -509,8 +531,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
if ( keys.jump ) {
|
||||
pod::Vector3f yump = metadata.system.physics.jump;
|
||||
if ( collider.body && !collider.shared ) {
|
||||
pod::Vector3f yump = uf::vector::decode(metadata["system"]["physics"]["jump"], pod::Vector3f{});
|
||||
if ( fabs(yump.x) > 0.001f ) physics.linear.velocity.x = yump.x;
|
||||
if ( fabs(yump.y) > 0.001f ) physics.linear.velocity.y = yump.y;
|
||||
if ( fabs(yump.z) > 0.001f ) physics.linear.velocity.z = yump.z;
|
||||
@ -518,9 +540,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
ext::bullet::move( collider, physics.linear.velocity );
|
||||
#endif
|
||||
} else {
|
||||
if ( metadata["system"]["physics"]["jump"][0].as<float>() != 0 ) transform.position.x += metadata["system"]["physics"]["jump"][0].as<float>() * uf::physics::time::delta;
|
||||
if ( metadata["system"]["physics"]["jump"][1].as<float>() != 0 ) transform.position.y += metadata["system"]["physics"]["jump"][1].as<float>() * uf::physics::time::delta;
|
||||
if ( metadata["system"]["physics"]["jump"][2].as<float>() != 0 ) transform.position.z += metadata["system"]["physics"]["jump"][2].as<float>() * uf::physics::time::delta;
|
||||
transform.position += yump * uf::physics::time::delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -531,7 +551,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
ext::bullet::applyRotation( collider, transform.up, -speed.rotate );
|
||||
#endif
|
||||
} else {
|
||||
uf::transform::rotate( transform, transform.up, -speed.rotate ), stats.updateCamera = true;
|
||||
uf::transform::rotate( transform, transform.up, -speed.rotate );
|
||||
}
|
||||
stats.updateCamera = true;
|
||||
}
|
||||
@ -541,14 +561,14 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
ext::bullet::applyRotation( collider, transform.up, speed.rotate );
|
||||
#endif
|
||||
} else {
|
||||
uf::transform::rotate( transform, transform.up, speed.rotate ), stats.updateCamera = true;
|
||||
uf::transform::rotate( transform, transform.up, speed.rotate );
|
||||
}
|
||||
stats.updateCamera = true;
|
||||
}
|
||||
if ( keys.crouch ) {
|
||||
pod::Vector3f yump = metadata.system.physics.jump;
|
||||
if ( stats.noclipped ) {
|
||||
if ( collider.body && !collider.shared ) {
|
||||
pod::Vector3f yump = uf::vector::decode(metadata["system"]["physics"]["jump"], pod::Vector3f{});
|
||||
if ( fabs(yump.x) > 0.001f ) physics.linear.velocity.x = -yump.x;
|
||||
if ( fabs(yump.y) > 0.001f ) physics.linear.velocity.y = -yump.y;
|
||||
if ( fabs(yump.z) > 0.001f ) physics.linear.velocity.z = -yump.z;
|
||||
@ -557,18 +577,16 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
|
||||
if ( metadata["system"]["physics"]["jump"][0].as<float>() != 0 ) transform.position.x -= metadata["system"]["physics"]["jump"][0].as<float>() * uf::physics::time::delta;
|
||||
if ( metadata["system"]["physics"]["jump"][1].as<float>() != 0 ) transform.position.y -= metadata["system"]["physics"]["jump"][1].as<float>() * uf::physics::time::delta;
|
||||
if ( metadata["system"]["physics"]["jump"][2].as<float>() != 0 ) transform.position.z -= metadata["system"]["physics"]["jump"][2].as<float>() * uf::physics::time::delta;
|
||||
if ( !metadata.system.physics.collision ) {
|
||||
transform.position -= yump * uf::physics::time::delta;
|
||||
} else {
|
||||
if ( !metadata["system"]["crouching"].as<bool>() ) stats.deltaCrouch = true;
|
||||
metadata["system"]["crouching"] = true;
|
||||
if ( !metadata.system.crouching ) stats.deltaCrouch = true;
|
||||
metadata.system.crouching = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( metadata["system"]["crouching"].as<bool>() ) stats.deltaCrouch = true;
|
||||
metadata["system"]["crouching"] = false;
|
||||
if ( metadata.system.crouching ) stats.deltaCrouch = true;
|
||||
metadata.system.crouching = false;
|
||||
}
|
||||
}
|
||||
if ( stats.noclipped && !keys.forward && !keys.backwards && !keys.left && !keys.right && !keys.jump && !keys.crouch ) {
|
||||
@ -580,27 +598,27 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
if ( stats.deltaCrouch ) {
|
||||
float delta = metadata["system"]["physics"]["crouch"].as<float>();
|
||||
if ( metadata["system"]["crouching"].as<bool>() ) camera.getTransform().position.y -= delta;
|
||||
float delta = metadata.system.physics.crouch;
|
||||
if ( metadata.system.crouching ) camera.getTransform().position.y -= delta;
|
||||
else camera.getTransform().position.y += delta;
|
||||
stats.updateCamera = true;
|
||||
}
|
||||
|
||||
#if UF_USE_OPENAL
|
||||
if ( stats.floored ) {
|
||||
if ( stats.walking ) {
|
||||
auto& emitter = this->getComponent<uf::MappedSoundEmitter>();
|
||||
int cycle = rand() % metadata["audio"]["footstep"]["list"].size();
|
||||
std::string filename = metadata["audio"]["footstep"]["list"][cycle].as<std::string>();
|
||||
int cycle = rand() % metadata.audio.footstep.list.size();
|
||||
std::string filename = metadata.audio.footstep.list[cycle];
|
||||
uf::Audio& footstep = emitter.add(filename);
|
||||
|
||||
bool playing = false;
|
||||
for ( uint i = 0; i < metadata["audio"]["footstep"]["list"].size(); ++i ) {
|
||||
uf::Audio& audio = emitter.add(metadata["audio"]["footstep"]["list"][i].as<std::string>());
|
||||
for ( uint i = 0; i < metadata.audio.footstep.list.size(); ++i ) {
|
||||
uf::Audio& audio = emitter.add(metadata.audio.footstep.list[i]);
|
||||
if ( audio.playing() ) playing = true;
|
||||
}
|
||||
if ( !playing ) {
|
||||
footstep.play();
|
||||
footstep.setVolume(metadata["audio"]["footstep"]["volume"].as<float>());
|
||||
footstep.setVolume(metadata.audio.footstep.volume);
|
||||
footstep.setPosition( transform.position );
|
||||
|
||||
// [0, 1]
|
||||
@ -618,171 +636,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
stats.targetAnimation = "idle_wank";
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
TIMER(0.25, keys.vee && ) {
|
||||
if ( ext::json::isNull( metadata["system"]["physics"]["backup"]["collision"] ) )
|
||||
metadata["system"]["physics"]["backup"]["collision"] = metadata["system"]["physics"]["collision"];
|
||||
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
|
||||
metadata["system"]["physics"]["collision"] = metadata["system"]["physics"]["backup"]["collision"];
|
||||
} else {
|
||||
metadata["system"]["physics"]["collision"] = 0;
|
||||
}
|
||||
|
||||
std::cout << "Toggling noclip: " << transform.position.x << ", " << transform.position.y << ", " << transform.position.z << std::endl;
|
||||
std::cout << metadata.dump(1, '\t') << std::endl;
|
||||
|
||||
// metadata["system"]["physics"]["collision"] = !metadata["system"]["physics"]["collision"].as<bool>();
|
||||
physics.linear.velocity = {0,0,0};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( ext::json::isObject( metadata["system"]["physics"]["clamp"] ) ) {
|
||||
if ( ext::json::isArray( metadata["system"]["physics"]["clamp"]["x"] ) ) {
|
||||
transform.position.x = std::clamp( transform.position.x, metadata["system"]["physics"]["clamp"]["x"][0].as<float>(), metadata["system"]["physics"]["clamp"]["x"][1].as<float>() );
|
||||
}
|
||||
if ( ext::json::isArray( metadata["system"]["physics"]["clamp"]["y"] ) ) {
|
||||
auto previous = transform.position.y;
|
||||
transform.position.y = std::clamp( transform.position.y, metadata["system"]["physics"]["clamp"]["y"][0].as<float>(), metadata["system"]["physics"]["clamp"]["y"][1].as<float>() );
|
||||
if ( transform.position.y > previous ) {
|
||||
physics.linear.velocity.y = 0;
|
||||
stats.floored = true;
|
||||
}
|
||||
}
|
||||
if ( ext::json::isArray( metadata["system"]["physics"]["clamp"]["z"] ) ) {
|
||||
transform.position.z = std::clamp( transform.position.z, metadata["system"]["physics"]["clamp"]["z"][0].as<float>(), metadata["system"]["physics"]["clamp"]["z"][1].as<float>() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( metadata["system"]["control"].as<bool>() ) {
|
||||
if ( stats.floored ) {
|
||||
pod::Transform<> translator = transform;
|
||||
if ( ext::openvr::context ) {
|
||||
bool useController = true;
|
||||
translator.orientation = uf::quaternion::multiply( transform.orientation * pod::Vector4f{1,1,1,1}, useController ? (ext::openvr::controllerQuaternion( vr::Controller_Hand::Hand_Right ) * pod::Vector4f{1,1,1,1}) : ext::openvr::hmdQuaternion() );
|
||||
translator = uf::transform::reorient( translator );
|
||||
|
||||
translator.forward *= { 1, 0, 1 };
|
||||
translator.right *= { 1, 0, 1 };
|
||||
|
||||
translator.forward = uf::vector::normalize( translator.forward );
|
||||
translator.right = uf::vector::normalize( translator.right );
|
||||
}
|
||||
if ( keys.forward || keys.backwards ) {
|
||||
int polarity = keys.forward ? 1 : -1;
|
||||
float mag = uf::vector::magnitude(physics.linear.velocity * pod::Vector3{1, 0, 1});
|
||||
if ( mag < speed.limitSquared ) {
|
||||
physics.linear.velocity += translator.forward * speed.move * polarity;
|
||||
mag = uf::vector::magnitude(physics.linear.velocity);
|
||||
} else mag = speed.limitSquared;
|
||||
pod::Vector3 correction = translator.forward * sqrt(mag) * polarity;
|
||||
if ( stats.impulse ) {
|
||||
physics.linear.velocity.x = correction.x;
|
||||
physics.linear.velocity.z = correction.z;
|
||||
} else {
|
||||
correction *= uf::physics::time::delta;
|
||||
transform.position.x += correction.x;
|
||||
transform.position.z += correction.z;
|
||||
}
|
||||
stats.updateCamera = (stats.walking = true);
|
||||
}
|
||||
if ( keys.left || keys.right ) {
|
||||
int polarity = keys.right ? 1 : -1;
|
||||
float mag = uf::vector::magnitude(physics.linear.velocity * pod::Vector3{1, 0, 1});
|
||||
if ( mag < speed.limitSquared ) {
|
||||
physics.linear.velocity += translator.right * speed.move * polarity;
|
||||
mag = uf::vector::magnitude(physics.linear.velocity);
|
||||
} else mag = speed.limitSquared;
|
||||
pod::Vector3 correction = translator.right * sqrt(mag) * polarity;
|
||||
if ( stats.impulse ) {
|
||||
physics.linear.velocity.x = correction.x;
|
||||
physics.linear.velocity.z = correction.z;
|
||||
} else {
|
||||
correction *= uf::physics::time::delta;
|
||||
transform.position.x += correction.x;
|
||||
transform.position.z += correction.z;
|
||||
}
|
||||
stats.updateCamera = (stats.walking = true);
|
||||
}
|
||||
if ( keys.jump ) {
|
||||
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
|
||||
if ( metadata["system"]["physics"]["jump"][0].as<float>() != 0 ) transform.position.x += metadata["system"]["physics"]["jump"][0].as<float>() * uf::physics::time::delta;
|
||||
if ( metadata["system"]["physics"]["jump"][1].as<float>() != 0 ) transform.position.y += metadata["system"]["physics"]["jump"][1].as<float>() * uf::physics::time::delta;
|
||||
if ( metadata["system"]["physics"]["jump"][2].as<float>() != 0 ) transform.position.z += metadata["system"]["physics"]["jump"][2].as<float>() * uf::physics::time::delta;
|
||||
} else {
|
||||
if ( metadata["system"]["physics"]["jump"][0].as<float>() != 0 ) physics.linear.velocity.x = metadata["system"]["physics"]["jump"][0].as<float>();
|
||||
if ( metadata["system"]["physics"]["jump"][1].as<float>() != 0 ) physics.linear.velocity.y = metadata["system"]["physics"]["jump"][1].as<float>();
|
||||
if ( metadata["system"]["physics"]["jump"][2].as<float>() != 0 ) physics.linear.velocity.z = metadata["system"]["physics"]["jump"][2].as<float>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( keys.lookLeft ) {
|
||||
uf::transform::rotate( transform, transform.up, -speed.rotate ), stats.updateCamera = true;
|
||||
}
|
||||
if ( keys.lookRight ) {
|
||||
uf::transform::rotate( transform, transform.up, speed.rotate ), stats.updateCamera = true;
|
||||
}
|
||||
|
||||
if ( keys.crouch ) {
|
||||
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
|
||||
if ( metadata["system"]["physics"]["jump"][0].as<float>() != 0 ) transform.position.x -= metadata["system"]["physics"]["jump"][0].as<float>() * uf::physics::time::delta;
|
||||
if ( metadata["system"]["physics"]["jump"][1].as<float>() != 0 ) transform.position.y -= metadata["system"]["physics"]["jump"][1].as<float>() * uf::physics::time::delta;
|
||||
if ( metadata["system"]["physics"]["jump"][2].as<float>() != 0 ) transform.position.z -= metadata["system"]["physics"]["jump"][2].as<float>() * uf::physics::time::delta;
|
||||
} else {
|
||||
if ( !metadata["system"]["crouching"].as<bool>() ) stats.deltaCrouch = true;
|
||||
metadata["system"]["crouching"] = true;
|
||||
}
|
||||
} else {
|
||||
if ( metadata["system"]["crouching"].as<bool>() ) stats.deltaCrouch = true;
|
||||
metadata["system"]["crouching"] = false;
|
||||
}
|
||||
}
|
||||
if ( stats.deltaCrouch ) {
|
||||
float delta = metadata["system"]["physics"]["crouch"].as<float>();
|
||||
if ( metadata["system"]["crouching"].as<bool>() ) camera.getTransform().position.y -= delta;
|
||||
else camera.getTransform().position.y += delta;
|
||||
stats.updateCamera = true;
|
||||
}
|
||||
|
||||
if ( stats.floored ) {
|
||||
if ( stats.walking ) {
|
||||
uf::SoundEmitter& emitter = this->getComponent<uf::SoundEmitter>();
|
||||
int cycle = rand() % metadata["audio"]["footstep"]["list"].size();
|
||||
std::string filename = metadata["audio"]["footstep"]["list"][cycle].as<std::string>();
|
||||
uf::Audio& footstep = emitter.add(filename);
|
||||
|
||||
bool playing = false;
|
||||
for ( uint i = 0; i < metadata["audio"]["footstep"]["list"].size(); ++i ) {
|
||||
uf::Audio& audio = emitter.add(metadata["audio"]["footstep"]["list"][i].as<std::string>());
|
||||
if ( audio.playing() ) playing = true;
|
||||
}
|
||||
if ( !playing ) {
|
||||
footstep.play();
|
||||
footstep.setVolume(metadata["audio"]["footstep"]["volume"].as<float>());
|
||||
footstep.setPosition( transform.position );
|
||||
|
||||
// [0, 1]
|
||||
float modulation = (rand() % 100) / 100.0;
|
||||
// [0, 0.1]
|
||||
modulation *= 0.1f;
|
||||
// [-0.05, 0.05]
|
||||
modulation -= 0.05f;
|
||||
if ( keys.running ) modulation += 0.5f;
|
||||
footstep.setPitch(1 + modulation);
|
||||
}
|
||||
// set animation to walk
|
||||
stats.targetAnimation = "walk";
|
||||
} else if ( !keys.jump ) {
|
||||
physics.linear.velocity.x = 0;
|
||||
physics.linear.velocity.y = 0;
|
||||
physics.linear.velocity.z = 0;
|
||||
stats.targetAnimation = "idle_wank";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !UF_ENV_DREAMCAST
|
||||
// set animation to idle
|
||||
if ( stats.targetAnimation != "" ) {
|
||||
auto* playerModel = this->findByName("Player: Model");
|
||||
@ -796,54 +651,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
{
|
||||
auto flatten = uf::transform::flatten( transform );
|
||||
static pod::Quaternion<> storedCameraOrientation = transform.orientation;
|
||||
|
||||
const pod::Quaternion<> prevCameraOrientation = storedCameraOrientation;
|
||||
const pod::Quaternion<> curCameraOrientation = transform.orientation;
|
||||
const pod::Quaternion<> deltaOrientation = uf::quaternion::multiply( curCameraOrientation, uf::quaternion::inverse( prevCameraOrientation ) ) ;
|
||||
const pod::Vector3f deltaAngles = uf::quaternion::eulerAngles( deltaOrientation );
|
||||
float magnitude = uf::vector::magnitude( deltaOrientation );
|
||||
if ( magnitude > 0.0001f ) {
|
||||
uf::Serializer payload;
|
||||
payload["previous"] = uf::vector::encode( prevCameraOrientation );
|
||||
payload["current"] = uf::vector::encode( curCameraOrientation );
|
||||
payload["delta"] = uf::vector::encode( deltaOrientation );
|
||||
payload["euler"] = uf::vector::encode( deltaAngles );
|
||||
payload["angle"]["pitch"] = deltaAngles.x;
|
||||
payload["angle"]["yaw"] = deltaAngles.y;
|
||||
payload["angle"]["roll"] = deltaAngles.z;
|
||||
payload["magnitude"] = magnitude;
|
||||
this->callHook("controller:Camera.Rotated", payload);
|
||||
}
|
||||
storedCameraOrientation = transform.orientation;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
// translate movement in HMD to give HUD feedback
|
||||
if ( ext::openvr::context ) {
|
||||
static pod::Quaternion<> prevCameraOrientation = ext::openvr::hmdQuaternion();
|
||||
const pod::Quaternion<> curCameraOrientation = ext::openvr::hmdQuaternion();
|
||||
const pod::Vector3f prevEulerAngle = uf::quaternion::eulerAngles( prevCameraOrientation );
|
||||
const pod::Vector3f curEulerAngle = uf::quaternion::eulerAngles( curCameraOrientation );
|
||||
const pod::Vector3f deltaAngles = uf::vector::subtract( curEulerAngle, prevEulerAngle );
|
||||
float magnitude = uf::vector::magnitude( deltaAngles );
|
||||
if ( magnitude > 0.0001f ) {
|
||||
uf::Serializer payload;
|
||||
payload["previous"] = uf::vector::encode( prevCameraOrientation );
|
||||
payload["current"] = uf::vector::encode( curCameraOrientation );
|
||||
payload["euler"] = uf::vector::encode( deltaAngles );
|
||||
payload["angle"]["pitch"] = deltaAngles.x;
|
||||
payload["angle"]["yaw"] = deltaAngles.y;
|
||||
payload["angle"]["roll"] = deltaAngles.z;
|
||||
payload["magnitude"] = magnitude;
|
||||
this->callHook("controller:Camera.Rotated", payload);
|
||||
}
|
||||
prevCameraOrientation = curCameraOrientation;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
#if UF_USE_LUA
|
||||
#define TRACK_ORIENTATION(ORIENTATION) {\
|
||||
static pod::Quaternion<> storedCameraOrientation = ORIENTATION;\
|
||||
const pod::Quaternion<> prevCameraOrientation = storedCameraOrientation;\
|
||||
@ -854,7 +663,6 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
combinedDeltaOrientation = uf::quaternion::multiply( deltaOrientation, combinedDeltaOrientation );\
|
||||
storedCameraOrientation = ORIENTATION;\
|
||||
}
|
||||
|
||||
{
|
||||
pod::Quaternion<> combinedDeltaOrientation = {0,0,0,1};
|
||||
pod::Vector3f combinedDeltaAngles = {};
|
||||
@ -871,10 +679,29 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
|
||||
this->callHook("controller:Camera.Rotated", payload);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ( stats.updateCamera ) camera.updateView();
|
||||
|
||||
|
||||
if ( stats.updateCamera )
|
||||
camera.updateView();
|
||||
#if UF_ENTITY_METADATA_USE_JSON
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
auto& metadataSystem = metadataJson["system"]
|
||||
metadataSystem["menu"] = metadata.system.menu;
|
||||
metadataSystem["control"] = metadata.system.control;
|
||||
metadataSystem["crouching"] = metadata.system.crouching;
|
||||
metadataSystem["noclipped"] = metadata.system.noclipped;
|
||||
auto& metadataSystemPhysics = metadataSystem["physics"]
|
||||
metadataSystemPhysics["impulse"] = metadata.system.physics.impulse;
|
||||
metadataSystemPhysics["rotate"] = metadata.system.physics.rotate;
|
||||
metadataSystemPhysics["move"] = metadata.system.physics.move;
|
||||
metadataSystemPhysics["run"] = metadata.system.physics.run;
|
||||
metadataSystemPhysics["walk"] = metadata.system.physics.walk;
|
||||
metadataSystemPhysics["collision"] = metadata.system.physics.collision;
|
||||
metadataSystemPhysics["jump"] = uf::vector::encode(metadata.system.physics.jump);
|
||||
metadataSystemPhysics["crouch"] = metadata.system.physics.crouch;
|
||||
auto& metadataAudioFootstep = metadata["audio"]["footstep"];
|
||||
metadataAudioFootstep["list"] = metadata.audio.footstep.list;
|
||||
metadataAudioFootstep["volume"] = metadata.audio.footstep.volume
|
||||
#endif
|
||||
}
|
||||
|
||||
void ext::PlayerBehavior::render( uf::Object& self ){}
|
||||
|
@ -4,14 +4,39 @@
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/utils/math/vector.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API PlayerBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace PlayerBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
struct Metadata {
|
||||
struct {
|
||||
struct {
|
||||
bool collision = true;
|
||||
bool impulse = true;
|
||||
float crouch = -1.0f;
|
||||
float rotate = 1.0f;
|
||||
float move = 1.0f;
|
||||
float run = 1.0f;
|
||||
float walk = 1.0f;
|
||||
pod::Vector3f jump = {0,8,0};
|
||||
} physics;
|
||||
bool control = true;
|
||||
std::string menu = "";
|
||||
bool crouching = false;
|
||||
bool noclipped = false;
|
||||
} system;
|
||||
struct {
|
||||
struct {
|
||||
std::vector<std::string> list;
|
||||
float volume;
|
||||
} footstep;
|
||||
} audio;
|
||||
};
|
||||
}
|
||||
}
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API PlayerModelBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace PlayerModelBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "behavior.h"
|
||||
|
||||
#include <uf/utils/graphic/mesh.h>
|
||||
@ -162,4 +163,5 @@ void ext::PortalBehavior::destroy( uf::Object& self ){
|
||||
uf::renderer::removeRenderMode( &renderMode, false );
|
||||
this->deleteComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
}
|
||||
#undef this
|
||||
#undef this
|
||||
#endif
|
@ -6,20 +6,20 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API PortalsBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
class EXT_API PortalBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace PortalsBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
namespace PortalBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <uf/utils/math/collision.h>
|
||||
|
||||
#include "../light/behavior.h"
|
||||
#include "../../ext.h"
|
||||
#include "../../gui/gui.h"
|
||||
|
||||
@ -29,7 +30,7 @@ UF_BEHAVIOR_REGISTER_CPP(ext::ExtSceneBehavior)
|
||||
#define this ((uf::Scene*) &self)
|
||||
void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Serializer& metadataJson = this->getComponent<uf::Serializer>();
|
||||
|
||||
this->addHook( "system:Quit.%UID%", [&](ext::json::Value& json){
|
||||
std::cout << json << std::endl;
|
||||
@ -38,21 +39,19 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
this->addHook( "world:Music.LoadPrevious.%UID%", [&](ext::json::Value& json){
|
||||
|
||||
if ( metadata["previous bgm"]["filename"] == "" ) return;
|
||||
if ( metadataJson["previous bgm"]["filename"] == "" ) return;
|
||||
|
||||
std::string filename = metadata["previous bgm"]["filename"].as<std::string>();
|
||||
float timestamp = metadata["previous bgm"]["timestamp"].as<float>();
|
||||
|
||||
// std::cout << metadata["previous bgm"] << std::endl;
|
||||
std::string filename = metadataJson["previous bgm"]["filename"].as<std::string>();
|
||||
float timestamp = metadataJson["previous bgm"]["timestamp"].as<float>();
|
||||
|
||||
uf::Audio& audio = this->getComponent<uf::Audio>();
|
||||
if ( audio.playing() ) {
|
||||
metadata["previous bgm"]["filename"] = audio.getFilename();
|
||||
metadata["previous bgm"]["timestamp"] = audio.getTime();
|
||||
metadataJson["previous bgm"]["filename"] = audio.getFilename();
|
||||
metadataJson["previous bgm"]["timestamp"] = audio.getTime();
|
||||
audio.stop();
|
||||
}
|
||||
audio.load(filename);
|
||||
audio.setVolume(metadata["volumes"]["bgm"].as<float>());
|
||||
audio.setVolume(metadataJson["volumes"]["bgm"].as<float>());
|
||||
audio.setTime(timestamp);
|
||||
audio.play();
|
||||
});
|
||||
@ -70,7 +69,7 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
if ( audio.playing() ) audio.stop();
|
||||
|
||||
audio.load(filename);
|
||||
audio.setVolume(metadata["volumes"]["bgm"].as<float>());
|
||||
audio.setVolume(metadataJson["volumes"]["bgm"].as<float>());
|
||||
audio.play();
|
||||
});
|
||||
|
||||
@ -83,12 +82,12 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
uf::Object* manager = (uf::Object*) this->globalFindByName("Gui Manager");
|
||||
if ( !manager ) return;
|
||||
uf::Serializer payload;
|
||||
std::string config = metadata["menus"]["pause"].is<std::string>() ? metadata["menus"]["pause"].as<std::string>() : "/scenes/worldscape/gui/pause/menu.json";
|
||||
std::string config = metadataJson["menus"]["pause"].is<std::string>() ? metadataJson["menus"]["pause"].as<std::string>() : "/scenes/worldscape/gui/pause/menu.json";
|
||||
uf::Object& gui = manager->loadChild(config, false);
|
||||
payload["uid"] = gui.getUid();
|
||||
|
||||
uf::Serializer& metadata = gui.getComponent<uf::Serializer>();
|
||||
metadata["menu"] = json["menu"];
|
||||
uf::Serializer& metadataJson = gui.getComponent<uf::Serializer>();
|
||||
metadataJson["menu"] = json["menu"];
|
||||
|
||||
gui.initialize();
|
||||
// return payload;
|
||||
@ -101,27 +100,20 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
});
|
||||
this->addHook( "shader:Update.%UID%", [&](ext::json::Value& _json){
|
||||
uf::Serializer json = _json;
|
||||
json["mode"] = json["mode"].as<size_t>() | metadata["system"]["renderer"]["shader"]["mode"].as<size_t>();
|
||||
metadata["system"]["renderer"]["shader"]["mode"] = json["mode"];
|
||||
metadata["system"]["renderer"]["shader"]["parameters"] = json["parameters"];
|
||||
json["mode"] = json["mode"].as<size_t>() | metadataJson["system"]["renderer"]["shader"]["mode"].as<size_t>();
|
||||
metadataJson["system"]["renderer"]["shader"]["mode"] = json["mode"];
|
||||
metadataJson["system"]["renderer"]["shader"]["parameters"] = json["parameters"];
|
||||
});
|
||||
/* store viewport size */ {
|
||||
// metadata["system"]["window"]["size"]["x"] = uf::renderer::settings::width;
|
||||
// metadata["system"]["window"]["size"]["y"] = uf::renderer::settings::height;
|
||||
// ext::gui::size.current.x = uf::renderer::settings::width;
|
||||
// ext::gui::size.current.y = uf::renderer::settings::height;
|
||||
|
||||
this->addHook( "window:Resized", [&](ext::json::Value& json){
|
||||
pod::Vector2ui size; {
|
||||
size.x = json["window"]["size"]["x"].as<size_t>();
|
||||
size.y = json["window"]["size"]["y"].as<size_t>();
|
||||
}
|
||||
|
||||
metadata["system"]["window"] = json["system"]["window"];
|
||||
ext::gui::size.current = size;
|
||||
});
|
||||
}
|
||||
/* store viewport size */
|
||||
this->addHook( "window:Resized", [&](ext::json::Value& json){
|
||||
pod::Vector2ui size; {
|
||||
size.x = json["window"]["size"]["x"].as<size_t>();
|
||||
size.y = json["window"]["size"]["y"].as<size_t>();
|
||||
}
|
||||
|
||||
metadataJson["system"]["window"] = json["system"]["window"];
|
||||
ext::gui::size.current = size;
|
||||
});
|
||||
// lock control
|
||||
{
|
||||
uf::Serializer payload;
|
||||
@ -141,14 +133,13 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
};
|
||||
|
||||
auto& noiseGenerator = this->getComponent<uf::PerlinNoise>();
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
noiseGenerator.seed(rand());
|
||||
|
||||
float high = std::numeric_limits<float>::min();
|
||||
float low = std::numeric_limits<float>::max();
|
||||
float amplitude = metadata["noise"]["amplitude"].is<float>() ? metadata["noise"]["amplitude"].as<float>() : 1.5;
|
||||
pod::Vector3ui size = uf::vector::decode(metadata["noise"]["size"], pod::Vector3ui{256, 256, 256});
|
||||
pod::Vector3d coefficients = uf::vector::decode(metadata["noise"]["coefficients"], pod::Vector3d{3.0, 3.0, 3.0});
|
||||
float amplitude = metadataJson["noise"]["amplitude"].is<float>() ? metadataJson["noise"]["amplitude"].as<float>() : 1.5;
|
||||
pod::Vector3ui size = uf::vector::decode(metadataJson["noise"]["size"], pod::Vector3ui{256, 256, 256});
|
||||
pod::Vector3d coefficients = uf::vector::decode(metadataJson["noise"]["coefficients"], pod::Vector3d{3.0, 3.0, 3.0});
|
||||
|
||||
std::vector<uint8_t> pixels(size.x * size.y * size.z);
|
||||
std::vector<float> perlins(size.x * size.y * size.z);
|
||||
@ -211,36 +202,31 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
texture.fromBuffers( (void*) pixels.data(), pixels.size(), uf::renderer::enums::Format::R8G8B8A8_UNORM, size.x, size.y, 1, filenames.size() );
|
||||
}
|
||||
#endif
|
||||
|
||||
auto& metadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
|
||||
metadata.max.textures = metadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>();
|
||||
metadata.max.lights = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>();
|
||||
metadata.light.enabled = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["enabled"].as<bool>() && metadataJson["light"]["should"].as<bool>();
|
||||
metadata.light.shadowSamples = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["shadow samples"].as<size_t>();
|
||||
metadata.light.shadowThreshold = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["shadow threshold"].as<size_t>();
|
||||
metadata.light.updateThreshold = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["update threshold"].as<size_t>();
|
||||
metadata.light.ambient = uf::vector::decode( metadataJson["light"]["ambient"], pod::Vector4f{ 1, 1, 1, 1 } );
|
||||
metadata.light.specular = uf::vector::decode( metadataJson["light"]["specular"], pod::Vector4f{ 1, 1, 1, 1 } );
|
||||
metadata.fog.color = uf::vector::decode( metadataJson["light"]["fog"]["color"], pod::Vector3f{ 1, 1, 1 } );
|
||||
metadata.fog.stepScale = metadataJson["light"]["fog"]["step scale"].as<float>();
|
||||
metadata.fog.absorbtion = metadataJson["light"]["fog"]["absorbtion"].as<float>();
|
||||
metadata.fog.range = uf::vector::decode( metadataJson["light"]["fog"]["range"], pod::Vector2f{ 0, 0 } );
|
||||
metadata.fog.density.offset = uf::vector::decode( metadataJson["light"]["fog"]["density"]["offset"], pod::Vector4f{ 0, 0, 0, 0 } );
|
||||
metadata.fog.density.timescale = metadataJson["light"]["fog"]["density"]["timescale"].as<float>();
|
||||
metadata.fog.density.threshold = metadataJson["light"]["fog"]["density"]["threshold"].as<float>();
|
||||
metadata.fog.density.multiplier = metadataJson["light"]["fog"]["density"]["multiplier"].as<float>();
|
||||
metadata.fog.density.scale = metadataJson["light"]["fog"]["density"]["scale"].as<float>();
|
||||
}
|
||||
void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
/* check if audio needs to loop */ {
|
||||
auto& bgm = this->getComponent<uf::Audio>();
|
||||
float current = bgm.getTime();
|
||||
float end = bgm.getDuration();
|
||||
float epsilon = 0.005f;
|
||||
if ( current + epsilon >= end || !bgm.playing() ) {
|
||||
// intro to main transition
|
||||
std::string filename = bgm.getFilename();
|
||||
filename = assetLoader.getOriginal(filename);
|
||||
if ( filename.find("_intro") != std::string::npos ) {
|
||||
assetLoader.load(uf::string::replace( filename, "_intro", "" ), this->formatHookName("asset:Load.%UID%"));
|
||||
// loop
|
||||
} else {
|
||||
bgm.setTime(0);
|
||||
if ( !bgm.playing() ) bgm.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
uf::hooks.call("game:Frame.Start");
|
||||
}
|
||||
|
||||
auto& metadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
/* Regain control if nothing requests it */ {
|
||||
uf::Object* menu = (uf::Object*) this->globalFindByName("Gui: Menu");
|
||||
if ( !menu ) {
|
||||
if ( !this->globalFindByName("Gui: Menu") ) {
|
||||
uf::Serializer payload;
|
||||
payload["state"] = false;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
@ -251,7 +237,11 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
uf::hooks.call("game:Frame.Start");
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
/* Print World Tree */ {
|
||||
TIMER(1, uf::Window::isKeyPressed("U") && ) {
|
||||
std::function<void(uf::Entity*, int)> filter = []( uf::Entity* entity, int indent ) {
|
||||
@ -301,7 +291,27 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
uf::iostream << instantiator << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#if UF_USE_OPENAL
|
||||
auto& assetLoader = this->getComponent<uf::Asset>();
|
||||
/* check if audio needs to loop */ {
|
||||
auto& bgm = this->getComponent<uf::Audio>();
|
||||
float current = bgm.getTime();
|
||||
float end = bgm.getDuration();
|
||||
float epsilon = 0.005f;
|
||||
if ( current + epsilon >= end || !bgm.playing() ) {
|
||||
// intro to main transition
|
||||
std::string filename = bgm.getFilename();
|
||||
filename = assetLoader.getOriginal(filename);
|
||||
if ( filename.find("_intro") != std::string::npos ) {
|
||||
assetLoader.load(uf::string::replace( filename, "_intro", "" ), this->formatHookName("asset:Load.%UID%"));
|
||||
// loop
|
||||
} else {
|
||||
bgm.setTime(0);
|
||||
if ( !bgm.playing() ) bgm.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Updates Sound Listener */ {
|
||||
auto& controller = this->getController();
|
||||
// copy
|
||||
@ -312,15 +322,40 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
transform = uf::transform::reorient( transform );
|
||||
}
|
||||
transform.forward *= -1;
|
||||
#if UF_USE_OPENAL
|
||||
ext::oal.listener( "POSITION", { transform.position.x, transform.position.y, transform.position.z } );
|
||||
ext::oal.listener( "VELOCITY", { 0, 0, 0 } );
|
||||
ext::oal.listener( "ORIENTATION", { transform.forward.x, transform.forward.y, transform.forward.z, transform.up.x, transform.up.y, transform.up.z } );
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UF_USE_VULKAN
|
||||
/* Update lights */ if ( metadata["light"]["should"].as<bool>() ) {
|
||||
#if UF_ENTITY_METADATA_USE_JSON
|
||||
metadata.max.textures = metadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>();
|
||||
metadata.max.lights = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>();
|
||||
metadata.light.enabled = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["enabled"].as<bool>() && metadataJson["light"]["should"].as<bool>();
|
||||
metadata.light.shadowSamples = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["shadow samples"].as<size_t>();
|
||||
metadata.light.shadowThreshold = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["shadow threshold"].as<size_t>();
|
||||
metadata.light.updateThreshold = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["update threshold"].as<size_t>();
|
||||
metadata.light.ambient = uf::vector::decode( metadataJson["light"]["ambient"], pod::Vector4f{ 1, 1, 1, 1 } );
|
||||
metadata.light.specular = uf::vector::decode( metadataJson["light"]["specular"], pod::Vector4f{ 1, 1, 1, 1 } );
|
||||
metadata.fog.color = uf::vector::decode( metadataJson["light"]["fog"]["color"], pod::Vector3f{ 1, 1, 1 } );
|
||||
metadata.fog.stepScale = metadataJson["light"]["fog"]["step scale"].as<float>();
|
||||
metadata.fog.absorbtion = metadataJson["light"]["fog"]["absorbtion"].as<float>();
|
||||
metadata.fog.range = uf::vector::decode( metadataJson["light"]["fog"]["range"], pod::Vector2f{ 0, 0 } );
|
||||
metadata.fog.density.offset = uf::vector::decode( metadataJson["light"]["fog"]["density"]["offset"], pod::Vector4f{ 0, 0, 0, 0 } );
|
||||
metadata.fog.density.timescale = metadataJson["light"]["fog"]["density"]["timescale"].as<float>();
|
||||
metadata.fog.density.threshold = metadataJson["light"]["fog"]["density"]["threshold"].as<float>();
|
||||
metadata.fog.density.multiplier = metadataJson["light"]["fog"]["density"]["multiplier"].as<float>();
|
||||
metadata.fog.density.scale = metadataJson["light"]["fog"]["density"]["scale"].as<float>();
|
||||
#else
|
||||
if ( !metadata.max.textures ) metadata.max.textures = metadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>();
|
||||
if ( !metadata.max.lights ) metadata.max.lights = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>();
|
||||
if ( !metadata.light.enabled ) metadata.light.enabled = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["enabled"].as<bool>() && metadataJson["light"]["should"].as<bool>();
|
||||
if ( !metadata.light.shadowSamples ) metadata.light.shadowSamples = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["shadow samples"].as<size_t>();
|
||||
if ( !metadata.light.shadowThreshold ) metadata.light.shadowThreshold = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["shadow threshold"].as<size_t>();
|
||||
if ( !metadata.light.updateThreshold ) metadata.light.updateThreshold = metadataJson["system"]["config"]["engine"]["scenes"]["lights"]["update threshold"].as<size_t>();
|
||||
#endif
|
||||
|
||||
/* Update lights */ if ( metadata.light.enabled ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
@ -329,8 +364,79 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
auto& controllerTransform = controller.getComponent<pod::Transform<>>();
|
||||
std::vector<uf::Graphic*> blitters = renderMode.getBlitters();
|
||||
|
||||
size_t maxTextures = metadata["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>();
|
||||
#if UF_USE_OPENGL
|
||||
struct LightInfo {
|
||||
uf::Entity* entity = NULL;
|
||||
pod::Vector4f position = {0,0,0,1};
|
||||
pod::Vector4f color = {0,0,0,1};
|
||||
float distance = 0;
|
||||
float power = 0;
|
||||
};
|
||||
std::vector<LightInfo> entities;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( entity == &controller || entity == this ) continue;
|
||||
if ( entity->getName() != "Light" && !entity->hasComponent<ext::LightBehavior::Metadata>() ) continue;
|
||||
auto& metadata = entity->getComponent<ext::LightBehavior::Metadata>();
|
||||
if ( metadata.power <= 0 ) continue;
|
||||
LightInfo& info = entities.emplace_back();
|
||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||
auto flatten = uf::transform::flatten( transform );
|
||||
info.entity = entity;
|
||||
info.position = flatten.position;
|
||||
info.position.w = 1;
|
||||
info.color = metadata.color;
|
||||
info.color.w = 1;
|
||||
info.distance = uf::vector::magnitude( uf::vector::subtract( flatten.position, controllerTransform.position ) );
|
||||
info.power = metadata.power;
|
||||
}
|
||||
} else {
|
||||
this->process([&]( uf::Entity* entity ) { if ( !entity ) return;
|
||||
if ( entity == &controller || entity == this ) return;
|
||||
if ( entity->getName() != "Light" && !entity->hasComponent<ext::LightBehavior::Metadata>() ) return;
|
||||
auto& metadata = entity->getComponent<ext::LightBehavior::Metadata>();
|
||||
if ( metadata.power <= 0 ) return;
|
||||
LightInfo& info = entities.emplace_back();
|
||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||
auto flatten = uf::transform::flatten( transform );
|
||||
info.entity = entity;
|
||||
info.position = flatten.position;
|
||||
info.position.w = 1;
|
||||
info.color = metadata.color;
|
||||
info.color.w = 1;
|
||||
info.distance = uf::vector::magnitude( uf::vector::subtract( flatten.position, controllerTransform.position ) );
|
||||
info.power = metadata.power;
|
||||
});
|
||||
}
|
||||
std::sort( entities.begin(), entities.end(), [&]( LightInfo& l, LightInfo& r ){
|
||||
return l.distance < r.distance;
|
||||
});
|
||||
|
||||
static GLint glMaxLights = 0;
|
||||
if ( !glMaxLights ) glGetIntegerv(GL_MAX_LIGHTS, &glMaxLights);
|
||||
metadata.max.lights = std::min( (size_t) glMaxLights, metadata.max.lights );
|
||||
|
||||
// add lighting
|
||||
{
|
||||
size_t i = 0;
|
||||
for ( ; i < entities.size() && i < metadata.max.lights; ++i ) {
|
||||
auto& info = entities[i];
|
||||
uf::Entity* entity = info.entity;
|
||||
GLenum target = GL_LIGHT0+i;
|
||||
GL_ERROR_CHECK(glEnable(target));
|
||||
GL_ERROR_CHECK(glLightfv(target, GL_AMBIENT, &metadata.light.ambient[0]));
|
||||
GL_ERROR_CHECK(glLightfv(target, GL_SPECULAR, &metadata.light.specular[0]));
|
||||
GL_ERROR_CHECK(glLightfv(target, GL_DIFFUSE, &info.color[0]));
|
||||
GL_ERROR_CHECK(glLightfv(target, GL_POSITION, &info.position[0]));
|
||||
GL_ERROR_CHECK(glLightf(target, GL_CONSTANT_ATTENUATION, 0.0f));
|
||||
GL_ERROR_CHECK(glLightf(target, GL_LINEAR_ATTENUATION, 0));
|
||||
GL_ERROR_CHECK(glLightf(target, GL_QUADRATIC_ATTENUATION, 1.0f / info.power));
|
||||
}
|
||||
for ( ; i < metadata.max.lights; ++i ) GL_ERROR_CHECK(glDisable(GL_LIGHT0+i));
|
||||
}
|
||||
#elif UF_USE_VULKAN
|
||||
size_t maxTextures = metadata.max.textures;
|
||||
struct UniformDescriptor {
|
||||
struct Matrices {
|
||||
alignas(16) pod::Matrix4f view[2];
|
||||
@ -378,73 +484,82 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
|
||||
struct LightInfo {
|
||||
uf::Entity* entity = NULL;
|
||||
pod::Vector4f color = {0,0,0,0};
|
||||
pod::Vector3f position = {0,0,0};
|
||||
float power = 0;
|
||||
float distance = 0;
|
||||
float bias = 0;
|
||||
bool shadows = false;
|
||||
size_t type = 0;
|
||||
};
|
||||
std::vector<LightInfo> entities;
|
||||
std::vector<pod::Graph*> graphs;
|
||||
|
||||
this->process([&]( uf::Entity* entity ) { if ( !entity ) return;
|
||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||
if ( entity == &controller ) return;
|
||||
if ( entity == this ) return;
|
||||
if ( uf::scene::useGraph ) {
|
||||
auto graph = uf::scene::generateGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( entity == &controller || entity == this ) continue;
|
||||
if ( entity->hasComponent<pod::Graph>() ) graphs.emplace_back(&entity->getComponent<pod::Graph>());
|
||||
// if ( entity->hasComponent<pod::Graph>() && entity->hasComponent<uf::Graphic>() ) graphs.emplace_back(entity);
|
||||
//
|
||||
if ( entity->getName() != "Light" && !ext::json::isObject( metadata["light"] ) ) return;
|
||||
//
|
||||
if ( entity->getName() != "Light" && !entity->hasComponent<ext::LightBehavior::Metadata>() ) continue;
|
||||
auto& metadata = entity->getComponent<ext::LightBehavior::Metadata>();
|
||||
if ( entity->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = entity->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
metadata["system"]["renderer"]["rendered"] = false;
|
||||
if ( metadata["system"]["renderer"]["mode"].as<std::string>() == "in-range" ) {
|
||||
renderMode.execute = false;
|
||||
}
|
||||
if ( metadata.renderer.mode == "in-range" ) renderMode.execute;
|
||||
}
|
||||
// is a component of an shadowing point light
|
||||
if ( metadata["light"]["bound"].as<bool>() ) return;
|
||||
if ( metadata.power <= 0 ) continue;
|
||||
LightInfo& info = entities.emplace_back();
|
||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||
auto flatten = uf::transform::flatten( transform );
|
||||
info.entity = entity;
|
||||
info.position = flatten.position;
|
||||
info.color = metadata.color;
|
||||
info.color.w = metadata.power;
|
||||
info.distance = uf::vector::magnitude( uf::vector::subtract( flatten.position, controllerTransform.position ) );
|
||||
info.shadows = metadata["light"]["shadows"].as<bool>();
|
||||
info.shadows = metadata.shadows;
|
||||
info.bias = metadata.bias;
|
||||
info.type = metadata.type;
|
||||
}
|
||||
} else {
|
||||
this->process([&]( uf::Entity* entity ) { if ( !entity ) return;
|
||||
if ( entity == &controller || entity == this ) return;
|
||||
if ( entity->hasComponent<pod::Graph>() ) graphs.emplace_back(&entity->getComponent<pod::Graph>());
|
||||
if ( entity->getName() != "Light" && !entity->hasComponent<ext::LightBehavior::Metadata>() ) return;
|
||||
auto& metadata = entity->getComponent<ext::LightBehavior::Metadata>();
|
||||
if ( entity->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = entity->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
if ( metadata.renderer.mode == "in-range" ) renderMode.execute;
|
||||
}
|
||||
if ( metadata.power <= 0 ) return;
|
||||
LightInfo& info = entities.emplace_back();
|
||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||
auto flatten = uf::transform::flatten( transform );
|
||||
info.entity = entity;
|
||||
info.position = flatten.position;
|
||||
info.color = metadata.color;
|
||||
info.color.w = metadata.power;
|
||||
info.distance = uf::vector::magnitude( uf::vector::subtract( flatten.position, controllerTransform.position ) );
|
||||
info.shadows = metadata.shadows;
|
||||
info.bias = metadata.bias;
|
||||
info.type = metadata.type;
|
||||
});
|
||||
}
|
||||
std::sort( entities.begin(), entities.end(), [&]( LightInfo& l, LightInfo& r ){
|
||||
return l.distance < r.distance;
|
||||
});
|
||||
|
||||
int shadowSamples = metadata["system"]["config"]["engine"]["scenes"]["lights"]["shadow samples"].as<size_t>();
|
||||
int& shadowSamples = metadata.light.shadowSamples;
|
||||
int& shadowThreshold = metadata.light.shadowThreshold;
|
||||
if ( shadowSamples <= 0 ) shadowSamples = 16;
|
||||
|
||||
int shadowThreshold = metadata["system"]["config"]["engine"]["scenes"]["lights"]["shadow threshold"].as<size_t>();
|
||||
if ( shadowThreshold <= 0 ) shadowThreshold = std::numeric_limits<int>::max();
|
||||
{
|
||||
std::vector<LightInfo> scratch;
|
||||
scratch.reserve(entities.size());
|
||||
for ( size_t i = 0; i < entities.size(); ++i ) {
|
||||
auto& info = entities[i];
|
||||
auto& metadata = info.entity->getComponent<uf::Serializer>();
|
||||
if ( info.shadows && --shadowThreshold <= 0 ) info.shadows = false;
|
||||
scratch.emplace_back(info);
|
||||
}
|
||||
entities = scratch;
|
||||
}
|
||||
|
||||
if ( controllerMetadata["light"]["should"].as<bool>() ) {
|
||||
auto& info = entities.emplace_back();
|
||||
info.entity = &controller;
|
||||
info.position = controllerTransform.position;
|
||||
info.distance = 0;
|
||||
info.shadows = false;
|
||||
}
|
||||
|
||||
if ( !metadata["light"]["fog"]["step scale"].is<float>() ) metadata["light"]["fog"]["step scale"] = 16.0f;
|
||||
if ( !metadata["light"]["fog"]["absorbtion"].is<float>() ) metadata["light"]["fog"]["absorbtion"] = 0.85f;
|
||||
if ( !metadata["light"]["fog"]["density"]["threshold"].is<float>() ) metadata["light"]["fog"]["density"]["threshold"] = 0.5f;
|
||||
if ( !metadata["light"]["fog"]["density"]["multiplier"].is<float>() ) metadata["light"]["fog"]["density"]["multiplier"] = 5.0f;
|
||||
if ( !metadata["light"]["fog"]["density"]["scale"].is<float>() ) metadata["light"]["fog"]["density"]["scale"] = 50.0f;
|
||||
|
||||
for ( auto* blitter : blitters ) {
|
||||
auto& graphic = *blitter;
|
||||
@ -462,38 +577,27 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
uniforms->matrices.iProjectionView[i] = uf::matrix::inverse( uniforms->matrices.projection[i] * uniforms->matrices.view[i] );
|
||||
}
|
||||
|
||||
uniforms->ambient = uf::vector::decode( metadata["light"]["ambient"], uniforms->ambient );
|
||||
uniforms->ambient = metadata.light.ambient;
|
||||
uniforms->msaa = ext::vulkan::settings::msaa;
|
||||
// uniforms->msaa = metadata["system"]["config"]["engine"]["ext"]["vulkan"]["framebuffer"]["msaa"].as<size_t>();
|
||||
uniforms->poissonSamples = shadowSamples;
|
||||
/*
|
||||
pod::Transform<> transform = controller.getComponent<pod::Transform<>>();
|
||||
if ( controller.hasComponent<uf::Camera>() ) {
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
transform.position += camera.getTransform().position;
|
||||
transform = uf::transform::reorient( transform );
|
||||
}
|
||||
uniforms->position = transform.position;
|
||||
*/
|
||||
|
||||
uniforms->fog.color = uf::vector::decode( metadata["light"]["fog"]["color"], uniforms->fog.color );
|
||||
uniforms->fog.color.w = metadata["light"]["fog"]["step scale"].as<float>();
|
||||
uniforms->fog.color = metadata.fog.color;
|
||||
uniforms->fog.color.w = metadata.fog.stepScale;
|
||||
|
||||
float timescale = metadata["light"]["fog"]["density"]["timescale"].as<float>();
|
||||
uniforms->fog.offset = uf::vector::decode( metadata["light"]["fog"]["density"]["offset"], uniforms->fog.offset ) * uf::physics::time::current * timescale;
|
||||
uniforms->fog.offset.w = metadata["light"]["fog"]["density"]["scale"].as<float>();
|
||||
float timescale = metadata.fog.density.timescale;
|
||||
uniforms->fog.offset = metadata.fog.density.offset * uf::physics::time::current * timescale;
|
||||
uniforms->fog.offset.w = metadata.fog.density.scale;
|
||||
|
||||
uniforms->fog.densityThreshold = metadata["light"]["fog"]["density"]["threshold"].as<float>();
|
||||
uniforms->fog.densityMultiplier = metadata["light"]["fog"]["density"]["multiplier"].as<float>();
|
||||
uniforms->fog.absorbtion = metadata["light"]["fog"]["absorbtion"].as<float>();
|
||||
uniforms->fog.densityThreshold = metadata.fog.density.threshold;
|
||||
uniforms->fog.densityMultiplier = metadata.fog.density.multiplier;
|
||||
uniforms->fog.absorbtion = metadata.fog.absorbtion;
|
||||
|
||||
uniforms->fog.range = uf::vector::decode( metadata["light"]["fog"]["range"], uniforms->fog.range );
|
||||
uniforms->fog.range = metadata.fog.range;
|
||||
|
||||
uniforms->mode.type.x = metadata["system"]["renderer"]["shader"]["mode"].as<size_t>();
|
||||
uniforms->mode.type.y = metadata["system"]["renderer"]["shader"]["scalar"].as<size_t>();
|
||||
|
||||
uniforms->mode.parameters = uf::vector::decode( metadata["system"]["renderer"]["shader"]["parameters"], uniforms->mode.parameters );
|
||||
if ( metadata["system"]["renderer"]["shader"]["parameters"][3].as<std::string>() == "time" ) {
|
||||
uniforms->mode.type.x = metadataJson["system"]["renderer"]["shader"]["mode"].as<size_t>();
|
||||
uniforms->mode.type.y = metadataJson["system"]["renderer"]["shader"]["scalar"].as<size_t>();
|
||||
uniforms->mode.parameters = uf::vector::decode( metadataJson["system"]["renderer"]["shader"]["parameters"], uniforms->mode.parameters );
|
||||
if ( metadataJson["system"]["renderer"]["shader"]["parameters"][3].as<std::string>() == "time" ) {
|
||||
uniforms->mode.parameters.w = uf::physics::time::current;
|
||||
}
|
||||
|
||||
@ -501,16 +605,14 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
for ( auto& texture : graphic.material.textures ) previousTextures.emplace_back(texture.image);
|
||||
|
||||
graphic.material.textures.clear();
|
||||
// add noise texture
|
||||
graphic.material.textures.emplace_back().aliasTexture(this->getComponent<uf::renderer::Texture3D>());
|
||||
graphic.material.textures.emplace_back().aliasTexture(this->getComponent<uf::renderer::TextureCube>());
|
||||
|
||||
size_t updateThreshold = metadata["system"]["config"]["engine"]["scenes"]["lights"]["update threshold"].as<size_t>();
|
||||
size_t maxLights = metadata["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>();
|
||||
size_t& updateThreshold = metadata.light.updateThreshold;
|
||||
size_t textureSlot = 0;
|
||||
|
||||
std::vector<pod::Light::Storage> lights;
|
||||
lights.reserve( maxLights );
|
||||
lights.reserve( metadata.max.lights );
|
||||
|
||||
std::vector<pod::Material::Storage> materials;
|
||||
materials.reserve(maxTextures);
|
||||
@ -523,64 +625,53 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
drawCalls.reserve(maxTextures);
|
||||
|
||||
// add materials
|
||||
{
|
||||
for ( auto* entity : graphs ) {
|
||||
auto& graph = *entity;
|
||||
for ( auto* entity : graphs ) {
|
||||
auto& graph = *entity;
|
||||
|
||||
drawCalls.emplace_back(pod::DrawCall::Storage{
|
||||
materials.size(),
|
||||
graph.materials.size(),
|
||||
textures.size(),
|
||||
graph.textures.size()
|
||||
});
|
||||
|
||||
for ( auto& material : graph.materials ) materials.emplace_back( material.storage );
|
||||
for ( auto& texture : graph.textures ) textures.emplace_back( texture.storage );
|
||||
drawCalls.emplace_back(pod::DrawCall::Storage{
|
||||
materials.size(),
|
||||
graph.materials.size(),
|
||||
textures.size(),
|
||||
graph.textures.size()
|
||||
});
|
||||
|
||||
for ( auto& material : graph.materials ) materials.emplace_back( material.storage );
|
||||
for ( auto& texture : graph.textures ) textures.emplace_back( texture.storage );
|
||||
|
||||
for ( auto& texture : graph.textures ) {
|
||||
if ( !texture.texture.device ) continue;
|
||||
for ( auto& texture : graph.textures ) {
|
||||
if ( !texture.texture.device ) continue;
|
||||
|
||||
graphic.material.textures.emplace_back().aliasTexture(texture.texture);
|
||||
++textureSlot;
|
||||
graphic.material.textures.emplace_back().aliasTexture(texture.texture);
|
||||
++textureSlot;
|
||||
|
||||
if ( graph.atlas ) break;
|
||||
}
|
||||
if ( graph.atlas ) break;
|
||||
}
|
||||
|
||||
uniforms->lengths.materials = std::min( materials.size(), maxTextures );
|
||||
uniforms->lengths.textures = std::min( textures.size(), maxTextures );
|
||||
uniforms->lengths.drawCalls = std::min( drawCalls.size(), maxTextures );
|
||||
}
|
||||
|
||||
uniforms->lengths.materials = std::min( materials.size(), maxTextures );
|
||||
uniforms->lengths.textures = std::min( textures.size(), maxTextures );
|
||||
uniforms->lengths.drawCalls = std::min( drawCalls.size(), maxTextures );
|
||||
// add lighting
|
||||
for ( size_t i = 0; i < entities.size() && lights.size() < maxLights; ++i ) {
|
||||
for ( size_t i = 0; i < entities.size() && lights.size() < metadata.max.lights; ++i ) {
|
||||
auto& info = entities[i];
|
||||
uf::Entity* entity = info.entity;
|
||||
|
||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||
auto& metadata = entity->getComponent<ext::LightBehavior::Metadata>();
|
||||
auto& camera = entity->getComponent<uf::Camera>();
|
||||
metadata["system"]["renderer"]["rendered"] = true;
|
||||
metadata.renderer.rendered = true;
|
||||
|
||||
pod::Light::Storage light;
|
||||
light.position = info.position;
|
||||
|
||||
light.color = uf::vector::decode( metadata["light"]["color"], light.color );
|
||||
light.color.w = metadata["light"]["power"].as<float>();
|
||||
|
||||
if ( metadata["light"]["type"].is<size_t>() ) {
|
||||
light.type = metadata["light"]["type"].as<size_t>();
|
||||
} else if ( metadata["light"]["type"].is<std::string>() ) {
|
||||
std::string lightType = metadata["light"]["type"].as<std::string>();
|
||||
if ( lightType == "point" ) light.type = 1;
|
||||
else if ( lightType == "spot" ) light.type = 2;
|
||||
}
|
||||
|
||||
light.color = info.color;
|
||||
light.type = info.type;
|
||||
light.mapIndex = -1;
|
||||
|
||||
light.depthBias = metadata["light"]["bias"]["shader"].as<float>();
|
||||
light.depthBias = info.bias;
|
||||
if ( info.shadows && entity->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = entity->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
if ( metadata["system"]["renderer"]["mode"].as<std::string>() == "in-range" && --updateThreshold > 0 ) {
|
||||
if ( metadata.renderer.mode == "in-range" && --updateThreshold > 0 ) {
|
||||
renderMode.execute = true;
|
||||
}
|
||||
size_t view = 0;
|
||||
@ -601,14 +692,9 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
} else {
|
||||
lights.emplace_back(light);
|
||||
}
|
||||
uniforms->lengths.lights = std::min( lights.size(), maxLights );
|
||||
}
|
||||
/*
|
||||
while ( textureSlot++ < maxTextures + 3 ) {
|
||||
graphic.material.textures.emplace_back().aliasTexture(uf::renderer::Texture2D::empty);
|
||||
}
|
||||
*/
|
||||
{
|
||||
uniforms->lengths.lights = std::min( lights.size(), metadata.max.lights );
|
||||
bool shouldUpdate = graphic.material.textures.size() != previousTextures.size();
|
||||
for ( size_t i = 0; !shouldUpdate && i < previousTextures.size() && i < graphic.material.textures.size(); ++i ) {
|
||||
if ( previousTextures[i] != graphic.material.textures[i].image )
|
||||
@ -633,8 +719,8 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
shader.updateUniform( "UBO", uniform );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void ext::ExtSceneBehavior::render( uf::Object& self ) {}
|
||||
void ext::ExtSceneBehavior::destroy( uf::Object& self ) {}
|
||||
|
@ -4,14 +4,42 @@
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/utils/math/vector.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API ExtSceneBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace ExtSceneBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
struct Metadata {
|
||||
struct {
|
||||
size_t textures = 256;
|
||||
size_t lights = 256;
|
||||
} max;
|
||||
struct {
|
||||
bool enabled = true;
|
||||
int shadowSamples = 4;
|
||||
int shadowThreshold = 8;
|
||||
size_t updateThreshold = 4;
|
||||
pod::Vector4f ambient = {0,0,0,1};
|
||||
pod::Vector4f specular = {1,1,1,1};
|
||||
} light;
|
||||
struct {
|
||||
pod::Vector3f color = {1,1,1};
|
||||
float stepScale = 16.0f;
|
||||
float absorbtion = 0.85f;
|
||||
pod::Vector2f range = {};
|
||||
struct {
|
||||
pod::Vector4f offset = {};
|
||||
float timescale = 0.5f;
|
||||
float threshold = 0.5f;
|
||||
float multiplier = 5.0f;
|
||||
float scale = 50.0f;
|
||||
} density;
|
||||
} fog;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "behavior.h"
|
||||
|
||||
#include <uf/utils/time/time.h>
|
||||
@ -319,4 +320,5 @@ void ext::SceneCollisionBehavior::destroy( uf::Object& self ){
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#undef this
|
||||
#undef this
|
||||
#endif
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API SceneCollisionBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace SceneCollisionBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API SoundEmitterBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace SoundEmitterBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "behavior.h"
|
||||
|
||||
#include <uf/utils/hook/hook.h>
|
||||
@ -110,4 +111,5 @@ void ext::HousamoSpriteBehavior::initialize( uf::Object& self ) {
|
||||
void ext::HousamoSpriteBehavior::tick( uf::Object& self ) {}
|
||||
void ext::HousamoSpriteBehavior::render( uf::Object& self ){}
|
||||
void ext::HousamoSpriteBehavior::destroy( uf::Object& self ){}
|
||||
#undef this
|
||||
#undef this
|
||||
#endif
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API HousamoSpriteBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace HousamoSpriteBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -46,11 +46,11 @@ namespace {
|
||||
#endif
|
||||
uf::Serializer defaultSettings;
|
||||
}
|
||||
|
||||
/*
|
||||
ext::Gui::Gui(){
|
||||
this->addBehavior<ext::GuiBehavior>();
|
||||
}
|
||||
|
||||
*/
|
||||
std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string ) {
|
||||
std::vector<pod::GlyphBox> gs;
|
||||
#if UF_USE_FREETYPE
|
||||
@ -844,6 +844,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
void ext::GuiBehavior::tick( uf::Object& self ) {
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
#if 0
|
||||
if ( metadata["text settings"]["fade in speed"].is<double>() && !metadata["system"]["faded in"].as<bool>() ) {
|
||||
float speed = metadata["text settings"]["fade in speed"].as<float>();
|
||||
float alpha = metadata["text settings"]["color"][3].as<float>();
|
||||
@ -858,21 +859,7 @@ void ext::GuiBehavior::tick( uf::Object& self ) {
|
||||
metadata["text settings"]["color"][3] = alpha + speed;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if ( this->hasComponent<uf::Graphic>() && metadata["experimental"].as<bool>() ) {
|
||||
auto& image = this->getComponent<uf::Image>();
|
||||
auto& pixels = image.getPixels();
|
||||
size_t channels = image.getChannels();
|
||||
size_t len = pixels.size();
|
||||
uint8_t red = fmod( uf::physics::time::current * 64.0f, 255.0f );
|
||||
for ( size_t i = 0; i < len; i += channels ) {
|
||||
pixels[i] = red;
|
||||
}
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& texture = graphic.material.textures.front();
|
||||
texture.update( image );
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
template<size_t N = uf::renderer::settings::maxViews>
|
||||
struct UniformDescriptor {
|
||||
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API GuiBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace GuiBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -23,8 +23,7 @@ namespace ext {
|
||||
class EXT_API Gui : public uf::Object {
|
||||
public:
|
||||
typedef uf::BaseMesh<pod::Vertex_3F2F3F> glyph_mesh_t;
|
||||
|
||||
Gui();
|
||||
// Gui();
|
||||
std::vector<pod::GlyphBox> generateGlyphs( const std::string& = "" );
|
||||
void load( const uf::Image& );
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if UF_USE_ULTRALIGHT
|
||||
#include "behavior.h"
|
||||
#include "../gui.h"
|
||||
|
||||
@ -118,4 +119,5 @@ void ext::GuiHtmlBehavior::render( uf::Object& self ){
|
||||
}
|
||||
void ext::GuiHtmlBehavior::destroy( uf::Object& self ){
|
||||
}
|
||||
#undef this
|
||||
#undef this
|
||||
#endif
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API GuiHtmlBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace GuiHtmlBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
@ -101,7 +101,6 @@ void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
|
||||
});
|
||||
}
|
||||
void ext::GuiManagerBehavior::tick( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void ext::GuiManagerBehavior::render( uf::Object& self ){
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
|
@ -6,12 +6,12 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API GuiManagerBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace GuiManagerBehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE;
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
155
ext/main.cpp
155
ext/main.cpp
@ -4,6 +4,7 @@
|
||||
#include <uf/ext/oal/oal.h>
|
||||
|
||||
#include <uf/spec/terminal/terminal.h>
|
||||
#include <uf/spec/controller/controller.h>
|
||||
|
||||
#include <uf/utils/time/time.h>
|
||||
#include <uf/utils/audio/audio.h>
|
||||
@ -137,17 +138,11 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define UF_DEBUG_TRACE_MSG() UF_DEBUG_PRINT_MARKER(); malloc_stats();
|
||||
#else
|
||||
#define UF_DEBUG_TRACE_MSG()
|
||||
#endif
|
||||
|
||||
void EXT_API ext::load() {
|
||||
ext::config = getConfig();
|
||||
}
|
||||
void EXT_API ext::initialize() {
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
/* Arguments */ {
|
||||
bool modified = false;
|
||||
auto& arguments = ::config["arguments"];
|
||||
@ -189,20 +184,9 @@ void EXT_API ext::initialize() {
|
||||
// #include "./inits/persistence.inl"
|
||||
}
|
||||
/* Testing scope */ {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
#if UF_USE_LUA
|
||||
/* Lua */ {
|
||||
ext::lua::main = ::config["engine"]["ext"]["lua"]["main"].as<std::string>();
|
||||
for ( auto it = ::config["engine"]["ext"]["lua"]["modules"].begin(); it != ::config["engine"]["ext"]["lua"]["modules"].end(); ++it ) {
|
||||
std::string key = it.key();
|
||||
ext::lua::modules[key] = ::config["engine"]["ext"]["lua"]["modules"][key].as<std::string>();
|
||||
}
|
||||
ext::lua::initialize();
|
||||
}
|
||||
#endif
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
/* Parse config */ {
|
||||
/* Set memory pool sizes */ {
|
||||
auto deduceSize = []( const ext::json::Value& value )->size_t{
|
||||
@ -249,7 +233,7 @@ void EXT_API ext::initialize() {
|
||||
}
|
||||
}
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
if ( ::config["engine"]["limiters"]["framerate"].as<std::string>() == "auto" && ::config["window"]["refresh rate"].is<size_t>() ) {
|
||||
double scale = 1.0;
|
||||
size_t refreshRate = ::config["window"]["refresh rate"].as<size_t>();
|
||||
@ -291,7 +275,10 @@ void EXT_API ext::initialize() {
|
||||
::config["engine"]["threads"]["workers"] = threads;
|
||||
uf::iostream << "Using " << threads << " worker threads" << "\n";
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
if ( ::config["engine"]["scenes"]["use graph"].is<bool>() ) {
|
||||
uf::scene::useGraph = ::config["engine"]["scenes"]["use graph"].as<bool>();
|
||||
}
|
||||
|
||||
#if UF_USE_BULLET
|
||||
// set bullet parameters
|
||||
ext::bullet::debugDrawEnabled = ::config["engine"]["ext"]["bullet"]["debug draw"]["enabled"].as<bool>();
|
||||
@ -383,7 +370,6 @@ void EXT_API ext::initialize() {
|
||||
uf::renderer::settings::experimental::deferredAliasOutputToSwapchain = ::config["engine"]["ext"][RENDERER]["experimental"]["deferred alias output to swapchain"].as<bool>();
|
||||
uf::renderer::settings::experimental::vsync = ::config["engine"]["ext"][RENDERER]["experimental"]["vsync"].as<bool>();
|
||||
uf::renderer::settings::experimental::hdr = ::config["engine"]["ext"][RENDERER]["experimental"]["hdr"].as<bool>();
|
||||
|
||||
#endif
|
||||
#define JSON_TO_VKFORMAT( key ) if ( ::config["engine"]["ext"][RENDERER]["formats"][#key].is<std::string>() ) {\
|
||||
std::string format = ::config["engine"]["ext"][RENDERER]["formats"][#key].as<std::string>();\
|
||||
@ -396,13 +382,28 @@ void EXT_API ext::initialize() {
|
||||
JSON_TO_VKFORMAT(normal);
|
||||
JSON_TO_VKFORMAT(position);
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
/* Init controllers */ {
|
||||
spec::controller::initialize();
|
||||
}
|
||||
|
||||
#if UF_USE_LUA
|
||||
/* Lua */ {
|
||||
ext::lua::main = ::config["engine"]["ext"]["lua"]["main"].as<std::string>();
|
||||
for ( auto it = ::config["engine"]["ext"]["lua"]["modules"].begin(); it != ::config["engine"]["ext"]["lua"]["modules"].end(); ++it ) {
|
||||
std::string key = it.key();
|
||||
ext::lua::modules[key] = ::config["engine"]["ext"]["lua"]["modules"][key].as<std::string>();
|
||||
}
|
||||
ext::lua::initialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UF_USE_BULLET
|
||||
/* Bullet */ {
|
||||
ext::bullet::initialize();
|
||||
}
|
||||
#endif
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
#if UF_USE_OPENVR
|
||||
ext::openvr::enabled = ::config["engine"]["ext"]["vr"]["enable"].as<bool>();
|
||||
ext::openvr::swapEyes = ::config["engine"]["ext"]["vr"]["swap eyes"].as<bool>();
|
||||
@ -421,17 +422,15 @@ void EXT_API ext::initialize() {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
/* Create initial scene (kludge) */ {
|
||||
uf::Scene& scene = uf::instantiator::instantiate<uf::Scene>(); //new uf::Scene;
|
||||
uf::scene::scenes.push_back(&scene);
|
||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||
metadata["system"]["config"] = ::config;
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
/* Initialize Vulkan */ {
|
||||
// uf::renderer::width = ::config["window"]["size"]["x"].as<int>();
|
||||
// uf::renderer::height = ::config["window"]["size"]["y"].as<int>();
|
||||
#if UF_USE_VULKAN
|
||||
// setup render mode
|
||||
if ( ::config["engine"]["render modes"]["gui"].as<bool>() ) {
|
||||
@ -447,7 +446,7 @@ void EXT_API ext::initialize() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
#if UF_USE_OPENVR
|
||||
if ( ext::openvr::enabled ) {
|
||||
ext::openvr::initialize();
|
||||
@ -507,10 +506,10 @@ void EXT_API ext::initialize() {
|
||||
});
|
||||
}
|
||||
#endif
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
uf::renderer::initialize();
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
/* */ {
|
||||
pod::Thread& threadMain = uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false );
|
||||
pod::Thread& threadPhysics = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true );
|
||||
@ -521,17 +520,20 @@ void EXT_API ext::initialize() {
|
||||
}
|
||||
#endif
|
||||
#if UF_USE_ULTRALIGHT
|
||||
/* Ultralight-UX */ if ( ::config["engine"]["ext"]["ultralight"]["enabled"].as<bool>() ) {
|
||||
if ( ::config["engine"]["ext"]["ultralight"]["scale"].is<double>() ) {
|
||||
ext::ultralight::scale = ::config["engine"]["ext"]["ultralight"]["scale"].as<double>();
|
||||
{
|
||||
auto& ultralight = ::config["engine"]["ext"]["ultralight"];
|
||||
/* Ultralight-UX */ if ( ultralight["enabled"].as<bool>() ) {
|
||||
if ( ultralight["scale"].is<double>() ) {
|
||||
ext::ultralight::scale = ultralight["scale"].as<double>();
|
||||
}
|
||||
if ( ultralight["log"].is<size_t>() ) {
|
||||
ext::ultralight::log = ultralight["log"].as<size_t>();
|
||||
}
|
||||
ext::ultralight::initialize();
|
||||
}
|
||||
if ( ::config["engine"]["ext"]["ultralight"]["log"].is<size_t>() ) {
|
||||
ext::ultralight::log = ::config["engine"]["ext"]["ultralight"]["log"].as<size_t>();
|
||||
}
|
||||
ext::ultralight::initialize();
|
||||
}
|
||||
#endif
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
// #define DEBUG_PRINT() std::cout << __FILE__ << ":" __FUNCTION__ << "@" << __LINE__ << std::endl;
|
||||
/* Add hooks */ {
|
||||
uf::hooks.addHook( "game:Scene.Load", [&](ext::json::Value& json){
|
||||
@ -564,7 +566,7 @@ void EXT_API ext::initialize() {
|
||||
ext::ready = false;
|
||||
});
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
|
||||
/* Initialize root scene*/ {
|
||||
uf::Serializer payload;
|
||||
payload["scene"] = ::config["engine"]["scenes"]["start"];
|
||||
@ -582,8 +584,8 @@ void EXT_API ext::initialize() {
|
||||
assetLoader.processQueue();
|
||||
return 0;}, false );
|
||||
}
|
||||
UF_DEBUG_TRACE_MSG();
|
||||
}
|
||||
|
||||
void EXT_API ext::tick() {
|
||||
/* Timer */ {
|
||||
times.prevTime = times.curTime;
|
||||
@ -591,11 +593,15 @@ void EXT_API ext::tick() {
|
||||
times.deltaTime = times.curTime - times.prevTime;
|
||||
}
|
||||
|
||||
/* Tick controllers */ {
|
||||
spec::controller::tick();
|
||||
}
|
||||
#if UF_USE_OPENVR
|
||||
/* OpenVR */ if ( ext::openvr::context ) {
|
||||
ext::openvr::tick();
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
/* Print Entity Information */ {
|
||||
TIMER(1, uf::Window::isKeyPressed("P") && ) {
|
||||
// uf::iostream << uf::renderer::allocatorStats() << "\n";
|
||||
@ -637,38 +643,44 @@ void EXT_API ext::tick() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto& bulletThread = uf::thread::get("Physics");
|
||||
#endif
|
||||
/* Update physics timer */ {
|
||||
uf::physics::tick();
|
||||
}
|
||||
|
||||
#if UF_USE_BULLET
|
||||
auto& bulletThread = uf::thread::get("Physics");
|
||||
/* Update bullet */ {
|
||||
#if 1
|
||||
//UF_TIMER_TRACE_INIT();
|
||||
ext::bullet::tick();
|
||||
//UF_TIMER_TRACE("[TICK] BULLET");
|
||||
#else
|
||||
if ( ::config["engine"]["ext"]["bullet"]["multithreaded"].as<bool>() ) {
|
||||
uf::thread::add( bulletThread, [&]() -> int { ext::bullet::tick(); return 0;}, true );
|
||||
} else {
|
||||
ext::bullet::tick();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
//UF_TIMER_TRACE("ticking physics");
|
||||
/* Update entities */ {
|
||||
uf::scene::tick();
|
||||
}
|
||||
|
||||
//UF_TIMER_TRACE("ticking scene");
|
||||
/* Tick Main Thread Queue */ {
|
||||
pod::Thread& thread = uf::thread::get("Main");
|
||||
uf::thread::process( thread );
|
||||
}
|
||||
|
||||
/* Garbage collection */ if ( ::config["engine"]["debug"]["garbage collection"]["enabled"].as<bool>() ) {
|
||||
double every = ::config["engine"]["debug"]["garbage collection"]["every"].as<double>();
|
||||
uint8_t mode = ::config["engine"]["debug"]["garbage collection"]["mode"].as<uint64_t>();
|
||||
bool announce = ::config["engine"]["debug"]["garbage collection"]["announce"].as<bool>();
|
||||
TIMER( every ) {
|
||||
size_t collected = uf::instantiator::collect( mode );
|
||||
if ( announce && collected > 0 ) {
|
||||
uf::iostream << "GC collected " << (int) collected << " unused entities" << "\n";
|
||||
{
|
||||
auto& gc = ::config["engine"]["debug"]["garbage collection"];
|
||||
/* Garbage collection */ if ( gc["enabled"].as<bool>() ) {
|
||||
double every = gc["every"].as<double>();
|
||||
uint8_t mode = gc["mode"].as<uint64_t>();
|
||||
bool announce = gc["announce"].as<bool>();
|
||||
TIMER( every ) {
|
||||
size_t collected = uf::instantiator::collect( mode );
|
||||
if ( announce && collected > 0 ) UF_DEBUG_MSG("GC collected " << (int) collected << " unused entities");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -678,23 +690,29 @@ void EXT_API ext::tick() {
|
||||
}
|
||||
#endif
|
||||
/* Update vulkan */ {
|
||||
//UF_TIMER_TRACE_INIT();
|
||||
uf::renderer::tick();
|
||||
//UF_TIMER_TRACE("[TICK] RENDERER");
|
||||
}
|
||||
//UF_TIMER_TRACE("ticking renderer");
|
||||
#if UF_USE_DISCORD
|
||||
/* Discord */ if ( ::config["engine"]["ext"]["discord"]["enable"].as<bool>() ) {
|
||||
ext::discord::tick();
|
||||
}
|
||||
#endif
|
||||
/* FPS Print */ if ( ::config["engine"]["debug"]["framerate"]["print"].as<bool>() ) {
|
||||
++::times.frames;
|
||||
double every = ::config["engine"]["debug"]["framerate"]["every"].as<double>();
|
||||
TIMER( every ) {
|
||||
// uf::iostream << "Framerate: " << (1.0/times.deltaTime) << " FPS | Frametime: " << (times.deltaTime * 1000) << "ms" << "\n";
|
||||
uf::iostream << "System: " << (every * 1000.0/::times.frames) << " ms/frame | Time: " << time << " | Frames: " << ::times.frames << " | FPS: " << ::times.frames / time << "\n";
|
||||
::times.frames = 0;
|
||||
{
|
||||
auto& fps = ::config["engine"]["debug"]["framerate"];
|
||||
/* FPS Print */ if ( fps["print"].as<bool>() ) {
|
||||
++::times.frames;
|
||||
double every = fps["every"].as<double>();
|
||||
TIMER( every ) {
|
||||
// UF_DEBUG_MSG("Framerate: " << (1.0/times.deltaTime) << " FPS | Frametime: " << (times.deltaTime * 1000) << "ms");
|
||||
UF_DEBUG_MSG("System: " << (every * 1000.0/::times.frames) << " ms/frame | Time: " << time << " | Frames: " << ::times.frames << " | FPS: " << ::times.frames / time);
|
||||
::times.frames = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Frame limiter of sorts I guess */ if ( false ) if ( ::times.limiter > 0 ) {
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
@ -708,13 +726,16 @@ void EXT_API ext::tick() {
|
||||
}
|
||||
timer.reset();
|
||||
}
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
if ( ::config["engine"]["ext"]["bullet"]["multithreaded"].as<bool>() ) {
|
||||
uf::thread::wait( bulletThread );
|
||||
}
|
||||
#endif
|
||||
//UF_TIMER_TRACE("ticking");
|
||||
}
|
||||
void EXT_API ext::render() {
|
||||
|
||||
//UF_TIMER_TRACE_INIT();
|
||||
#if UF_USE_ULTRALIGHT
|
||||
/* Ultralight-UX */ if ( ::config["engine"]["ext"]["ultralight"]["enabled"].as<bool>() ) {
|
||||
ext::ultralight::render();
|
||||
@ -734,11 +755,15 @@ void EXT_API ext::render() {
|
||||
ext::openvr::submit();
|
||||
}
|
||||
#endif
|
||||
//UF_TIMER_TRACE("[RENDER]");
|
||||
}
|
||||
void EXT_API ext::terminate() {
|
||||
/* Kill threads */ {
|
||||
uf::thread::terminate();
|
||||
}
|
||||
/* Terminate controllers */ {
|
||||
spec::controller::terminate();
|
||||
}
|
||||
#if UF_USE_BULLET
|
||||
/* Kill bullet */ {
|
||||
ext::bullet::terminate();
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "behavior.h"
|
||||
|
||||
#include <uf/utils/time/time.h>
|
||||
@ -208,4 +209,5 @@ void ext::RayTracingSceneBehavior::destroy( uf::Object& self ) {
|
||||
uf::renderer::removeRenderMode( &renderMode, false );
|
||||
}
|
||||
}
|
||||
#undef this
|
||||
#undef this
|
||||
#endif
|
@ -6,12 +6,11 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API RayTracingSceneBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
namespace RayTracingSceneBehavior {
|
||||
void attach( uf::Object& );
|
||||
void initialize( uf::Object& );
|
||||
void tick( uf::Object& );
|
||||
void render( uf::Object& );
|
||||
void destroy( uf::Object& );
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user