1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-01-17 21:09:00 +01:00

rooms export to GLTF (WIP)

This commit is contained in:
XProger 2021-01-08 09:00:55 +03:00
parent 764b1899e4
commit a25e42e65f
6 changed files with 306 additions and 101 deletions

View File

@ -151,11 +151,11 @@
#define _OS_X360 1
// TODO
#elif __NDLESS__
#define _OS_TNS 1
#define _GAPI_SW 1
#include <os.h>
#define _OS_TNS 1
#define _GAPI_SW 1
#include <os.h>
#undef OS_PTHREAD_MT
#undef OS_PTHREAD_MT
#endif
#if !defined(_OS_PSP) && !defined(_OS_TNS)

View File

@ -12,35 +12,226 @@
namespace Extension {
const float MESH_SCALE = 1.0f / 256.0f;
#ifdef GEOMETRY_EXPORT
void exportTexture(const char *name, Texture *tex) {
void exportTexture(const char *dir, const char *name, Texture *tex) {
char *data32 = new char[tex->width * tex->height * 4];
tex->bind(sDiffuse);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data32);
Texture::SaveBMP(name, data32, tex->width, tex->height);
char path[256];
sprintf(path, "%s/%s", dir, name);
Texture::SaveBMP(path, data32, tex->width, tex->height);
delete[] data32;
}
void exportModel(IGame *game, TR::Model &model) {
void exportRooms(IGame *game, const char *dir) {
TR::Level *level = game->getLevel();
MeshBuilder *mesh = game->getMesh();
typedef uint32 MeshIndex;
struct MeshVertex {
vec3 coord;
vec3 normal;
vec2 texCoord;
ubyte4 color;
};
char name[256];
sprintf(name, "%s/rooms.glb", dir);
LOG("export rooms: %s\n", name);
FILE *file = fopen(name, "wb");
if (!file) {
LOG("dump: can't dump rooms to file \"%s\"!\n", name);
return;
}
Index *indices = new Index[1024 * 1024];
Vertex *vertices = new Vertex[1024 * 1024];
mat4 flip = mat4(
-1, 0, 0, 0,
0, -1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
mat4 flipInv = flip.inverseOrtho();
struct RoomParams {
int iStart;
int vStart;
int iCount;
int vCount;
} roomParams[1024];
int iCount = 0, vCount = 0;
// get geometry data
for (int roomIndex = 0; roomIndex < level->roomsCount; roomIndex++) {
RoomParams &params = roomParams[roomIndex];
params.iStart = iCount;
params.vStart = vCount;
MeshBuilder::Geometry geom;
for (int transp = 0; transp < 3; transp++) {
int blendMask = mesh->getBlendMask(transp);
TR::Room &room = level->rooms[roomIndex];
// room geometry
mesh->buildRoom(geom, NULL, blendMask, room, level, indices, vertices, iCount, vCount, params.vStart);
// static meshes
for (int j = 0; j < room.meshesCount; j++) {
TR::Room::Mesh &m = room.meshes[j];
TR::StaticMesh *s = &level->staticMeshes[m.meshIndex];
if (!level->meshOffsets[s->mesh]) continue;
TR::Mesh &staticMesh = level->meshes[level->meshOffsets[s->mesh]];
int x = m.x - room.info.x;
int y = m.y;
int z = m.z - room.info.z;
int d = m.rotation.value / 0x4000;
mesh->buildMesh(geom, blendMask, staticMesh, level, indices, vertices, iCount, vCount, params.vStart, 0, x, y, z, d, m.color, true, false);
}
}
params.iCount = iCount - params.iStart;
params.vCount = vCount - params.vStart;
}
for (int i = 0; i < iCount; i += 3) { // CCW -> CW
swap(indices[i], indices[i + 2]);
}
// get model geometry
int verticesOffset = 0;
int indicesOffset = verticesOffset + vCount * sizeof(MeshVertex);
int bufferSize = indicesOffset + iCount * sizeof(MeshIndex);
char *bufferData = new char[bufferSize];
MeshVertex *gVertices = (MeshVertex*)(bufferData + verticesOffset);
for (int i = 0; i < vCount; i++) {
Vertex &src = vertices[i];
MeshVertex &dst = gVertices[i];
dst.coord = src.coord;
dst.normal = src.normal;
dst.texCoord = src.texCoord;
dst.normal = dst.normal.normal();
dst.coord = flip * (dst.coord * MESH_SCALE);
dst.normal = flip * dst.normal;
dst.texCoord *= (1.0f / 32767.0f);
dst.color = src.light;
}
for (int i = 0; i < iCount; i++) {
MeshIndex &dst = ((MeshIndex*)(bufferData + indicesOffset))[i];
dst = indices[i];
}
GLTF *gltf = new GLTF();
JSON *nodes;
gltf->addScene("Scene", &nodes);
int accessorIndex = 0;
int nodeIndex = 0;
for (int roomIndex = 0; roomIndex < level->roomsCount; roomIndex++) {
TR::Room &room = level->rooms[roomIndex];
RoomParams &params = roomParams[roomIndex];
if (params.iCount == 0) {
continue;
}
sprintf(name, "%d_mesh", roomIndex);
gltf->addMesh(name, 0, accessorIndex + 0, accessorIndex + 1, accessorIndex + 2, accessorIndex + 3, accessorIndex + 4, -1, -1);
sprintf(name, "%d", roomIndex);
gltf->addNode(name, nodeIndex, -1, vec3(float(-room.info.x), 0, float(room.info.z)) * MESH_SCALE, quat(0, 0, 0, 1));
nodes->add(NULL, nodeIndex); // mesh
nodeIndex++;
vec4 vMin(+INF), vMax(-INF);
for (int i = params.vStart; i < params.vStart + params.vCount; i++) {
MeshVertex &v = gVertices[i];
vMin.x = min(vMin.x, v.coord.x);
vMin.y = min(vMin.y, v.coord.y);
vMin.z = min(vMin.z, v.coord.z);
vMax.x = max(vMax.x, v.coord.x);
vMax.y = max(vMax.y, v.coord.y);
vMax.z = max(vMax.z, v.coord.z);
}
gltf->addAccessor(0, sizeof(MeshIndex), params.iStart * sizeof(MeshIndex), params.iCount, GLTF::SCALAR, GL_UNSIGNED_INT); // 0
gltf->addAccessor(1, sizeof(MeshVertex), params.vStart * sizeof(MeshVertex) + (int)OFFSETOF(MeshVertex, coord), params.vCount, GLTF::VEC3, GL_FLOAT, false, vMin, vMax); // 1
gltf->addAccessor(1, sizeof(MeshVertex), params.vStart * sizeof(MeshVertex) + (int)OFFSETOF(MeshVertex, normal), params.vCount, GLTF::VEC3, GL_FLOAT); // 2
gltf->addAccessor(1, sizeof(MeshVertex), params.vStart * sizeof(MeshVertex) + (int)OFFSETOF(MeshVertex, texCoord), params.vCount, GLTF::VEC2, GL_FLOAT); // 3
gltf->addAccessor(1, sizeof(MeshVertex), params.vStart * sizeof(MeshVertex) + (int)OFFSETOF(MeshVertex, color), params.vCount, GLTF::VEC4, GL_UNSIGNED_BYTE, true); // 4
accessorIndex += 5;
}
gltf->addSampler(GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_REPEAT, GL_REPEAT);
gltf->addImage("rooms.bmp");
gltf->addTexture("texture", 0, 0);
gltf->addMaterial("material", 0, 0, 1.0f, 0.0f);
delete[] vertices;
delete[] indices;
gltf->addBufferView(0, 0, indicesOffset, sizeof(MeshIndex) * iCount); // 0
gltf->addBufferView(0, sizeof(MeshVertex), verticesOffset, sizeof(MeshVertex) * vCount); // 1
gltf->addBuffer(bufferData, bufferSize); // 0
delete[] bufferData;
char *buffer = new char[gltf->getBufferSize()];
int size = gltf->save(buffer);
delete gltf;
fwrite(buffer, 1, size, file);
delete[] buffer;
fclose(file);
}
void exportModel(IGame *game, const char *dir, TR::Model &model) {
TR::Level *level = game->getLevel();
MeshBuilder *mesh = game->getMesh();
typedef uint32 MeshIndex;
struct ModelVertex {
vec3 coord;
vec3 normal;
vec2 texCoord;
ubyte4 color;
ubyte4 joints;
ubyte4 weights;
};
typedef uint32 ModelIndex;
char name[256];
sprintf(name, "models/dump/%d.glb", int(model.type));
sprintf(name, "%s/model_%d.glb", dir, int(model.type));
LOG("export model: %s\n", name);
FILE *file = fopen(name, "wb");
if (!file) {
@ -61,6 +252,7 @@ namespace Extension {
anim->setAnim(0);
animRate = max((int)(anim->anims + anim->index)->frameRate, 1);
animFrames = anim->framesCount / animRate;
ASSERT(animFrames > 0);
}
// get model geometry
@ -89,7 +281,7 @@ namespace Extension {
int rotationOffset = translationOffset + animFrames * sizeof(vec3);
int verticesOffset = rotationOffset + model.mCount * animFrames * sizeof(quat);
int indicesOffset = verticesOffset + vCount * sizeof(ModelVertex);
int bufferSize = indicesOffset + iCount * sizeof(ModelIndex);
int bufferSize = indicesOffset + iCount * sizeof(MeshIndex);
char *bufferData = new char[bufferSize];
@ -113,11 +305,10 @@ namespace Extension {
dst.texCoord = src.texCoord;
dst.normal = dst.normal.normal();
dst.coord = flip * dst.coord;
dst.coord = flip * (dst.coord * MESH_SCALE);
dst.normal = flip * dst.normal;
dst.texCoord *= (1.0f / 32767.0f);
dst.color = src.color;
dst.joints = ubyte4(uint8(src.coord.w / 2), 0, 0, 0);
dst.weights = ubyte4(255, 0, 0, 0);
@ -131,29 +322,28 @@ namespace Extension {
}
for (int i = 0; i < iCount; i++) {
ModelIndex &dst = ((ModelIndex*)(bufferData + indicesOffset))[i];
MeshIndex &dst = ((MeshIndex*)(bufferData + indicesOffset))[i];
dst = indices[i];
}
GLTF *gltf = new GLTF();
gltf->addSampler(GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_REPEAT, GL_REPEAT);
gltf->addImage("objects.bmp");
gltf->addImage("models.bmp");
gltf->addTexture("texture", 0, 0);
gltf->addMaterial("material", 0, 0, 1.0f, 0.0f);
delete[] vertices;
delete[] indices;
gltf->addAccessor(0, 0, iCount, GLTF::SCALAR, GL_UNSIGNED_INT); // 0
gltf->addAccessor(1, (int)OFFSETOF(ModelVertex, coord), vCount, GLTF::VEC3, GL_FLOAT, false, vMin, vMax); // 1
gltf->addAccessor(1, (int)OFFSETOF(ModelVertex, normal), vCount, GLTF::VEC3, GL_FLOAT); // 2
gltf->addAccessor(1, (int)OFFSETOF(ModelVertex, texCoord), vCount, GLTF::VEC2, GL_FLOAT); // 3
//gltf->addAccessor(1, (int)OFFSETOF(ModelVertex, color), vCount, GLTF::VEC4, GL_UNSIGNED_BYTE); // TODO
gltf->addAccessor(1, (int)OFFSETOF(ModelVertex, joints), vCount, GLTF::VEC4, GL_UNSIGNED_BYTE); // 4
gltf->addAccessor(1, (int)OFFSETOF(ModelVertex, weights), vCount, GLTF::VEC4, GL_UNSIGNED_BYTE, true); // 5
gltf->addAccessor(0, sizeof(MeshIndex), 0, iCount, GLTF::SCALAR, GL_UNSIGNED_INT); // 0
gltf->addAccessor(1, sizeof(ModelVertex), (int)OFFSETOF(ModelVertex, coord), vCount, GLTF::VEC3, GL_FLOAT, false, vMin, vMax); // 1
gltf->addAccessor(1, sizeof(ModelVertex), (int)OFFSETOF(ModelVertex, normal), vCount, GLTF::VEC3, GL_FLOAT); // 2
gltf->addAccessor(1, sizeof(ModelVertex), (int)OFFSETOF(ModelVertex, texCoord), vCount, GLTF::VEC2, GL_FLOAT); // 3
gltf->addAccessor(1, sizeof(ModelVertex), (int)OFFSETOF(ModelVertex, joints), vCount, GLTF::VEC4, GL_UNSIGNED_BYTE); // 4
gltf->addAccessor(1, sizeof(ModelVertex), (int)OFFSETOF(ModelVertex, weights), vCount, GLTF::VEC4, GL_UNSIGNED_BYTE, true); // 5
gltf->addBufferView(0, 0, indicesOffset, sizeof(ModelIndex) * iCount); // 0
gltf->addBufferView(0, 0, indicesOffset, sizeof(MeshIndex) * iCount); // 0
gltf->addBufferView(0, sizeof(ModelVertex), verticesOffset, sizeof(ModelVertex) * vCount); // 1
sprintf(name, "%d_mesh", int(model.type));
@ -182,13 +372,13 @@ namespace Extension {
timeline[i] = i * animRate / 30.0f;
}
gltf->addBufferView(0, 0, timelineOffset, animFrames * sizeof(float)); // 2
gltf->addAccessor(2, 0, animFrames, GLTF::SCALAR, GL_FLOAT, false, vec4(timeline[0], 0, 0, 0), vec4(timeline[animFrames - 1], 0, 0, 1)); // 6
gltf->addAccessor(2, 0, 0, animFrames, GLTF::SCALAR, GL_FLOAT, false, vec4(timeline[0], 0, 0, 0), vec4(timeline[animFrames - 1], 0, 0, 1)); // 6
}
{ // root translation (output)
vec3 *translation = (vec3*)(bufferData + translationOffset);
gltf->addBufferView(0, 0, translationOffset, animFrames * sizeof(vec3)); // 3
gltf->addAccessor(3, 0, animFrames, GLTF::VEC3, GL_FLOAT); // 7+
gltf->addAccessor(3, 0, 0, animFrames, GLTF::VEC3, GL_FLOAT); // 7+
JSON *sampler = samplers->add(JSON::OBJECT); // 0
sampler->add("input", 6); // timeline
@ -203,8 +393,7 @@ namespace Extension {
for (int j = 0; j < animFrames; j++) {
TR::AnimFrame *frame = anim->getFrame(anim->anims + anim->index, j);
translation[j] = frame->pos;
translation[j] = flip * translation[j];
translation[j] = flip * (vec3((float)frame->pos.x, (float)frame->pos.y, (float)frame->pos.z) * MESH_SCALE);
}
}
@ -227,7 +416,7 @@ namespace Extension {
*ptr = matrix.getRot();
ptr++;
}
gltf->addAccessor(4, i * animFrames * sizeof(quat), animFrames, GLTF::VEC4, GL_FLOAT); // 8+
gltf->addAccessor(4, 0, i * animFrames * sizeof(quat), animFrames, GLTF::VEC4, GL_FLOAT); // 8+
JSON *sampler = samplers->add(JSON::OBJECT); // 1+
sampler->add("input", 6); // timeline
@ -271,7 +460,7 @@ namespace Extension {
for (int i = 0; i < model.mCount; i++) {
sprintf(name, "joint_%d", i + 1);
JSON* node = gltf->addNode(name, -1, -1, jointPos, quat(0, 0, 0, 1));
JSON* node = gltf->addNode(name, -1, -1, jointPos * MESH_SCALE, quat(0, 0, 0, 1));
JSON* children = new JSON(JSON::ARRAY, "children");
for (int j = 0; j < model.mCount; j++) {
@ -287,13 +476,13 @@ namespace Extension {
}
joints[i] = i + 1;
TR::Node &t = *((TR::Node*)&level->nodesData[model.node] + i);
jointPos = flip * vec3((float)t.x, (float)t.y, (float)t.z);
}
gltf->addSkin("skin", -1, 1, joints, model.mCount);
char *buffer = new char[gltf->getBufferSize()];
int size = gltf->save(buffer);
delete gltf;
@ -302,24 +491,27 @@ namespace Extension {
delete[] buffer;
LOG("export model: %s\n", name);
fclose(file);
}
void exportGeometry(IGame *game, Texture *atlasRooms, Texture *atlasObjects, Texture *atlasSprites) {
CreateDirectory("models", NULL);
CreateDirectory("models/dump/", NULL);
exportTexture("models/dump/rooms", atlasRooms);
exportTexture("models/dump/objects", atlasObjects);
exportTexture("models/dump/sprites", atlasSprites);
char dir[256];
sprintf(dir, "dump/%s", TR::LEVEL_INFO[game->getLevel()->id].name);
CreateDirectory("dump", NULL);
CreateDirectory(dir, NULL);
exportTexture(dir, "rooms", atlasRooms);
exportTexture(dir, "models", atlasObjects);
TR::Level *level = game->getLevel();
MeshBuilder *mesh = game->getMesh();
exportRooms(game, dir);
for (int i = 0; i < level->modelsCount; i++) {
exportModel(game, level->models[i]);
exportModel(game, dir, level->models[i]);
}
}
#endif

View File

@ -67,61 +67,61 @@
#include <SDL2/SDL.h>
#if defined(_GAPI_GLES) // Default in SDL2 is GLES3. If we want GLES2, pass -D_GAPI_GLES2.
#if defined (_GAPI_GLES2) // We want GLES2 on SDL2
#include <SDL2/SDL_opengles2.h>
#include <SDL2/SDL_opengles2_gl2ext.h>
#if defined (_GAPI_GLES2) // We want GLES2 on SDL2
#include <SDL2/SDL_opengles2.h>
#include <SDL2/SDL_opengles2_gl2ext.h>
#define GL_CLAMP_TO_BORDER 0x812D
#define GL_TEXTURE_BORDER_COLOR 0x1004
#define GL_CLAMP_TO_BORDER 0x812D
#define GL_TEXTURE_BORDER_COLOR 0x1004
#define GL_TEXTURE_COMPARE_MODE 0x884C
#define GL_TEXTURE_COMPARE_FUNC 0x884D
#define GL_COMPARE_REF_TO_TEXTURE 0x884E
#define GL_TEXTURE_COMPARE_MODE 0x884C
#define GL_TEXTURE_COMPARE_FUNC 0x884D
#define GL_COMPARE_REF_TO_TEXTURE 0x884E
#undef GL_RG
#undef GL_RG32F
#undef GL_RG16F
#undef GL_RGBA32F
#undef GL_RGBA16F
#undef GL_HALF_FLOAT
#undef GL_RG
#undef GL_RG32F
#undef GL_RG16F
#undef GL_RGBA32F
#undef GL_RGBA16F
#undef GL_HALF_FLOAT
#define GL_RG GL_RGBA
#define GL_RGBA32F GL_RGBA
#define GL_RGBA16F GL_RGBA
#define GL_RG32F GL_RGBA
#define GL_RG16F GL_RGBA
#define GL_HALF_FLOAT GL_HALF_FLOAT_OES
#define GL_RG GL_RGBA
#define GL_RGBA32F GL_RGBA
#define GL_RGBA16F GL_RGBA
#define GL_RG32F GL_RGBA
#define GL_RG16F GL_RGBA
#define GL_HALF_FLOAT GL_HALF_FLOAT_OES
#define GL_TEXTURE_WRAP_R 0
#define GL_DEPTH_STENCIL GL_DEPTH_STENCIL_OES
#define GL_UNSIGNED_INT_24_8 GL_UNSIGNED_INT_24_8_OES
//We need this on GLES2, too.
#define GL_TEXTURE_MAX_LEVEL GL_TEXTURE_MAX_LEVEL_APPLE
#define GL_TEXTURE_WRAP_R 0
#define GL_DEPTH_STENCIL GL_DEPTH_STENCIL_OES
#define GL_UNSIGNED_INT_24_8 GL_UNSIGNED_INT_24_8_OES
//We need this on GLES2, too.
#define GL_TEXTURE_MAX_LEVEL GL_TEXTURE_MAX_LEVEL_APPLE
#define glTexImage3D(...) 0
#ifndef GL_TEXTURE_3D // WUUUUUT!?
#define GL_TEXTURE_3D GL_TEXTURE_3D_OES
#endif
#define glTexImage3D(...) 0
#ifndef GL_TEXTURE_3D // WUUUUUT!?
#define GL_TEXTURE_3D GL_TEXTURE_3D_OES
#endif
#define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES
#define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES
#else // We want GLES3 on SDL2
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <GLES2/gl2ext.h>
#endif //GAPI_GLES2
// These are needed for both GLES2 and GLES3 on SDL2
#define glGenVertexArrays(...)
#define glDeleteVertexArrays(...)
#define glBindVertexArray(...)
#define glGetProgramBinary(...)
#define glProgramBinary(...)
// These are needed for both GLES2 and GLES3 on SDL2
#define glGenVertexArrays(...)
#define glDeleteVertexArrays(...)
#define glBindVertexArray(...)
#define glGetProgramBinary(...)
#define glProgramBinary(...)
#define PFNGLGENVERTEXARRAYSPROC PFNGLGENVERTEXARRAYSOESPROC
#define PFNGLDELETEVERTEXARRAYSPROC PFNGLDELETEVERTEXARRAYSOESPROC
#define PFNGLBINDVERTEXARRAYPROC PFNGLBINDVERTEXARRAYOESPROC
#define PFNGLGETPROGRAMBINARYPROC PFNGLGETPROGRAMBINARYOESPROC
#define PFNGLPROGRAMBINARYPROC PFNGLPROGRAMBINARYOESPROC
#define PFNGLGENVERTEXARRAYSPROC PFNGLGENVERTEXARRAYSOESPROC
#define PFNGLDELETEVERTEXARRAYSPROC PFNGLDELETEVERTEXARRAYSOESPROC
#define PFNGLBINDVERTEXARRAYPROC PFNGLBINDVERTEXARRAYOESPROC
#define PFNGLGETPROGRAMBINARYPROC PFNGLGETPROGRAMBINARYOESPROC
#define PFNGLPROGRAMBINARYPROC PFNGLPROGRAMBINARYOESPROC
#else // We want OpenGL on SDL2, not GLES
#include <SDL2/SDL_opengl.h>

View File

@ -26,9 +26,9 @@ struct GLTF {
JSON *textures;
JSON *materials;
JSON *nodes;
JSON *scenes;
JSON *skins;
JSON *animations;
JSON *scenes;
char *binaryData;
int binarySize;
@ -46,9 +46,9 @@ struct GLTF {
accessors = root->add(JSON::ARRAY, "accessors");
meshes = root->add(JSON::ARRAY, "meshes");
nodes = root->add(JSON::ARRAY, "nodes");
skins = root->add(JSON::ARRAY, "skins");
animations = root->add(JSON::ARRAY, "animations");
scenes = root->add(JSON::ARRAY, "scenes");
skins = NULL;//root->add(JSON::ARRAY, "skins");
animations = NULL;//root->add(JSON::ARRAY, "animations");
asset->add("generator", "OpenLara");
asset->add("version", "2.0");
@ -120,13 +120,17 @@ struct GLTF {
return header->length;
}
JSON* addAccessor(int bufferView, int byteOffset, int count, AccessorType type, int format, bool normalized = false, const vec4 &vMin = vec4(0.0f), const vec4 &vMax = vec4(0.0f)) {
JSON* addAccessor(int bufferView, int byteStride, int byteOffset, int count, AccessorType type, int format, bool normalized = false, const vec4 &vMin = vec4(0.0f), const vec4 &vMax = vec4(0.0f)) {
static const char *AccessorTypeName[ACCESSOR_TYPE_MAX] = { ACCESSOR_TYPES(DECL_STR) };
JSON *item = accessors->add(JSON::OBJECT);
item->add("bufferView", bufferView);
if (byteStride) {
//item->add("byteStride", byteStride);
}
if (byteOffset) {
item->add("byteOffset", byteOffset);
}
@ -280,6 +284,10 @@ struct GLTF {
}
JSON *addSkin(const char *name, int inverseBindMatrices, int skeleton, int *joints, int jointsCount) {
if (!skins) {
skins = root->add(JSON::ARRAY, "skins");
}
JSON *item = skins->add(JSON::OBJECT);
if (name) {
@ -301,6 +309,9 @@ struct GLTF {
}
JSON* addAnimation(const char *name, JSON **samplers, JSON **channels) {
if (!animations) {
animations = root->add(JSON::ARRAY, "animations");
}
JSON *item = animations->add(JSON::OBJECT);
if (name) item->add("name", name);

View File

@ -273,7 +273,7 @@ enum StringID {
, "Suomi" \
, "{Cesky" \
, "\x11\x02\x8A\x02\x6C\x01\x54\x03\x02\xFF\xFF" \
, "Magyar"
, "Magyar"
#define LANG_PREFIXES "_EN", "_FR", "_DE", "_ES", "_IT", "_PL", "_PT", "_RU", "_JA", "_GR", "_FI", "_CZ", "_CN", "_HU"
@ -341,7 +341,7 @@ void ensureLanguage(int lang) {
ASSERT(COUNT(STR_CZ) == STR_MAX);
ASSERT(COUNT(STR_CN) == STR_MAX);
ASSERT(COUNT(STR_HU) == STR_MAX);
lang += STR_LANG_EN;
switch (lang) {

View File

@ -348,8 +348,8 @@ struct MeshBuilder {
Geometry &geom = range.geometry[transp];
// rooms geometry
buildRoom(geom, range.dynamic[transp], blendMask, room, level, indices, vertices, iCount, vCount, vStartRoom);
// room geometry
buildRoom(geom, range.dynamic + transp, blendMask, room, level, indices, vertices, iCount, vCount, vStartRoom);
// static meshes
for (int j = 0; j < room.meshesCount; j++) {
@ -1004,11 +1004,13 @@ struct MeshBuilder {
return 1 << texAttribute;
}
void buildRoom(Geometry &geom, Dynamic &dyn, int blendMask, const TR::Room &room, TR::Level *level, Index *indices, Vertex *vertices, int &iCount, int &vCount, int vStart) {
void buildRoom(Geometry &geom, Dynamic *dyn, int blendMask, const TR::Room &room, TR::Level *level, Index *indices, Vertex *vertices, int &iCount, int &vCount, int vStart) {
const TR::Room::Data &d = room.data;
dyn.count = 0;
dyn.faces = NULL;
if (dyn) {
dyn->count = 0;
dyn->faces = NULL;
}
for (int j = 0; j < d.fCount; j++) {
TR::Face &f = d.faces[j];
@ -1023,9 +1025,9 @@ struct MeshBuilder {
if (!(blendMask & getBlendMask(t.attribute)))
continue;
if (t.animated) {
ASSERT(dyn.count < 0xFFFF);
dyn.count++;
if (dyn && t.animated) {
ASSERT(dyn->count < 0xFFFF);
dyn->count++;
continue;
}
@ -1036,9 +1038,9 @@ struct MeshBuilder {
}
// if room has non-static polygons, fill the list of dynamic faces
if (dyn.count) {
dyn.faces = new uint16[dyn.count];
dyn.count = 0;
if (dyn && dyn->count) {
dyn->faces = new uint16[dyn->count];
dyn->count = 0;
for (int j = 0; j < d.fCount; j++) {
TR::Face &f = d.faces[j];
TR::TextureInfo &t = level->objectTextures[f.flags.texture];
@ -1049,7 +1051,7 @@ struct MeshBuilder {
continue;
if (t.animated)
dyn.faces[dyn.count++] = j;
dyn->faces[dyn->count++] = j;
}
}
}