Archived
1
Fork 0

Load worlds from files and add fov animation property

This commit is contained in:
Joshua Goins 2018-12-14 21:08:39 -05:00
parent 608b93e53b
commit 3be69363ca
10 changed files with 2429 additions and 884 deletions

View file

@ -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
View 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

File diff suppressed because it is too large Load diff

View file

@ -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
View file

@ -0,0 +1,3 @@
{
"albedoTexture": "tile.jpg"
}

15
data/test.world Normal file
View file

@ -0,0 +1,15 @@
{
"meshes": [
{
"position": "0,0,0",
"path": "scene.obj",
"material": "test.material"
}
],
"lights": [
{
"position": "66,56,25",
"type": 1
}
]
}

View file

@ -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;

View file

@ -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 {

View file

@ -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);

View file

@ -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);