Import art objects in level
This commit is contained in:
parent
9a197dabe7
commit
0f4f852528
|
@ -72,6 +72,22 @@ void FezLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IOSyst
|
|||
auto trileSetName = std::string(levelRoot.attribute("trileSetName").as_string());
|
||||
trileSetName = ai_tolower(trileSetName);
|
||||
|
||||
// Create material for triles
|
||||
auto myMat = new aiMaterial();
|
||||
aiString matName("TrileSet");
|
||||
myMat->AddProperty(&matName, AI_MATKEY_NAME);
|
||||
|
||||
// Embed texture for triles
|
||||
auto myTex = CreateTex(std::string(mFezAssetDir / "trile sets" / (trileSetName + ".png")), pIOHandler);
|
||||
mTextures.push_back(myTex);
|
||||
|
||||
// Put tex ref into material
|
||||
aiString tName("*0");
|
||||
myMat->AddProperty(&tName, AI_MATKEY_TEXTURE(aiTextureType_BASE_COLOR, 0));
|
||||
|
||||
//store material in scene
|
||||
mMaterials.push_back(myMat);
|
||||
|
||||
// Find and read trile set XML file
|
||||
std::unique_ptr<IOStream> trileFile;
|
||||
trileFile.reset(pIOHandler->Open(mFezAssetDir / "trile sets" / (trileSetName + ".xml")));
|
||||
|
@ -109,107 +125,83 @@ void FezLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IOSyst
|
|||
auto trileRoot = new aiNode("Triles");
|
||||
pScene->mRootNode->addChildren(1, &trileRoot);
|
||||
|
||||
// Begin filling out trile emplacements
|
||||
// Begin filling out trile nodes
|
||||
auto xmlTrileT = levelRoot.child("Triles");
|
||||
for (auto t : xmlTrileT.children()) {
|
||||
if (std::string(t.name()) != "Entry") {
|
||||
ASSIMP_LOG_WARN("Unknown tag found in Level Triles XML.");
|
||||
AddTrileInstances(xmlTrileT, trileRoot);
|
||||
|
||||
// Create child for art objects
|
||||
auto aoRoot = new aiNode("Art Objects");
|
||||
pScene->mRootNode->addChildren(1, &aoRoot);
|
||||
|
||||
// For some reason, it needs a positioning adjustment...
|
||||
aiMatrix4x4::Translation(aiVector3D(-0.5,-0.5, -0.5), aoRoot->mTransformation);
|
||||
|
||||
// Begin filling out art objects
|
||||
auto xmlAoRoot = levelRoot.child("ArtObjects");
|
||||
for (auto t : xmlAoRoot.children()) {
|
||||
XmlNode instance;
|
||||
if (std::string(t.name()) == "Entry") {
|
||||
instance = t.child("ArtObjectInstance");
|
||||
} else if (std::string(t.name()) == "ArtObjectInstance") {
|
||||
instance = t;
|
||||
} else {
|
||||
ASSIMP_LOG_WARN("AO instance not found in a node.");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto instance = t.child("TrileInstance");
|
||||
if (instance.empty()) {
|
||||
ASSIMP_LOG_WARN("Trile instance not found in a node.");
|
||||
auto aoName = std::string(instance.attribute("name").as_string("INVALID"));
|
||||
if (aoName == "INVALID") {
|
||||
ASSIMP_LOG_WARN("AO instance found without a valid name!");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto trileID = instance.attribute("trileId").as_int(-1);
|
||||
if (trileID == -1) {
|
||||
ASSIMP_LOG_WARN("Trile instance found without a valid trileId!");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto meshID = GetTrileMeshFromId(trileID);
|
||||
auto meshID = GetArtObjectFromName(aoName, pIOHandler);
|
||||
|
||||
// Create node, link found mesh
|
||||
auto trileNode = new aiNode();
|
||||
trileNode->mNumMeshes = 1;
|
||||
trileNode->mMeshes = new unsigned int[1];
|
||||
trileNode->mMeshes[0] = meshID;
|
||||
auto aoNode = new aiNode();
|
||||
aoNode->mNumMeshes = 1;
|
||||
aoNode->mMeshes = new unsigned int[1];
|
||||
aoNode->mMeshes[0] = meshID;
|
||||
|
||||
aoNode->mName = aiString("AO_" + aoName);
|
||||
auto pos = GetFezVec3(instance.child("Position"));
|
||||
auto orient = instance.attribute("orientation").as_int(0);
|
||||
auto rotate = GetFezQuat(instance.child("Rotation"));
|
||||
auto scale = GetFezVec3(instance.child("Scale"));
|
||||
|
||||
// Create transformation matrix
|
||||
aiMatrix4x4 transform = aiMatrix4x4::Translation(pos, transform);
|
||||
aiMatrix4x4 rotate = aiMatrix4x4::RotationY(gc_orient[orient], rotate);
|
||||
aoNode->mTransformation = aiMatrix4x4 (scale, rotate, pos);
|
||||
|
||||
trileNode->mTransformation = transform * rotate;
|
||||
|
||||
trileRoot->addChildren(1, &trileNode);
|
||||
aoRoot->addChildren(1, &aoNode);
|
||||
}
|
||||
|
||||
|
||||
// Fill in meshes from vector
|
||||
pScene->mNumMeshes = mTrileMeshes.size();
|
||||
pScene->mNumMeshes = mMeshes.size();
|
||||
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
|
||||
for (int i = 0; i < mTrileMeshes.size(); i++) {
|
||||
pScene->mMeshes[i] = mTrileMeshes[i];
|
||||
for (int i = 0; i < mMeshes.size(); i++) {
|
||||
pScene->mMeshes[i] = mMeshes[i];
|
||||
}
|
||||
|
||||
// Create material
|
||||
pScene->mNumMaterials = 1;
|
||||
pScene->mMaterials = new aiMaterial * [1];
|
||||
// Fill in materials from vector
|
||||
pScene->mNumMaterials = mMaterials.size();
|
||||
pScene->mMaterials = new aiMaterial * [mMaterials.size()];
|
||||
for (int i = 0; i < mMaterials.size(); i++) {
|
||||
pScene->mMaterials[i] = mMaterials.at(i);
|
||||
}
|
||||
|
||||
auto myMat = new aiMaterial();
|
||||
aiString matName("TrileSet");
|
||||
myMat->AddProperty(&matName, AI_MATKEY_NAME);
|
||||
aiString texturePath(std::string(mFezAssetDir / "trile sets" / (trileSetName + ".png")));
|
||||
// Fill in textures from vector
|
||||
pScene->mNumTextures = mTextures.size();
|
||||
pScene->mTextures = new aiTexture *[mTextures.size()];
|
||||
for (int i = 0; i < mTextures.size(); i++) {
|
||||
pScene->mTextures[i] = mTextures.at(i);
|
||||
}
|
||||
|
||||
|
||||
// Create embedded texture ref
|
||||
auto trileTex = new aiTexture();
|
||||
trileTex->mFilename = texturePath;
|
||||
|
||||
// PNG file, compressed
|
||||
strcpy(trileTex->achFormatHint, "png");
|
||||
trileTex->mHeight = 0;
|
||||
|
||||
// Open texture file for reading
|
||||
std::unique_ptr<IOStream> texFile;
|
||||
texFile.reset(pIOHandler->Open(mFezAssetDir / "trile sets" / (trileSetName + ".png")));
|
||||
|
||||
// Create buffer, read data, store into texture instance
|
||||
auto texDat = new unsigned char[texFile->FileSize()];
|
||||
trileTex->mWidth = texFile->FileSize();
|
||||
texFile->Read(texDat, 1, texFile->FileSize());
|
||||
trileTex->pcData = (aiTexel*)texDat;
|
||||
|
||||
// Store embedded texture into scene
|
||||
pScene->mNumTextures = 1;
|
||||
pScene->mTextures = new aiTexture *[1];
|
||||
pScene->mTextures[0] = trileTex;
|
||||
|
||||
// Put ref into material
|
||||
aiString tName("*0");
|
||||
myMat->AddProperty(&tName, AI_MATKEY_TEXTURE(aiTextureType_BASE_COLOR, 0));
|
||||
|
||||
//store material in scene
|
||||
pScene->mMaterials[0] = myMat;
|
||||
}
|
||||
|
||||
unsigned int FezLoader::GetTrileMeshFromId(const int trileId) {
|
||||
if (auto search = mTrileMap.find(trileId); search != mTrileMap.end()) {
|
||||
return search->second;
|
||||
}
|
||||
|
||||
// We need to create an aiMesh instance and add it to the vector.
|
||||
auto trileXML = mTriles.at(trileId);
|
||||
aiMesh *FezLoader::CreateMesh(const Assimp::XmlNode &xmlSIIP) {
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("FEZ CreateMesh called");
|
||||
|
||||
auto mesh = new aiMesh();
|
||||
|
||||
auto xmlSIIP = trileXML.child("Geometry").child("ShaderInstancedIndexedPrimitives");
|
||||
// TODO: check type="TriangleList"
|
||||
|
||||
auto xmlVerts = xmlSIIP.child("Vertices");
|
||||
auto xmlIdx = xmlSIIP.child("Indices");
|
||||
|
||||
|
@ -261,15 +253,81 @@ unsigned int FezLoader::GetTrileMeshFromId(const int trileId) {
|
|||
mesh->mTextureCoords[0][i] = v.texCoord;
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
unsigned int FezLoader::GetTrileMeshFromId(const int trileId) {
|
||||
if (auto search = mTrileMap.find(trileId); search != mTrileMap.end()) {
|
||||
return search->second;
|
||||
}
|
||||
|
||||
// We need to create an aiMesh instance and add it to the vector.
|
||||
auto trileXML = mTriles.at(trileId);
|
||||
auto xmlSIIP = trileXML.child("Geometry").child("ShaderInstancedIndexedPrimitives");
|
||||
|
||||
// Create mesh
|
||||
auto mesh = CreateMesh(xmlSIIP);
|
||||
mesh->mName = "Trile#" + std::to_string(trileId);
|
||||
|
||||
// Only one material for all triles.
|
||||
mesh->mMaterialIndex = 0;
|
||||
|
||||
// Add entry to trile map and add mesh to vector
|
||||
mTrileMap[trileId] = mTrileMeshes.size();
|
||||
mTrileMeshes.push_back(mesh);
|
||||
mTrileMap[trileId] = mMeshes.size();
|
||||
mMeshes.push_back(mesh);
|
||||
|
||||
return mTrileMap[trileId];
|
||||
}
|
||||
|
||||
unsigned int FezLoader::GetArtObjectFromName(const std::string &name, IOSystem *pIOHandler) {
|
||||
if (auto search = mAOMap.find(name); search != mAOMap.end()) {
|
||||
return search->second;
|
||||
}
|
||||
|
||||
auto AOXmlPath = mFezAssetDir / "art objects" / (ai_tolower(name) + ".xml");
|
||||
|
||||
if (!pIOHandler->Exists(AOXmlPath)) {
|
||||
ASSIMP_LOG_ERROR("Art Object specified that doesn't exist: ", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<IOStream> aoXmlFile;
|
||||
aoXmlFile.reset(pIOHandler->Open(AOXmlPath));
|
||||
|
||||
XmlParser p;
|
||||
p.parse(aoXmlFile.get());
|
||||
|
||||
XmlNode aoXmlRoot = p.getRootNode().child("ArtObject");
|
||||
|
||||
if (std::string(aoXmlRoot.name()) != name) {
|
||||
ASSIMP_LOG_WARN("Art Object name mismatch! ", name, " != ", aoXmlRoot.name());
|
||||
}
|
||||
|
||||
// Create mesh
|
||||
aiMesh* m = CreateMesh(aoXmlRoot.child("ShaderInstancedIndexedPrimitives"));
|
||||
m->mName = "AO_" + name;
|
||||
|
||||
// Load texture
|
||||
auto myTex = CreateTex(mFezAssetDir / "art objects" / (ai_tolower(name) + ".png"), pIOHandler);
|
||||
|
||||
// Create material
|
||||
auto myMat = new aiMaterial();
|
||||
|
||||
// Put tex ref into material
|
||||
aiString tName('*' + std::to_string(mMaterials.size()));
|
||||
myMat->AddProperty(&tName, AI_MATKEY_TEXTURE(aiTextureType_BASE_COLOR, 0));
|
||||
mTextures.push_back(myTex);
|
||||
|
||||
// Put material ref into mesh
|
||||
m->mMaterialIndex = mMaterials.size();
|
||||
mMaterials.push_back(myMat);
|
||||
|
||||
auto i = mMeshes.size();
|
||||
mAOMap[name] = i;
|
||||
mMeshes.push_back(m);
|
||||
return i;
|
||||
}
|
||||
|
||||
aiVector3D FezLoader::GetFezVec3(const XmlNode &t, bool direct) {
|
||||
if (direct) {
|
||||
return {t.attribute("x").as_float(), t.attribute("y").as_float(), t.attribute("z").as_float()};
|
||||
|
@ -287,6 +345,80 @@ aiVector2D FezLoader::GetFezVec2(const XmlNode &t, bool direct) {
|
|||
}
|
||||
|
||||
}
|
||||
void FezLoader::AddTrileInstances(const XmlNode &tis, aiNode *trileRoot) {
|
||||
for (auto t : tis.children()) {
|
||||
XmlNode instance;
|
||||
if (std::string(t.name()) == "Entry") {
|
||||
instance = t.child("TrileInstance");
|
||||
} else if (std::string(t.name()) == "TrileInstance") {
|
||||
instance = t;
|
||||
} else {
|
||||
ASSIMP_LOG_WARN("Trile instance not found in a node.");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto trileID = instance.attribute("trileId").as_int(-1);
|
||||
if (trileID == -1) {
|
||||
ASSIMP_LOG_WARN("Trile instance found without a valid trileId!");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto meshID = GetTrileMeshFromId(trileID);
|
||||
|
||||
// Create node, link found mesh
|
||||
auto trileNode = new aiNode();
|
||||
trileNode->mNumMeshes = 1;
|
||||
trileNode->mMeshes = new unsigned int[1];
|
||||
trileNode->mMeshes[0] = meshID;
|
||||
|
||||
trileNode->mName = aiString("Trile_ID#" + std::to_string(trileID));
|
||||
auto pos = GetFezVec3(instance.child("Position"));
|
||||
auto orient = instance.attribute("orientation").as_int(0);
|
||||
|
||||
// Create transformation matrix
|
||||
aiMatrix4x4 transform = aiMatrix4x4::Translation(pos, transform);
|
||||
aiMatrix4x4 rotate = aiMatrix4x4::RotationY(gc_orient[orient], rotate);
|
||||
|
||||
trileNode->mTransformation = transform * rotate;
|
||||
|
||||
trileRoot->addChildren(1, &trileNode);
|
||||
|
||||
auto overlapped = instance.child("OverlappedTriles");
|
||||
if (!overlapped.empty()) {
|
||||
AddTrileInstances(overlapped, trileRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiTexture *FezLoader::CreateTex(const std::string &path, IOSystem *pIOHandler) {
|
||||
// Create embedded texture ref
|
||||
auto myTex = new aiTexture();
|
||||
myTex->mFilename = path;
|
||||
|
||||
// PNG file, compressed
|
||||
strcpy(myTex->achFormatHint, "png");
|
||||
myTex->mHeight = 0;
|
||||
|
||||
// Open texture file for reading
|
||||
std::unique_ptr<IOStream> texFile;
|
||||
texFile.reset(pIOHandler->Open(path));
|
||||
|
||||
// Create buffer, read data, store into texture instance
|
||||
auto texDat = new unsigned char[texFile->FileSize()];
|
||||
myTex->mWidth = texFile->FileSize();
|
||||
texFile->Read(texDat, 1, texFile->FileSize());
|
||||
myTex->pcData = (aiTexel*)texDat;
|
||||
|
||||
return myTex;
|
||||
}
|
||||
aiQuaternion FezLoader::GetFezQuat(const XmlNode &t, bool direct) {
|
||||
if (direct) {
|
||||
return {t.attribute("w").as_float(), t.attribute("x").as_float(), t.attribute("y").as_float(), t.attribute("z").as_float()};
|
||||
} else {
|
||||
auto c = t.child("Quaternion");
|
||||
return {c.attribute("w").as_float(), c.attribute("x").as_float(), c.attribute("y").as_float(), c.attribute("z").as_float()};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <assimp/BaseImporter.h>
|
||||
#include <assimp/XmlParser.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/material.h>
|
||||
#include <assimp/texture.h>
|
||||
#include <map>
|
||||
#include <filesystem>
|
||||
|
||||
|
@ -23,8 +25,14 @@ protected:
|
|||
unsigned int GetTrileMeshFromId(const int trileId);
|
||||
|
||||
aiVector3D GetFezVec3(const XmlNode &t, bool direct = false);
|
||||
aiQuaternion GetFezQuat(const XmlNode &t, bool direct = false);
|
||||
aiVector2D GetFezVec2(const XmlNode &t, bool direct = false);
|
||||
|
||||
void AddTrileInstances(const XmlNode &tis, aiNode *trileRoot);
|
||||
|
||||
aiMesh *CreateMesh(const XmlNode &xmlSIIP);
|
||||
|
||||
aiTexture *CreateTex(const std::string &path, IOSystem *pIOHandler);
|
||||
private:
|
||||
std::filesystem::path mFezAssetDir;
|
||||
std::string mFileName;
|
||||
|
@ -33,7 +41,11 @@ private:
|
|||
|
||||
std::map<int, XmlNode> mTriles;
|
||||
std::map<int, unsigned int> mTrileMap;
|
||||
std::vector<aiMesh*> mTrileMeshes;
|
||||
std::map<std::string, unsigned int> mAOMap;
|
||||
std::vector<aiMesh*> mMeshes;
|
||||
std::vector<aiMaterial*> mMaterials;
|
||||
std::vector<aiTexture*> mTextures;
|
||||
unsigned int GetArtObjectFromName(const std::string &name, IOSystem *pIOHandler);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue