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/scene.obj
|
||||
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": [
|
||||
{
|
||||
"world": "test.world",
|
||||
"start": 0,
|
||||
"end": 5,
|
||||
"meshes": [
|
||||
{
|
||||
"name": "suzanne",
|
||||
"path": "data/suzanne.obj"
|
||||
"path": "suzanne.obj",
|
||||
"material": "test.material"
|
||||
},
|
||||
{
|
||||
"name": "suzanne2",
|
||||
"path": "data/suzanne.obj"
|
||||
"path": "suzanne.obj",
|
||||
"material": "test.material"
|
||||
}
|
||||
],
|
||||
"animations": [
|
||||
|
@ -67,12 +70,14 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"world": "test.world",
|
||||
"start": 5,
|
||||
"end": 10,
|
||||
"meshes": [
|
||||
{
|
||||
"name": "suzanne",
|
||||
"path": "data/suzanne.obj"
|
||||
"path": "suzanne.obj",
|
||||
"material": "test.material"
|
||||
}
|
||||
],
|
||||
"animations": [
|
||||
|
@ -89,6 +94,20 @@
|
|||
"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 {
|
||||
public:
|
||||
glm::vec3 position = glm::vec3(0), target = glm::vec3(0);
|
||||
float fov = 75.0f;
|
||||
float focusDistance = 0.0f;
|
||||
float aperture = 0.0f;
|
||||
float near = 0.1f, far = 100.0f;
|
||||
|
|
|
@ -7,11 +7,13 @@ class Mesh;
|
|||
|
||||
struct Keyframe {
|
||||
int time = 0;
|
||||
glm::vec3 value = glm::vec3(0);
|
||||
glm::vec3 valueVec3 = glm::vec3(0);
|
||||
int valueInt = 0;
|
||||
};
|
||||
|
||||
enum class AnimationProperty {
|
||||
Position
|
||||
Position,
|
||||
FoV
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
|
|
156
src/main.cpp
156
src/main.cpp
|
@ -44,6 +44,8 @@ int windowFullscreen = 0;
|
|||
std::string currentGraphicsPreset = "Medium";
|
||||
GraphicsConfig graphicsConfig;
|
||||
|
||||
World* world = nullptr;
|
||||
|
||||
int toInt(const std::string &str) {
|
||||
std::stringstream ss(str);
|
||||
|
||||
|
@ -98,9 +100,11 @@ void writeConfig() {
|
|||
config.save("user.cfg");
|
||||
}
|
||||
|
||||
Mesh* loadMesh(const char* path) {
|
||||
Mesh* loadMesh(const std::string& path) {
|
||||
std::string fixedPath = "data/" + path;
|
||||
|
||||
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();
|
||||
|
||||
|
@ -146,8 +150,58 @@ std::vector<std::string> tokenize(const std::string& str) {
|
|||
return tokens;
|
||||
}
|
||||
|
||||
Cinematic* loadCinematic(const char* path) {
|
||||
std::ifstream file(path);
|
||||
Material* loadMaterial(const std::string& 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)
|
||||
return nullptr;
|
||||
|
||||
|
@ -160,9 +214,12 @@ Cinematic* loadCinematic(const char* path) {
|
|||
shot->start = shotObject["start"];
|
||||
shot->end = shotObject["end"];
|
||||
|
||||
world = loadWorld(shotObject["world"]);
|
||||
|
||||
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->material = loadMaterial(meshObject["material"]);
|
||||
|
||||
shot->meshes.push_back(mesh);
|
||||
}
|
||||
|
@ -177,18 +234,26 @@ Cinematic* loadCinematic(const char* path) {
|
|||
const auto property = animationObject["property"];
|
||||
if(property == "position")
|
||||
animation->property = AnimationProperty::Position;
|
||||
else if(property == "fov")
|
||||
animation->property = AnimationProperty::FoV;
|
||||
|
||||
for(auto keyframeObject : animationObject["keyframes"]) {
|
||||
Keyframe keyframe;
|
||||
keyframe.time = keyframeObject["time"];
|
||||
|
||||
auto tokens = tokenize(keyframeObject["value"]);
|
||||
if(animation->property == AnimationProperty::Position) {
|
||||
auto tokens = tokenize(keyframeObject["value"]);
|
||||
|
||||
keyframe.value[0] = atof(tokens[0].c_str());
|
||||
keyframe.value[1] = atof(tokens[1].c_str());
|
||||
keyframe.value[2] = atof(tokens[2].c_str());
|
||||
keyframe.valueVec3[0] = atof(tokens[0].c_str());
|
||||
keyframe.valueVec3[1] = atof(tokens[1].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);
|
||||
|
@ -209,6 +274,10 @@ int main(int argc, char* argv[]) {
|
|||
if(argc > 2 && strcmp(argv[1], "--cinematic") == 0)
|
||||
cinematicMode = true;
|
||||
|
||||
bool record = false;
|
||||
if(argc > 3 && strcmp(argv[2], "--record") == 0)
|
||||
record = true;
|
||||
|
||||
window = SDL_CreateWindow("Graph",
|
||||
windowX,
|
||||
windowY,
|
||||
|
@ -235,31 +304,15 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
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)
|
||||
cinematic = loadCinematic(argv[2]);
|
||||
else {
|
||||
Material* material = new Material();
|
||||
material->albedoTexturePath = "data/tile.jpg";
|
||||
|
||||
renderer->fillMaterialBuffers(material);
|
||||
|
||||
Mesh* mesh = loadMesh("data/scene.obj");
|
||||
mesh->material = material;
|
||||
|
||||
world.meshes.push_back(mesh);
|
||||
world = loadWorld("test.world");
|
||||
}
|
||||
|
||||
Camera camera;
|
||||
camera.position = {5.0, 5.0, 5.0};
|
||||
|
||||
float currentTime = 0.0f, lastTime = 0.0f, animationTime = 0.0f;
|
||||
Shot* currentShot = nullptr;
|
||||
|
||||
|
@ -303,11 +356,11 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
if(animationTime >= shot->start && animationTime < shot->end && currentShot != shot) {
|
||||
if(currentShot != nullptr) {
|
||||
world.meshes.clear();
|
||||
world->meshes.clear();
|
||||
}
|
||||
|
||||
for(auto mesh : shot->meshes)
|
||||
world.meshes.push_back(mesh);
|
||||
world->meshes.push_back(mesh);
|
||||
|
||||
currentShot = shot;
|
||||
}
|
||||
|
@ -317,7 +370,7 @@ int main(int argc, char* argv[]) {
|
|||
if(animationTime >= endTime) {
|
||||
currentShot = nullptr;
|
||||
|
||||
world.meshes.clear();
|
||||
world->meshes.clear();
|
||||
}
|
||||
|
||||
if(currentShot != nullptr) {
|
||||
|
@ -335,12 +388,22 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
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)
|
||||
animation->target->position = pos;
|
||||
else
|
||||
camera.position = pos;
|
||||
if(animation->target == nullptr)
|
||||
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)
|
||||
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("Target", &camera.target[0], 0.1f);
|
||||
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::Render();
|
||||
renderer->render(world, camera, target);
|
||||
renderer->render(*world, camera, target);
|
||||
|
||||
if(cinematicMode) {
|
||||
if(cinematicMode)
|
||||
animationTime += deltaTime;
|
||||
|
||||
if(record) {
|
||||
static int frameNum = 0;
|
||||
std::string screenshotName = "frame" + std::to_string(frameNum) + ".ppm";
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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));
|
||||
|
||||
vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &vp);
|
||||
|
|
Reference in a new issue