diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp index 088c3916..33567cc9 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp @@ -1,3 +1,7 @@ +///////////////////////////////////// +// Created by Pontus Fransson 2013 // +///////////////////////////////////// + #include "LevelParser.h" #include "Loader.h" @@ -9,7 +13,7 @@ using namespace Utility::DynamicMemory; LevelParser::LevelParser() { - formatVersion.formatVersionMajor = 1; + formatVersion.formatVersionMajor = 2; formatVersion.formatVersionMinor = 0; } @@ -29,35 +33,100 @@ std::vector> LevelParser::Parse(std::string filen char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize); //Read format version - FormatVersion levelFormatVersion; + LevelLoaderInternal::FormatVersion levelFormatVersion; ParseObject(&buffer[counter], &levelFormatVersion, sizeof(levelFormatVersion)); counter += sizeof(levelFormatVersion); if(this->formatVersion != levelFormatVersion) { //Do something if it's not the same version + + //Returns an empty vector, because it will most likely fail to read the level format. + return objects; } while(counter < bufferSize) { //Get typeID - ObjectTypeHeader typeID; + ObjectType typeID; ParseObject(&buffer[counter], &typeID, sizeof(typeID)); - switch((int)typeID.typeID) + switch((int)typeID) { case ObjectType_LevelMetaData: { - LevelMetaData* header = new LevelMetaData; - ParseLevelMetaData(&buffer[counter], *header, counter); + SmartPointer header = new LevelMetaData; + ParseLevelMetaData(&buffer[counter], *(LevelMetaData*)header.Get(), counter); objects.push_back(header); break; } - //This is by design, static and dynamic is using the same converter. Do not add anything inbetween them. + //This is by design, static and dynamic is using the same converter. Do not add anything inbetween them. + //Unless they are changed to not be the same. case ObjectType_Static: case ObjectType_Dynamic: { - ObjectHeader* header = new ObjectHeader; - ParseObject(&buffer[counter], *header, counter); - objects.push_back(header); + //Get specialType. + ObjectSpecialType specialType; + ParseObject(&buffer[counter+4], &specialType, sizeof(typeID)); + + switch(specialType) + { + //These three does not have any specail variables at this time. + //There for they are using the same 'parser'. + case ObjectSpecialType_World: + case ObjectSpecialType_Building: + case ObjectSpecialType_Damaging: + case ObjectSpecialType_Explosive: + { + ObjectHeader* header = new ObjectHeader; + ParseObject(&buffer[counter], *header, counter); + objects.push_back(header); + + break; + } + case ObjectSpecialType_JumpPad: + { + JumpPadAttributes* header = new JumpPadAttributes; + ParseObject(&buffer[counter], *header, counter); + + //Read the spec + ParseObject(&buffer[counter], header->direction, 16); + objects.push_back(header); + + break; + } + case ObjectSpecialType_BoostPad: + { + JumpPadAttributes* header = new JumpPadAttributes; + ParseObject(&buffer[counter], *header, counter); + + ParseObject(&buffer[counter], header->direction, 16); + objects.push_back(header); + + break; + } + case ObjectSpecialType_Portal: + { + PortalAttributes* header = new PortalAttributes; + ParseObject(&buffer[counter], *header, counter); + + ParseObject(&buffer[counter], header->destination, 12); + objects.push_back(header); + + break; + } + case ObjectSpecialType_SpawnPoint: + { + SpawnPointAttributes* header = new SpawnPointAttributes; + ParseObject(&buffer[counter], *header, counter); + + ParseObject(&buffer[counter], header->spawnPosition, 12); + objects.push_back(header); + + break; + } + default: + //Couldn't find specialType + break; + } break; } @@ -68,7 +137,12 @@ std::vector> LevelParser::Parse(std::string filen //Get Light type ParseObject(&buffer[counter+4], &lightType, sizeof(lightType)); - switch(lightType) + //We only support PointLight for now. + BasicLight* header = new BasicLight; + ParseObject(&buffer[counter], header, sizeof(*header)); + counter += sizeof(*header); + objects.push_back(header); + /*switch(lightType) { case LightType_PointLight: { @@ -98,7 +172,7 @@ std::vector> LevelParser::Parse(std::string filen //Undefined LightType. break; } - break; + break;*/ } default: //Couldn't find typeID. FAIL!!!!!! @@ -123,21 +197,25 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize); //Read format version - FormatVersion levelFormatVersion; + LevelLoaderInternal::FormatVersion levelFormatVersion; ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion)); counter += sizeof(levelFormatVersion); if(this->formatVersion != levelFormatVersion) { //Do something if it's not the same version + + //Returns an empty levelHeader with ObjectType_Unknown. + //Because it will not be able to read another version of the level format. + return levelHeader; } //Find the header in the returned string. while(counter < bufferSize) { - ObjectTypeHeader typeID; + ObjectType typeID; ParseObject(&buffer[counter], &typeID, sizeof(typeID)); - switch(typeID.typeID) + switch(typeID) { case ObjectType_LevelMetaData: ParseLevelMetaData(&buffer[counter], levelHeader, counter); @@ -149,6 +227,24 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) { ObjectHeader header; ParseObject(&buffer[counter], header, counter); + + switch(header.specialTypeID) + { + case ObjectSpecialType_JumpPad: + counter += sizeof(16); + break; + case ObjectSpecialType_BoostPad: + counter += sizeof(16); + break; + case ObjectSpecialType_Portal: + counter += sizeof(12); + break; + case ObjectSpecialType_SpawnPoint: + counter += sizeof(12); + break; + default: + break; + } break; } @@ -157,6 +253,9 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) LightType lightType; ParseObject(&buffer[counter+4], &lightType, sizeof(lightType)); + //We only support pointlight for now. + counter += sizeof(BasicLight); + /* switch(lightType) { case LightType_PointLight: @@ -177,7 +276,7 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) default: //Undefined LightType. break; - } + }*/ } default: diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.h b/Code/Game/GameLogic/LevelLoader/LevelParser.h index 9ad30642..346b75b5 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.h +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.h @@ -23,7 +23,7 @@ namespace GameLogic LevelMetaData ParseHeader(std::string filename); private: - FormatVersion formatVersion; + LevelLoaderInternal::FormatVersion formatVersion; }; } diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index 8287dafb..d87e42b2 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -9,7 +9,7 @@ namespace GameLogic /************************************ Enums *************************************/ - + enum ObjectType { ObjectType_LevelMetaData, @@ -23,6 +23,21 @@ namespace GameLogic ObjectType_Unknown = -1 }; + enum ObjectSpecialType + { + ObjectSpecialType_World, //Always the main celestial body + ObjectSpecialType_Building, + ObjectSpecialType_Damaging, + ObjectSpecialType_Explosive, + ObjectSpecialType_JumpPad, + ObjectSpecialType_BoostPad, + ObjectSpecialType_Portal, + ObjectSpecialType_SpawnPoint, + + ObjectSpecialType_Count, + ObjectSpecialType_Unknown = -1 + }; + enum UsePhysics { UsePhysics_UseFullPhysics, @@ -38,16 +53,18 @@ namespace GameLogic { CollisionGeometryType_Box, CollisionGeometryType_Sphere, + CollisionGeometryType_Cylinder, CollisionGeometryType_Count, CollisionGeometryType_Unknown = -1 }; + //Only supports Pointlight right now. enum LightType { LightType_PointLight, - LightType_DirectionalLight, - LightType_SpotLight, + //LightType_DirectionalLight, + //LightType_SpotLight, LightType_Count, LightType_Unknown = -1 @@ -80,38 +97,93 @@ namespace GameLogic /************************************ Structs *************************************/ - - struct FormatVersion + namespace LevelLoaderInternal { - unsigned int formatVersionMajor; - unsigned int formatVersionMinor; - - bool operator ==(const FormatVersion& obj) + struct FormatVersion { - return (this->formatVersionMajor != obj.formatVersionMajor && this->formatVersionMinor != obj.formatVersionMinor); - } + unsigned int formatVersionMajor; + unsigned int formatVersionMinor; + + FormatVersion() + : formatVersionMajor(0), formatVersionMinor(0) + {} - bool operator !=(const FormatVersion& obj) - { - return !(*this == obj); - } - }; + FormatVersion(unsigned int major, unsigned int minor) + : formatVersionMajor(major), formatVersionMinor(minor) + {} + + bool operator ==(const FormatVersion& obj) + { + return (this->formatVersionMajor == obj.formatVersionMajor && this->formatVersionMinor == obj.formatVersionMinor); + } + + bool operator !=(const FormatVersion& obj) + { + return !(*this == obj); + } + }; + } struct ObjectTypeHeader { ObjectType typeID; + + //Unless this is here the object destructor wont be called. + virtual ~ObjectTypeHeader(){} }; - struct PhysicsObject + namespace LevelLoaderInternal { - UsePhysics usePhysics; - float mass; - float inertiaMagnitude[3]; - float inertiaRotation[3]; - float frictionCoeffStatic; - float frictionCoeffDynamic; - CollisionGeometryType geometryType; - }; + const FormatVersion boundingVolumeVersion(1, 0); + + struct BoundingVolumeBase + { + float position[3]; + }; + + struct BoundingVolumeBox : public BoundingVolumeBase + { + float size[3]; + float angularAxis[3]; + float angle; + }; + + struct BoundingVolumeSphere : public BoundingVolumeBase + { + float radius; + }; + + struct BoundingVolumeCylinder : public BoundingVolumeBase + { + float length; + float angularAxis[3]; + float angle; + float radius; + }; + + struct BoundingVolume + { + CollisionGeometryType geoType; + union + { + LevelLoaderInternal::BoundingVolumeBox box; + LevelLoaderInternal::BoundingVolumeSphere sphere; + LevelLoaderInternal::BoundingVolumeCylinder cylinder; + }; + }; + + struct PhysicsObject + { + UsePhysics usePhysics; + float mass; + float inertiaMagnitude[3]; + float inertiaRotation[3]; + float frictionCoeffStatic; + float frictionCoeffDynamic; + float restitutionCoeff; + BoundingVolume boundingVolume; + }; + } struct LevelMetaData : public ObjectTypeHeader { @@ -123,10 +195,15 @@ namespace GameLogic WorldSize worldSize; std::string overviewPicturePath; std::vector gameModesSupported; + + virtual ~LevelMetaData(){} + }; - struct ObjectHeader : public ObjectTypeHeader, public PhysicsObject + struct ObjectHeader : public ObjectTypeHeader, public LevelLoaderInternal::PhysicsObject { + //Special type id for special objects: portal, jumppad, exploding objects, etc. + ObjectSpecialType specialTypeID; //Model, std::string ModelFile; //Position @@ -136,8 +213,29 @@ namespace GameLogic float angle; //Scale float scale[3]; + + virtual ~ObjectHeader(){} }; + /************************************ + Special objects + *************************************/ + + struct JumpPadAttributes : public ObjectHeader + { + float direction[3]; + float power; + }; + + struct PortalAttributes : public ObjectHeader + { + float destination[3]; + }; + + struct SpawnPointAttributes : public ObjectHeader + { + float spawnPosition[3]; + }; /************************************ Lights @@ -145,12 +243,13 @@ namespace GameLogic struct BasicLight : public ObjectTypeHeader { - LightType lightType; - float ambientColor[3]; - float diffuseColor[3]; - float specularColor[3]; + LightType lightType; //Is not used right now + float color[3]; + float position[3]; + float raduis; + float intensity; }; - + /* We only support pointlight right now. struct PointLight : public BasicLight { float position[3]; @@ -166,7 +265,7 @@ namespace GameLogic float direction[3]; float range; float attenuation[3]; - }; + };*/ } #endif \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp index 95236c05..e8c055b3 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp @@ -4,6 +4,7 @@ #include "ParseFunctions.h" #include "../../../Misc/Packing/Packing.h" +#include "Loader.h" #include using namespace Oyster::Packing; @@ -29,6 +30,9 @@ namespace GameLogic memcpy(&header.typeID, &buffer[start], 4); start += 4; + memcpy(&header.specialTypeID, &buffer[start], 4); + start += 4; + memcpy(&tempSize, &buffer[start], 4); start += 4; @@ -36,13 +40,18 @@ namespace GameLogic header.ModelFile.assign(&tempName[0], &tempName[tempSize]); start += tempSize; + //The reset of the object struct //3 float[3], 1 float memcpy(&header.position, &buffer[start], 40); start += 40; - //2 float[3], 3 float, 2 uint + //Physics struct + //2 float[3], 4 float, 1 uint memcpy(&header.usePhysics, &buffer[start], 44); start += 44; + + //Read path for bounding volume + ParseBoundingVolume(&buffer[start], header.boundingVolume, start); size += start; } @@ -107,5 +116,55 @@ namespace GameLogic size += start; } + + void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size) + { + int start = 0; + int tempSize = 0; + char tempName[128]; + + memcpy(&tempSize, &buffer[start], 4); + start += 4; + + memcpy(&tempName, &buffer[start], tempSize); + + string fileName; + fileName.assign(&tempName[0], &tempName[tempSize]); + start += tempSize; + + //Läs in filen. + int fileLength = 0; + Loader loader; + char* buf = loader.LoadFile("E:\\Dropbox\\Programming\\Github\\Danbias\\Bin\\Content\\Worlds\\cgf\\"+ fileName, fileLength); + + LevelLoaderInternal::FormatVersion version; + memcpy(&version, &buffer[0], sizeof(version)); + + memcpy(&volume.geoType, &buf[8], sizeof(volume.geoType)); + //start += sizeof(volume.geoType); + + switch(volume.geoType) + { + case CollisionGeometryType_Box: + memcpy(&volume.box, &buf[12], sizeof(volume.box)); + //start += sizeof(volume.box); + break; + + case CollisionGeometryType_Sphere: + memcpy(&volume.sphere, &buf[12], sizeof(volume.sphere)); + //start += sizeof(volume.sphere); + break; + + case CollisionGeometryType_Cylinder: + memcpy(&volume.cylinder, &buf[12], sizeof(volume.cylinder)); + //start += sizeof(volume.cylinder); + break; + + default: + break; + } + + size += start; + } } } \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h index f68a9289..f66351b4 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h @@ -21,6 +21,7 @@ namespace GameLogic void ParseObject(char* buffer, void *header, int size); void ParseObject(char* buffer, ObjectHeader& header, int& size); void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size); + void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size); } }