mirror of https://github.com/bjornbytes/lovr.git
Model:getMaterial(name|index); rm Model:setMaterial;
This commit is contained in:
parent
bd773d2d6c
commit
4d3bfea67c
|
@ -74,20 +74,26 @@ static int l_lovrModelPose(lua_State* L) {
|
||||||
|
|
||||||
static int l_lovrModelGetMaterial(lua_State* L) {
|
static int l_lovrModelGetMaterial(lua_State* L) {
|
||||||
Model* model = luax_checktype(L, 1, Model);
|
Model* model = luax_checktype(L, 1, Model);
|
||||||
Material* material = lovrModelGetMaterial(model);
|
|
||||||
luax_pushtype(L, Material, material);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_lovrModelSetMaterial(lua_State* L) {
|
uint32_t material;
|
||||||
Model* model = luax_checktype(L, 1, Model);
|
switch (lua_type(L, 2)) {
|
||||||
if (lua_isnoneornil(L, 2)) {
|
case LUA_TNUMBER:
|
||||||
lovrModelSetMaterial(model, NULL);
|
material = lua_tointeger(L, 2) - 1;
|
||||||
} else {
|
break;
|
||||||
Material* material = luax_checktype(L, 2, Material);
|
case LUA_TSTRING: {
|
||||||
lovrModelSetMaterial(model, material);
|
const char* name = lua_tostring(L, 2);
|
||||||
|
ModelData* modelData = lovrModelGetModelData(model);
|
||||||
|
uint32_t* index = map_get(&modelData->materialMap, name);
|
||||||
|
lovrAssert(index, "Model has no material named '%s'", name);
|
||||||
|
material = *index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return luaL_typerror(L, 2, "nil, number, or string");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
luax_pushtype(L, Material, lovrModelGetMaterial(model, material));
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_lovrModelGetAABB(lua_State* L) {
|
static int l_lovrModelGetAABB(lua_State* L) {
|
||||||
|
@ -138,7 +144,6 @@ const luaL_Reg lovrModel[] = {
|
||||||
{ "animate", l_lovrModelAnimate },
|
{ "animate", l_lovrModelAnimate },
|
||||||
{ "pose", l_lovrModelPose },
|
{ "pose", l_lovrModelPose },
|
||||||
{ "getMaterial", l_lovrModelGetMaterial },
|
{ "getMaterial", l_lovrModelGetMaterial },
|
||||||
{ "setMaterial", l_lovrModelSetMaterial },
|
|
||||||
{ "getAABB", l_lovrModelGetAABB },
|
{ "getAABB", l_lovrModelGetAABB },
|
||||||
{ "getNodePose", l_lovrModelGetNodePose },
|
{ "getNodePose", l_lovrModelGetNodePose },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
|
|
|
@ -21,7 +21,6 @@ struct Model {
|
||||||
struct Mesh** meshes;
|
struct Mesh** meshes;
|
||||||
struct Texture** textures;
|
struct Texture** textures;
|
||||||
struct Material** materials;
|
struct Material** materials;
|
||||||
struct Material* userMaterial;
|
|
||||||
NodeTransform* localTransforms;
|
NodeTransform* localTransforms;
|
||||||
float* globalTransforms;
|
float* globalTransforms;
|
||||||
bool transformsDirty;
|
bool transformsDirty;
|
||||||
|
@ -48,34 +47,27 @@ static void updateGlobalTransform(Model* model, uint32_t nodeIndex, mat4 parent)
|
||||||
static void renderNode(Model* model, uint32_t nodeIndex, uint32_t instances) {
|
static void renderNode(Model* model, uint32_t nodeIndex, uint32_t instances) {
|
||||||
ModelNode* node = &model->data->nodes[nodeIndex];
|
ModelNode* node = &model->data->nodes[nodeIndex];
|
||||||
mat4 globalTransform = model->globalTransforms + 16 * nodeIndex;
|
mat4 globalTransform = model->globalTransforms + 16 * nodeIndex;
|
||||||
|
float poseMatrix[16 * MAX_BONES];
|
||||||
|
float* pose = NULL;
|
||||||
|
|
||||||
if (node->primitiveCount > 0) {
|
if (node->skin != ~0u) {
|
||||||
bool animated = node->skin != ~0u;
|
ModelSkin* skin = &model->data->skins[node->skin];
|
||||||
float pose[16 * MAX_BONES];
|
pose = poseMatrix;
|
||||||
|
|
||||||
if (animated) {
|
for (uint32_t j = 0; j < skin->jointCount; j++) {
|
||||||
ModelSkin* skin = &model->data->skins[node->skin];
|
mat4 globalJointTransform = model->globalTransforms + 16 * skin->joints[j];
|
||||||
|
mat4 inverseBindMatrix = skin->inverseBindMatrices + 16 * j;
|
||||||
|
mat4 jointPose = pose + 16 * j;
|
||||||
|
|
||||||
for (uint32_t j = 0; j < skin->jointCount; j++) {
|
mat4_set(jointPose, globalTransform);
|
||||||
mat4 globalJointTransform = model->globalTransforms + 16 * skin->joints[j];
|
mat4_invert(jointPose);
|
||||||
mat4 inverseBindMatrix = skin->inverseBindMatrices + 16 * j;
|
mat4_multiply(jointPose, globalJointTransform);
|
||||||
mat4 jointPose = pose + 16 * j;
|
mat4_multiply(jointPose, inverseBindMatrix);
|
||||||
|
|
||||||
mat4_set(jointPose, globalTransform);
|
|
||||||
mat4_invert(jointPose);
|
|
||||||
mat4_multiply(jointPose, globalJointTransform);
|
|
||||||
mat4_multiply(jointPose, inverseBindMatrix);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < node->primitiveCount; i++) {
|
for (uint32_t i = 0; i < node->primitiveCount; i++) {
|
||||||
ModelPrimitive* primitive = &model->data->primitives[node->primitiveIndex + i];
|
lovrGraphicsDrawMesh(model->meshes[node->primitiveIndex + i], globalTransform, instances, pose);
|
||||||
Mesh* mesh = model->meshes[node->primitiveIndex + i];
|
|
||||||
Material* material = primitive->material == ~0u ? NULL : model->materials[primitive->material];
|
|
||||||
lovrMeshSetMaterial(mesh, model->userMaterial ? model->userMaterial : material);
|
|
||||||
lovrMeshSetDrawMode(mesh, primitive->mode);
|
|
||||||
lovrGraphicsDrawMesh(mesh, globalTransform, instances, animated ? pose : NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < node->childCount; i++) {
|
for (uint32_t i = 0; i < node->childCount; i++) {
|
||||||
|
@ -88,6 +80,45 @@ Model* lovrModelCreate(ModelData* data) {
|
||||||
model->data = data;
|
model->data = data;
|
||||||
lovrRetain(data);
|
lovrRetain(data);
|
||||||
|
|
||||||
|
// Materials
|
||||||
|
if (data->materialCount > 0) {
|
||||||
|
model->materials = malloc(data->materialCount * sizeof(Material*));
|
||||||
|
|
||||||
|
if (data->textureCount > 0) {
|
||||||
|
model->textures = calloc(data->textureCount, sizeof(Texture*));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < data->materialCount; i++) {
|
||||||
|
Material* material = lovrMaterialCreate();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < MAX_MATERIAL_SCALARS; j++) {
|
||||||
|
lovrMaterialSetScalar(material, j, data->materials[i].scalars[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < MAX_MATERIAL_COLORS; j++) {
|
||||||
|
lovrMaterialSetColor(material, j, data->materials[i].colors[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < MAX_MATERIAL_TEXTURES; j++) {
|
||||||
|
uint32_t index = data->materials[i].textures[j];
|
||||||
|
|
||||||
|
if (index != ~0u) {
|
||||||
|
if (!model->textures[index]) {
|
||||||
|
TextureData* textureData = data->textures[index];
|
||||||
|
bool srgb = j == TEXTURE_DIFFUSE || j == TEXTURE_EMISSIVE;
|
||||||
|
model->textures[index] = lovrTextureCreate(TEXTURE_2D, &textureData, 1, srgb, true, 0);
|
||||||
|
lovrTextureSetFilter(model->textures[index], data->materials[i].filters[j]);
|
||||||
|
lovrTextureSetWrap(model->textures[index], data->materials[i].wraps[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
lovrMaterialSetTexture(material, j, model->textures[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model->materials[i] = material;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Geometry
|
// Geometry
|
||||||
if (data->primitiveCount > 0) {
|
if (data->primitiveCount > 0) {
|
||||||
if (data->bufferCount > 0) {
|
if (data->bufferCount > 0) {
|
||||||
|
@ -99,6 +130,10 @@ Model* lovrModelCreate(ModelData* data) {
|
||||||
ModelPrimitive* primitive = &data->primitives[i];
|
ModelPrimitive* primitive = &data->primitives[i];
|
||||||
model->meshes[i] = lovrMeshCreate(primitive->mode, NULL, 0);
|
model->meshes[i] = lovrMeshCreate(primitive->mode, NULL, 0);
|
||||||
|
|
||||||
|
if (primitive->material != ~0u) {
|
||||||
|
lovrMeshSetMaterial(model->meshes[i], model->materials[primitive->material]);
|
||||||
|
}
|
||||||
|
|
||||||
bool setDrawRange = false;
|
bool setDrawRange = false;
|
||||||
for (uint32_t j = 0; j < MAX_DEFAULT_ATTRIBUTES; j++) {
|
for (uint32_t j = 0; j < MAX_DEFAULT_ATTRIBUTES; j++) {
|
||||||
if (primitive->attributes[j]) {
|
if (primitive->attributes[j]) {
|
||||||
|
@ -149,45 +184,6 @@ Model* lovrModelCreate(ModelData* data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Materials
|
|
||||||
if (data->materialCount > 0) {
|
|
||||||
model->materials = malloc(data->materialCount * sizeof(Material*));
|
|
||||||
|
|
||||||
if (data->textureCount > 0) {
|
|
||||||
model->textures = calloc(data->textureCount, sizeof(Texture*));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < data->materialCount; i++) {
|
|
||||||
Material* material = lovrMaterialCreate();
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < MAX_MATERIAL_SCALARS; j++) {
|
|
||||||
lovrMaterialSetScalar(material, j, data->materials[i].scalars[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < MAX_MATERIAL_COLORS; j++) {
|
|
||||||
lovrMaterialSetColor(material, j, data->materials[i].colors[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < MAX_MATERIAL_TEXTURES; j++) {
|
|
||||||
uint32_t index = data->materials[i].textures[j];
|
|
||||||
|
|
||||||
if (index != ~0u) {
|
|
||||||
if (!model->textures[index]) {
|
|
||||||
TextureData* textureData = data->textures[index];
|
|
||||||
bool srgb = j == TEXTURE_DIFFUSE || j == TEXTURE_EMISSIVE;
|
|
||||||
model->textures[index] = lovrTextureCreate(TEXTURE_2D, &textureData, 1, srgb, true, 0);
|
|
||||||
lovrTextureSetFilter(model->textures[index], data->materials[i].filters[j]);
|
|
||||||
lovrTextureSetWrap(model->textures[index], data->materials[i].wraps[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
lovrMaterialSetTexture(material, j, model->textures[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
model->materials[i] = material;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
model->localTransforms = malloc(sizeof(NodeTransform) * data->nodeCount);
|
model->localTransforms = malloc(sizeof(NodeTransform) * data->nodeCount);
|
||||||
model->globalTransforms = malloc(16 * sizeof(float) * data->nodeCount);
|
model->globalTransforms = malloc(16 * sizeof(float) * data->nodeCount);
|
||||||
lovrModelResetPose(model);
|
lovrModelResetPose(model);
|
||||||
|
@ -208,7 +204,6 @@ void lovrModelDestroy(void* ref) {
|
||||||
for (uint32_t i = 0; i < model->data->materialCount; i++) {
|
for (uint32_t i = 0; i < model->data->materialCount; i++) {
|
||||||
lovrRelease(Material, model->materials[i]);
|
lovrRelease(Material, model->materials[i]);
|
||||||
}
|
}
|
||||||
lovrRelease(Material, model->userMaterial);
|
|
||||||
lovrRelease(ModelData, model->data);
|
lovrRelease(ModelData, model->data);
|
||||||
free(model->globalTransforms);
|
free(model->globalTransforms);
|
||||||
free(model->localTransforms);
|
free(model->localTransforms);
|
||||||
|
@ -323,7 +318,7 @@ void lovrModelPose(Model* model, uint32_t nodeIndex, float position[4], float ro
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lovrAssert(nodeIndex < model->data->nodeCount, "Invalid node index '%d' (Model only has %d nodes)", nodeIndex, model->data->nodeCount);
|
lovrAssert(nodeIndex < model->data->nodeCount, "Invalid node index '%d' (Model only has %d node)", nodeIndex + 1, model->data->nodeCount, model->data->nodeCount == 1 ? "" : "s");
|
||||||
NodeTransform* transform = &model->localTransforms[nodeIndex];
|
NodeTransform* transform = &model->localTransforms[nodeIndex];
|
||||||
if (alpha >= 1.f) {
|
if (alpha >= 1.f) {
|
||||||
vec3_init(transform->properties[PROP_TRANSLATION], position);
|
vec3_init(transform->properties[PROP_TRANSLATION], position);
|
||||||
|
@ -351,14 +346,9 @@ void lovrModelResetPose(Model* model) {
|
||||||
model->transformsDirty = true;
|
model->transformsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material* lovrModelGetMaterial(Model* model) {
|
Material* lovrModelGetMaterial(Model* model, uint32_t material) {
|
||||||
return model->userMaterial;
|
lovrAssert(material < model->data->materialCount, "Invalid material index '%d' (Model only has %d material%s)", material + 1, model->data->materialCount, model->data->materialCount == 1 ? "" : "s");
|
||||||
}
|
return model->materials[material];
|
||||||
|
|
||||||
void lovrModelSetMaterial(Model* model, Material* material) {
|
|
||||||
lovrRetain(material);
|
|
||||||
lovrRelease(Material, model->userMaterial);
|
|
||||||
model->userMaterial = material;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void applyAABB(Model* model, uint32_t nodeIndex, float aabb[6]) {
|
static void applyAABB(Model* model, uint32_t nodeIndex, float aabb[6]) {
|
||||||
|
|
|
@ -20,6 +20,5 @@ void lovrModelAnimate(Model* model, uint32_t animationIndex, float time, float a
|
||||||
void lovrModelGetNodePose(Model* model, uint32_t nodeIndex, float position[4], float rotation[4], CoordinateSpace space);
|
void lovrModelGetNodePose(Model* model, uint32_t nodeIndex, float position[4], float rotation[4], CoordinateSpace space);
|
||||||
void lovrModelPose(Model* model, uint32_t nodeIndex, float position[4], float rotation[4], float alpha);
|
void lovrModelPose(Model* model, uint32_t nodeIndex, float position[4], float rotation[4], float alpha);
|
||||||
void lovrModelResetPose(Model* model);
|
void lovrModelResetPose(Model* model);
|
||||||
struct Material* lovrModelGetMaterial(Model* model);
|
struct Material* lovrModelGetMaterial(Model* model, uint32_t material);
|
||||||
void lovrModelSetMaterial(Model* model, struct Material* material);
|
|
||||||
void lovrModelGetAABB(Model* model, float aabb[6]);
|
void lovrModelGetAABB(Model* model, float aabb[6]);
|
||||||
|
|
Loading…
Reference in New Issue