Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f79b33e8dc |
@ -12,11 +12,25 @@ if (LUA_ENABLED)
|
|||||||
find_package(Lua REQUIRED)
|
find_package(Lua REQUIRED)
|
||||||
include_directories(${LUA_INCLUDE_DIR})
|
include_directories(${LUA_INCLUDE_DIR})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
option(GUILE_ENABLED "Guile 2.0 scripting support" OFF)
|
||||||
|
if (GUILE_ENABLED)
|
||||||
|
add_compile_definitions(GUILE_SCRIPTING)
|
||||||
|
## Find pkg-config
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
## Use pkg-config to find Guile 2.0
|
||||||
|
pkg_check_modules(GUILE REQUIRED guile-2.0)
|
||||||
|
include_directories(${GUILE_INCLUDE_DIRS})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_executable(couch core/couch.cpp)
|
add_executable(couch core/couch.cpp)
|
||||||
|
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
target_link_libraries(couch couchlib)
|
target_link_libraries(couch couchlib)
|
||||||
target_link_libraries(couch couchlib_luascripting)
|
target_link_libraries(couch couchlib_luascripting)
|
||||||
|
target_link_libraries(couch couchlib_guilescripting)
|
||||||
|
|
||||||
add_subdirectory(scripting)
|
add_subdirectory(scripting)
|
||||||
if (LUA_ENABLED)
|
if (LUA_ENABLED)
|
||||||
|
@ -65,12 +65,16 @@ target_sources(couchlib PUBLIC
|
|||||||
|
|
||||||
|
|
||||||
add_library(couchlib_luascripting STATIC)
|
add_library(couchlib_luascripting STATIC)
|
||||||
|
|
||||||
target_sources(couchlib_luascripting PUBLIC
|
target_sources(couchlib_luascripting PUBLIC
|
||||||
Scripting/Lua.h
|
Scripting/Lua.h
|
||||||
Scripting/Lua.cpp)
|
Scripting/Lua.cpp)
|
||||||
target_link_libraries(couchlib_luascripting couchlua)
|
target_link_libraries(couchlib_luascripting couchlua)
|
||||||
|
|
||||||
|
add_library(couchlib_guilescripting STATIC)
|
||||||
|
target_sources(couchlib_guilescripting PUBLIC
|
||||||
|
Scripting/Guile.h
|
||||||
|
Scripting/Guile.cpp)
|
||||||
|
target_link_libraries(couchlib_guilescripting couchguile)
|
||||||
|
|
||||||
target_include_directories(couchlib
|
target_include_directories(couchlib
|
||||||
PUBLIC
|
PUBLIC
|
||||||
@ -90,6 +94,9 @@ target_link_libraries(couchlib GLEW::GLEW)
|
|||||||
if (LUA_ENABLED)
|
if (LUA_ENABLED)
|
||||||
target_link_libraries(couchlib_luascripting ${LUA_LIBRARIES})
|
target_link_libraries(couchlib_luascripting ${LUA_LIBRARIES})
|
||||||
endif ()
|
endif ()
|
||||||
|
if (GUILE_ENABLED)
|
||||||
|
target_link_libraries(couchlib_guilescripting ${GUILE_LIBRARIES})
|
||||||
|
endif ()
|
||||||
target_link_libraries(couchlib ${BULLET_LIBRARIES})
|
target_link_libraries(couchlib ${BULLET_LIBRARIES})
|
||||||
target_link_libraries(couchlib ${ASSIMP_LIBRARY})
|
target_link_libraries(couchlib ${ASSIMP_LIBRARY})
|
||||||
|
|
||||||
|
@ -14,26 +14,10 @@ Input *Input::GetInstance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Input::Use(Window *window){
|
void Input::Use(Window window){
|
||||||
this->window = window;
|
glfwSetInputMode(window.glfwWindow, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
glfwSetKeyCallback(window->glfwWindow, (GLFWkeyfun)HandleKeys);
|
glfwSetKeyCallback(window.glfwWindow, (GLFWkeyfun)HandleKeys);
|
||||||
glfwSetCursorPosCallback(window->glfwWindow, (GLFWcursorposfun)HandleMousePosition);
|
glfwSetCursorPosCallback(window.glfwWindow, (GLFWcursorposfun)HandleMousePosition);
|
||||||
}
|
|
||||||
|
|
||||||
void Input::SetMouseMode(MouseMode mouseMode) {
|
|
||||||
this->mouseMode = mouseMode;
|
|
||||||
|
|
||||||
switch(mouseMode) {
|
|
||||||
case MouseMode::VISIBLE:
|
|
||||||
glfwSetInputMode(window->glfwWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
||||||
break;
|
|
||||||
case MouseMode::CAPTURED:
|
|
||||||
glfwSetInputMode(window->glfwWindow, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
||||||
break;
|
|
||||||
case MouseMode::HIDDEN:
|
|
||||||
glfwSetInputMode(window->glfwWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::HandleKeys(GLFWwindow *_, int keys, int code, int action, int mods) {
|
void Input::HandleKeys(GLFWwindow *_, int keys, int code, int action, int mods) {
|
||||||
|
@ -13,20 +13,13 @@ typedef void (*MousePositionHandler)(double xpos, double ypos, double xrel, doub
|
|||||||
|
|
||||||
class Input {
|
class Input {
|
||||||
public:
|
public:
|
||||||
enum MouseMode {
|
|
||||||
VISIBLE, HIDDEN, CAPTURED
|
|
||||||
};
|
|
||||||
|
|
||||||
static Input *GetInstance();
|
static Input *GetInstance();
|
||||||
void Use(Window *window);
|
void Use(Window window);
|
||||||
void SetMouseMode(MouseMode mouseMode);
|
|
||||||
std::vector<KeyHandler> keyHandlers;
|
std::vector<KeyHandler> keyHandlers;
|
||||||
std::vector<MousePositionHandler> mousePositionHandlers;
|
std::vector<MousePositionHandler> mousePositionHandlers;
|
||||||
private:
|
private:
|
||||||
bool firstMousePositionUpdate = true;
|
bool firstMousePositionUpdate = true;
|
||||||
double lastx, lasty;
|
double lastx, lasty;
|
||||||
MouseMode mouseMode;
|
|
||||||
Window *window;
|
|
||||||
Input();
|
Input();
|
||||||
static void HandleKeys(GLFWwindow *_, int key, int code, int action, int mods);
|
static void HandleKeys(GLFWwindow *_, int key, int code, int action, int mods);
|
||||||
static void HandleMousePosition(GLFWwindow *_, double xpos, double ypos);
|
static void HandleMousePosition(GLFWwindow *_, double xpos, double ypos);
|
||||||
|
103
core/Scripting/Guile.cpp
Normal file
103
core/Scripting/Guile.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#include "Guile.h"
|
||||||
|
|
||||||
|
#include "../Util.h"
|
||||||
|
|
||||||
|
void Guile::Initialize() {
|
||||||
|
#ifdef GUILE_SCRIPTING
|
||||||
|
language = this;
|
||||||
|
// Initialize Guile
|
||||||
|
scm_with_guile(Guile::inner_init, NULL);
|
||||||
|
|
||||||
|
// Bind input functions
|
||||||
|
Input *input = Input::GetInstance();
|
||||||
|
if (HasHook("onkey")) {
|
||||||
|
input->keyHandlers.push_back(GuileKeyHandler);
|
||||||
|
}
|
||||||
|
if (HasHook("onmousemotion")) {
|
||||||
|
input->mousePositionHandlers.push_back(GuileMousePositionHandler);
|
||||||
|
}
|
||||||
|
#else // GUILE_SCRIPTING
|
||||||
|
Util::Die("Guile is selected as the scripting language, but this binary was built without Guile support.");
|
||||||
|
#endif // GUILE_SCRIPTING
|
||||||
|
}
|
||||||
|
|
||||||
|
void Guile::Update(double delta) {
|
||||||
|
#ifdef GUILE_SCRIPTING
|
||||||
|
if (HasHook("update")) {
|
||||||
|
scm_with_guile(Guile::inner_update, &delta);
|
||||||
|
}
|
||||||
|
#endif // GUILE_SCRIPTING
|
||||||
|
}
|
||||||
|
|
||||||
|
void Guile::Close() {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Guile::HasHook(const char *name) {
|
||||||
|
bool exists = false;
|
||||||
|
#ifdef GUILE_SCRIPTING
|
||||||
|
exists = scm_with_guile(Guile::inner_has_hook, (void *) name);
|
||||||
|
#endif // GUILE_SCRIPTING
|
||||||
|
return exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GUILE_SCRIPTING
|
||||||
|
|
||||||
|
void Guile::GuileKeyHandler(int key, int code, int action, int mods) {
|
||||||
|
Guile::key_event ev {key, code, action, mods};
|
||||||
|
scm_with_guile(Guile::inner_key_handler, &ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Guile::GuileMousePositionHandler(double xpos, double ypos, double relx, double rely) {
|
||||||
|
Guile::mouse_position_event ev {xpos, ypos, relx, rely};
|
||||||
|
scm_with_guile(Guile::inner_mouse_position_handler, &ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Guile::inner_init(void* empty) {
|
||||||
|
// Init swig
|
||||||
|
SWIG_init();
|
||||||
|
// Load main file
|
||||||
|
scm_c_primitive_load("main.scm");
|
||||||
|
// Execute the init function if it exists
|
||||||
|
if (ScriptingLanguage::language->HasHook("init")) {
|
||||||
|
scm_call_0(scm_c_eval_string("init"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Guile::inner_update(void *data) {
|
||||||
|
double delta = *(double*) data;
|
||||||
|
if (ScriptingLanguage::language->HasHook("update")) {
|
||||||
|
scm_call_1(scm_c_eval_string("update"), scm_from_double(delta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Guile::inner_has_hook(void *data) {
|
||||||
|
const char *name = (const char *) data;
|
||||||
|
return (void *) scm_to_bool(scm_defined_p(scm_from_locale_symbol(name), SCM_UNDEFINED));
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Guile::inner_key_handler(void *data) {
|
||||||
|
Guile::key_event *ev = (Guile::key_event*) data;
|
||||||
|
if (ScriptingLanguage::language->HasHook("onkey")) {
|
||||||
|
scm_call_4(scm_c_eval_string("onkey"),
|
||||||
|
scm_from_int(ev->key),
|
||||||
|
scm_from_int(ev->code),
|
||||||
|
scm_from_int(ev->action),
|
||||||
|
scm_from_int(ev->mods));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Guile::inner_mouse_position_handler(void *data) {
|
||||||
|
Guile::mouse_position_event *ev = (Guile::mouse_position_event *) data;
|
||||||
|
if (ScriptingLanguage::language->HasHook("onmousemotion")) {
|
||||||
|
scm_call_4(scm_c_eval_string("onmousemotion"),
|
||||||
|
scm_from_double(ev->xpos),
|
||||||
|
scm_from_double(ev->ypos),
|
||||||
|
scm_from_double(ev->relx),
|
||||||
|
scm_from_double(ev->rely));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // GUILE_SCRIPTING
|
||||||
|
|
46
core/Scripting/Guile.h
Normal file
46
core/Scripting/Guile.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef GUILE_H
|
||||||
|
#define GUILE_H
|
||||||
|
|
||||||
|
#include "../Input.h"
|
||||||
|
|
||||||
|
#ifdef GUILE_SCRIPTING
|
||||||
|
#include <libguile.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void SWIG_init();
|
||||||
|
#endif // GUILE_SCRIPTING
|
||||||
|
|
||||||
|
#include "ScriptingLanguage.h"
|
||||||
|
|
||||||
|
class Guile : public ScriptingLanguage {
|
||||||
|
public:
|
||||||
|
void Initialize();
|
||||||
|
void Update(double delta);
|
||||||
|
void Close();
|
||||||
|
bool HasHook(const char *name);
|
||||||
|
private:
|
||||||
|
#ifdef GUILE_SCRIPTING
|
||||||
|
struct key_event {
|
||||||
|
int key;
|
||||||
|
int code;
|
||||||
|
int action;
|
||||||
|
int mods;
|
||||||
|
};
|
||||||
|
struct mouse_position_event {
|
||||||
|
double xpos;
|
||||||
|
double ypos;
|
||||||
|
double relx;
|
||||||
|
double rely;
|
||||||
|
};
|
||||||
|
static void *inner_init(void *empty);
|
||||||
|
static void *inner_update(void *delta);
|
||||||
|
static void *inner_has_hook(void *name);
|
||||||
|
static void *inner_key_handler(void *ev);
|
||||||
|
static void *inner_mouse_position_handler(void *ev);
|
||||||
|
static void GuileKeyHandler(int key, int code, int action, int mods);
|
||||||
|
static void GuileMousePositionHandler(double xpos, double ypos, double relx, double rely);
|
||||||
|
#endif // GUILE_SCRIPTING
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* GUILE_H */
|
@ -30,11 +30,14 @@
|
|||||||
#include "Rigidbody.h"
|
#include "Rigidbody.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
|
||||||
|
|
||||||
#include "Scripting/Lua.h"
|
#include "Scripting/Lua.h"
|
||||||
|
#include "Scripting/Guile.h"
|
||||||
|
|
||||||
Node *root;
|
Node *root;
|
||||||
|
|
||||||
|
char script_type = 'l';
|
||||||
|
ScriptingLanguage *sl;
|
||||||
|
|
||||||
void render(Node *curr, Shader *shader, Matrix model) {
|
void render(Node *curr, Shader *shader, Matrix model) {
|
||||||
Spatial *spatial = dynamic_cast<Spatial*>(curr);
|
Spatial *spatial = dynamic_cast<Spatial*>(curr);
|
||||||
if (spatial) {
|
if (spatial) {
|
||||||
@ -57,11 +60,27 @@ void render(Node *curr, Shader *shader, Matrix model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parse_args(int argc, char* argv[]) {
|
||||||
|
int curr = 1;
|
||||||
|
while (curr < argc) {
|
||||||
|
if (argv[curr][0] == '-') {
|
||||||
|
switch(argv[curr][1]) {
|
||||||
|
case 'l':
|
||||||
|
++curr;
|
||||||
|
script_type = argv[curr][0];
|
||||||
|
++curr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chdir(argv[curr]);
|
||||||
|
++curr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (argc == 2) {
|
parse_args(argc, argv);
|
||||||
chdir(argv[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Window window;
|
Window window;
|
||||||
window.Init();
|
window.Init();
|
||||||
@ -69,7 +88,7 @@ int main(int argc, char *argv[]) {
|
|||||||
root = Node::GetRoot();
|
root = Node::GetRoot();
|
||||||
|
|
||||||
Input *input = Input::GetInstance();
|
Input *input = Input::GetInstance();
|
||||||
input->Use(&window);
|
input->Use(window);
|
||||||
|
|
||||||
Camera defaultCamera;
|
Camera defaultCamera;
|
||||||
|
|
||||||
@ -84,9 +103,15 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
Matrix projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f);
|
Matrix projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f);
|
||||||
|
|
||||||
// TODO Allow multiple scripting languages
|
switch(script_type) {
|
||||||
Lua *lua = new Lua();
|
case 'l':
|
||||||
lua->Initialize();
|
sl = new Lua();
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
sl = new Guile();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sl->Initialize();
|
||||||
|
|
||||||
|
|
||||||
double lastTime = glfwGetTime();
|
double lastTime = glfwGetTime();
|
||||||
@ -97,7 +122,7 @@ int main(int argc, char *argv[]) {
|
|||||||
world->Step(delta);
|
world->Step(delta);
|
||||||
|
|
||||||
// Script update
|
// Script update
|
||||||
lua->Update(delta);
|
ScriptingLanguage::GetCurrentLanguage()->Update(delta);
|
||||||
|
|
||||||
// Delete freed nodes
|
// Delete freed nodes
|
||||||
root->DoFree();
|
root->DoFree();
|
||||||
@ -158,7 +183,7 @@ int main(int argc, char *argv[]) {
|
|||||||
lastTime = curTime;
|
lastTime = curTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua->Close();
|
ScriptingLanguage::GetCurrentLanguage()->Close();
|
||||||
window.Close();
|
window.Close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,6 @@ function init()
|
|||||||
local material
|
local material
|
||||||
local transform
|
local transform
|
||||||
|
|
||||||
couch.Input.GetInstance():SetMouseMode(couch.Input.CAPTURED)
|
|
||||||
|
|
||||||
freecam.init_camera()
|
freecam.init_camera()
|
||||||
freecam.camera:Translate(couch.Vector3(0.0, 0.0, 10.0))
|
freecam.camera:Translate(couch.Vector3(0.0, 0.0, 10.0))
|
||||||
|
|
||||||
|
5
demo/scm/exampleworld/main.scm
Normal file
5
demo/scm/exampleworld/main.scm
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
(define (init)
|
||||||
|
(display "Hello from init!")
|
||||||
|
(newline))
|
||||||
|
(display "Hello from main.scm!")
|
||||||
|
(newline)
|
@ -4,7 +4,6 @@ set_property(SOURCE couch.i PROPERTY CPLUSPLUS ON)
|
|||||||
set_property(SOURCE couch.i PROPERTY USE_TARGET_INCLUDE_DIRECTORIES ON)
|
set_property(SOURCE couch.i PROPERTY USE_TARGET_INCLUDE_DIRECTORIES ON)
|
||||||
|
|
||||||
if (LUA_ENABLED)
|
if (LUA_ENABLED)
|
||||||
## Find Lua
|
|
||||||
swig_add_library(couchlua
|
swig_add_library(couchlua
|
||||||
TYPE STATIC
|
TYPE STATIC
|
||||||
LANGUAGE lua
|
LANGUAGE lua
|
||||||
@ -17,3 +16,17 @@ if (LUA_ENABLED)
|
|||||||
couchlib
|
couchlib
|
||||||
${LUA_LIBRARIES})
|
${LUA_LIBRARIES})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (GUILE_ENABLED)
|
||||||
|
swig_add_library(couchguile
|
||||||
|
TYPE STATIC
|
||||||
|
LANGUAGE guile
|
||||||
|
SOURCES couch.i)
|
||||||
|
|
||||||
|
target_include_directories(couchguile PRIVATE "${PROJECT_SOURCE_DIR}/core")
|
||||||
|
|
||||||
|
swig_link_libraries(couchguile
|
||||||
|
PRIVATE
|
||||||
|
couchlib
|
||||||
|
${GUILE_LIBRARIES})
|
||||||
|
endif ()
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "Skybox.h"
|
#include "Skybox.h"
|
||||||
#include "Rigidbody.h"
|
#include "Rigidbody.h"
|
||||||
#include "CollisionShape.h"
|
#include "CollisionShape.h"
|
||||||
#include "Input.h"
|
|
||||||
struct RaycastResult {
|
struct RaycastResult {
|
||||||
bool hit;
|
bool hit;
|
||||||
Vector3 position;
|
Vector3 position;
|
||||||
@ -74,4 +73,3 @@ public:
|
|||||||
%include "Skybox.h"
|
%include "Skybox.h"
|
||||||
%include "Rigidbody.h"
|
%include "Rigidbody.h"
|
||||||
%include "CollisionShape.h"
|
%include "CollisionShape.h"
|
||||||
%include "Input.h"
|
|
||||||
|
Loading…
Reference in New Issue
Block a user