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* blobs;
jsmntok_t* views;
jsmntok_t* images;
jsmntok_t* nodes;
jsmntok_t* meshes;
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);
token += nomValue(json, token, 1, 0);
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);
case HASH16("images"):
info->images = token;
model->imageCount = token->size;
info->totalSize += token->size * sizeof(TextureData);
token += nomValue(json, token, 1, 0);
break;
case HASH16("meshes"):
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);
info->totalSize += model->primitiveCount * sizeof(ModelPrimitive);
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"):
info->skins = token;
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;
int childIndex = 0;
int count = (token++)->size; // Enter array
int count = (token++)->size;
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
TextureData** image = &model->images[i];
int keyCount = (token++)->size;
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);
}
case HASH16("bufferView"): {
int viewIndex = NOM_INT(json, token);
ModelView* view = &model->views[viewIndex];
void* data = (uint8_t*) model->blobs[view->blob].data + view->offset;
Blob* blob = lovrBlobCreate(data, view->length, NULL);
*image = lovrTextureDataCreateFromBlob(blob, true);
blob->data = NULL; // FIXME
lovrRelease(blob);
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);
}
case HASH16("uri"): {
size_t size = 0;
char* uri = (char*) json + token->start;
size_t length = token->end - token->start;
uri[length] = '\0'; // Change the quote into a terminator (I'll be b0k)
void* data = io.read(uri, &size);
lovrAssert(data && size > 0, "Unable to read image at '%s'", uri);
uri[length] = '"';
Blob* blob = lovrBlobCreate(data, size, NULL);
*image = lovrTextureDataCreateFromBlob(blob, true);
lovrRelease(blob);
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) {
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->blobs = (ModelBlob*) (model->data + offset), offset += model->blobCount * sizeof(ModelBlob);
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->meshes = (ModelMesh*) (model->data + offset), offset += model->meshCount * sizeof(ModelMesh);
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);
parseBlobs(jsonData, info.blobs, model, io, (void*) binData);
parseViews(jsonData, info.views, model);
parseNodes(jsonData, info.nodes, model);
parseImages(jsonData, info.images, model, io);
parseMeshes(jsonData, info.meshes, model);
parseNodes(jsonData, info.nodes, model);
parseSkins(jsonData, info.skins, model);
return model;

View File

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

View File

@ -1,3 +1,4 @@
#include "data/modelData.h"
#include "graphics/texture.h"
#include "graphics/shader.h"
#include "util.h"
@ -5,29 +6,6 @@
#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 {
Ref ref;
float scalars[MAX_MATERIAL_SCALARS];