2013-07-07 22:10:29 +02:00
|
|
|
#include "renderwure/loaders/LoaderCOL.hpp"
|
2013-07-02 08:06:03 +02:00
|
|
|
#include <string>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
template<class T> T readType(char* data, size_t* offset)
|
|
|
|
{
|
|
|
|
size_t orgoff = *offset; *offset += sizeof(T);
|
|
|
|
return *reinterpret_cast<T*>(data+orgoff);
|
|
|
|
}
|
|
|
|
|
2013-07-07 22:10:29 +02:00
|
|
|
bool LoaderCOL::load(char* data, const size_t size)
|
|
|
|
{
|
|
|
|
char* dataptr = data;
|
|
|
|
int version = 1;
|
|
|
|
size_t dataI = 0;
|
|
|
|
|
|
|
|
while( dataI < size ) {
|
|
|
|
size_t file_base = dataI;
|
|
|
|
CollTHeader head = readType<CollTHeader>(data, &dataI);
|
|
|
|
switch(head.magic[3]) {
|
|
|
|
case 'L':
|
|
|
|
break;
|
|
|
|
case '2':
|
|
|
|
version = 2;
|
|
|
|
break;
|
|
|
|
case '3':
|
|
|
|
version = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
CollTHeaderV2 head2;
|
|
|
|
CollTHeaderV3 head3;
|
|
|
|
std::vector<CollTSphere> spheres;
|
|
|
|
std::vector<CollTBox> boxes;
|
2013-07-22 02:49:02 +02:00
|
|
|
std::vector<CollTVertex> meshvertices;
|
2013-07-22 03:38:43 +02:00
|
|
|
std::vector<CollTFaceTriangle> meshfaces;
|
2013-07-07 22:10:29 +02:00
|
|
|
|
|
|
|
if(version >= 2)
|
|
|
|
{
|
|
|
|
head2 = readType<CollTHeaderV2>(data, &dataI);
|
|
|
|
if(version >= 3)
|
|
|
|
{
|
|
|
|
head3 = readType<CollTHeaderV3>(data, &dataI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(version == 1)
|
|
|
|
{
|
|
|
|
head2.numspheres = readType<uint32_t>(data, &dataI);
|
|
|
|
head2.offsetspheres = file_base-4;
|
|
|
|
}
|
|
|
|
// Read spheres
|
|
|
|
for( size_t i = 0; i < head2.numspheres; ++i ) {
|
|
|
|
if(version == 1) {
|
|
|
|
auto s1 = readType<CollTSphereV1>(data, &dataI);
|
|
|
|
spheres.push_back({ s1.center, s1.radius, s1.surface });
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
spheres.push_back(readType<CollTSphere>(data, &dataI));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(version == 1)
|
|
|
|
{
|
|
|
|
// skip unused bytes
|
|
|
|
dataI += sizeof(uint32_t);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(version == 1)
|
|
|
|
{
|
|
|
|
head2.numboxes = readType<uint32_t>(data, &dataI);
|
|
|
|
head2.offsetboxes = dataI-4;
|
|
|
|
}
|
|
|
|
for( size_t i = 0; i < head2.numboxes; ++i) {
|
|
|
|
boxes.push_back(readType<CollTBox>(data, &dataI));
|
|
|
|
}
|
2013-07-22 02:49:02 +02:00
|
|
|
|
2013-07-07 22:10:29 +02:00
|
|
|
if(version == 1)
|
2013-07-22 02:49:02 +02:00
|
|
|
{
|
|
|
|
uint32_t numverts = readType<uint32_t>(data, &dataI);
|
|
|
|
head2.offsetverts = dataI;
|
|
|
|
// Skip the vertex data for now, since it's accessed retroactivly.
|
|
|
|
dataI += numverts * sizeof(CollTVertex);
|
2013-07-07 22:10:29 +02:00
|
|
|
}
|
2013-07-22 02:49:02 +02:00
|
|
|
else {
|
|
|
|
// TODO support version 2 & 3.
|
|
|
|
}
|
|
|
|
|
2013-07-07 22:10:29 +02:00
|
|
|
if(version == 1)
|
|
|
|
{
|
|
|
|
head2.numfaces = readType<uint32_t>(data, &dataI);
|
|
|
|
}
|
2013-07-22 02:49:02 +02:00
|
|
|
size_t maxvert = 0;
|
|
|
|
meshfaces.reserve(head2.numfaces);
|
|
|
|
for( size_t f = 0; f < head2.numfaces; ++f) {
|
|
|
|
// todo: Support 2-3
|
|
|
|
CollTFaceV1 face = readType<CollTFaceV1>(data, &dataI);
|
|
|
|
size_t maxv = std::max(face.a, std::max(face.b, face.c));
|
|
|
|
maxvert = std::max( maxvert, maxv );
|
2013-07-22 03:38:43 +02:00
|
|
|
meshfaces.push_back({face.a, face.b, face.c});
|
2013-07-22 02:49:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Load up to maxvert vertices.
|
2013-07-22 03:38:43 +02:00
|
|
|
meshvertices.reserve(maxvert+1);
|
|
|
|
for( size_t v = 0, vertI = head2.offsetverts; v < maxvert+1; ++v ) {
|
2013-07-22 02:49:02 +02:00
|
|
|
CollTVertex vert = readType<CollTVertex>(data, &vertI);
|
|
|
|
meshvertices.push_back(vert);
|
|
|
|
}
|
|
|
|
|
2013-07-07 22:10:29 +02:00
|
|
|
dataI += sizeof(CollTFace) * head2.numfaces;
|
|
|
|
|
|
|
|
instances.push_back({
|
|
|
|
version,
|
|
|
|
head,
|
|
|
|
head2,
|
|
|
|
head3,
|
|
|
|
spheres,
|
2013-07-22 02:49:02 +02:00
|
|
|
boxes,
|
|
|
|
meshvertices,
|
|
|
|
meshfaces
|
2013-07-07 22:10:29 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
dataI = file_base + head.size + sizeof(char) * 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-07-02 08:06:03 +02:00
|
|
|
bool LoaderCOL::load(const std::string& file)
|
|
|
|
{
|
|
|
|
std::ifstream dfile(file.c_str());
|
|
|
|
if ( ! dfile.is_open()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
dfile.seekg(0, std::ios_base::end);
|
|
|
|
size_t length = dfile.tellg();
|
|
|
|
dfile.seekg(0);
|
|
|
|
char* data = new char[length];
|
|
|
|
dfile.read(data, length);
|
|
|
|
|
2013-07-07 22:10:29 +02:00
|
|
|
auto res = load(data, length);
|
2013-07-02 08:06:03 +02:00
|
|
|
|
2013-07-07 22:10:29 +02:00
|
|
|
delete[] data;
|
2013-07-02 08:06:03 +02:00
|
|
|
|
2013-07-07 22:10:29 +02:00
|
|
|
return res;
|
2013-07-02 08:06:03 +02:00
|
|
|
}
|