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;
		}
Esempio n. 2
0
		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;
		}