diff --git a/include/Engine/Core/EntityXMLFile.h b/include/Engine/Core/EntityXMLFile.h
index d7c34e3a..6fa71dad 100644
--- a/include/Engine/Core/EntityXMLFile.h
+++ b/include/Engine/Core/EntityXMLFile.h
@@ -132,9 +132,10 @@ private:
void parseComponentInfo();
void parseDefaults();
void predictComponentAllocation();
- void parseEntityGraph();
+ void parseEntityGraph(World* world, xercesc::DOMElement* parent, EntityID parentEntity);
std::size_t getTypeStride(std::string typeName);
float getFloatAttribute(const xercesc::DOMElement* element, const char* attribute) const;
+ void writeData(const xercesc::DOMElement* element, std::string typeName, char* outData);
};
#endif
\ No newline at end of file
diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml
index 8ca6b684..9b379495 100644
--- a/resources/Schema/Entities/Test.xml
+++ b/resources/Schema/Entities/Test.xml
@@ -3,10 +3,12 @@
-
-
-
+
+
+
+ Models/Core/UnitSphere.obj
+
12
11.11
@@ -14,7 +16,5 @@
-
-
\ No newline at end of file
diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd
index 2f0a6311..bd7de5a3 100644
--- a/resources/Schema/Types/Entity.xsd
+++ b/resources/Schema/Types/Entity.xsd
@@ -11,6 +11,7 @@
+
diff --git a/src/Engine/Core/EntityXMLFile.cpp b/src/Engine/Core/EntityXMLFile.cpp
index f64faeb6..b96e366e 100644
--- a/src/Engine/Core/EntityXMLFile.cpp
+++ b/src/Engine/Core/EntityXMLFile.cpp
@@ -67,7 +67,8 @@ void EntityXMLFile::PopulateWorld(World* world)
}
// 4. Parse entity hierarchy
- //parseEntityGraph();
+ auto root = m_DOMDocument->getDocumentElement();
+ parseEntityGraph(world, root, 0);
}
@@ -261,41 +262,7 @@ void EntityXMLFile::parseDefaults()
std::string fieldType = ci.second.FieldTypes.at(fieldName);
unsigned int fieldOffset = ci.second.FieldOffsets.at(fieldName);
-
- XSValue::DataType dataType = XSValue::getDataType(XSTR(fieldType.c_str()));
- if (dataType == XSValue::DataType::dt_MAXCOUNT) {
- if (fieldType == "Vector") {
- glm::vec3 vec;
- vec.x = getFloatAttribute(fieldElement, "X");
- vec.y = getFloatAttribute(fieldElement, "Y");
- vec.z = getFloatAttribute(fieldElement, "Z");
- memcpy(ci.second.Defaults.get() + fieldOffset, reinterpret_cast(&vec), getTypeStride(fieldType));
- } else if (fieldType == "Color") {
- glm::vec4 vec;
- vec.r = getFloatAttribute(fieldElement, "R");
- vec.g = getFloatAttribute(fieldElement, "G");
- vec.b = getFloatAttribute(fieldElement, "B");
- vec.a = getFloatAttribute(fieldElement, "A");
- memcpy(ci.second.Defaults.get() + fieldOffset, reinterpret_cast(&vec), getTypeStride(fieldType));
- } else if (fieldType == "Quaternion") {
- glm::quat q;
- q.x = getFloatAttribute(fieldElement, "X");
- q.y = getFloatAttribute(fieldElement, "Y");
- q.z = getFloatAttribute(fieldElement, "Z");
- q.w = getFloatAttribute(fieldElement, "W");
- memcpy(ci.second.Defaults.get() + fieldOffset, reinterpret_cast(&q), getTypeStride(fieldType));
- }
- } else if (dataType == XSValue::DataType::dt_string) {
- char* str = XMLString::transcode(fieldElement->getTextContent());
- std::string standardString(str);
- //new (ci.second.Defaults.get() + fieldOffset) std::string(str);
- XMLString::release(&str);
- memcpy(ci.second.Defaults.get() + fieldOffset, &standardString, getTypeStride(fieldType));
- } else {
- XSValue::Status status;
- XSValue* val = XSValue::getActualValue(fieldElement->getTextContent(), dataType, status);
- memcpy(ci.second.Defaults.get() + fieldOffset, reinterpret_cast(&val->fData.fValue), getTypeStride(fieldType));
- }
+ writeData(fieldElement, fieldType, ci.second.Defaults.get() + fieldOffset);
}
}
}
@@ -334,11 +301,56 @@ void EntityXMLFile::predictComponentAllocation()
}
}
-void EntityXMLFile::parseEntityGraph()
+void EntityXMLFile::parseEntityGraph(World* world, xercesc::DOMElement* element, EntityID parentEntity)
{
- //using namespace xercesc;
+ using namespace xercesc;
- //auto root = m_DOMDocument->getDocumentElement();
+ // Create entity
+ EntityID entity = world->CreateEntity(parentEntity);
+ LOG_DEBUG("Created entity %i, parent %i", entity, parentEntity);
+
+ // Add components
+ auto components = m_DOMDocument->evaluate(XSTR("Components/*"), element, nullptr, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, nullptr);
+ for (int i = 0; i < components->getSnapshotLength(); i++) {
+ components->snapshotItem(i);
+ auto componentElement = dynamic_cast(components->getNodeValue());
+ std::string componentName = XSTR(componentElement->getLocalName());
+ auto& ci = m_ComponentInfo.at(componentName);
+
+ // Attach the component
+ auto c = world->AttachComponent(entity, componentName);
+ LOG_DEBUG("Attached %s component", componentName.c_str());
+
+ // Write field data
+ auto fields = componentElement->getChildNodes();
+ for (int j = 0; j < fields->getLength(); ++j) {
+ auto fieldNode = fields->item(j);
+ auto nodeType = fieldNode->getNodeType();
+ if (nodeType != DOMNode::ELEMENT_NODE) {
+ continue;
+ }
+ auto field = dynamic_cast(fields->item(j));
+ //const XMLCh* value = fields->item(j)->getTextContent();
+ std::string fieldName(XSTR(field->getLocalName()));
+ if (ci.FieldTypes.find(fieldName) == ci.FieldTypes.end()) {
+ std::cout << "Warning: Component \"" << componentName << "\" contains invalid field \"" << fieldName << "\". Skipping." << std::endl;
+ continue;
+ }
+
+ std::string fieldType = ci.FieldTypes.at(fieldName);
+ unsigned int fieldOffset = ci.FieldOffsets.at(fieldName);
+ std::string fieldValue(XSTR(field->getTextContent()));
+ LOG_DEBUG(" %s %s = %s", fieldType.c_str(), fieldName.c_str(), fieldValue.c_str());
+ writeData(field, fieldType, c.Data + fieldOffset);
+ }
+ }
+
+ // Recurse children
+ auto children = m_DOMDocument->evaluate(XSTR("Children/Entity"), element, nullptr, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, nullptr);
+ for (int i = 0; i < children->getSnapshotLength(); i++) {
+ children->snapshotItem(i);
+ parseEntityGraph(world, dynamic_cast(children->getNodeValue()), entity);
+ }
//auto components = m_DOMDocument->getElementsByTagNameNS(XSTR("components"), XSTR("*"));
//for (int i = 0; i < components->getLength(); ++i) {
@@ -425,4 +437,45 @@ float EntityXMLFile::getFloatAttribute(const xercesc::DOMElement* element, const
} else {
return val->fData.fValue.f_float;
}
-}
\ No newline at end of file
+}
+
+void EntityXMLFile::writeData(const xercesc::DOMElement* element, std::string typeName, char* outData)
+{
+ using namespace xercesc;
+
+ XSValue::DataType dataType = XSValue::getDataType(XSTR(typeName.c_str()));
+ if (dataType == XSValue::DataType::dt_MAXCOUNT) {
+ if (typeName == "Vector") {
+ glm::vec3 vec;
+ vec.x = getFloatAttribute(element, "X");
+ vec.y = getFloatAttribute(element, "Y");
+ vec.z = getFloatAttribute(element, "Z");
+ memcpy(outData, reinterpret_cast(&vec), getTypeStride(typeName));
+ } else if (typeName == "Color") {
+ glm::vec4 vec;
+ vec.r = getFloatAttribute(element, "R");
+ vec.g = getFloatAttribute(element, "G");
+ vec.b = getFloatAttribute(element, "B");
+ vec.a = getFloatAttribute(element, "A");
+ memcpy(outData, reinterpret_cast(&vec), getTypeStride(typeName));
+ } else if (typeName == "Quaternion") {
+ glm::quat q;
+ q.x = getFloatAttribute(element, "X");
+ q.y = getFloatAttribute(element, "Y");
+ q.z = getFloatAttribute(element, "Z");
+ q.w = getFloatAttribute(element, "W");
+ memcpy(outData, reinterpret_cast(&q), getTypeStride(typeName));
+ }
+ } else if (dataType == XSValue::DataType::dt_string) {
+ char* str = XMLString::transcode(element->getTextContent());
+ std::string standardString(str);
+ new (outData) std::string(str);
+ XMLString::release(&str);
+ //memcpy(outData, reinterpret_cast(&standardString), getTypeStride(typeName));
+ } else {
+ XSValue::Status status;
+ XSValue* val = XSValue::getActualValue(element->getTextContent(), dataType, status);
+ memcpy(outData, reinterpret_cast(&val->fData.fValue), getTypeStride(typeName));
+ }
+}
+
diff --git a/src/Engine/Rendering/RawModel.cpp b/src/Engine/Rendering/RawModel.cpp
index c14fec08..962c278f 100644
--- a/src/Engine/Rendering/RawModel.cpp
+++ b/src/Engine/Rendering/RawModel.cpp
@@ -34,10 +34,10 @@ RawModel::RawModel(std::string fileName)
numIndices += face.mNumIndices;
}
}
- LOG_DEBUG("Vertex count %i", numVertices);
- LOG_DEBUG("Index count %i", numIndices);
+ //LOG_DEBUG("Vertex count %i", numVertices);
+ //LOG_DEBUG("Index count %i", numIndices);
- LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
+ //LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
std::vector> boneInfo;
std::map boneNameMapping;
@@ -132,35 +132,35 @@ RawModel::RawModel(std::string fileName)
matGroup.EndIndex = m_Indices.size() - 1;
// Material shininess
material->Get(AI_MATKEY_SHININESS, matGroup.Shininess);
- LOG_DEBUG("Shininess: %f", matGroup.Shininess);
+ //LOG_DEBUG("Shininess: %f", matGroup.Shininess);
// Diffuse texture
- LOG_DEBUG("%i diffuse textures found", material->GetTextureCount(aiTextureType_DIFFUSE));
+ //LOG_DEBUG("%i diffuse textures found", material->GetTextureCount(aiTextureType_DIFFUSE));
if (material->GetTextureCount(aiTextureType_DIFFUSE)) {
aiString path;
aiTextureMapping mapping;
material->GetTexture(aiTextureType_DIFFUSE, 0, &path, &mapping);
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
- LOG_DEBUG("Diffuse texture: %s", absolutePath.c_str());
+ //LOG_DEBUG("Diffuse texture: %s", absolutePath.c_str());
matGroup.Texture = std::shared_ptr(ResourceManager::Load(absolutePath));
}
// Normal map
- LOG_DEBUG("%i normal maps found", material->GetTextureCount(aiTextureType_HEIGHT));
+ //LOG_DEBUG("%i normal maps found", material->GetTextureCount(aiTextureType_HEIGHT));
if (material->GetTextureCount(aiTextureType_HEIGHT)) {
aiString path;
aiTextureMapping mapping;
material->GetTexture(aiTextureType_HEIGHT, 0, &path, &mapping);
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
- LOG_DEBUG("Normal map: %s", absolutePath.c_str());
+ //LOG_DEBUG("Normal map: %s", absolutePath.c_str());
matGroup.NormalMap = std::shared_ptr(ResourceManager::Load(absolutePath));
}
// Specular map
- LOG_DEBUG("%i specular maps found", material->GetTextureCount(aiTextureType_SPECULAR));
+ //LOG_DEBUG("%i specular maps found", material->GetTextureCount(aiTextureType_SPECULAR));
if (material->GetTextureCount(aiTextureType_SPECULAR)) {
aiString path;
aiTextureMapping mapping;
material->GetTexture(aiTextureType_SPECULAR, 0, &path, &mapping);
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
- LOG_DEBUG("Specular map: %s", absolutePath.c_str());
+ //LOG_DEBUG("Specular map: %s", absolutePath.c_str());
matGroup.SpecularMap = std::shared_ptr(ResourceManager::Load(absolutePath));
}
TextureGroups.push_back(matGroup);
@@ -216,20 +216,20 @@ RawModel::RawModel(std::string fileName)
m_Skeleton = new Skeleton();
CreateSkeleton(boneInfo, boneNameMapping, scene->mRootNode, -1);
int numBones = m_Skeleton->Bones.size();
- LOG_DEBUG("Bone count: %i", numBones);
+ //LOG_DEBUG("Bone count: %i", numBones);
if (numBones > 0) {
m_Skeleton->PrintSkeleton();
}
}
// Animations
- LOG_DEBUG("Animation count: %i", scene->mNumAnimations);
+ //LOG_DEBUG("Animation count: %i", scene->mNumAnimations);
for (int i = 0; i < scene->mNumAnimations; ++i) {
auto animation = scene->mAnimations[i];
std::string animationName = animation->mName.C_Str();
- LOG_DEBUG("Animation: %s", animationName.c_str());
- LOG_DEBUG("Duration: %f", animation->mDuration);
- LOG_DEBUG("Ticks per second: %f", animation->mTicksPerSecond);
+ //LOG_DEBUG("Animation: %s", animationName.c_str());
+ //LOG_DEBUG("Duration: %f", animation->mDuration);
+ //LOG_DEBUG("Ticks per second: %f", animation->mTicksPerSecond);
Skeleton::Animation skelAnim;
skelAnim.Name = animationName;
@@ -303,7 +303,7 @@ void RawModel::CreateSkeleton(std::vector> &b
// Find the bone by name in the bone info list
if (boneNameMapping.find(nodeName) == boneNameMapping.end()) {
- LOG_DEBUG("Node \"%s\" was not a bone", nodeName.c_str());
+ //LOG_DEBUG("Node \"%s\" was not a bone", nodeName.c_str());
} else {
glm::mat4 offsetMatrix;
int ID = boneNameMapping[nodeName];
diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/src/Engine/Rendering/RenderQueueFactory.cpp
index 9a7d89a1..aec304ed 100644
--- a/src/Engine/Rendering/RenderQueueFactory.cpp
+++ b/src/Engine/Rendering/RenderQueueFactory.cpp
@@ -36,12 +36,15 @@ glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent)
void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
{
for(auto& modelC : world->GetComponents("Model")) {
- ModelJob job;
std::string resource = modelC["Resource"];
+ if (resource.empty()) {
+ continue;
+ }
glm::vec4 color = modelC["Color"];
Model* model = ResourceManager::Load(resource);
for (auto texGroup : model->TextureGroups) {
+ ModelJob job;
job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0;
job.DiffuseTexture = texGroup.Texture.get();
job.NormalTexture = texGroup.NormalMap.get();