1
0
Fork 0
mirror of https://github.com/bjornbytes/lovr.git synced 2024-07-02 12:33:52 +00:00
lovr/src/api/l_graphics_model.c

260 lines
8.3 KiB
C
Raw Normal View History

#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* data = lovrModelGetInfo(model)->data;
uint64_t animationIndex = map_get(&data->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* data = lovrModelGetInfo(model)->data;
uint64_t nodeIndex = map_get(&data->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);
ModelData* data = lovrModelGetInfo(model)->data;
luax_pushtype(L, ModelData, data);
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);
ModelData* data = lovrModelGetInfo(model)->data;
float* vertices = NULL;
uint32_t* indices = NULL;
uint32_t vertexCount = 0;
uint32_t indexCount = 0;
lovrModelDataGetTriangles(data, &vertices, &indices, &vertexCount, &indexCount);
lua_createtable(L, vertexCount * 3, 0);
for (uint32_t i = 0; i < vertexCount * 3; 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);
ModelData* data = lovrModelGetInfo(model)->data;
uint32_t vertexCount, indexCount;
lovrModelDataGetTriangles(data, NULL, NULL, &vertexCount, &indexCount);
lua_pushinteger(L, indexCount / 3);
return 1;
}
static int l_lovrModelGetVertexCount(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
uint32_t vertexCount, indexCount;
lovrModelDataGetTriangles(data, NULL, NULL, &vertexCount, &indexCount);
lua_pushinteger(L, vertexCount);
return 1;
}
static int l_lovrModelGetWidth(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, bounds[1] - bounds[0]);
return 1;
}
static int l_lovrModelGetHeight(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, bounds[3] - bounds[2]);
return 1;
}
static int l_lovrModelGetDepth(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, bounds[5] - bounds[4]);
return 1;
}
static int l_lovrModelGetDimensions(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, 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);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, 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 3;
}
static int l_lovrModelGetBoundingBox(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, 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);
ModelData* data = lovrModelGetInfo(model)->data;
float sphere[4];
lovrModelDataGetBoundingSphere(data, 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 }
};