diff --git a/data/test.cim b/data/test.cim index 3c78685..8b625d4 100644 --- a/data/test.cim +++ b/data/test.cim @@ -81,17 +81,31 @@ } ], "animations": [ + { + "target": "suzanne", + "property": "position", + "keyframes": [ + { + "time": 5, + "value": "0,5,0" + }, + { + "time": 10, + "value": "0,5,0" + } + ] + }, { "target": "camera", "property": "position", "keyframes": [ { "time": 5, - "value": "-5,0,2" + "value": "-5,5,2" }, { "time": 10, - "value": "5,0,2" + "value": "5,5,2" } ] }, @@ -108,6 +122,20 @@ "value": 75 } ] + }, + { + "target": "camera", + "property": "target", + "keyframes": [ + { + "time": 5, + "value": "0,5,0" + }, + { + "time": 10, + "value": "0,5,0" + } + ] } ] } diff --git a/include/cinematic.h b/include/cinematic.h index c6d7d3f..f112884 100644 --- a/include/cinematic.h +++ b/include/cinematic.h @@ -13,6 +13,7 @@ struct Keyframe { enum class AnimationProperty { Position, + Target, FoV }; diff --git a/include/mesh.h b/include/mesh.h index bd54768..b864a09 100644 --- a/include/mesh.h +++ b/include/mesh.h @@ -15,7 +15,7 @@ struct Vertex { class Mesh { public: - std::string name; + std::string name, tag; glm::vec3 position; Material* material = nullptr; diff --git a/src/main.cpp b/src/main.cpp index 0c8773e..61558cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -214,13 +214,16 @@ Cinematic* loadCinematic(const std::string& path) { shot->start = shotObject["start"]; shot->end = shotObject["end"]; - world = loadWorld(shotObject["world"]); + // TODO: concurrent worlds not implemented, we just load the first one + if(world == nullptr) + world = loadWorld(shotObject["world"]); for(auto meshObject : shotObject["meshes"]) { Mesh* mesh = loadMesh(meshObject["path"]); mesh->name = meshObject["name"]; mesh->material = loadMaterial(meshObject["material"]); - + mesh->tag = "cinematic"; + shot->meshes.push_back(mesh); } @@ -234,6 +237,8 @@ Cinematic* loadCinematic(const std::string& path) { const auto property = animationObject["property"]; if(property == "position") animation->property = AnimationProperty::Position; + else if(property == "target") + animation->property = AnimationProperty::Target; else if(property == "fov") animation->property = AnimationProperty::FoV; @@ -241,7 +246,7 @@ Cinematic* loadCinematic(const std::string& path) { Keyframe keyframe; keyframe.time = keyframeObject["time"]; - if(animation->property == AnimationProperty::Position) { + if(animation->property == AnimationProperty::Position || animation->property == AnimationProperty::Target) { auto tokens = tokenize(keyframeObject["value"]); keyframe.valueVec3[0] = atof(tokens[0].c_str()); @@ -360,7 +365,20 @@ int main(int argc, char* argv[]) { if(animationTime >= shot->start && animationTime < shot->end && currentShot != shot) { if(currentShot != nullptr) { - world->meshes.clear(); + for(auto mesh : world->meshes) { + if(mesh->tag == "cinematic") { + renderer->destroyMaterialBuffers(mesh->material); + delete mesh->material; + + renderer->destroyMeshBuffers(mesh); + delete mesh; + } + } + + world->meshes.erase(std::remove_if(world->meshes.begin(), + world->meshes.end(), + [](Mesh* m){return m->tag == "cinematic";}), + world->meshes.end()); } for(auto mesh : shot->meshes) @@ -399,13 +417,23 @@ int main(int argc, char* argv[]) { if(animation->target == nullptr) camera.position = pos; - else + else { animation->target->position = pos; + } } break; + case AnimationProperty::Target: + { + auto pos = currentFrame.valueVec3 + delta * (nextFrame.valueVec3 - currentFrame.valueVec3); + + camera.target = pos; + } + break; case AnimationProperty::FoV: + { auto pos = currentFrame.valueInt + delta * (nextFrame.valueInt - currentFrame.valueInt); camera.fov = pos; + } break; } } @@ -453,6 +481,16 @@ int main(int argc, char* argv[]) { renderer->takeScreenshot(screenshotName.c_str(), target); } } + + for(auto mesh : world->meshes) { + renderer->destroyMaterialBuffers(mesh->material); + delete mesh->material; + + renderer->destroyMeshBuffers(mesh); + delete mesh; + } + + delete world; renderer->destroyRenderTarget(target); diff --git a/src/worldpass.cpp b/src/worldpass.cpp index 903b997..d404876 100644 --- a/src/worldpass.cpp +++ b/src/worldpass.cpp @@ -63,7 +63,8 @@ void WorldPass::render(VkCommandBuffer commandBuffer, World& world, Camera& came glm::mat4 vp; vp = glm::perspective(glm::radians(camera.fov), (float)target->extent.width / target->extent.height, camera.near, camera.far); vp *= glm::lookAt(camera.position, camera.target, glm::vec3(0, -1, 0)); - + vp = glm::translate(vp, mesh->position); + vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &vp); vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT, sizeof(glm::mat4), sizeof(glm::mat4), &world.lights[0]->matrix);