bool SkeletonAnimation::Load(Rid rid) { if(data.data != nullptr) { data.Delete(); } frameCount = 0; frameRate = 0.0f; Document doc; if(!doc.Load(rid)) { Console::Error("Could not parse file as document <rid %d>", rid); return false; } uint32 count; if(!doc.root->ResolveAsUInt("bone_count.#0", &count)) { Console::Error("Could not find bone count in animation document"); return false; } data.SetSize(count); data.Zero(); if(!doc.root->ResolveAsFloat("frame_rate.#0", &frameRate)) { Console::Error("Could not find frame rate in animation document"); return false; } if(!doc.root->ResolveAsUInt("frame_count.#0", &frameCount)) { Console::Error("Could not find frame count in animation document"); return false; } for(uint32 i = 3; i < doc.root->count; i++) { Document::Node *boneNode = doc.root->children[i]; uint32 bone = i-3; data[bone].SetSize(boneNode->count); data[bone].Zero(); for(uint32 j = 0; j < boneNode->count; j++) { Document::Node *n = boneNode->children[j]; KeyFrame &kf = data[bone][j]; kf.frame = n->ValueAsUInt(); kf.offset = Vector3(n->children[0]->ValueAsFloat(), n->children[1]->ValueAsFloat(), n->children[2]->ValueAsFloat()); Vector3 eulerAngles = Vector3(n->children[3]->ValueAsFloat(), n->children[4]->ValueAsFloat(), n->children[5]->ValueAsFloat()) * MAKI_DEG_TO_RAD; kf.rot.FromEulerAngles(eulerAngles); } } this->rid = rid; return true; }
bool Material::Load(Rid rid) { CoreManagers *res = CoreManagers::Get(); Engine *eng = Engine::Get(); if(rid == RID_NONE) { Console::Error("Failed to load material, rid is RID_NONE"); return false; } Document doc; if(!doc.Load(rid)) { Console::Error("Failed to parse material file <rid %d>", rid); return false; } ShaderProgram *shader = nullptr; Rid shaderProgramRid = RID_NONE; Document::Node *n = nullptr; char *shaderProgramPath = doc.root->ResolveValue("shader.#0"); if(shaderProgramPath == nullptr) { Console::Error("Material did not specify a shader"); goto failed; } shaderProgramRid = Engine::Get()->assets->PathToRid(shaderProgramPath); if(shaderProgramRid == RID_NONE) { Console::Error("Could not resolve rid from shader program path: %s", shaderProgramPath); goto failed; } shaderProgram = res->shaderProgramManager->Load(shaderProgramRid); if(shaderProgram == HANDLE_NONE) { goto failed; } shader = ShaderProgramManager::Get(shaderProgram); n = doc.root->Resolve("texture_set"); if(n != nullptr) { Rid textureSetRids[TextureSet::MAX_TEXTURES_PER_SET]; uint32 textureSetSize = n->count; assert(textureSetSize < TextureSet::MAX_TEXTURES_PER_SET); for(uint32 i = 0; i < n->count; i++) { Rid texRid = eng->assets->PathToRid(n->children[i]->value); if(texRid == RID_NONE) { Console::Error("Could not resolve rid from texture path: %s", n->children[i]->value); goto failed; } textureSetRids[i] = texRid; } textureSet = res->textureSetManager->Load(textureSetSize, textureSetRids); if(textureSet == HANDLE_NONE) { Console::Error("Failed to construct texture set from rid list"); goto failed; } } n = doc.root->Resolve("uniforms"); if(n != nullptr) { for(uint32 i = 0; i < n->count; i++) { Document::Node *uniform = n->children[i]; if(uniform->count != 1) { Console::Error("Uniform node must have a single child specifying data type"); goto failed; } Document::Node *dataType = uniform->children[0]; if(dataType->count == 0) { Console::Error("Uniform data type node must have at least one child"); goto failed; } uint32 valueCount = dataType->count; char *buffer = (char *)Allocator::Malloc(valueCount*4); for(uint32 i = 0; i < valueCount; i++) { if(dataType->value[0] == 'f') { ((float *)buffer)[i] = dataType->children[i]->ValueAsFloat(); } else if(dataType->value[0] == 'u') { ((uint32 *)buffer)[i] = (uint32)dataType->children[i]->ValueAsInt(); } else if(dataType->value[0] == 'i') { ((int32 *)buffer)[i] = (int32)dataType->children[i]->ValueAsInt(); } else { SAFE_DELETE_ARRAY(buffer); Console::Error("Unrecognized uniform data type: %s", dataType->value); goto failed; } } if(PushConstant(uniform->value, valueCount*4, buffer) == -1) { Console::Warning("Warning, material has unbound uniforms <rid %d>", rid); } } } this->rid = rid; return true; failed: TextureSetManager::Free(textureSet); ShaderProgramManager::Free(shaderProgram); return false; }