|
|
@ -225,20 +225,20 @@ static void export_lightmap(const world_t* world, const face_t* face, const Boun |
|
|
case 0: |
|
|
case 0: |
|
|
case 3: |
|
|
case 3: |
|
|
// Towards X
|
|
|
// Towards X
|
|
|
width = ceil(bounds.max.y / 16) - floor(bounds.min.y / 16); |
|
|
|
|
|
height = ceil(bounds.max.z / 16) - floor(bounds.min.z / 16); |
|
|
|
|
|
|
|
|
width = (int)(ceil(bounds.max.y / 16) - floor(bounds.min.y / 16)); |
|
|
|
|
|
height = (int)(ceil(bounds.max.z / 16) - floor(bounds.min.z / 16)); |
|
|
break; |
|
|
break; |
|
|
case 1: |
|
|
case 1: |
|
|
case 4: |
|
|
case 4: |
|
|
// Towards Y
|
|
|
// Towards Y
|
|
|
width = ceil(bounds.max.x / 16) - floor(bounds.min.x / 16); |
|
|
|
|
|
height = ceil(bounds.max.z / 16) - floor(bounds.min.z / 16); |
|
|
|
|
|
|
|
|
width = (int)(ceil(bounds.max.x / 16) - floor(bounds.min.x / 16)); |
|
|
|
|
|
height = (int)(ceil(bounds.max.z / 16) - floor(bounds.min.z / 16)); |
|
|
break; |
|
|
break; |
|
|
case 2: |
|
|
case 2: |
|
|
case 5: |
|
|
case 5: |
|
|
// Towards Z
|
|
|
// Towards Z
|
|
|
width = ceil(bounds.max.x / 16) - floor(bounds.min.x / 16); |
|
|
|
|
|
height = ceil(bounds.max.y / 16) - floor(bounds.min.y / 16); |
|
|
|
|
|
|
|
|
width = (int)(ceil(bounds.max.x / 16) - floor(bounds.min.x / 16)); |
|
|
|
|
|
height = (int)(ceil(bounds.max.y / 16) - floor(bounds.min.y / 16)); |
|
|
break; |
|
|
break; |
|
|
default: |
|
|
default: |
|
|
printf("Error: unknown plane type %d\n", plane->type); |
|
|
printf("Error: unknown plane type %d\n", plane->type); |
|
|
@ -297,23 +297,18 @@ int process_faces(const world_t* world) |
|
|
outVertex.y = (short)(inVertex->Y * 4); |
|
|
outVertex.y = (short)(inVertex->Y * 4); |
|
|
outVertex.z = (short)(inVertex->Z * 4); |
|
|
outVertex.z = (short)(inVertex->Z * 4); |
|
|
} |
|
|
} |
|
|
outVertex.baseLight = 0; |
|
|
|
|
|
outVertex.finalLight = 0; |
|
|
|
|
|
outVertex.r = 0; |
|
|
|
|
|
|
|
|
|
|
|
outVertices.push_back(outVertex); |
|
|
outVertices.push_back(outVertex); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
std::vector<ps1bsp_triangle_t> outTriangles; |
|
|
|
|
|
std::vector<ps1bsp_face_t> outFaces; |
|
|
std::vector<ps1bsp_face_t> outFaces; |
|
|
|
|
|
|
|
|
std::vector<unsigned short> faceVertIndices; |
|
|
|
|
|
|
|
|
std::vector<ps1bsp_facevertex_t> outFaceVertices; |
|
|
for (int faceIdx = 0; faceIdx < world->numFaces; ++faceIdx) |
|
|
for (int faceIdx = 0; faceIdx < world->numFaces; ++faceIdx) |
|
|
{ |
|
|
{ |
|
|
face_t* face = &world->faces[faceIdx]; |
|
|
face_t* face = &world->faces[faceIdx]; |
|
|
|
|
|
|
|
|
ps1bsp_face_t outFace = { 0 }; |
|
|
ps1bsp_face_t outFace = { 0 }; |
|
|
outFace.firstVertexIndex = faceVertIndices.size(); |
|
|
|
|
|
|
|
|
outFace.firstFaceVertex = (unsigned short)outFaceVertices.size(); |
|
|
|
|
|
|
|
|
// Traverse the list of face edges to collect all of the face's vertices
|
|
|
// Traverse the list of face edges to collect all of the face's vertices
|
|
|
BoundBox bounds; |
|
|
BoundBox bounds; |
|
|
@ -325,7 +320,10 @@ int process_faces(const world_t* world) |
|
|
world->edges[edgeIdx].vertex0 : |
|
|
world->edges[edgeIdx].vertex0 : |
|
|
world->edges[-edgeIdx].vertex1; |
|
|
world->edges[-edgeIdx].vertex1; |
|
|
|
|
|
|
|
|
faceVertIndices.push_back(vertIndex); |
|
|
|
|
|
|
|
|
ps1bsp_facevertex_t faceVertex; |
|
|
|
|
|
faceVertex.index = vertIndex; |
|
|
|
|
|
faceVertex.light = 0; |
|
|
|
|
|
outFaceVertices.push_back(faceVertex); |
|
|
|
|
|
|
|
|
// Calculate bounding box of this face
|
|
|
// Calculate bounding box of this face
|
|
|
const vertex_t* vertex = &world->vertices[vertIndex]; |
|
|
const vertex_t* vertex = &world->vertices[vertIndex]; |
|
|
@ -335,15 +333,18 @@ int process_faces(const world_t* world) |
|
|
bounds.includePoint(vertex->toVec()); |
|
|
bounds.includePoint(vertex->toVec()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Accumulate lightmap contribution of this face on each vertex
|
|
|
|
|
|
if (face->lightmap >= 0) |
|
|
|
|
|
|
|
|
// Sample lightmap contribution of this face on each vertex
|
|
|
|
|
|
for (size_t faceVertIdx = outFace.firstFaceVertex; faceVertIdx < outFaceVertices.size(); ++faceVertIdx) |
|
|
{ |
|
|
{ |
|
|
for (int indexIdx = outFace.firstVertexIndex; indexIdx < faceVertIndices.size(); ++indexIdx) |
|
|
|
|
|
|
|
|
ps1bsp_facevertex_t& faceVertex = outFaceVertices[faceVertIdx]; |
|
|
|
|
|
unsigned char lightmap = sample_lightmap(world, face, bounds, world->vertices[faceVertex.index].toVec()); |
|
|
|
|
|
faceVertex.light = lightmap + (0xFF - face->baselight); |
|
|
|
|
|
|
|
|
|
|
|
if (face->lightmap >= 0) |
|
|
{ |
|
|
{ |
|
|
int vertIndex = faceVertIndices[indexIdx]; |
|
|
|
|
|
unsigned char light = sample_lightmap(world, face, bounds, world->vertices[vertIndex].toVec()); |
|
|
|
|
|
*(unsigned short*)(&outVertices[vertIndex].baseLight) += light + (0xFF - face->baselight); |
|
|
|
|
|
outVertices[vertIndex].r++; |
|
|
|
|
|
|
|
|
ps1bsp_vertex_t& vertex = outVertices[faceVertex.index]; |
|
|
|
|
|
*(unsigned short*)(&vertex.baseLight) += faceVertex.light; |
|
|
|
|
|
vertex.r++; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -351,11 +352,11 @@ int process_faces(const world_t* world) |
|
|
//if (face->ledge_num >= 10)
|
|
|
//if (face->ledge_num >= 10)
|
|
|
// export_lightmap(world, face, bounds, faceIdx);
|
|
|
// export_lightmap(world, face, bounds, faceIdx);
|
|
|
|
|
|
|
|
|
outFace.numVertices = faceVertIndices.size() - outFace.firstVertexIndex; |
|
|
|
|
|
|
|
|
outFace.numFaceVertices = (unsigned short)(outFaceVertices.size() - outFace.firstFaceVertex); |
|
|
outFaces.push_back(outFace); |
|
|
outFaces.push_back(outFace); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Average the lightmap values for this vertex
|
|
|
|
|
|
|
|
|
// Average the lightmap values for each vertex
|
|
|
for (auto iter = outVertices.begin(); iter != outVertices.end(); ++iter) |
|
|
for (auto iter = outVertices.begin(); iter != outVertices.end(); ++iter) |
|
|
{ |
|
|
{ |
|
|
unsigned char count = (*iter).r; |
|
|
unsigned char count = (*iter).r; |
|
|
@ -369,20 +370,20 @@ int process_faces(const world_t* world) |
|
|
|
|
|
|
|
|
// Write triangle and face data to file
|
|
|
// Write triangle and face data to file
|
|
|
fwrite(outVertices.data(), sizeof(ps1bsp_vertex_t), outVertices.size(), fbsp); |
|
|
fwrite(outVertices.data(), sizeof(ps1bsp_vertex_t), outVertices.size(), fbsp); |
|
|
fwrite(faceVertIndices.data(), sizeof(unsigned short), faceVertIndices.size(), fbsp); |
|
|
|
|
|
|
|
|
fwrite(outFaceVertices.data(), sizeof(ps1bsp_facevertex_t), outFaceVertices.size(), fbsp); |
|
|
fwrite(outFaces.data(), sizeof(ps1bsp_face_t), outFaces.size(), fbsp); |
|
|
fwrite(outFaces.data(), sizeof(ps1bsp_face_t), outFaces.size(), fbsp); |
|
|
|
|
|
|
|
|
// Update header information
|
|
|
// Update header information
|
|
|
outHeader.numVertices = outVertices.size(); |
|
|
|
|
|
outHeader.numFaceVertIndices = faceVertIndices.size(); |
|
|
|
|
|
outHeader.numFaces = outFaces.size(); |
|
|
|
|
|
|
|
|
outHeader.numVertices = (unsigned short)outVertices.size(); |
|
|
|
|
|
outHeader.numFaceVertices = (unsigned short)outFaceVertices.size(); |
|
|
|
|
|
outHeader.numFaces = (unsigned short)outFaces.size(); |
|
|
|
|
|
|
|
|
// Write final header
|
|
|
// Write final header
|
|
|
fseek(fbsp, 0, SEEK_SET); |
|
|
fseek(fbsp, 0, SEEK_SET); |
|
|
fwrite(&outHeader, sizeof(ps1bsp_header_t), 1, fbsp); |
|
|
fwrite(&outHeader, sizeof(ps1bsp_header_t), 1, fbsp); |
|
|
fclose(fbsp); |
|
|
fclose(fbsp); |
|
|
|
|
|
|
|
|
printf("PS1BSP: wrote %d vertices, %d indices, %d faces\n", outHeader.numVertices, outHeader.numFaceVertIndices, outHeader.numFaces); |
|
|
|
|
|
|
|
|
printf("PS1BSP: wrote %d vertices, %d indices, %d faces\n", outHeader.numVertices, outHeader.numFaceVertices, outHeader.numFaces); |
|
|
|
|
|
|
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|