mirror of
https://github.com/bjornbytes/lovr.git
synced 2024-07-02 12:33:52 +00:00
248 lines
7.7 KiB
C
248 lines
7.7 KiB
C
|
#include "api.h"
|
||
|
#include "graphics/graphics.h"
|
||
|
#include "data/modelData.h"
|
||
|
#include "core/maf.h"
|
||
|
#include "util.h"
|
||
|
#include <lua.h>
|
||
|
#include <lauxlib.h>
|
||
|
|
||
|
static uint32_t luax_checkanimation(lua_State* L, int index, Model* model) {
|
||
|
switch (lua_type(L, index)) {
|
||
|
case LUA_TSTRING: {
|
||
|
size_t length;
|
||
|
const char* name = lua_tolstring(L, index, &length);
|
||
|
ModelData* modelData = lovrModelGetModelData(model);
|
||
|
uint64_t animationIndex = map_get(&modelData->animationMap, hash64(name, length));
|
||
|
lovrCheck(animationIndex != MAP_NIL, "ModelData has no animation named '%s'", name);
|
||
|
return (uint32_t) animationIndex;
|
||
|
}
|
||
|
case LUA_TNUMBER: return lua_tointeger(L, index) - 1;
|
||
|
default: return luax_typeerror(L, index, "number or string"), ~0u;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint32_t luax_checknodeindex(lua_State* L, int index, Model* model) {
|
||
|
switch (lua_type(L, index)) {
|
||
|
case LUA_TSTRING: {
|
||
|
size_t length;
|
||
|
const char* name = lua_tolstring(L, index, &length);
|
||
|
ModelData* modelData = lovrModelGetModelData(model);
|
||
|
uint64_t nodeIndex = map_get(&modelData->nodeMap, hash64(name, length));
|
||
|
lovrCheck(nodeIndex != MAP_NIL, "ModelData has no node named '%s'", name);
|
||
|
return (uint32_t) nodeIndex;
|
||
|
}
|
||
|
case LUA_TNUMBER: return lua_tointeger(L, index) - 1;
|
||
|
default: return luax_typeerror(L, index, "number or string"), ~0u;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetModelData(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
luax_pushtype(L, ModelData, lovrModelGetModelData(model));
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelAnimate(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
uint32_t animation = luax_checkanimation(L, 2, model);
|
||
|
float time = luax_checkfloat(L, 3);
|
||
|
float alpha = luax_optfloat(L, 4, 1.f);
|
||
|
lovrModelAnimate(model, animation, time, alpha);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelResetPose(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
lovrModelResetPose(model);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetNodePose(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
uint32_t node = luax_checknodeindex(L, 2, model);
|
||
|
float position[4], rotation[4], angle, ax, ay, az;
|
||
|
CoordinateSpace space = luax_checkenum(L, 3, CoordinateSpace, "global");
|
||
|
lovrModelGetNodePose(model, node, position, rotation, space);
|
||
|
lua_pushnumber(L, position[0]);
|
||
|
lua_pushnumber(L, position[1]);
|
||
|
lua_pushnumber(L, position[2]);
|
||
|
quat_getAngleAxis(rotation, &angle, &ax, &ay, &az);
|
||
|
lua_pushnumber(L, angle);
|
||
|
lua_pushnumber(L, ax);
|
||
|
lua_pushnumber(L, ay);
|
||
|
lua_pushnumber(L, az);
|
||
|
return 7;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelSetNodePose(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
uint32_t node = luax_checknodeindex(L, 2, model);
|
||
|
int index = 3;
|
||
|
float position[4], rotation[4];
|
||
|
index = luax_readvec3(L, index, position, NULL);
|
||
|
index = luax_readquat(L, index, rotation, NULL);
|
||
|
float alpha = luax_optfloat(L, index, 1.f);
|
||
|
lovrModelSetNodePose(model, node, position, rotation, alpha);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetTexture(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
uint32_t index = luaL_checkinteger(L, 2);
|
||
|
Texture* texture = lovrModelGetTexture(model, index);
|
||
|
luax_pushtype(L, Texture, texture);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetMaterial(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
uint32_t index = luaL_checkinteger(L, 2);
|
||
|
Material* material = lovrModelGetMaterial(model, index);
|
||
|
luax_pushtype(L, Material, material);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetVertexBuffer(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
Buffer* buffer = lovrModelGetVertexBuffer(model);
|
||
|
luax_pushtype(L, Buffer, buffer);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetIndexBuffer(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
Buffer* buffer = lovrModelGetIndexBuffer(model);
|
||
|
luax_pushtype(L, Buffer, buffer);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
static int l_lovrModelGetTriangles(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
float* vertices = NULL;
|
||
|
uint32_t* indices = NULL;
|
||
|
uint32_t vertexCount;
|
||
|
uint32_t indexCount;
|
||
|
lovrModelGetTriangles(model, &vertices, &vertexCount, &indices, &indexCount);
|
||
|
|
||
|
lua_createtable(L, vertexCount * 3, 0);
|
||
|
for (uint32_t i = 0; i < vertexCount; i++) {
|
||
|
lua_pushnumber(L, vertices[i]);
|
||
|
lua_rawseti(L, -2, i + 1);
|
||
|
}
|
||
|
|
||
|
lua_createtable(L, indexCount, 0);
|
||
|
for (uint32_t i = 0; i < indexCount; i++) {
|
||
|
lua_pushinteger(L, indices[i] + 1);
|
||
|
lua_rawseti(L, -2, i + 1);
|
||
|
}
|
||
|
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetTriangleCount(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
uint32_t count = lovrModelGetTriangleCount(model);
|
||
|
lua_pushinteger(L, count);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetVertexCount(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
uint32_t count = lovrModelGetVertexCount(model);
|
||
|
lua_pushinteger(L, count);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetWidth(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
float bounds[6];
|
||
|
lovrModelGetBoundingBox(model, bounds);
|
||
|
lua_pushnumber(L, bounds[1] - bounds[0]);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetHeight(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
float bounds[6];
|
||
|
lovrModelGetBoundingBox(model, bounds);
|
||
|
lua_pushnumber(L, bounds[3] - bounds[2]);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetDepth(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
float bounds[6];
|
||
|
lovrModelGetBoundingBox(model, bounds);
|
||
|
lua_pushnumber(L, bounds[5] - bounds[4]);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetDimensions(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
float bounds[6];
|
||
|
lovrModelGetBoundingBox(model, bounds);
|
||
|
lua_pushnumber(L, bounds[1] - bounds[0]);
|
||
|
lua_pushnumber(L, bounds[3] - bounds[2]);
|
||
|
lua_pushnumber(L, bounds[5] - bounds[4]);
|
||
|
return 3;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetCenter(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
float bounds[6];
|
||
|
lovrModelGetBoundingBox(model, bounds);
|
||
|
lua_pushnumber(L, (bounds[0] + bounds[1]) / 2.f);
|
||
|
lua_pushnumber(L, (bounds[2] + bounds[3]) / 2.f);
|
||
|
lua_pushnumber(L, (bounds[4] + bounds[5]) / 2.f);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetBoundingBox(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
float bounds[6];
|
||
|
lovrModelGetBoundingBox(model, bounds);
|
||
|
lua_pushnumber(L, bounds[0]);
|
||
|
lua_pushnumber(L, bounds[1]);
|
||
|
lua_pushnumber(L, bounds[2]);
|
||
|
lua_pushnumber(L, bounds[3]);
|
||
|
lua_pushnumber(L, bounds[4]);
|
||
|
lua_pushnumber(L, bounds[5]);
|
||
|
return 6;
|
||
|
}
|
||
|
|
||
|
static int l_lovrModelGetBoundingSphere(lua_State* L) {
|
||
|
Model* model = luax_checktype(L, 1, Model);
|
||
|
float sphere[4];
|
||
|
lovrModelGetBoundingSphere(model, sphere);
|
||
|
lua_pushnumber(L, sphere[0]);
|
||
|
lua_pushnumber(L, sphere[1]);
|
||
|
lua_pushnumber(L, sphere[2]);
|
||
|
lua_pushnumber(L, sphere[3]);
|
||
|
return 4;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
const luaL_Reg lovrModel[] = {
|
||
|
{ "getModelData", l_lovrModelGetModelData },
|
||
|
{ "animate", l_lovrModelAnimate },
|
||
|
{ "resetPose", l_lovrModelResetPose },
|
||
|
{ "getNodePose", l_lovrModelGetNodePose },
|
||
|
{ "setNodePose", l_lovrModelSetNodePose },
|
||
|
{ "getTexture", l_lovrModelGetTexture },
|
||
|
{ "getMaterial", l_lovrModelGetMaterial },
|
||
|
{ "getVertexBuffer", l_lovrModelGetVertexBuffer },
|
||
|
{ "getIndexBuffer", l_lovrModelGetIndexBuffer },
|
||
|
/*{ "getTriangles", l_lovrModelGetTriangles },
|
||
|
{ "getTriangleCount", l_lovrModelGetTriangleCount },
|
||
|
{ "getVertexCount", l_lovrModelGetVertexCount },
|
||
|
{ "getWidth", l_lovrModelGetWidth },
|
||
|
{ "getHeight", l_lovrModelGetHeight },
|
||
|
{ "getDepth", l_lovrModelGetDepth },
|
||
|
{ "getDimensions", l_lovrModelGetDimensions },
|
||
|
{ "getCenter", l_lovrModelGetCenter },
|
||
|
{ "getBoundingBox", l_lovrModelGetBoundingBox },
|
||
|
{ "getBoundingSphere", l_lovrModelGetBoundingSphere },*/
|
||
|
{ NULL, NULL }
|
||
|
};
|