Parse images;

This commit is contained in:
bjorn 2018-12-17 14:40:07 -08:00 committed by Bjorn Swenson
parent 4ed3cad851
commit 92aa1a234b
3 changed files with 140 additions and 81 deletions

View File

@ -19,6 +19,7 @@ typedef struct {
jsmntok_t* animations; jsmntok_t* animations;
jsmntok_t* blobs; jsmntok_t* blobs;
jsmntok_t* views; jsmntok_t* views;
jsmntok_t* images;
jsmntok_t* nodes; jsmntok_t* nodes;
jsmntok_t* meshes; jsmntok_t* meshes;
jsmntok_t* skins; jsmntok_t* skins;
@ -101,12 +102,11 @@ static void preparse(const char* json, jsmntok_t* tokens, int tokenCount, ModelD
info->totalSize += token->size * sizeof(ModelView); info->totalSize += token->size * sizeof(ModelView);
token += nomValue(json, token, 1, 0); token += nomValue(json, token, 1, 0);
break; break;
case HASH16("nodes"): case HASH16("images"):
info->nodes = token; info->images = token;
model->nodeCount = token->size; model->imageCount = token->size;
info->totalSize += token->size * sizeof(ModelNode); info->totalSize += token->size * sizeof(TextureData);
token = aggregate(json, token, HASH16("children"), &info->childCount); token += nomValue(json, token, 1, 0);
info->totalSize += info->childCount * sizeof(uint32_t);
break; break;
case HASH16("meshes"): case HASH16("meshes"):
info->meshes = token; info->meshes = token;
@ -115,6 +115,13 @@ static void preparse(const char* json, jsmntok_t* tokens, int tokenCount, ModelD
token = aggregate(json, token, HASH16("primitives"), &model->primitiveCount); token = aggregate(json, token, HASH16("primitives"), &model->primitiveCount);
info->totalSize += model->primitiveCount * sizeof(ModelPrimitive); info->totalSize += model->primitiveCount * sizeof(ModelPrimitive);
break; break;
case HASH16("nodes"):
info->nodes = token;
model->nodeCount = token->size;
info->totalSize += token->size * sizeof(ModelNode);
token = aggregate(json, token, HASH16("children"), &info->childCount);
info->totalSize += info->childCount * sizeof(uint32_t);
break;
case HASH16("skins"): case HASH16("skins"):
info->skins = token; info->skins = token;
model->skinCount = token->size; model->skinCount = token->size;
@ -304,67 +311,41 @@ static void parseViews(const char* json, jsmntok_t* token, ModelData* model) {
} }
} }
static void parseNodes(const char* json, jsmntok_t* token, ModelData* model) { static void parseImages(const char* json, jsmntok_t* token, ModelData* model, ModelDataIO io) {
if (!token) return; if (!token) return;
int childIndex = 0; int count = (token++)->size;
int count = (token++)->size; // Enter array
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
ModelNode* node = &model->nodes[i]; TextureData** image = &model->images[i];
float translation[3] = { 0, 0, 0 }; int keyCount = (token++)->size;
float rotation[4] = { 0, 0, 0, 0 };
float scale[3] = { 1, 1, 1 };
bool matrix = false;
int keyCount = (token++)->size; // Enter object
for (int k = 0; k < keyCount; k++) { for (int k = 0; k < keyCount; k++) {
switch (NOM_KEY(json, token)) { switch (NOM_KEY(json, token)) {
case HASH16("mesh"): node->mesh = NOM_INT(json, token); break; case HASH16("bufferView"): {
case HASH16("skin"): node->skin = NOM_INT(json, token); break; int viewIndex = NOM_INT(json, token);
case HASH16("children"): ModelView* view = &model->views[viewIndex];
node->children = &model->nodeChildren[childIndex]; void* data = (uint8_t*) model->blobs[view->blob].data + view->offset;
node->childCount = (token++)->size; Blob* blob = lovrBlobCreate(data, view->length, NULL);
for (uint32_t j = 0; j < node->childCount; j++) { *image = lovrTextureDataCreateFromBlob(blob, true);
model->nodeChildren[childIndex++] = NOM_INT(json, token); blob->data = NULL; // FIXME
} lovrRelease(blob);
break; break;
case HASH16("matrix"): }
lovrAssert(token->size == 16, "Node matrix needs 16 elements"); case HASH16("uri"): {
matrix = true; size_t size = 0;
for (int j = 0; j < token->size; j++) { char* uri = (char*) json + token->start;
node->transform[j] = NOM_FLOAT(json, token); size_t length = token->end - token->start;
} uri[length] = '\0'; // Change the quote into a terminator (I'll be b0k)
break; void* data = io.read(uri, &size);
case HASH16("translation"): lovrAssert(data && size > 0, "Unable to read image at '%s'", uri);
lovrAssert(token->size == 3, "Node translation needs 3 elements"); uri[length] = '"';
translation[0] = NOM_FLOAT(json, token); Blob* blob = lovrBlobCreate(data, size, NULL);
translation[1] = NOM_FLOAT(json, token); *image = lovrTextureDataCreateFromBlob(blob, true);
translation[2] = NOM_FLOAT(json, token); lovrRelease(blob);
break;
case HASH16("rotation"):
lovrAssert(token->size == 4, "Node rotation needs 4 elements");
rotation[0] = NOM_FLOAT(json, token);
rotation[1] = NOM_FLOAT(json, token);
rotation[2] = NOM_FLOAT(json, token);
rotation[3] = NOM_FLOAT(json, token);
break;
case HASH16("scale"):
lovrAssert(token->size == 3, "Node scale needs 3 elements");
scale[0] = NOM_FLOAT(json, token);
scale[1] = NOM_FLOAT(json, token);
scale[2] = NOM_FLOAT(json, token);
break; break;
}
default: token += nomValue(json, token, 1, 0); break; default: token += nomValue(json, token, 1, 0); break;
} }
} }
// Fix it in post
if (!matrix) {
mat4_identity(node->transform);
mat4_translate(node->transform, translation[0], translation[1], translation[2]);
mat4_rotateQuat(node->transform, rotation);
mat4_scale(node->transform, scale[0], scale[1], scale[2]);
}
} }
} }
@ -437,6 +418,70 @@ static void parseMeshes(const char* json, jsmntok_t* token, ModelData* model) {
} }
} }
static void parseNodes(const char* json, jsmntok_t* token, ModelData* model) {
if (!token) return;
int childIndex = 0;
int count = (token++)->size; // Enter array
for (int i = 0; i < count; i++) {
ModelNode* node = &model->nodes[i];
float translation[3] = { 0, 0, 0 };
float rotation[4] = { 0, 0, 0, 0 };
float scale[3] = { 1, 1, 1 };
bool matrix = false;
int keyCount = (token++)->size; // Enter object
for (int k = 0; k < keyCount; k++) {
switch (NOM_KEY(json, token)) {
case HASH16("mesh"): node->mesh = NOM_INT(json, token); break;
case HASH16("skin"): node->skin = NOM_INT(json, token); break;
case HASH16("children"):
node->children = &model->nodeChildren[childIndex];
node->childCount = (token++)->size;
for (uint32_t j = 0; j < node->childCount; j++) {
model->nodeChildren[childIndex++] = NOM_INT(json, token);
}
break;
case HASH16("matrix"):
lovrAssert(token->size == 16, "Node matrix needs 16 elements");
matrix = true;
for (int j = 0; j < token->size; j++) {
node->transform[j] = NOM_FLOAT(json, token);
}
break;
case HASH16("translation"):
lovrAssert(token->size == 3, "Node translation needs 3 elements");
translation[0] = NOM_FLOAT(json, token);
translation[1] = NOM_FLOAT(json, token);
translation[2] = NOM_FLOAT(json, token);
break;
case HASH16("rotation"):
lovrAssert(token->size == 4, "Node rotation needs 4 elements");
rotation[0] = NOM_FLOAT(json, token);
rotation[1] = NOM_FLOAT(json, token);
rotation[2] = NOM_FLOAT(json, token);
rotation[3] = NOM_FLOAT(json, token);
break;
case HASH16("scale"):
lovrAssert(token->size == 3, "Node scale needs 3 elements");
scale[0] = NOM_FLOAT(json, token);
scale[1] = NOM_FLOAT(json, token);
scale[2] = NOM_FLOAT(json, token);
break;
default: token += nomValue(json, token, 1, 0); break;
}
}
// Fix it in post
if (!matrix) {
mat4_identity(node->transform);
mat4_translate(node->transform, translation[0], translation[1], translation[2]);
mat4_rotateQuat(node->transform, rotation);
mat4_scale(node->transform, scale[0], scale[1], scale[2]);
}
}
}
static void parseSkins(const char* json, jsmntok_t* token, ModelData* model) { static void parseSkins(const char* json, jsmntok_t* token, ModelData* model) {
if (!token) return; if (!token) return;
@ -511,6 +556,7 @@ ModelData* lovrModelDataInit(ModelData* model, Blob* blob, ModelDataIO io) {
model->animations = (ModelAnimation*) (model->data + offset), offset += model->animationCount * sizeof(ModelAnimation); model->animations = (ModelAnimation*) (model->data + offset), offset += model->animationCount * sizeof(ModelAnimation);
model->blobs = (ModelBlob*) (model->data + offset), offset += model->blobCount * sizeof(ModelBlob); model->blobs = (ModelBlob*) (model->data + offset), offset += model->blobCount * sizeof(ModelBlob);
model->views = (ModelView*) (model->data + offset), offset += model->viewCount * sizeof(ModelView); model->views = (ModelView*) (model->data + offset), offset += model->viewCount * sizeof(ModelView);
model->images = (TextureData**) (model->data + offset), offset += model->imageCount * sizeof(TextureData*);
model->primitives = (ModelPrimitive*) (model->data + offset), offset += model->primitiveCount * sizeof(ModelPrimitive); model->primitives = (ModelPrimitive*) (model->data + offset), offset += model->primitiveCount * sizeof(ModelPrimitive);
model->meshes = (ModelMesh*) (model->data + offset), offset += model->meshCount * sizeof(ModelMesh); model->meshes = (ModelMesh*) (model->data + offset), offset += model->meshCount * sizeof(ModelMesh);
model->nodes = (ModelNode*) (model->data + offset), offset += model->nodeCount * sizeof(ModelNode); model->nodes = (ModelNode*) (model->data + offset), offset += model->nodeCount * sizeof(ModelNode);
@ -522,8 +568,9 @@ ModelData* lovrModelDataInit(ModelData* model, Blob* blob, ModelDataIO io) {
parseAnimations(jsonData, info.animations, model); parseAnimations(jsonData, info.animations, model);
parseBlobs(jsonData, info.blobs, model, io, (void*) binData); parseBlobs(jsonData, info.blobs, model, io, (void*) binData);
parseViews(jsonData, info.views, model); parseViews(jsonData, info.views, model);
parseNodes(jsonData, info.nodes, model); parseImages(jsonData, info.images, model, io);
parseMeshes(jsonData, info.meshes, model); parseMeshes(jsonData, info.meshes, model);
parseNodes(jsonData, info.nodes, model);
parseSkins(jsonData, info.skins, model); parseSkins(jsonData, info.skins, model);
return model; return model;

View File

@ -1,4 +1,5 @@
#include "data/blob.h" #include "data/blob.h"
#include "data/textureData.h"
#include "util.h" #include "util.h"
#include "lib/map/map.h" #include "lib/map/map.h"
#include "lib/vec/vec.h" #include "lib/vec/vec.h"
@ -28,6 +29,29 @@ typedef enum {
DRAW_TRIANGLE_FAN DRAW_TRIANGLE_FAN
} DrawMode; } DrawMode;
typedef enum {
SCALAR_METALNESS,
SCALAR_ROUGHNESS,
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,
TEXTURE_ENVIRONMENT_MAP,
MAX_MATERIAL_TEXTURES
} MaterialTexture;
typedef enum { typedef enum {
SMOOTH_STEP, SMOOTH_STEP,
SMOOTH_LINEAR, SMOOTH_LINEAR,
@ -93,6 +117,12 @@ typedef struct {
int stride; int stride;
} ModelView; } ModelView;
typedef struct {
float scalars[MAX_MATERIAL_SCALARS];
Color colors[MAX_MATERIAL_COLORS];
int textures[MAX_MATERIAL_TEXTURES];
} ModelMaterial;
typedef struct { typedef struct {
DrawMode mode; DrawMode mode;
int attributes[MAX_DEFAULT_ATTRIBUTES]; int attributes[MAX_DEFAULT_ATTRIBUTES];
@ -153,6 +183,8 @@ typedef struct {
ModelAnimation* animations; ModelAnimation* animations;
ModelBlob* blobs; ModelBlob* blobs;
ModelView* views; ModelView* views;
TextureData** images;
ModelMaterial* materials;
ModelPrimitive* primitives; ModelPrimitive* primitives;
ModelMesh* meshes; ModelMesh* meshes;
ModelNode* nodes; ModelNode* nodes;
@ -163,6 +195,8 @@ typedef struct {
int animationCount; int animationCount;
int blobCount; int blobCount;
int viewCount; int viewCount;
int imageCount;
int materialCount;
int primitiveCount; int primitiveCount;
int meshCount; int meshCount;
int nodeCount; int nodeCount;

View File

@ -1,3 +1,4 @@
#include "data/modelData.h"
#include "graphics/texture.h" #include "graphics/texture.h"
#include "graphics/shader.h" #include "graphics/shader.h"
#include "util.h" #include "util.h"
@ -5,29 +6,6 @@
#pragma once #pragma once
typedef enum {
SCALAR_METALNESS,
SCALAR_ROUGHNESS,
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,
TEXTURE_ENVIRONMENT_MAP,
MAX_MATERIAL_TEXTURES
} MaterialTexture;
typedef struct { typedef struct {
Ref ref; Ref ref;
float scalars[MAX_MATERIAL_SCALARS]; float scalars[MAX_MATERIAL_SCALARS];