mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-06 13:16:52 +02:00
#370 levels converter
This commit is contained in:
@@ -182,7 +182,7 @@ X_INLINE int32 classify(int32 x, int32 y, int32 x0, int32 y0, int32 x1, int32 y1
|
|||||||
(y > y1 ? CLIP_BOTTOM : 0);
|
(y > y1 ? CLIP_BOTTOM : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
X_INLINE void transform(Vertex* points, int32 count)
|
X_INLINE void transformVertices(Vertex* points, int32 count)
|
||||||
{
|
{
|
||||||
Matrix& m = matrixGet();
|
Matrix& m = matrixGet();
|
||||||
int32 mx = m.e03;
|
int32 mx = m.e03;
|
||||||
@@ -226,7 +226,7 @@ bool transformBoxRect(const AABBs* box, RectMinMax* rect)
|
|||||||
{ b.maxX, b.maxY, b.maxZ, 1 << 16 }
|
{ b.maxX, b.maxY, b.maxZ, 1 << 16 }
|
||||||
};
|
};
|
||||||
|
|
||||||
transform(v, 8);
|
transformVertices(v, 8);
|
||||||
|
|
||||||
*rect = RectMinMax( INT_MAX, INT_MAX, INT_MIN, INT_MIN );
|
*rect = RectMinMax( INT_MAX, INT_MAX, INT_MIN, INT_MIN );
|
||||||
|
|
||||||
@@ -333,16 +333,8 @@ void unpackMesh_c(const MeshVertex* vertices, int32 vCount)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void transformRoom(const Room* room)
|
void projectVertices(int32 vCount)
|
||||||
{
|
{
|
||||||
int32 vCount = room->info->verticesCount;
|
|
||||||
if (vCount <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
unpackRoom(room->data.vertices, vCount);
|
|
||||||
|
|
||||||
transform(gVertices, vCount);
|
|
||||||
|
|
||||||
int32 x0 = viewportRel.x0;
|
int32 x0 = viewportRel.x0;
|
||||||
int32 y0 = viewportRel.y0;
|
int32 y0 = viewportRel.y0;
|
||||||
int32 x1 = viewportRel.x1;
|
int32 x1 = viewportRel.x1;
|
||||||
@@ -350,7 +342,7 @@ void transformRoom(const Room* room)
|
|||||||
|
|
||||||
Vertex* res = gVertices;
|
Vertex* res = gVertices;
|
||||||
|
|
||||||
for (int32 i = 0; i < vCount; i++, res++)
|
for (int32 i = 0; i < vCount; i++)
|
||||||
{
|
{
|
||||||
int32 x = res->x;
|
int32 x = res->x;
|
||||||
int32 y = res->y;
|
int32 y = res->y;
|
||||||
@@ -372,7 +364,21 @@ void transformRoom(const Room* room)
|
|||||||
res->x = x;
|
res->x = x;
|
||||||
res->y = y;
|
res->y = y;
|
||||||
res->z = (z << CLIP_SHIFT) | clip;
|
res->z = (z << CLIP_SHIFT) | clip;
|
||||||
|
res++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void transformRoom(const Room* room)
|
||||||
|
{
|
||||||
|
int32 vCount = room->info->verticesCount;
|
||||||
|
if (vCount <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unpackRoom(room->data.vertices, vCount);
|
||||||
|
|
||||||
|
transformVertices(gVertices, vCount);
|
||||||
|
|
||||||
|
projectVertices(vCount);
|
||||||
|
|
||||||
gVerticesCount += vCount;
|
gVerticesCount += vCount;
|
||||||
}
|
}
|
||||||
@@ -381,38 +387,9 @@ void transformMesh(const MeshVertex* vertices, int32 vCount, const uint16* vInte
|
|||||||
{
|
{
|
||||||
unpackMesh(vertices, vCount);
|
unpackMesh(vertices, vCount);
|
||||||
|
|
||||||
transform(gVertices, vCount);
|
transformVertices(gVertices, vCount);
|
||||||
|
|
||||||
int32 x0 = viewportRel.x0;
|
projectVertices(vCount);
|
||||||
int32 y0 = viewportRel.y0;
|
|
||||||
int32 x1 = viewportRel.x1;
|
|
||||||
int32 y1 = viewportRel.y1;
|
|
||||||
|
|
||||||
Vertex* res = gVertices;
|
|
||||||
|
|
||||||
for (int32 i = 0; i < vCount; i++, res++)
|
|
||||||
{
|
|
||||||
int32 x = res->x;
|
|
||||||
int32 y = res->y;
|
|
||||||
int32 z = res->z;
|
|
||||||
int32 clip = 0;
|
|
||||||
|
|
||||||
if (z < (VIEW_MIN_F >> FIXED_SHIFT)) {
|
|
||||||
z = (VIEW_MIN_F >> FIXED_SHIFT);
|
|
||||||
clip = CLIP_NEAR;
|
|
||||||
} else if (z >= (VIEW_MAX_F >> FIXED_SHIFT)) {
|
|
||||||
z = (VIEW_MAX_F >> FIXED_SHIFT);
|
|
||||||
clip = CLIP_FAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
PERSPECTIVE(x, y, z);
|
|
||||||
|
|
||||||
clip |= classify(x, y, x0, y0, x1, y1);
|
|
||||||
|
|
||||||
res->x = x;
|
|
||||||
res->y = y;
|
|
||||||
res->z = (z << CLIP_SHIFT) | clip;
|
|
||||||
}
|
|
||||||
|
|
||||||
gVerticesCount += vCount;
|
gVerticesCount += vCount;
|
||||||
}
|
}
|
||||||
|
@@ -998,22 +998,6 @@ struct LevelPC
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vertex3DO
|
|
||||||
{
|
|
||||||
int8 y;
|
|
||||||
uint8 zero;
|
|
||||||
uint8 x;
|
|
||||||
uint8 z;
|
|
||||||
|
|
||||||
void write(FileStream &f) const
|
|
||||||
{
|
|
||||||
f.write(y);
|
|
||||||
f.write(zero);
|
|
||||||
f.write(x);
|
|
||||||
f.write(z);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Sprite
|
struct Sprite
|
||||||
{
|
{
|
||||||
uint16 index;
|
uint16 index;
|
||||||
@@ -1533,8 +1517,8 @@ struct LevelPC
|
|||||||
|
|
||||||
struct BoxComp
|
struct BoxComp
|
||||||
{
|
{
|
||||||
int8 minZ, maxZ;
|
uint8 minZ, maxZ;
|
||||||
int8 minX, maxX;
|
uint8 minX, maxX;
|
||||||
int16 floor;
|
int16 floor;
|
||||||
int16 overlap;
|
int16 overlap;
|
||||||
|
|
||||||
@@ -2016,12 +2000,21 @@ struct LevelPC
|
|||||||
Room::VertexComp roomVertices[MAX_ROOM_VERTICES];
|
Room::VertexComp roomVertices[MAX_ROOM_VERTICES];
|
||||||
int32 roomVerticesCount;
|
int32 roomVerticesCount;
|
||||||
|
|
||||||
int32 addRoomVertex(const Room::Vertex &v, bool ignoreG = false)
|
int32 addRoomVertex(int32 yOffset, const Room::Vertex &v, bool ignoreG = false)
|
||||||
{
|
{
|
||||||
Room::VertexComp comp;
|
Room::VertexComp comp;
|
||||||
comp.x = v.pos.x / 1024;
|
int32 px = v.pos.x >> 10;
|
||||||
comp.y = v.pos.y / 256;
|
int32 py = (v.pos.y - yOffset) >> 8;
|
||||||
comp.z = v.pos.z / 1024;
|
int32 pz = v.pos.z >> 10;
|
||||||
|
|
||||||
|
ASSERT(py >= 0);
|
||||||
|
ASSERT(px < 32);
|
||||||
|
ASSERT(py < 64);
|
||||||
|
ASSERT(pz < 32);
|
||||||
|
|
||||||
|
comp.x = px;
|
||||||
|
comp.y = py;
|
||||||
|
comp.z = pz;
|
||||||
comp.g = ignoreG ? 0 : (v.lighting >> 5);
|
comp.g = ignoreG ? 0 : (v.lighting >> 5);
|
||||||
|
|
||||||
for (int32 i = 0; i < roomVerticesCount; i++)
|
for (int32 i = 0; i < roomVerticesCount; i++)
|
||||||
@@ -2460,8 +2453,19 @@ struct LevelPC
|
|||||||
ASSERT(room->info.yTop >= -32768 && room->info.yTop <= 32767);
|
ASSERT(room->info.yTop >= -32768 && room->info.yTop <= 32767);
|
||||||
info.x = room->info.x / 256;
|
info.x = room->info.x / 256;
|
||||||
info.z = room->info.z / 256;
|
info.z = room->info.z / 256;
|
||||||
info.yBottom = room->info.yBottom;
|
info.yBottom = -32768;
|
||||||
info.yTop = room->info.yTop;
|
info.yTop = 32767;
|
||||||
|
|
||||||
|
for (int32 j = 0; j < room->vCount; j++)
|
||||||
|
{
|
||||||
|
Room::Vertex &v = room->vertices[j];
|
||||||
|
if (v.pos.y < info.yTop) {
|
||||||
|
info.yTop = v.pos.y;
|
||||||
|
}
|
||||||
|
if (v.pos.y > info.yBottom) {
|
||||||
|
info.yBottom = v.pos.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info.spritesCount = room->sCount;
|
info.spritesCount = room->sCount;
|
||||||
info.quadsCount = room->qCount;
|
info.quadsCount = room->qCount;
|
||||||
@@ -2491,10 +2495,10 @@ struct LevelPC
|
|||||||
for (int32 i = 0; i < room->qCount; i++)
|
for (int32 i = 0; i < room->qCount; i++)
|
||||||
{
|
{
|
||||||
Quad q = room->quads[i];
|
Quad q = room->quads[i];
|
||||||
q.indices[0] = addRoomVertex(room->vertices[q.indices[0]]);
|
q.indices[0] = addRoomVertex(info.yTop, room->vertices[q.indices[0]]);
|
||||||
q.indices[1] = addRoomVertex(room->vertices[q.indices[1]]);
|
q.indices[1] = addRoomVertex(info.yTop, room->vertices[q.indices[1]]);
|
||||||
q.indices[2] = addRoomVertex(room->vertices[q.indices[2]]);
|
q.indices[2] = addRoomVertex(info.yTop, room->vertices[q.indices[2]]);
|
||||||
q.indices[3] = addRoomVertex(room->vertices[q.indices[3]]);
|
q.indices[3] = addRoomVertex(info.yTop, room->vertices[q.indices[3]]);
|
||||||
q.write(f);
|
q.write(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2502,9 +2506,9 @@ struct LevelPC
|
|||||||
for (int32 i = 0; i < room->tCount; i++)
|
for (int32 i = 0; i < room->tCount; i++)
|
||||||
{
|
{
|
||||||
Triangle t = room->triangles[i];
|
Triangle t = room->triangles[i];
|
||||||
t.indices[0] = addRoomVertex(room->vertices[t.indices[0]]);
|
t.indices[0] = addRoomVertex(info.yTop, room->vertices[t.indices[0]]);
|
||||||
t.indices[1] = addRoomVertex(room->vertices[t.indices[1]]);
|
t.indices[1] = addRoomVertex(info.yTop, room->vertices[t.indices[1]]);
|
||||||
t.indices[2] = addRoomVertex(room->vertices[t.indices[2]]);
|
t.indices[2] = addRoomVertex(info.yTop, room->vertices[t.indices[2]]);
|
||||||
t.write(f);
|
t.write(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2931,12 +2935,14 @@ struct LevelPC
|
|||||||
struct Texture3DO {
|
struct Texture3DO {
|
||||||
int32 data;
|
int32 data;
|
||||||
int32 plut;
|
int32 plut;
|
||||||
|
uint32 _shift;
|
||||||
|
|
||||||
|
// not in file
|
||||||
uint8 wShift;
|
uint8 wShift;
|
||||||
uint8 hShift;
|
uint8 hShift;
|
||||||
uint16 color;
|
uint16 color;
|
||||||
uint32 _unused;
|
uint32 _unused;
|
||||||
|
|
||||||
// not in file
|
|
||||||
uint32 pre0;
|
uint32 pre0;
|
||||||
uint32 pre1;
|
uint32 pre1;
|
||||||
uint8* src;
|
uint8* src;
|
||||||
@@ -3675,8 +3681,19 @@ struct LevelPC
|
|||||||
ASSERT(room->info.yTop >= -32768 && room->info.yTop <= 32767);
|
ASSERT(room->info.yTop >= -32768 && room->info.yTop <= 32767);
|
||||||
info.x = room->info.x / 256;
|
info.x = room->info.x / 256;
|
||||||
info.z = room->info.z / 256;
|
info.z = room->info.z / 256;
|
||||||
info.yBottom = room->info.yBottom;
|
info.yBottom = -32768;
|
||||||
info.yTop = room->info.yTop;
|
info.yTop = 32767;
|
||||||
|
|
||||||
|
for (int32 j = 0; j < room->vCount; j++)
|
||||||
|
{
|
||||||
|
Room::Vertex &v = room->vertices[j];
|
||||||
|
if (v.pos.y < info.yTop) {
|
||||||
|
info.yTop = v.pos.y;
|
||||||
|
}
|
||||||
|
if (v.pos.y > info.yBottom) {
|
||||||
|
info.yBottom = v.pos.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info.spritesCount = room->sCount;
|
info.spritesCount = room->sCount;
|
||||||
info.quadsCount = room->qCount;
|
info.quadsCount = room->qCount;
|
||||||
@@ -3716,10 +3733,10 @@ struct LevelPC
|
|||||||
uint32 intensity = ((v0.lighting + v1.lighting + v2.lighting + v3.lighting) / 4) >> 5;
|
uint32 intensity = ((v0.lighting + v1.lighting + v2.lighting + v3.lighting) / 4) >> 5;
|
||||||
ASSERT(intensity <= 255);
|
ASSERT(intensity <= 255);
|
||||||
|
|
||||||
q.indices[0] = addRoomVertex(v0, true);
|
q.indices[0] = addRoomVertex(info.yTop, v0, true);
|
||||||
q.indices[1] = addRoomVertex(v1, true);
|
q.indices[1] = addRoomVertex(info.yTop, v1, true);
|
||||||
q.indices[2] = addRoomVertex(v2, true);
|
q.indices[2] = addRoomVertex(info.yTop, v2, true);
|
||||||
q.indices[3] = addRoomVertex(v3, true);
|
q.indices[3] = addRoomVertex(info.yTop, v3, true);
|
||||||
|
|
||||||
RoomQuad3DO comp;
|
RoomQuad3DO comp;
|
||||||
comp.indices[0] = q.indices[0];
|
comp.indices[0] = q.indices[0];
|
||||||
@@ -3756,9 +3773,9 @@ struct LevelPC
|
|||||||
uint32 intensity = ((v0.lighting + v1.lighting + v2.lighting) / 3) >> 5;
|
uint32 intensity = ((v0.lighting + v1.lighting + v2.lighting) / 3) >> 5;
|
||||||
ASSERT(intensity <= 255);
|
ASSERT(intensity <= 255);
|
||||||
|
|
||||||
t.indices[0] = addRoomVertex(v0, true);
|
t.indices[0] = addRoomVertex(info.yTop, v0, true);
|
||||||
t.indices[1] = addRoomVertex(v1, true);
|
t.indices[1] = addRoomVertex(info.yTop, v1, true);
|
||||||
t.indices[2] = addRoomVertex(v2, true);
|
t.indices[2] = addRoomVertex(info.yTop, v2, true);
|
||||||
|
|
||||||
RoomTriangle3DO comp;
|
RoomTriangle3DO comp;
|
||||||
comp.indices[0] = t.indices[0];
|
comp.indices[0] = t.indices[0];
|
||||||
@@ -3781,16 +3798,30 @@ struct LevelPC
|
|||||||
|
|
||||||
info.vertices = f.align4();
|
info.vertices = f.align4();
|
||||||
info.verticesCount = roomVerticesCount;
|
info.verticesCount = roomVerticesCount;
|
||||||
for (int32 i = 0; i < roomVerticesCount; i++)
|
for (int32 i = 0; i < roomVerticesCount; i += 4)
|
||||||
{
|
{
|
||||||
const Room::VertexComp &v = roomVertices[i];
|
Room::VertexComp v[4];
|
||||||
|
|
||||||
Room::Vertex3DO comp;
|
for (int32 j = 0; j < 4; j++)
|
||||||
comp.x = v.x;
|
{
|
||||||
comp.y = v.y;
|
if (i + j < roomVerticesCount) {
|
||||||
comp.z = v.z;
|
v[j] = roomVertices[i + j];
|
||||||
comp.zero = 0;
|
} else {
|
||||||
comp.write(f);
|
memset(&v[j], 0, sizeof(v[j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint32 value = v[0].x | (v[0].y << 5) | (v[0].z << 11);
|
||||||
|
value |= (v[1].x | (v[1].y << 5) | (v[1].z << 11)) << 16;
|
||||||
|
f.write(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint32 value = v[2].x | (v[2].y << 5) | (v[2].z << 11);
|
||||||
|
value |= (v[3].x | (v[3].y << 5) | (v[3].z << 11)) << 16;
|
||||||
|
f.write(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info.sprites = f.align4();
|
info.sprites = f.align4();
|
||||||
@@ -4217,10 +4248,10 @@ struct LevelPC
|
|||||||
const LevelPC::Box* box = boxes + i;
|
const LevelPC::Box* box = boxes + i;
|
||||||
|
|
||||||
BoxComp comp;
|
BoxComp comp;
|
||||||
comp.minX = box->minX / 1024;
|
comp.minX = box->minX >> 10;
|
||||||
comp.minZ = box->minZ / 1024;
|
comp.minZ = box->minZ >> 10;
|
||||||
comp.maxX = (box->maxX + 1) / 1024;
|
comp.maxX = (box->maxX + 1) >> 10;
|
||||||
comp.maxZ = (box->maxZ + 1) / 1024;
|
comp.maxZ = (box->maxZ + 1) >> 10;
|
||||||
comp.floor = box->floor;
|
comp.floor = box->floor;
|
||||||
comp.overlap = box->overlap;
|
comp.overlap = box->overlap;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user