Load worlds from files and add fov animation property
This commit is contained in:
parent
608b93e53b
commit
3be69363ca
10 changed files with 2429 additions and 884 deletions
|
@ -92,4 +92,6 @@ add_data(Graph
|
||||||
data/bokeh.png
|
data/bokeh.png
|
||||||
data/scene.obj
|
data/scene.obj
|
||||||
data/tile.jpg
|
data/tile.jpg
|
||||||
data/graphics_presets.cfg)
|
data/graphics_presets.cfg
|
||||||
|
data/test.world
|
||||||
|
data/test.material)
|
||||||
|
|
12
data/suzanne.mtl
Normal file
12
data/suzanne.mtl
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Blender MTL File: 'None'
|
||||||
|
# Material Count: 1
|
||||||
|
|
||||||
|
newmtl None
|
||||||
|
Ns 96.078431
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Kd 0.640000 0.640000 0.640000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.000000
|
||||||
|
d 1.000000
|
||||||
|
illum 2
|
3081
data/suzanne.obj
3081
data/suzanne.obj
File diff suppressed because it is too large
Load diff
|
@ -1,16 +1,19 @@
|
||||||
{
|
{
|
||||||
"shots": [
|
"shots": [
|
||||||
{
|
{
|
||||||
|
"world": "test.world",
|
||||||
"start": 0,
|
"start": 0,
|
||||||
"end": 5,
|
"end": 5,
|
||||||
"meshes": [
|
"meshes": [
|
||||||
{
|
{
|
||||||
"name": "suzanne",
|
"name": "suzanne",
|
||||||
"path": "data/suzanne.obj"
|
"path": "suzanne.obj",
|
||||||
|
"material": "test.material"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "suzanne2",
|
"name": "suzanne2",
|
||||||
"path": "data/suzanne.obj"
|
"path": "suzanne.obj",
|
||||||
|
"material": "test.material"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"animations": [
|
"animations": [
|
||||||
|
@ -67,12 +70,14 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"world": "test.world",
|
||||||
"start": 5,
|
"start": 5,
|
||||||
"end": 10,
|
"end": 10,
|
||||||
"meshes": [
|
"meshes": [
|
||||||
{
|
{
|
||||||
"name": "suzanne",
|
"name": "suzanne",
|
||||||
"path": "data/suzanne.obj"
|
"path": "suzanne.obj",
|
||||||
|
"material": "test.material"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"animations": [
|
"animations": [
|
||||||
|
@ -89,6 +94,20 @@
|
||||||
"value": "5,0,2"
|
"value": "5,0,2"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "camera",
|
||||||
|
"property": "fov",
|
||||||
|
"keyframes": [
|
||||||
|
{
|
||||||
|
"time": 5,
|
||||||
|
"value": 35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 10,
|
||||||
|
"value": 75
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
3
data/test.material
Normal file
3
data/test.material
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"albedoTexture": "tile.jpg"
|
||||||
|
}
|
15
data/test.world
Normal file
15
data/test.world
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"meshes": [
|
||||||
|
{
|
||||||
|
"position": "0,0,0",
|
||||||
|
"path": "scene.obj",
|
||||||
|
"material": "test.material"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lights": [
|
||||||
|
{
|
||||||
|
"position": "66,56,25",
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
class Camera {
|
class Camera {
|
||||||
public:
|
public:
|
||||||
glm::vec3 position = glm::vec3(0), target = glm::vec3(0);
|
glm::vec3 position = glm::vec3(0), target = glm::vec3(0);
|
||||||
|
float fov = 75.0f;
|
||||||
float focusDistance = 0.0f;
|
float focusDistance = 0.0f;
|
||||||
float aperture = 0.0f;
|
float aperture = 0.0f;
|
||||||
float near = 0.1f, far = 100.0f;
|
float near = 0.1f, far = 100.0f;
|
||||||
|
|
|
@ -7,11 +7,13 @@ class Mesh;
|
||||||
|
|
||||||
struct Keyframe {
|
struct Keyframe {
|
||||||
int time = 0;
|
int time = 0;
|
||||||
glm::vec3 value = glm::vec3(0);
|
glm::vec3 valueVec3 = glm::vec3(0);
|
||||||
|
int valueInt = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class AnimationProperty {
|
enum class AnimationProperty {
|
||||||
Position
|
Position,
|
||||||
|
FoV
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Animation {
|
struct Animation {
|
||||||
|
|
150
src/main.cpp
150
src/main.cpp
|
@ -44,6 +44,8 @@ int windowFullscreen = 0;
|
||||||
std::string currentGraphicsPreset = "Medium";
|
std::string currentGraphicsPreset = "Medium";
|
||||||
GraphicsConfig graphicsConfig;
|
GraphicsConfig graphicsConfig;
|
||||||
|
|
||||||
|
World* world = nullptr;
|
||||||
|
|
||||||
int toInt(const std::string &str) {
|
int toInt(const std::string &str) {
|
||||||
std::stringstream ss(str);
|
std::stringstream ss(str);
|
||||||
|
|
||||||
|
@ -98,9 +100,11 @@ void writeConfig() {
|
||||||
config.save("user.cfg");
|
config.save("user.cfg");
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh* loadMesh(const char* path) {
|
Mesh* loadMesh(const std::string& path) {
|
||||||
|
std::string fixedPath = "data/" + path;
|
||||||
|
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate);
|
const aiScene* scene = importer.ReadFile(fixedPath.c_str(), aiProcess_Triangulate);
|
||||||
|
|
||||||
Mesh* mesh = new Mesh();
|
Mesh* mesh = new Mesh();
|
||||||
|
|
||||||
|
@ -146,8 +150,58 @@ std::vector<std::string> tokenize(const std::string& str) {
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cinematic* loadCinematic(const char* path) {
|
Material* loadMaterial(const std::string& path) {
|
||||||
std::ifstream file(path);
|
std::ifstream file("data/" + path);
|
||||||
|
|
||||||
|
nlohmann::json json;
|
||||||
|
file >> json;
|
||||||
|
|
||||||
|
Material* material = new Material();
|
||||||
|
material->albedoTexturePath = "data/" + json["albedoTexture"].get<std::string>();
|
||||||
|
|
||||||
|
renderer->fillMaterialBuffers(material);
|
||||||
|
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
World* loadWorld(const std::string& path) {
|
||||||
|
std::ifstream file("data/" + path);
|
||||||
|
|
||||||
|
nlohmann::json json;
|
||||||
|
file >> json;
|
||||||
|
|
||||||
|
World* world = new World();
|
||||||
|
|
||||||
|
for(auto meshObject : json["meshes"]) {
|
||||||
|
Mesh* mesh = loadMesh(meshObject["path"]);
|
||||||
|
mesh->material = loadMaterial(meshObject["material"]);
|
||||||
|
|
||||||
|
auto tokens = tokenize(meshObject["position"]);
|
||||||
|
|
||||||
|
mesh->position[0] = atof(tokens[0].c_str());
|
||||||
|
mesh->position[1] = atof(tokens[1].c_str());
|
||||||
|
mesh->position[2] = atof(tokens[2].c_str());
|
||||||
|
|
||||||
|
world->meshes.push_back(mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto lightObject : json["lights"]) {
|
||||||
|
Light* light = new Light();
|
||||||
|
|
||||||
|
auto tokens = tokenize(lightObject["position"]);
|
||||||
|
|
||||||
|
light->position[0] = atof(tokens[0].c_str());
|
||||||
|
light->position[1] = atof(tokens[1].c_str());
|
||||||
|
light->position[2] = atof(tokens[2].c_str());
|
||||||
|
|
||||||
|
world->lights.push_back(light);
|
||||||
|
}
|
||||||
|
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cinematic* loadCinematic(const std::string& path) {
|
||||||
|
std::ifstream file("data/" + path);
|
||||||
if(!file)
|
if(!file)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -160,9 +214,12 @@ Cinematic* loadCinematic(const char* path) {
|
||||||
shot->start = shotObject["start"];
|
shot->start = shotObject["start"];
|
||||||
shot->end = shotObject["end"];
|
shot->end = shotObject["end"];
|
||||||
|
|
||||||
|
world = loadWorld(shotObject["world"]);
|
||||||
|
|
||||||
for(auto meshObject : shotObject["meshes"]) {
|
for(auto meshObject : shotObject["meshes"]) {
|
||||||
Mesh* mesh = loadMesh(meshObject["path"].get<std::string>().c_str());
|
Mesh* mesh = loadMesh(meshObject["path"]);
|
||||||
mesh->name = meshObject["name"];
|
mesh->name = meshObject["name"];
|
||||||
|
mesh->material = loadMaterial(meshObject["material"]);
|
||||||
|
|
||||||
shot->meshes.push_back(mesh);
|
shot->meshes.push_back(mesh);
|
||||||
}
|
}
|
||||||
|
@ -177,18 +234,26 @@ Cinematic* loadCinematic(const char* path) {
|
||||||
const auto property = animationObject["property"];
|
const auto property = animationObject["property"];
|
||||||
if(property == "position")
|
if(property == "position")
|
||||||
animation->property = AnimationProperty::Position;
|
animation->property = AnimationProperty::Position;
|
||||||
|
else if(property == "fov")
|
||||||
|
animation->property = AnimationProperty::FoV;
|
||||||
|
|
||||||
for(auto keyframeObject : animationObject["keyframes"]) {
|
for(auto keyframeObject : animationObject["keyframes"]) {
|
||||||
Keyframe keyframe;
|
Keyframe keyframe;
|
||||||
keyframe.time = keyframeObject["time"];
|
keyframe.time = keyframeObject["time"];
|
||||||
|
|
||||||
|
if(animation->property == AnimationProperty::Position) {
|
||||||
auto tokens = tokenize(keyframeObject["value"]);
|
auto tokens = tokenize(keyframeObject["value"]);
|
||||||
|
|
||||||
keyframe.value[0] = atof(tokens[0].c_str());
|
keyframe.valueVec3[0] = atof(tokens[0].c_str());
|
||||||
keyframe.value[1] = atof(tokens[1].c_str());
|
keyframe.valueVec3[1] = atof(tokens[1].c_str());
|
||||||
keyframe.value[2] = atof(tokens[2].c_str());
|
keyframe.valueVec3[2] = atof(tokens[2].c_str());
|
||||||
|
|
||||||
animation->keyframes.push_back(keyframe);
|
animation->keyframes.push_back(keyframe);
|
||||||
|
} else if(animation->property == AnimationProperty::FoV) {
|
||||||
|
keyframe.valueInt = keyframeObject["value"];
|
||||||
|
|
||||||
|
animation->keyframes.push_back(keyframe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shot->animations.push_back(animation);
|
shot->animations.push_back(animation);
|
||||||
|
@ -209,6 +274,10 @@ int main(int argc, char* argv[]) {
|
||||||
if(argc > 2 && strcmp(argv[1], "--cinematic") == 0)
|
if(argc > 2 && strcmp(argv[1], "--cinematic") == 0)
|
||||||
cinematicMode = true;
|
cinematicMode = true;
|
||||||
|
|
||||||
|
bool record = false;
|
||||||
|
if(argc > 3 && strcmp(argv[2], "--record") == 0)
|
||||||
|
record = true;
|
||||||
|
|
||||||
window = SDL_CreateWindow("Graph",
|
window = SDL_CreateWindow("Graph",
|
||||||
windowX,
|
windowX,
|
||||||
windowY,
|
windowY,
|
||||||
|
@ -235,31 +304,15 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
RenderTarget* target = renderer->createSurfaceRenderTarget(surface);
|
RenderTarget* target = renderer->createSurfaceRenderTarget(surface);
|
||||||
|
|
||||||
World world;
|
|
||||||
|
|
||||||
auto light = new Light();
|
|
||||||
light->type = LightType::Directional;
|
|
||||||
light->position = glm::vec3(66, 56, 25);
|
|
||||||
|
|
||||||
world.lights.push_back(light);
|
|
||||||
|
|
||||||
Camera camera;
|
|
||||||
camera.position = {5.0, 5.0, 5.0};
|
|
||||||
|
|
||||||
if(cinematicMode)
|
if(cinematicMode)
|
||||||
cinematic = loadCinematic(argv[2]);
|
cinematic = loadCinematic(argv[2]);
|
||||||
else {
|
else {
|
||||||
Material* material = new Material();
|
world = loadWorld("test.world");
|
||||||
material->albedoTexturePath = "data/tile.jpg";
|
|
||||||
|
|
||||||
renderer->fillMaterialBuffers(material);
|
|
||||||
|
|
||||||
Mesh* mesh = loadMesh("data/scene.obj");
|
|
||||||
mesh->material = material;
|
|
||||||
|
|
||||||
world.meshes.push_back(mesh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Camera camera;
|
||||||
|
camera.position = {5.0, 5.0, 5.0};
|
||||||
|
|
||||||
float currentTime = 0.0f, lastTime = 0.0f, animationTime = 0.0f;
|
float currentTime = 0.0f, lastTime = 0.0f, animationTime = 0.0f;
|
||||||
Shot* currentShot = nullptr;
|
Shot* currentShot = nullptr;
|
||||||
|
|
||||||
|
@ -303,11 +356,11 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
if(animationTime >= shot->start && animationTime < shot->end && currentShot != shot) {
|
if(animationTime >= shot->start && animationTime < shot->end && currentShot != shot) {
|
||||||
if(currentShot != nullptr) {
|
if(currentShot != nullptr) {
|
||||||
world.meshes.clear();
|
world->meshes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto mesh : shot->meshes)
|
for(auto mesh : shot->meshes)
|
||||||
world.meshes.push_back(mesh);
|
world->meshes.push_back(mesh);
|
||||||
|
|
||||||
currentShot = shot;
|
currentShot = shot;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +370,7 @@ int main(int argc, char* argv[]) {
|
||||||
if(animationTime >= endTime) {
|
if(animationTime >= endTime) {
|
||||||
currentShot = nullptr;
|
currentShot = nullptr;
|
||||||
|
|
||||||
world.meshes.clear();
|
world->meshes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(currentShot != nullptr) {
|
if(currentShot != nullptr) {
|
||||||
|
@ -335,12 +388,22 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
const float delta = (animationTime - currentFrame.time) / (nextFrame.time - currentFrame.time);
|
const float delta = (animationTime - currentFrame.time) / (nextFrame.time - currentFrame.time);
|
||||||
|
|
||||||
glm::vec3 pos = currentFrame.value + delta * (nextFrame.value - currentFrame.value);
|
switch(animation->property) {
|
||||||
|
case AnimationProperty::Position:
|
||||||
|
{
|
||||||
|
auto pos = currentFrame.valueVec3 + delta * (nextFrame.valueVec3 - currentFrame.valueVec3);
|
||||||
|
|
||||||
if(animation->target != nullptr)
|
if(animation->target == nullptr)
|
||||||
animation->target->position = pos;
|
|
||||||
else
|
|
||||||
camera.position = pos;
|
camera.position = pos;
|
||||||
|
else
|
||||||
|
animation->target->position = pos;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AnimationProperty::FoV:
|
||||||
|
auto pos = currentFrame.valueInt + delta * (nextFrame.valueInt - currentFrame.valueInt);
|
||||||
|
camera.fov = pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +425,7 @@ int main(int argc, char* argv[]) {
|
||||||
if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)
|
if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)
|
||||||
io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
|
io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
|
||||||
|
|
||||||
ImGui::DragFloat3("Light Position", &world.lights[0]->position[0]);
|
ImGui::DragFloat3("Light Position", &world->lights[0]->position[0]);
|
||||||
ImGui::DragFloat3("Camera Position", &camera.position[0], 0.1f);
|
ImGui::DragFloat3("Camera Position", &camera.position[0], 0.1f);
|
||||||
ImGui::DragFloat3("Target", &camera.target[0], 0.1f);
|
ImGui::DragFloat3("Target", &camera.target[0], 0.1f);
|
||||||
ImGui::DragFloat("Aperture", &camera.aperture, 0.01f, 0.0f, 1.0f);
|
ImGui::DragFloat("Aperture", &camera.aperture, 0.01f, 0.0f, 1.0f);
|
||||||
|
@ -370,11 +433,12 @@ int main(int argc, char* argv[]) {
|
||||||
ImGui::Text("dpack[2] = %f", (100 - camera.focusDistance) / 100.0f);
|
ImGui::Text("dpack[2] = %f", (100 - camera.focusDistance) / 100.0f);
|
||||||
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
renderer->render(world, camera, target);
|
renderer->render(*world, camera, target);
|
||||||
|
|
||||||
if(cinematicMode) {
|
if(cinematicMode)
|
||||||
animationTime += deltaTime;
|
animationTime += deltaTime;
|
||||||
|
|
||||||
|
if(record) {
|
||||||
static int frameNum = 0;
|
static int frameNum = 0;
|
||||||
std::string screenshotName = "frame" + std::to_string(frameNum) + ".ppm";
|
std::string screenshotName = "frame" + std::to_string(frameNum) + ".ppm";
|
||||||
frameNum++;
|
frameNum++;
|
||||||
|
@ -383,16 +447,6 @@ int main(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cinematic == nullptr) {
|
|
||||||
renderer->destroyMaterialBuffers(world.meshes[0]->material);
|
|
||||||
delete world.meshes[0]->material;
|
|
||||||
|
|
||||||
renderer->destroyMeshBuffers(world.meshes[0]);
|
|
||||||
delete world.meshes[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
delete light;
|
|
||||||
|
|
||||||
renderer->destroyRenderTarget(target);
|
renderer->destroyRenderTarget(target);
|
||||||
|
|
||||||
vkDestroySurfaceKHR(renderer->getInstance(), surface, nullptr);
|
vkDestroySurfaceKHR(renderer->getInstance(), surface, nullptr);
|
||||||
|
|
|
@ -61,7 +61,7 @@ void WorldPass::render(VkCommandBuffer commandBuffer, World& world, Camera& came
|
||||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 1, 1, &mesh->material->set, 0, nullptr);
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 1, 1, &mesh->material->set, 0, nullptr);
|
||||||
|
|
||||||
glm::mat4 vp;
|
glm::mat4 vp;
|
||||||
vp = glm::perspective(glm::radians(75.0f), (float)target->extent.width / target->extent.height, camera.near, camera.far);
|
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::lookAt(camera.position, camera.target, glm::vec3(0, -1, 0));
|
||||||
|
|
||||||
vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &vp);
|
vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &vp);
|
||||||
|
|
Reference in a new issue