Danbias/Code/OysterGraphics/FileLoader/DanLoader.cpp

421 lines
11 KiB
C++
Raw Normal View History

2014-01-17 08:51:12 +01:00
#include "GeneralLoader.h"
#include "../Definitions/GraphicalDefinition.h"
#include "../Model/ModelInfo.h"
#include "../Core/Core.h"
#include <fstream>
#include <string>
#define DANFILEVERSIONMAJOR 1
#define DANFILEVERSIONMINOR 1
#define FILEHEADERSIZE 8
#define VERTEXHEADERSIZE 4
#define VERTEXSIZE 88
///
enum HeaderType
{
VERTEXHEADER = 0, ///<
INDEXHEADER = 1, ///<
MATERIALHEADER = 2, ///<
SKELETONHEADER = 3, ///<
ANIMATIONHEADER = 4 ///<
};
///
struct FileHeader
{
unsigned int versionMajor; ///<
unsigned int versionMinor; ///<
///
FileHeader(char* data)
{
char* memPos = data; //
memcpy(&versionMajor, memPos, sizeof(unsigned int));
memPos += 4;
memcpy(&versionMinor, memPos, sizeof(unsigned int));
}
};
///
struct VertexHeader
{
unsigned int numVertices;
///
VertexHeader(char* data)
{
memcpy(&numVertices, data, sizeof(unsigned int));
}
};
///
typedef Oyster::Graphics::Definitions::FinalVertex Vertex;
///
struct IndexHeader
{
unsigned int numIndices;
///
IndexHeader(char* data)
{
memcpy(&numIndices, data, sizeof(unsigned int));
}
};
///
struct MaterialHeader
{
unsigned int diffuseMapPathLength;
char* diffuseMapPath;
unsigned int normalMapPathLength;
char* normalMapPath;
/*
///
MaterialHeader(char* data)
{
char* memPos = data; //
memcpy(&diffuseMapPathLength, memPos, sizeof(unsigned int));
memPos += 4;
diffuseMapPath = new char[diffuseMapPathLength];
memcpy(diffuseMapPath, memPos, diffuseMapPathLength);
memPos += diffuseMapPathLength;
memcpy(&normalMapPathLength, memPos, sizeof(unsigned int));
memPos += 4;
normalMapPath = new char[normalMapPathLength];
memcpy(normalMapPath, memPos, normalMapPathLength);
memPos += normalMapPathLength;
}
*/
};
///
struct SkeletonHeader
{
2014-01-22 16:31:33 +01:00
unsigned int numBones;
///
SkeletonHeader(char* data)
{
memcpy(&numBones, data, sizeof(unsigned int));
}
2014-01-17 08:51:12 +01:00
};
///
struct AnimationHeader
{
2014-01-22 16:31:33 +01:00
unsigned int numAnims;
2014-01-17 08:51:12 +01:00
2014-01-22 16:31:33 +01:00
AnimationHeader(char* data)
{
memcpy(&numAnims, data, sizeof(unsigned int));
}
2014-01-17 08:51:12 +01:00
};
///
2014-01-22 16:31:33 +01:00
void Oyster::Graphics::Loading::UnloadDAN(void* data)
{
Model::ModelInfo* info = (Model::ModelInfo*) data;
SAFE_DELETE(info->Vertices);
if(info->Indexed)
{
SAFE_DELETE(info->Indecies);
}
2014-01-31 16:29:50 +01:00
if(info->Animated)
{
//clean animation
delete[] info->bones;
for(int a = 0; a < info->AnimationCount; ++a)
{
for(int x = 0; x < info->Animations[a].Bones; ++x)
{
delete[] info->Animations[a].Keyframes[x];
}
delete[] info->Animations[a].Frames;
delete[] info->Animations[a].Keyframes;
}
delete[] info->Animations;
}
2014-01-22 16:31:33 +01:00
for(int i =0;i<info->Material.size();++i)
{
2014-01-31 16:29:50 +01:00
Core::loader.ReleaseResource(info->Material[i]);
2014-01-22 16:31:33 +01:00
}
delete info;
}
2014-01-17 08:51:12 +01:00
static wchar_t* charToWChar(const char* text)
{
2014-01-22 16:31:33 +01:00
// Convert to a wchar_t*
size_t origsize = strlen(text) + 1;
size_t convertedChars = 0;
2014-01-17 08:51:12 +01:00
wchar_t* wcstring = new wchar_t[origsize];
2014-01-22 16:31:33 +01:00
mbstowcs_s(&convertedChars, wcstring, origsize, text, _TRUNCATE);
2014-01-17 08:51:12 +01:00
return wcstring;
2014-01-22 16:31:33 +01:00
}
static void ReadData(void* Destination, std::ifstream& file, int size)
{
char* buffer = new char[size];
file.read(buffer,size);
memcpy(Destination,buffer,size);
delete[] buffer;
}
///
2014-01-31 16:29:50 +01:00
void* Oyster::Graphics::Loading::LoadDAN(const wchar_t filename[])
2014-01-22 16:31:33 +01:00
{
//
Oyster::Graphics::Model::ModelInfo* modelInfo = new Oyster::Graphics::Model::ModelInfo();
modelInfo->Indexed = false;
2014-01-27 14:24:13 +01:00
modelInfo->Animated = false;
2014-01-22 16:31:33 +01:00
// Open file in binary mode
2014-01-17 08:51:12 +01:00
std::ifstream danFile;
2014-01-22 16:31:33 +01:00
danFile.open(filename, std::ios::binary);
if (!danFile.is_open())
2014-01-31 16:29:50 +01:00
return NULL;
2014-01-22 16:31:33 +01:00
// Read file header
char* buffer = new char[sizeof(FileHeader)];
danFile.read(buffer, sizeof(FileHeader));
FileHeader fileHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// If problem with compatability then close file and return from method
if (fileHeader.versionMajor != DANFILEVERSIONMAJOR)
{
danFile.close();
2014-01-31 16:29:50 +01:00
return NULL;
2014-01-22 16:31:33 +01:00
}
// Read the .dan-file
while (!danFile.eof())
{
// read header type
unsigned int headerType;
ReadData(&headerType,danFile,4);
// handle header type
switch ((HeaderType)headerType)
{
// vertex header
case HeaderType::VERTEXHEADER:
{
// Fetch vertex header, number of vertices
buffer = new char[4];
danFile.read(buffer, 4);
VertexHeader vertexHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// Fetch all vertices
unsigned int bufferSize = VERTEXSIZE * vertexHeader.numVertices;
buffer = new char[bufferSize];
danFile.read(buffer, bufferSize);
// Do the deed
Oyster::Graphics::Core::Buffer* vertexBuffer = new Oyster::Graphics::Core::Buffer();
Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc;
bufferInitDesc.ElementSize = sizeof(Vertex);
bufferInitDesc.InitData = buffer;
bufferInitDesc.NumElements = vertexHeader.numVertices;
bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
vertexBuffer->Init(bufferInitDesc);
modelInfo->VertexCount = vertexHeader.numVertices;
modelInfo->Vertices = vertexBuffer;
delete[] buffer; // ( note: may crash here.)
break;
}
case HeaderType::INDEXHEADER:
{
// Fetch vertex header, number of vertices
buffer = new char[4];
danFile.read(buffer, 4);
IndexHeader indexHeader(buffer);
delete[] buffer; // ( note: may crash here.)
// Fetch all indices
unsigned int* indices = new unsigned int[indexHeader.numIndices];
unsigned int bufferSize = sizeof(unsigned int) * indexHeader.numIndices;
ReadData(indices,danFile,bufferSize);
// Do the deed
Oyster::Graphics::Core::Buffer* indexBuffer = new Oyster::Graphics::Core::Buffer();
Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc;
bufferInitDesc.ElementSize = sizeof(unsigned int);
bufferInitDesc.InitData = indices;
bufferInitDesc.NumElements = indexHeader.numIndices;
bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::INDEX_BUFFER;
bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
indexBuffer->Init(bufferInitDesc);
modelInfo->IndexCount = indexHeader.numIndices;
modelInfo->Indecies = indexBuffer;
modelInfo->Indexed = true;
delete[] indices; // ( note: may crash here.)
break;
}
// material header
case HeaderType::MATERIALHEADER:
{
// Fetch material header, 2 texture path strings
MaterialHeader materialHeader;
//read difuse map name length
ReadData(&materialHeader.diffuseMapPathLength,danFile,4);
//read diffuse map name
2014-01-17 08:51:12 +01:00
materialHeader.diffuseMapPath = new char[materialHeader.diffuseMapPathLength+1];
2014-01-22 16:31:33 +01:00
ReadData(materialHeader.diffuseMapPath,danFile,materialHeader.diffuseMapPathLength);
//null terminate
materialHeader.diffuseMapPath[materialHeader.diffuseMapPathLength] = 0;
//read normal map name length
ReadData(&materialHeader.normalMapPathLength,danFile,4);
//read difuse map name
2014-01-17 08:51:12 +01:00
materialHeader.normalMapPath = new char[materialHeader.normalMapPathLength + 1];
2014-01-22 16:31:33 +01:00
ReadData(materialHeader.normalMapPath,danFile,materialHeader.normalMapPathLength);
materialHeader.normalMapPath[materialHeader.normalMapPathLength] = 0;
//load diffuse map
wchar_t* path = charToWChar(materialHeader.diffuseMapPath);
2014-01-31 16:29:50 +01:00
ID3D11ShaderResourceView* diffuseMap = (ID3D11ShaderResourceView*)Core::loader.LoadResource((Core::texturePath + path).c_str(), Oyster::Graphics::Loading::LoadTexture, Oyster::Graphics::Loading::UnloadTexture);
2014-01-22 16:31:33 +01:00
delete[] path;
//load normal map
path = charToWChar(materialHeader.normalMapPath);
2014-01-31 16:29:50 +01:00
ID3D11ShaderResourceView* normalMap = (ID3D11ShaderResourceView*)Core::loader.LoadResource((Core::texturePath + path).c_str(), Oyster::Graphics::Loading::LoadTexture, Oyster::Graphics::Loading::UnloadTexture);
2014-01-22 16:31:33 +01:00
delete[] path;
//add to model
modelInfo->Material.push_back(diffuseMap);
modelInfo->Material.push_back(normalMap);
//clean up
delete[] materialHeader.diffuseMapPath;
delete[] materialHeader.normalMapPath;
break;
}
// skeleton header
case HeaderType::SKELETONHEADER:
{
// Fetch Skeleton header, number of Bones
buffer = new char[4];
danFile.read(buffer, 4);
SkeletonHeader skeletonHeader(buffer);
delete[] buffer; // ( note: may crash here.)
//array for bone data
2014-01-27 14:24:13 +01:00
Oyster::Graphics::Model::Bone* bones = new Oyster::Graphics::Model::Bone[skeletonHeader.numBones];
2014-01-22 16:31:33 +01:00
//read bones
2014-01-27 14:24:13 +01:00
ReadData(bones,danFile,skeletonHeader.numBones * sizeof(Oyster::Graphics::Model::Bone));
2014-01-22 16:31:33 +01:00
//read skeleton Hiarchy
modelInfo->BoneCount = skeletonHeader.numBones;
2014-01-27 14:24:13 +01:00
modelInfo->bones = bones;
2014-01-22 16:31:33 +01:00
break;
}
// animation header
case HeaderType::ANIMATIONHEADER:
{
//get num anims
buffer = new char[4];
danFile.read(buffer, 4);
AnimationHeader animationHeader(buffer);
delete[] buffer;
Oyster::Graphics::Model::Animation* anims = new Oyster::Graphics::Model::Animation[animationHeader.numAnims];
2014-01-31 16:29:50 +01:00
2014-01-22 16:31:33 +01:00
for(int a = 0; a < animationHeader.numAnims; ++a)
{
//read name of animation
int nameLength;
ReadData(&nameLength,danFile,4);
char* name = new char[nameLength + 1];
ReadData(name,danFile,nameLength);
name[nameLength] = 0;
wchar_t* wName = charToWChar(name);
anims[a].name = std::wstring(wName);
delete[] wName;
2014-01-31 16:29:50 +01:00
delete name;
2014-01-28 13:48:15 +01:00
2014-01-22 16:31:33 +01:00
//read nr of bones in animation
2014-01-27 14:24:13 +01:00
ReadData(&anims[a].Bones,danFile,4);
2014-01-22 16:31:33 +01:00
2014-01-31 16:29:50 +01:00
//read duration
ReadData(&anims[a].duration,danFile,8);
2014-01-22 16:31:33 +01:00
//create Frame array and Bone part of KeyFrameArray;
2014-01-27 14:24:13 +01:00
anims[a].Frames = new int[anims[a].Bones];
anims[a].Keyframes = new Oyster::Graphics::Model::Frame*[anims[a].Bones];
2014-01-22 16:31:33 +01:00
//loop per bone and gather data
2014-01-27 14:24:13 +01:00
for(int b = 0; b < anims[a].Bones; ++b)
2014-01-22 16:31:33 +01:00
{
2014-01-27 14:24:13 +01:00
//read bone index
int boneIndex;
ReadData(&boneIndex,danFile,4);
2014-01-22 16:31:33 +01:00
//read nr of frames per bone
2014-01-27 14:24:13 +01:00
ReadData(&anims[a].Frames[b],danFile,4);
2014-01-22 16:31:33 +01:00
//create frame matrix
2014-01-27 14:24:13 +01:00
anims[a].Keyframes[b] = new Oyster::Graphics::Model::Frame[anims[a].Frames[b]];
2014-01-22 16:31:33 +01:00
2014-01-27 14:24:13 +01:00
for(int f = 0; f < anims[a].Frames[b]; ++f)
2014-01-22 16:31:33 +01:00
{
//write index of bone
2014-01-27 14:24:13 +01:00
anims[a].Keyframes[b][f].bone.Parent = boneIndex;
2014-01-22 16:31:33 +01:00
//read bone transform
2014-01-27 14:24:13 +01:00
ReadData(&anims[a].Keyframes[b][f].bone.Transform,danFile,sizeof(Oyster::Math::Matrix));
2014-01-22 16:31:33 +01:00
2014-01-27 14:24:13 +01:00
ReadData(&anims[a].Keyframes[b][f].time,danFile,sizeof(double));
2014-01-22 16:31:33 +01:00
}
}
}
2014-01-27 14:24:13 +01:00
modelInfo->AnimationCount = animationHeader.numAnims;
modelInfo->Animations = anims;
modelInfo->Animated = true;
2014-01-22 16:31:33 +01:00
break;
}
}
}
// close file
danFile.close();
// Set modelinfo as output data
2014-01-31 16:29:50 +01:00
return modelInfo;
2014-01-17 08:51:12 +01:00
}