fish #9
Binary file not shown.
@ -10,6 +10,8 @@
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
|
||||
struct RenderContext
|
||||
{
|
||||
GLuint vertexArray;
|
||||
@ -22,6 +24,11 @@ namespace Core
|
||||
void initFromAssimpMesh(aiMesh* mesh);
|
||||
};
|
||||
|
||||
struct Node {
|
||||
std::vector<RenderContext> renderContexts;
|
||||
glm::mat4 matrix;
|
||||
int parent;
|
||||
};
|
||||
// vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...)
|
||||
// numVertices - liczba wierzcholkow do narysowania
|
||||
// elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z))
|
||||
|
@ -34,6 +34,29 @@ glm::mat4 cameraMatrix, perspectiveMatrix;
|
||||
Core::Shader_Loader shaderLoader;
|
||||
Core::RenderContext fishContext;
|
||||
|
||||
std::vector<glm::vec3> keyPoints({
|
||||
glm::vec3(5.0f, 5.0f, 5.0f),
|
||||
glm::vec3(5.0f, 5.0f, -5.0f),
|
||||
glm::vec3(-5.0f, 5.0f, -5.0f),
|
||||
glm::vec3(-5.0f, 5.0f, 5.0f),
|
||||
glm::vec3(5.0f, 5.0f, 5.0f),
|
||||
glm::vec3(5.0f, 5.0f, -5.0f),
|
||||
glm::vec3(-5.0f, 5.0f, -5.0f),
|
||||
glm::vec3(-5.0f, 5.0f, 5.0f),
|
||||
glm::vec3(5.0f, 5.0f, 5.0f),
|
||||
glm::vec3(5.0f, 5.0f, -5.0f),
|
||||
glm::vec3(-5.0f, 5.0f, -5.0f),
|
||||
glm::vec3(-5.0f, 5.0f, 5.0f),
|
||||
glm::vec3(5.0f, 5.0f, 5.0f),
|
||||
glm::vec3(5.0f, 5.0f, -5.0f),
|
||||
glm::vec3(-5.0f, 5.0f, -5.0f),
|
||||
glm::vec3(-5.0f, 5.0f, 5.0f),
|
||||
});
|
||||
|
||||
std::vector<glm::quat> keyRotation;
|
||||
|
||||
std::vector<Core::Node> fish;
|
||||
|
||||
std::string skyboxTextures[6] = {
|
||||
"models/skybox/right.jpg",
|
||||
"models/skybox/left.jpg",
|
||||
@ -161,6 +184,44 @@ glm::mat4 createCameraMatrix()
|
||||
return Core::createViewMatrixQuat(cameraPos, rotation);
|
||||
}
|
||||
|
||||
glm::mat4 animationMatrix(float time) {
|
||||
float speed = 2.;
|
||||
time = time * speed;
|
||||
std::vector<float> distances;
|
||||
float timeStep = 0;
|
||||
for (int i = 0; i < keyPoints.size() - 1; i++) {
|
||||
timeStep += (keyPoints[i] - keyPoints[i + 1]).length();
|
||||
distances.push_back((keyPoints[i] - keyPoints[i + 1]).length());
|
||||
}
|
||||
time = fmod(time, timeStep);
|
||||
|
||||
//index of first keyPoint
|
||||
int index = 0;
|
||||
|
||||
while (distances[index] <= time) {
|
||||
time = time - distances[index];
|
||||
index += 1;
|
||||
}
|
||||
|
||||
float t = time / distances[index];
|
||||
|
||||
int size = keyPoints.size() - 1;
|
||||
int rotationSize = keyRotation.size() - 1;
|
||||
|
||||
glm::vec3 pos = glm::catmullRom(keyPoints[index - 1], keyPoints[index], keyPoints[index + 1], keyPoints[index + 2], t);
|
||||
|
||||
glm::quat divideByFour = glm::quat(0.25f, 0.25f, 0.25f, 0.25f);
|
||||
auto a1 = keyRotation[index] * glm::exp(-(glm::log(glm::inverse(keyRotation[index]) * keyRotation[index - 1]) + glm::log(glm::inverse(keyRotation[index]) * keyRotation[index + 1])) * divideByFour);
|
||||
|
||||
auto a2 = keyRotation[index + 1] * glm::exp(-(glm::log(glm::inverse(keyRotation[index + 1]) * keyRotation[index]) + glm::log(glm::inverse(keyRotation[index + 1]) * keyRotation[index + 2])) * divideByFour);
|
||||
|
||||
auto animationRotation = glm::squad(keyRotation[index], keyRotation[index + 1], a1, a2, t);
|
||||
|
||||
glm::mat4 result = glm::translate(pos) * glm::mat4_cast(animationRotation);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void drawObjectColor(Core::RenderContext context, glm::mat4 modelMatrix, glm::vec3 color)
|
||||
{
|
||||
GLuint program = programColor;
|
||||
@ -203,7 +264,7 @@ void renderScene()
|
||||
perspectiveMatrix = Core::createPerspectiveMatrix();
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
float time = glutGet(GLUT_ELAPSED_TIME) / 1000.f;
|
||||
glUseProgram(skyboxProgram);
|
||||
glUniform1i(glGetUniformLocation(skyboxProgram, "skybox"), 0);
|
||||
glm::mat4 transformation = perspectiveMatrix * cameraMatrix;
|
||||
@ -214,9 +275,9 @@ void renderScene()
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glm::mat4 fishInitialTransformation = glm::translate(glm::vec3(-1, 0, -0.5)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.25f));
|
||||
glm::mat4 fishModelMatrix = glm::translate(cameraPos + cameraDir) * glm::mat4_cast(glm::inverse(rotation)) * fishInitialTransformation;
|
||||
//drawObjectColor(fishContext, fishModelMatrix, glm::vec3(0.6f));
|
||||
glm::mat4 fishInitialTransformation = glm::translate(glm::vec3(0, -0.5, -0.4)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.25f));
|
||||
glm::mat4 fishModelMatrix = glm::translate(cameraPos + cameraDir) * glm::mat4_cast(glm::inverse(rotation)) * animationMatrix(time);
|
||||
|
||||
drawObjectTexture(fishContext, fishModelMatrix, textureFish);
|
||||
glutSwapBuffers();
|
||||
}
|
||||
@ -284,6 +345,26 @@ void initSkybox()
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
}
|
||||
|
||||
void initKeyRotation() {
|
||||
glm::vec3 oldDirection = glm::vec3(0, 0, 1);
|
||||
glm::quat oldRotationCamera = glm::quat(1, 0, 0, 0);
|
||||
glm::vec3 direction;
|
||||
glm::quat rotation;
|
||||
for (int i = 0; i < keyPoints.size() - 1; i++) {
|
||||
//3.1
|
||||
direction = glm::normalize(keyPoints[i + 1] - keyPoints[i]);
|
||||
//3.2
|
||||
rotation = glm::normalize(glm::rotationCamera(oldDirection, direction) * oldRotationCamera);
|
||||
//3.3
|
||||
keyRotation.push_back(rotation);
|
||||
//3.4
|
||||
oldDirection = direction;
|
||||
oldRotationCamera = rotation;
|
||||
}
|
||||
keyRotation.push_back(glm::quat(1, 0, 0, 0));
|
||||
keyRotation.push_back(glm::quat(1, -1, 1, 1));
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@ -293,6 +374,7 @@ void init()
|
||||
cubemapTexture = loadCubemap();
|
||||
loadModelToContext("models/submarine.obj", fishContext);
|
||||
textureFish = Core::LoadTexture("textures/submarine.png");
|
||||
initKeyRotation();
|
||||
initSkybox();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user