mirror of https://github.com/bjornbytes/lovr.git
Rearrange some ModelData stuff;
This commit is contained in:
parent
7de6bdf242
commit
fb42bf3fbb
|
@ -50,7 +50,7 @@ StringEntry lovrDrawMode[] = {
|
|||
};
|
||||
|
||||
StringEntry lovrMaterialColor[] = {
|
||||
[COLOR_DIFFUSE] = ENTRY("diffuse"),
|
||||
[COLOR_BASE] = ENTRY("base"),
|
||||
[COLOR_EMISSIVE] = ENTRY("emissive"),
|
||||
{ 0 }
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ StringEntry lovrMaterialScalar[] = {
|
|||
};
|
||||
|
||||
StringEntry lovrMaterialTexture[] = {
|
||||
[TEXTURE_DIFFUSE] = ENTRY("diffuse"),
|
||||
[TEXTURE_COLOR] = ENTRY("color"),
|
||||
[TEXTURE_EMISSIVE] = ENTRY("emissive"),
|
||||
[TEXTURE_METALNESS] = ENTRY("metalness"),
|
||||
[TEXTURE_ROUGHNESS] = ENTRY("roughness"),
|
||||
|
|
|
@ -392,11 +392,21 @@ static int l_lovrModelDataGetMaterialName(lua_State* L) {
|
|||
static int l_lovrModelDataGetMaterialImage(lua_State* L) {
|
||||
ModelData* model = luax_checktype(L, 1, ModelData);
|
||||
ModelMaterial* material = luax_checkmaterial(L, 2, model);
|
||||
MaterialTexture type = luax_checkenum(L, 3, MaterialTexture, "diffuse");
|
||||
if (material->images[type] == ~0u) {
|
||||
MaterialTexture type = luax_checkenum(L, 3, MaterialTexture, "color");
|
||||
uint32_t index = ~0u;
|
||||
switch (type) {
|
||||
case TEXTURE_COLOR: index = material->colorTexture; break;
|
||||
case TEXTURE_EMISSIVE: index = material->emissiveTexture; break;
|
||||
case TEXTURE_METALNESS: index = material->metalnessRoughnessTexture; break;
|
||||
case TEXTURE_ROUGHNESS: index = material->metalnessRoughnessTexture; break;
|
||||
case TEXTURE_OCCLUSION: index = material->occlusionTexture; break;
|
||||
case TEXTURE_NORMAL: index = material->normalTexture; break;
|
||||
default: lovrUnreachable(); return 0;
|
||||
}
|
||||
if (index == ~0u) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
lua_pushinteger(L, material->images[type] + 1);
|
||||
lua_pushinteger(L, index + 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -404,20 +414,33 @@ static int l_lovrModelDataGetMaterialImage(lua_State* L) {
|
|||
static int l_lovrModelDataGetMaterialColor(lua_State* L) {
|
||||
ModelData* model = luax_checktype(L, 1, ModelData);
|
||||
ModelMaterial* material = luax_checkmaterial(L, 2, model);
|
||||
MaterialColor type = luax_checkenum(L, 3, MaterialColor, "diffuse");
|
||||
lua_pushnumber(L, material->colors[type][0]);
|
||||
lua_pushnumber(L, material->colors[type][1]);
|
||||
lua_pushnumber(L, material->colors[type][2]);
|
||||
lua_pushnumber(L, material->colors[type][3]);
|
||||
return 4;
|
||||
MaterialColor type = luax_checkenum(L, 3, MaterialColor, "base");
|
||||
switch (type) {
|
||||
case COLOR_BASE:
|
||||
lua_pushnumber(L, material->baseColor[0]);
|
||||
lua_pushnumber(L, material->baseColor[1]);
|
||||
lua_pushnumber(L, material->baseColor[2]);
|
||||
lua_pushnumber(L, material->baseColor[3]);
|
||||
return 4;
|
||||
case COLOR_EMISSIVE:
|
||||
lua_pushnumber(L, material->emissiveColor[0]);
|
||||
lua_pushnumber(L, material->emissiveColor[1]);
|
||||
lua_pushnumber(L, material->emissiveColor[2]);
|
||||
lua_pushnumber(L, 1.f);
|
||||
return 4;
|
||||
default: lovrUnreachable(); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int l_lovrModelDataGetMaterialValue(lua_State* L) {
|
||||
ModelData* model = luax_checktype(L, 1, ModelData);
|
||||
ModelMaterial* material = luax_checkmaterial(L, 2, model);
|
||||
MaterialScalar type = luax_checkenum(L, 3, MaterialScalar, NULL);
|
||||
lua_pushnumber(L, material->scalars[type]);
|
||||
return 1;
|
||||
switch (type) {
|
||||
case SCALAR_METALNESS: lua_pushnumber(L, material->metalness); return 1;
|
||||
case SCALAR_ROUGHNESS: lua_pushnumber(L, material->roughness); return 1;
|
||||
default: lovrUnreachable(); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int l_lovrModelDataGetAnimationCount(lua_State* L) {
|
||||
|
|
|
@ -5,11 +5,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define MAX_BONES 48
|
||||
|
||||
struct Blob;
|
||||
struct Image;
|
||||
|
||||
typedef struct {
|
||||
uint32_t blob;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
size_t stride;
|
||||
char* data;
|
||||
} ModelBuffer;
|
||||
|
||||
typedef enum {
|
||||
ATTR_POSITION,
|
||||
ATTR_NORMAL,
|
||||
|
@ -21,51 +27,6 @@ typedef enum {
|
|||
MAX_DEFAULT_ATTRIBUTES
|
||||
} DefaultAttribute;
|
||||
|
||||
typedef enum {
|
||||
DRAW_POINTS,
|
||||
DRAW_LINES,
|
||||
DRAW_LINE_LOOP,
|
||||
DRAW_LINE_STRIP,
|
||||
DRAW_TRIANGLES,
|
||||
DRAW_TRIANGLE_STRIP,
|
||||
DRAW_TRIANGLE_FAN
|
||||
} DrawMode;
|
||||
|
||||
typedef enum {
|
||||
SCALAR_METALNESS,
|
||||
SCALAR_ROUGHNESS,
|
||||
SCALAR_ALPHA_CUTOFF,
|
||||
MAX_MATERIAL_SCALARS
|
||||
} MaterialScalar;
|
||||
|
||||
typedef enum {
|
||||
COLOR_DIFFUSE,
|
||||
COLOR_EMISSIVE,
|
||||
MAX_MATERIAL_COLORS
|
||||
} MaterialColor;
|
||||
|
||||
typedef enum {
|
||||
TEXTURE_DIFFUSE,
|
||||
TEXTURE_EMISSIVE,
|
||||
TEXTURE_METALNESS,
|
||||
TEXTURE_ROUGHNESS,
|
||||
TEXTURE_OCCLUSION,
|
||||
TEXTURE_NORMAL,
|
||||
MAX_MATERIAL_TEXTURES
|
||||
} MaterialTexture;
|
||||
|
||||
typedef enum {
|
||||
SMOOTH_STEP,
|
||||
SMOOTH_LINEAR,
|
||||
SMOOTH_CUBIC
|
||||
} SmoothMode;
|
||||
|
||||
typedef enum {
|
||||
PROP_TRANSLATION,
|
||||
PROP_ROTATION,
|
||||
PROP_SCALE,
|
||||
} AnimationProperty;
|
||||
|
||||
typedef enum { I8, U8, I16, U16, I32, U32, F32 } AttributeType;
|
||||
|
||||
typedef union {
|
||||
|
@ -79,14 +40,6 @@ typedef union {
|
|||
float* f32;
|
||||
} AttributeData;
|
||||
|
||||
typedef struct {
|
||||
uint32_t blob;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
size_t stride;
|
||||
char* data;
|
||||
} ModelBuffer;
|
||||
|
||||
typedef struct {
|
||||
uint32_t offset;
|
||||
uint32_t buffer;
|
||||
|
@ -101,6 +54,72 @@ typedef struct {
|
|||
float max[4];
|
||||
} ModelAttribute;
|
||||
|
||||
typedef enum {
|
||||
DRAW_POINTS,
|
||||
DRAW_LINES,
|
||||
DRAW_LINE_LOOP,
|
||||
DRAW_LINE_STRIP,
|
||||
DRAW_TRIANGLES,
|
||||
DRAW_TRIANGLE_STRIP,
|
||||
DRAW_TRIANGLE_FAN
|
||||
} DrawMode;
|
||||
|
||||
typedef struct {
|
||||
ModelAttribute* attributes[MAX_DEFAULT_ATTRIBUTES];
|
||||
ModelAttribute* indices;
|
||||
DrawMode mode;
|
||||
uint32_t material;
|
||||
} ModelPrimitive;
|
||||
|
||||
typedef enum {
|
||||
SCALAR_METALNESS,
|
||||
SCALAR_ROUGHNESS,
|
||||
SCALAR_ALPHA_CUTOFF,
|
||||
MAX_MATERIAL_SCALARS
|
||||
} MaterialScalar;
|
||||
|
||||
typedef enum {
|
||||
COLOR_BASE,
|
||||
COLOR_EMISSIVE,
|
||||
MAX_MATERIAL_COLORS
|
||||
} MaterialColor;
|
||||
|
||||
typedef enum {
|
||||
TEXTURE_COLOR,
|
||||
TEXTURE_EMISSIVE,
|
||||
TEXTURE_METALNESS,
|
||||
TEXTURE_ROUGHNESS,
|
||||
TEXTURE_OCCLUSION,
|
||||
TEXTURE_NORMAL,
|
||||
MAX_MATERIAL_TEXTURES
|
||||
} MaterialTexture;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
float metalness;
|
||||
float roughness;
|
||||
float alphaCutoff;
|
||||
float baseColor[4];
|
||||
float emissiveColor[4];
|
||||
uint32_t colorTexture;
|
||||
uint32_t emissiveTexture;
|
||||
uint32_t metalnessRoughnessTexture;
|
||||
uint32_t occlusionTexture;
|
||||
uint32_t normalTexture;
|
||||
} ModelMaterial;
|
||||
|
||||
typedef enum {
|
||||
PROP_TRANSLATION,
|
||||
PROP_ROTATION,
|
||||
PROP_SCALE,
|
||||
} AnimationProperty;
|
||||
|
||||
typedef enum {
|
||||
SMOOTH_STEP,
|
||||
SMOOTH_LINEAR,
|
||||
SMOOTH_CUBIC
|
||||
} SmoothMode;
|
||||
|
||||
typedef struct {
|
||||
uint32_t nodeIndex;
|
||||
AnimationProperty property;
|
||||
|
@ -118,18 +137,10 @@ typedef struct {
|
|||
} ModelAnimation;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
float scalars[MAX_MATERIAL_SCALARS];
|
||||
float colors[MAX_MATERIAL_COLORS][4];
|
||||
uint32_t images[MAX_MATERIAL_TEXTURES];
|
||||
} ModelMaterial;
|
||||
|
||||
typedef struct {
|
||||
ModelAttribute* attributes[MAX_DEFAULT_ATTRIBUTES];
|
||||
ModelAttribute* indices;
|
||||
DrawMode mode;
|
||||
uint32_t material;
|
||||
} ModelPrimitive;
|
||||
uint32_t* joints;
|
||||
uint32_t jointCount;
|
||||
float* inverseBindMatrices;
|
||||
} ModelSkin;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
|
@ -149,32 +160,27 @@ typedef struct {
|
|||
bool matrix;
|
||||
} ModelNode;
|
||||
|
||||
typedef struct {
|
||||
uint32_t* joints;
|
||||
uint32_t jointCount;
|
||||
float* inverseBindMatrices;
|
||||
} ModelSkin;
|
||||
|
||||
typedef struct ModelData {
|
||||
uint32_t ref;
|
||||
void* data;
|
||||
|
||||
struct Blob** blobs;
|
||||
ModelBuffer* buffers;
|
||||
struct Image** images;
|
||||
ModelMaterial* materials;
|
||||
ModelBuffer* buffers;
|
||||
ModelAttribute* attributes;
|
||||
ModelPrimitive* primitives;
|
||||
ModelMaterial* materials;
|
||||
ModelAnimation* animations;
|
||||
ModelSkin* skins;
|
||||
ModelNode* nodes;
|
||||
uint32_t rootNode;
|
||||
|
||||
uint32_t blobCount;
|
||||
uint32_t bufferCount;
|
||||
uint32_t imageCount;
|
||||
uint32_t materialCount;
|
||||
uint32_t bufferCount;
|
||||
uint32_t attributeCount;
|
||||
uint32_t primitiveCount;
|
||||
uint32_t materialCount;
|
||||
uint32_t animationCount;
|
||||
uint32_t skinCount;
|
||||
uint32_t nodeCount;
|
||||
|
|
|
@ -73,15 +73,15 @@ static int nomValue(const char* data, jsmntok_t* token, int count, int sum) {
|
|||
}
|
||||
}
|
||||
|
||||
static jsmntok_t* nomTexture(const char* json, jsmntok_t* token, ModelMaterial* material, MaterialTexture textureType, gltfTexture* textures) {
|
||||
static jsmntok_t* nomTexture(const char* json, jsmntok_t* token, uint32_t* imageIndex, gltfTexture* textures) {
|
||||
for (int k = (token++)->size; k > 0; k--) {
|
||||
gltfString key = NOM_STR(json, token);
|
||||
if (STR_EQ(key, "index")) {
|
||||
uint32_t index = NOM_INT(json, token);
|
||||
gltfTexture* texture = &textures[index];
|
||||
material->images[textureType] = texture->image;
|
||||
*imageIndex = texture->image;
|
||||
} else if (STR_EQ(key, "texCoord")) {
|
||||
lovrAssert(NOM_INT(json, token) == 0, "Only one set of texture coordinates is supported");
|
||||
lovrAssert(NOM_INT(json, token) == 0, "Currently, only one set of texture coordinates is supported");
|
||||
} else {
|
||||
token += NOM_VALUE(json, token);
|
||||
}
|
||||
|
@ -643,12 +643,16 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
|
|||
jsmntok_t* token = info.materials;
|
||||
ModelMaterial* material = model->materials;
|
||||
for (int i = (token++)->size; i > 0; i--, material++) {
|
||||
material->scalars[SCALAR_METALNESS] = 1.f;
|
||||
material->scalars[SCALAR_ROUGHNESS] = 1.f;
|
||||
material->scalars[SCALAR_ALPHA_CUTOFF] = 0.f;
|
||||
memcpy(material->colors[COLOR_DIFFUSE], (float[4]) { 1.f, 1.f, 1.f, 1.f }, 16);
|
||||
memcpy(material->colors[COLOR_EMISSIVE], (float[4]) { 0.f, 0.f, 0.f, 0.f }, 16);
|
||||
memset(material->images, 0xff, MAX_MATERIAL_TEXTURES * sizeof(uint32_t));
|
||||
material->metalness = 1.f;
|
||||
material->roughness = 1.f;
|
||||
material->alphaCutoff = 0.f;
|
||||
memcpy(material->baseColor, (float[4]) { 1.f, 1.f, 1.f, 1.f }, 16);
|
||||
memcpy(material->emissiveColor, (float[4]) { 0.f, 0.f, 0.f, 0.f }, 16);
|
||||
material->colorTexture = ~0u;
|
||||
material->emissiveTexture = ~0u;
|
||||
material->metalnessRoughnessTexture = ~0u;
|
||||
material->occlusionTexture = ~0u;
|
||||
material->normalTexture = ~0u;
|
||||
|
||||
for (int k = (token++)->size; k > 0; k--) {
|
||||
gltfString key = NOM_STR(json, token);
|
||||
|
@ -657,36 +661,35 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
|
|||
gltfString key = NOM_STR(json, token);
|
||||
if (STR_EQ(key, "baseColorFactor")) {
|
||||
token++; // Enter array
|
||||
material->colors[COLOR_DIFFUSE][0] = NOM_FLOAT(json, token);
|
||||
material->colors[COLOR_DIFFUSE][1] = NOM_FLOAT(json, token);
|
||||
material->colors[COLOR_DIFFUSE][2] = NOM_FLOAT(json, token);
|
||||
material->colors[COLOR_DIFFUSE][3] = NOM_FLOAT(json, token);
|
||||
material->baseColor[0] = NOM_FLOAT(json, token);
|
||||
material->baseColor[1] = NOM_FLOAT(json, token);
|
||||
material->baseColor[2] = NOM_FLOAT(json, token);
|
||||
material->baseColor[3] = NOM_FLOAT(json, token);
|
||||
} else if (STR_EQ(key, "baseColorTexture")) {
|
||||
token = nomTexture(json, token, material, TEXTURE_DIFFUSE, textures);
|
||||
token = nomTexture(json, token, &material->colorTexture, textures);
|
||||
} else if (STR_EQ(key, "metallicFactor")) {
|
||||
material->scalars[SCALAR_METALNESS] = NOM_FLOAT(json, token);
|
||||
material->metalness = NOM_FLOAT(json, token);
|
||||
} else if (STR_EQ(key, "roughnessFactor")) {
|
||||
material->scalars[SCALAR_ROUGHNESS] = NOM_FLOAT(json, token);
|
||||
material->roughness = NOM_FLOAT(json, token);
|
||||
} else if (STR_EQ(key, "metallicRoughnessTexture")) {
|
||||
token = nomTexture(json, token, material, TEXTURE_METALNESS, textures);
|
||||
material->images[TEXTURE_ROUGHNESS] = material->images[TEXTURE_METALNESS];
|
||||
token = nomTexture(json, token, &material->metalnessRoughnessTexture, textures);
|
||||
} else {
|
||||
token += NOM_VALUE(json, token);
|
||||
}
|
||||
}
|
||||
} else if (STR_EQ(key, "normalTexture")) {
|
||||
token = nomTexture(json, token, material, TEXTURE_NORMAL, textures);
|
||||
token = nomTexture(json, token, &material->normalTexture, textures);
|
||||
} else if (STR_EQ(key, "occlusionTexture")) {
|
||||
token = nomTexture(json, token, material, TEXTURE_OCCLUSION, textures);
|
||||
token = nomTexture(json, token, &material->occlusionTexture, textures);
|
||||
} else if (STR_EQ(key, "emissiveTexture")) {
|
||||
token = nomTexture(json, token, material, TEXTURE_EMISSIVE, textures);
|
||||
token = nomTexture(json, token, &material->emissiveTexture, textures);
|
||||
} else if (STR_EQ(key, "emissiveFactor")) {
|
||||
token++; // Enter array
|
||||
material->colors[COLOR_EMISSIVE][0] = NOM_FLOAT(json, token);
|
||||
material->colors[COLOR_EMISSIVE][1] = NOM_FLOAT(json, token);
|
||||
material->colors[COLOR_EMISSIVE][2] = NOM_FLOAT(json, token);
|
||||
material->emissiveColor[0] = NOM_FLOAT(json, token);
|
||||
material->emissiveColor[1] = NOM_FLOAT(json, token);
|
||||
material->emissiveColor[2] = NOM_FLOAT(json, token);
|
||||
} else if (STR_EQ(key, "alphaCutoff")) {
|
||||
material->scalars[SCALAR_ALPHA_CUTOFF] = NOM_FLOAT(json, token);
|
||||
material->alphaCutoff = NOM_FLOAT(json, token);
|
||||
} else if (STR_EQ(key, "name")) {
|
||||
gltfString name = NOM_STR(json, token);
|
||||
map_set(&model->materialMap, hash64(name.data, name.length), model->materialCount - i);
|
||||
|
|
|
@ -47,12 +47,17 @@ static void parseMtl(char* path, char* base, ModelDataIO* io, arr_image_t* image
|
|||
if (STARTS_WITH(line, "newmtl ")) {
|
||||
map_set(names, hash64(line + 7, length - 7), materials->length);
|
||||
arr_push(materials, ((ModelMaterial) {
|
||||
.scalars[SCALAR_METALNESS] = 1.f,
|
||||
.scalars[SCALAR_ROUGHNESS] = 1.f,
|
||||
.colors[COLOR_DIFFUSE] = { 1.f, 1.f, 1.f, 1.f },
|
||||
.colors[COLOR_EMISSIVE] = { 0.f, 0.f, 0.f, 0.f }
|
||||
.metalness = 1.f,
|
||||
.roughness = 1.f,
|
||||
.alphaCutoff = 0.f,
|
||||
.baseColor = { 1.f, 1.f, 1.f, 1.f },
|
||||
.emissiveColor = { 0.f, 0.f, 0.f, 0.f },
|
||||
.colorTexture = ~0u,
|
||||
.emissiveTexture = ~0u,
|
||||
.metalnessRoughnessTexture = ~0u,
|
||||
.occlusionTexture = ~0u,
|
||||
.normalTexture = ~0u
|
||||
}));
|
||||
memset(&materials->data[materials->length - 1].images, 0xff, MAX_MATERIAL_TEXTURES * sizeof(int));
|
||||
} else if (line[0] == 'K' && line[1] == 'd' && line[2] == ' ') {
|
||||
float r, g, b;
|
||||
char* s = line + 3;
|
||||
|
@ -60,7 +65,7 @@ static void parseMtl(char* path, char* base, ModelDataIO* io, arr_image_t* image
|
|||
g = strtof(s, &s);
|
||||
b = strtof(s, &s);
|
||||
ModelMaterial* material = &materials->data[materials->length - 1];
|
||||
memcpy(material->colors[COLOR_DIFFUSE], (float[4]) { r, g, b, 1.f }, 16);
|
||||
memcpy(material->baseColor, (float[4]) { r, g, b, 1.f }, 16);
|
||||
} else if (STARTS_WITH(line, "map_Kd ")) {
|
||||
lovrAssert(base - path + (length - 7) < 1024, "Bad OBJ: Material image filename is too long");
|
||||
memcpy(base, line + 7, length - 7);
|
||||
|
@ -74,7 +79,7 @@ static void parseMtl(char* path, char* base, ModelDataIO* io, arr_image_t* image
|
|||
Image* image = lovrImageCreateFromFile(blob);
|
||||
lovrAssert(materials->length > 0, "Tried to set a material property without declaring a material first");
|
||||
ModelMaterial* material = &materials->data[materials->length - 1];
|
||||
material->images[TEXTURE_DIFFUSE] = (uint32_t) images->length;
|
||||
material->colorTexture = (uint32_t) images->length;
|
||||
arr_push(images, image);
|
||||
lovrRelease(blob, lovrBlobDestroy);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue