Working build with CMake 3.3.1
This commit is contained in:
@@ -36,6 +36,5 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
|
||||
|
||||
add_subdirectory(src/dd)
|
||||
add_subdirectory(src/game)
|
||||
add_subdirectory(src/tests)
|
||||
|
||||
@@ -178,4 +178,4 @@ private:
|
||||
double m_LastTime;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,36 +41,12 @@ public:
|
||||
{ }
|
||||
//void Update(double dt) override;
|
||||
|
||||
void Initialize() override;
|
||||
void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
|
||||
|
||||
Components::Transform AbsoluteTransform(EntityID entity);
|
||||
glm::vec3 AbsolutePosition(EntityID entity);
|
||||
glm::quat AbsoluteOrientation(EntityID entity);
|
||||
glm::vec3 AbsoluteScale(EntityID entity);
|
||||
|
||||
// Events
|
||||
EventRelay<TransformSystem, Events::Move> m_EMove;
|
||||
bool OnMove(const Events::Move &event);
|
||||
EventRelay<TransformSystem, Events::Rotate> m_ERotate;
|
||||
bool OnRotate(const Events::Rotate &event);
|
||||
private:
|
||||
struct MoveItems
|
||||
{
|
||||
EntityID Entity;
|
||||
glm::vec3 GoalPosition;
|
||||
float Speed;
|
||||
};
|
||||
std::unordered_map<EntityID, MoveItems> m_MoveItems;
|
||||
std::multimap<EntityID, MoveItems> m_QueuedMoveItems;
|
||||
struct RotationItems
|
||||
{
|
||||
EntityID Entity;
|
||||
glm::quat GoalRotation;
|
||||
double Time;
|
||||
};
|
||||
std::unordered_map<EntityID, RotationItems> m_RotationItems;
|
||||
std::multimap<EntityID, RotationItems> m_QueuedRotationItems;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+22
-26
@@ -9,7 +9,7 @@ find_package(ZLIB REQUIRED)
|
||||
find_package(PNG REQUIRED)
|
||||
# GLM
|
||||
|
||||
set(INCLUDE_PATH ${CMAKE_SOURCE_DIR}/include/dd)
|
||||
set(INCLUDE_PATH ${CMAKE_SOURCE_DIR}/include)
|
||||
include_directories(
|
||||
${INCLUDE_PATH}
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
@@ -31,59 +31,55 @@ file(GLOB SOURCE_FILES_Core_Util
|
||||
source_group(Core FILES ${SOURCE_FILES_Core})
|
||||
source_group(Core\\Util FILES ${SOURCE_FILES_Core_Util})
|
||||
|
||||
|
||||
file(GLOB SOURCE_FILES_Input
|
||||
"${INCLUDE_PATH}/Input/*.h"
|
||||
"Input/*.cpp"
|
||||
)
|
||||
source_group(Input FILES ${SOURCE_FILES_Input})
|
||||
|
||||
file(GLOB SOURCE_FILES_Particles
|
||||
"${INCLUDE_PATH}/Particles/*.h"
|
||||
"Particles/*.cpp"
|
||||
)
|
||||
source_group(Particles FILES ${SOURCE_FILES_Particles})
|
||||
|
||||
file(GLOB SOURCE_FILES_Rendering
|
||||
"${INCLUDE_PATH}/Rendering/*.h"
|
||||
)
|
||||
source_group(Rendering FILES ${SOURCE_FILES_Rendering})
|
||||
|
||||
file(GLOB SOURCE_FILES_Timer
|
||||
"${INCLUDE_PATH}/Timer/*.h"
|
||||
"Timer/*.cpp"
|
||||
)
|
||||
source_group(Timer FILES ${SOURCE_FILES_Timer})
|
||||
|
||||
file(GLOB SOURCE_FILES_Transform
|
||||
"${INCLUDE_PATH}/Transform/*.h"
|
||||
"Transform/*.cpp"
|
||||
)
|
||||
source_group(Transform FILES ${SOURCE_FILES_Transform})
|
||||
|
||||
file(GLOB SOURCE_FILES_Trigger
|
||||
"${INCLUDE_PATH}/Trigger/*.h"
|
||||
"Trigger/*.cpp"
|
||||
)
|
||||
source_group(Trigger FILES ${SOURCE_FILES_Trigger})
|
||||
|
||||
set(SOURCE_FILES
|
||||
${SOURCE_FILES_Core}
|
||||
${SOURCE_FILES_Core_Util}
|
||||
${SOURCE_FILES_Input}
|
||||
${SOURCE_FILES_Particles}
|
||||
${SOURCE_FILES_Rendering}
|
||||
${SOURCE_FILES_Timer}
|
||||
${SOURCE_FILES_Transform}
|
||||
${SOURCE_FILES_Trigger}
|
||||
)
|
||||
|
||||
add_library(daydream ${SOURCE_FILES})
|
||||
target_link_libraries(daydream
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||
endif()
|
||||
|
||||
add_library(game ${SOURCE_FILES})
|
||||
target_link_libraries(game
|
||||
${OPENGL_LIBRARIES}
|
||||
${GLEW_LIBRARIES}
|
||||
${GLFW_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${assimp_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
)
|
||||
)
|
||||
|
||||
add_executable(breakout
|
||||
main.cpp
|
||||
)
|
||||
target_link_libraries(breakout
|
||||
game
|
||||
${OPENGL_LIBRARIES}
|
||||
${GLEW_LIBRARIES}
|
||||
${GLFW_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${assimp_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
Executable
+377
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
This file is part of Daydream Engine.
|
||||
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
|
||||
|
||||
Daydream Engine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Daydream Engine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Core/Model.h"
|
||||
|
||||
dd::Model::Model(std::string fileName)
|
||||
{
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate);
|
||||
|
||||
if (scene == nullptr) {
|
||||
LOG_ERROR("Failed to load model \"%s\"", fileName.c_str());
|
||||
LOG_ERROR("Assimp error: %s", importer.GetErrorString());
|
||||
return;
|
||||
}
|
||||
|
||||
auto meshes = scene->mMeshes;
|
||||
|
||||
// Pre-count vertices
|
||||
int numVertices = 0;
|
||||
int numIndices = 0;
|
||||
for (int i = 0; i < scene->mNumMeshes; ++i) {
|
||||
numVertices += meshes[i]->mNumVertices;
|
||||
|
||||
// Faces
|
||||
for (int j = 0; j < meshes[i]->mNumFaces; ++j) {
|
||||
auto face = meshes[i]->mFaces[j];
|
||||
numIndices += face.mNumIndices;
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("Vertex count %i", numVertices);
|
||||
LOG_DEBUG("Index count %i", numIndices);
|
||||
|
||||
LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
|
||||
|
||||
std::vector<std::tuple<std::string, glm::mat4>> boneInfo;
|
||||
std::map<std::string, int> boneNameMapping;
|
||||
|
||||
for (int i = 0; i < scene->mNumMeshes; ++i) {
|
||||
auto mesh = meshes[i];
|
||||
auto material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
unsigned int indexOffset = m_Vertices.size();
|
||||
|
||||
// Vertices, normals and texture coordinates
|
||||
for (int vertexIndex = 0; vertexIndex < mesh->mNumVertices; ++vertexIndex) {
|
||||
Vertex desc;
|
||||
|
||||
// Position
|
||||
auto position = mesh->mVertices[vertexIndex];
|
||||
desc.Position = glm::vec3(position.x, position.y, position.z);
|
||||
|
||||
// Normal
|
||||
auto normal = mesh->mNormals[vertexIndex];
|
||||
desc.Normal = glm::vec3(normal.x, normal.y, normal.z);
|
||||
|
||||
//if (mesh->HasTangentsAndBitangents()) {
|
||||
// // Tangent
|
||||
// auto tangent = mesh->mTangents[vertexIndex];
|
||||
// desc.Tangent = glm::vec3(tangent.x, tangent.y, tangent.z);
|
||||
|
||||
// // Bi-tangent
|
||||
// auto bitangent = mesh->mBitangents[vertexIndex];
|
||||
// desc.BiTangent = glm::vec3(bitangent.x, bitangent.y, bitangent.z);
|
||||
//}
|
||||
|
||||
// UV
|
||||
if (mesh->HasTextureCoords(0)) {
|
||||
auto uv = mesh->mTextureCoords[0][vertexIndex];
|
||||
desc.TextureCoords = glm::vec2(uv.x, uv.y);
|
||||
}
|
||||
|
||||
// Material diffuse color
|
||||
aiColor4D diffuse;
|
||||
material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
|
||||
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, diffuse.a);
|
||||
// Material specular color
|
||||
aiColor4D specular;
|
||||
material->Get(AI_MATKEY_COLOR_SPECULAR, specular);
|
||||
desc.SpecularVertexColor = glm::vec4(specular.r, specular.g, specular.b, specular.a);
|
||||
|
||||
m_Vertices.push_back(desc);
|
||||
}
|
||||
|
||||
// Faces
|
||||
for (int j = 0; j < mesh->mNumFaces; ++j) {
|
||||
auto face = mesh->mFaces[j];
|
||||
for (int k = 0; k < face.mNumIndices; ++k) {
|
||||
unsigned int index = face.mIndices[k];
|
||||
m_Indices.push_back(indexOffset + index);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate normal mapping tangents
|
||||
for (int i = 0; i < m_Indices.size(); i += 3) {
|
||||
Vertex& v0 = m_Vertices[m_Indices[i]];
|
||||
Vertex& v1 = m_Vertices[m_Indices[i + 1]];
|
||||
Vertex& v2 = m_Vertices[m_Indices[i + 2]];
|
||||
|
||||
glm::vec3 edge1 = v1.Position - v0.Position;
|
||||
glm::vec3 edge2 = v2.Position - v0.Position;
|
||||
|
||||
float deltaU1 = v1.TextureCoords.x - v0.TextureCoords.x;
|
||||
float deltaV1 = v1.TextureCoords.y - v0.TextureCoords.y;
|
||||
float deltaU2 = v2.TextureCoords.x - v0.TextureCoords.x;
|
||||
float deltaV2 = v2.TextureCoords.y - v0.TextureCoords.y;
|
||||
|
||||
float f = 1.0f / (deltaU1 * deltaV2 - deltaU2 * deltaV1);
|
||||
|
||||
glm::vec3 tangent;
|
||||
tangent.x = f * (deltaV2 * edge1.x - deltaV1 * edge2.x);
|
||||
tangent.y = f * (deltaV2 * edge1.y - deltaV1 * edge2.y);
|
||||
tangent.z = f * (deltaV2 * edge1.z - deltaV1 * edge2.z);
|
||||
|
||||
v0.Tangent += tangent;
|
||||
v1.Tangent += tangent;
|
||||
v2.Tangent += tangent;
|
||||
}
|
||||
for (auto& vertex : m_Vertices) {
|
||||
vertex.Tangent = glm::normalize(vertex.Tangent);
|
||||
vertex.BiTangent = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal)));
|
||||
}
|
||||
|
||||
// Material info
|
||||
MaterialGroup matGroup;
|
||||
matGroup.StartIndex = indexOffset;
|
||||
matGroup.EndIndex = m_Indices.size() - 1;
|
||||
// Material shininess
|
||||
material->Get(AI_MATKEY_SHININESS, matGroup.Shininess);
|
||||
LOG_DEBUG("Shininess: %f", matGroup.Shininess);
|
||||
// Diffuse texture
|
||||
LOG_DEBUG("%i diffuse textures found", material->GetTextureCount(aiTextureType_DIFFUSE));
|
||||
if (material->GetTextureCount(aiTextureType_DIFFUSE)) {
|
||||
aiString path;
|
||||
aiTextureMapping mapping;
|
||||
material->GetTexture(aiTextureType_DIFFUSE, 0, &path, &mapping);
|
||||
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
|
||||
LOG_DEBUG("Diffuse texture: %s", absolutePath.c_str());
|
||||
matGroup.Texture = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
|
||||
}
|
||||
// Normal map
|
||||
LOG_DEBUG("%i normal maps found", material->GetTextureCount(aiTextureType_HEIGHT));
|
||||
if (material->GetTextureCount(aiTextureType_HEIGHT)) {
|
||||
aiString path;
|
||||
aiTextureMapping mapping;
|
||||
material->GetTexture(aiTextureType_HEIGHT, 0, &path, &mapping);
|
||||
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
|
||||
LOG_DEBUG("Normal map: %s", absolutePath.c_str());
|
||||
matGroup.NormalMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
|
||||
}
|
||||
// Specular map
|
||||
LOG_DEBUG("%i specular maps found", material->GetTextureCount(aiTextureType_SPECULAR));
|
||||
if (material->GetTextureCount(aiTextureType_SPECULAR)) {
|
||||
aiString path;
|
||||
aiTextureMapping mapping;
|
||||
material->GetTexture(aiTextureType_SPECULAR, 0, &path, &mapping);
|
||||
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
|
||||
LOG_DEBUG("Specular map: %s", absolutePath.c_str());
|
||||
matGroup.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
|
||||
}
|
||||
TextureGroups.push_back(matGroup);
|
||||
|
||||
// Bones
|
||||
std::map<int, std::vector<std::tuple<int, float>>> vertexWeights;
|
||||
for (int j = 0; j < mesh->mNumBones; ++j) {
|
||||
auto bone = mesh->mBones[j];
|
||||
std::string boneName = bone->mName.C_Str();
|
||||
|
||||
auto mat = bone->mOffsetMatrix;
|
||||
glm::mat4 glmMat(mat.a1, mat.b1, mat.c1, mat.d1,
|
||||
mat.a2, mat.b2, mat.c2, mat.d2,
|
||||
mat.a3, mat.b3, mat.c3, mat.d3,
|
||||
mat.a4, mat.b4, mat.c4, mat.d4);
|
||||
|
||||
int boneIndex;
|
||||
if (boneNameMapping.find(boneName) != boneNameMapping.end()) {
|
||||
boneIndex = boneNameMapping[boneName];
|
||||
} else {
|
||||
boneIndex = boneInfo.size();
|
||||
boneInfo.push_back(std::make_tuple(boneName, glmMat));
|
||||
boneNameMapping[boneName] = boneIndex;
|
||||
}
|
||||
|
||||
for (int k = 0; k < bone->mNumWeights; ++k) {
|
||||
auto weight = bone->mWeights[k];
|
||||
unsigned int offsetVertexId = weight.mVertexId + indexOffset;
|
||||
vertexWeights[offsetVertexId].push_back(std::make_tuple(boneIndex, weight.mWeight));
|
||||
}
|
||||
}
|
||||
for (auto &pair : vertexWeights) {
|
||||
auto weights = pair.second;
|
||||
Vertex& desc = m_Vertices[pair.first];
|
||||
|
||||
const int maxWeights = 8;
|
||||
if (weights.size() > maxWeights) {
|
||||
LOG_WARNING("Vertex weights (%i) greater than max weights per vertex (%i)", weights.size(), maxWeights);
|
||||
}
|
||||
for (int weightIndex = 0; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 4; ++weightIndex) {
|
||||
std::tie(desc.BoneIndices1[weightIndex], desc.BoneWeights1[weightIndex]) = weights[weightIndex];
|
||||
}
|
||||
for (int weightIndex = 4; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 8; ++weightIndex) {
|
||||
std::tie(desc.BoneIndices2[weightIndex - 4], desc.BoneWeights2[weightIndex - 4]) = weights[weightIndex];
|
||||
}
|
||||
}
|
||||
|
||||
//break;
|
||||
}
|
||||
|
||||
// Traverse the node tree and build a skeleton
|
||||
if (!boneInfo.empty()) {
|
||||
m_Skeleton = new Skeleton();
|
||||
CreateSkeleton(boneInfo, boneNameMapping, scene->mRootNode, -1);
|
||||
int numBones = m_Skeleton->Bones.size();
|
||||
LOG_DEBUG("Bone count: %i", numBones);
|
||||
if (numBones > 0) {
|
||||
m_Skeleton->PrintSkeleton();
|
||||
}
|
||||
}
|
||||
|
||||
// Animations
|
||||
LOG_DEBUG("Animation count: %i", scene->mNumAnimations);
|
||||
for (int i = 0; i < scene->mNumAnimations; ++i) {
|
||||
auto animation = scene->mAnimations[i];
|
||||
std::string animationName = animation->mName.C_Str();
|
||||
LOG_DEBUG("Animation: %s", animationName.c_str());
|
||||
LOG_DEBUG("Duration: %f", animation->mDuration);
|
||||
LOG_DEBUG("Ticks per second: %f", animation->mTicksPerSecond);
|
||||
|
||||
Skeleton::Animation skelAnim;
|
||||
skelAnim.Name = animationName;
|
||||
skelAnim.Duration = animation->mDuration / animation->mTicksPerSecond;
|
||||
|
||||
std::map<int, double> frameTimes;
|
||||
std::map<int, std::map<int, Skeleton::Animation::Keyframe::BoneProperty>> frameBoneProperties;
|
||||
// For each animation channel (bone)
|
||||
for (int channelIndex = 0; channelIndex < animation->mNumChannels; ++channelIndex) {
|
||||
auto channel = animation->mChannels[channelIndex];
|
||||
std::string boneName = channel->mNodeName.C_Str();
|
||||
int boneID = m_Skeleton->GetBoneID(boneName);
|
||||
if (boneID == -1) {
|
||||
LOG_ERROR("Animation referenced a bone that doesn't exist: %s", boneName.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// If you don't have the same amount of keyframes for every transformation type you're dumb.
|
||||
if (channel->mNumPositionKeys != channel->mNumRotationKeys || channel->mNumPositionKeys != channel->mNumScalingKeys) {
|
||||
LOG_ERROR("Hey, animation! You're dumb!", animationName.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int keyframe = 0; keyframe < channel->mNumPositionKeys; ++keyframe) {
|
||||
auto posKey = channel->mPositionKeys[keyframe];
|
||||
auto rotKey = channel->mRotationKeys[keyframe];
|
||||
auto scaleKey = channel->mScalingKeys[keyframe];
|
||||
|
||||
frameTimes[keyframe] = posKey.mTime;
|
||||
|
||||
auto &property = frameBoneProperties[keyframe][boneID];
|
||||
property.ID = keyframe;
|
||||
property.Position = glm::vec3(posKey.mValue.x, posKey.mValue.y, posKey.mValue.z);
|
||||
property.Rotation = glm::quat(rotKey.mValue.w, rotKey.mValue.x, rotKey.mValue.y, rotKey.mValue.z);
|
||||
property.Scale = glm::vec3(scaleKey.mValue.x, scaleKey.mValue.y, scaleKey.mValue.z);
|
||||
}
|
||||
}
|
||||
|
||||
// Create keyframes from bone properties
|
||||
for (auto &kv : frameBoneProperties) {
|
||||
int keyframe = kv.first;
|
||||
Skeleton::Animation::Keyframe animationFrame;
|
||||
animationFrame.Index = keyframe;
|
||||
animationFrame.Time = frameTimes[keyframe] / animation->mTicksPerSecond;
|
||||
for (auto &kv2 : kv.second) {
|
||||
int boneID = kv2.first;
|
||||
auto &property = kv2.second;
|
||||
animationFrame.BoneProperties[boneID] = property;
|
||||
}
|
||||
skelAnim.Keyframes.push_back(animationFrame);
|
||||
}
|
||||
|
||||
m_Skeleton->Animations[animationName] = skelAnim;
|
||||
}
|
||||
|
||||
// Generate GL buffers
|
||||
GLuint buffer;
|
||||
glGenBuffers(1, &buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &ElementBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(unsigned int), &m_Indices[0], GL_STATIC_DRAW);
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glBindVertexArray(VAO);
|
||||
GLERROR("GLEW: BufferFail4");
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4, 4, 4, 4, 4 };
|
||||
int stride = 0;
|
||||
for (int size : structSizes)
|
||||
stride += size;
|
||||
stride *= sizeof(GLfloat);
|
||||
int offset = 0;
|
||||
{
|
||||
int element = 0;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * offset)); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
}
|
||||
GLERROR("GLEW: BufferFail5");
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
glEnableVertexAttribArray(4);
|
||||
glEnableVertexAttribArray(5);
|
||||
glEnableVertexAttribArray(6);
|
||||
glEnableVertexAttribArray(7);
|
||||
glEnableVertexAttribArray(8);
|
||||
glEnableVertexAttribArray(9);
|
||||
glEnableVertexAttribArray(10);
|
||||
GLERROR("GLEW: BufferFail5");
|
||||
|
||||
//CreateBuffers();
|
||||
}
|
||||
|
||||
dd::Model::~Model()
|
||||
{
|
||||
if (m_Skeleton) {
|
||||
delete m_Skeleton;
|
||||
}
|
||||
}
|
||||
|
||||
void dd::Model::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID)
|
||||
{
|
||||
std::string nodeName = node->mName.C_Str();
|
||||
|
||||
// Find the bone by name in the bone info list
|
||||
if (boneNameMapping.find(nodeName) == boneNameMapping.end()) {
|
||||
LOG_DEBUG("Node \"%s\" was not a bone", nodeName.c_str());
|
||||
} else {
|
||||
glm::mat4 offsetMatrix;
|
||||
int ID = boneNameMapping[nodeName];
|
||||
std::tie(std::ignore, offsetMatrix) = boneInfo[ID];
|
||||
m_Skeleton->CreateBone(ID, parentID, nodeName, offsetMatrix);
|
||||
parentID = ID;
|
||||
}
|
||||
|
||||
for (int childIndex = 0; childIndex < node->mNumChildren; ++childIndex) {
|
||||
aiNode* child = node->mChildren[childIndex];
|
||||
CreateSkeleton(boneInfo, boneNameMapping, child, parentID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
This file is part of Daydream Engine.
|
||||
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
|
||||
|
||||
Daydream Engine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Daydream Engine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Core/OBJ.h"
|
||||
|
||||
bool dd::OBJ::LoadFromFile(std::string filename)
|
||||
{
|
||||
m_Path = boost::filesystem::path(filename);
|
||||
|
||||
// http://paulbourke.net/dataformats/obj/
|
||||
std::ifstream file(m_Path.string());
|
||||
if (!file.is_open())
|
||||
{
|
||||
LOG_ERROR("Failed to open .obj \"%s\": %s", m_Path.string().c_str(), strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
//LOG_INFO("Parsing .obj \"%s\"", m_Path.string().c_str());
|
||||
|
||||
std::string line;
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
if (line.length() == 0)
|
||||
continue;
|
||||
|
||||
std::stringstream ss(line);
|
||||
|
||||
std::string prefix;
|
||||
ss >> prefix;
|
||||
|
||||
// Ignore comments
|
||||
if (prefix == "#")
|
||||
continue;
|
||||
|
||||
// Material files
|
||||
if (prefix == "mtllib")
|
||||
{
|
||||
std::string materialFilename;
|
||||
ss >> materialFilename;
|
||||
m_MaterialPath = m_Path.branch_path() / materialFilename;
|
||||
ParseMaterial();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Material statement
|
||||
if (prefix == "usemtl")
|
||||
{
|
||||
std::string material;
|
||||
ss >> material;
|
||||
m_CurrentMaterial = &Materials[material];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Vertices
|
||||
if (prefix == "v")
|
||||
{
|
||||
float x, y, z;
|
||||
ss >> x >> y >> z;
|
||||
Vertices.push_back(std::make_tuple(x, y, z));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Normals
|
||||
if (prefix == "vn")
|
||||
{
|
||||
float x, y, z;
|
||||
ss >> x >> y >> z;
|
||||
Normals.push_back(std::make_tuple(x, y, z));
|
||||
}
|
||||
|
||||
// Texture coordinates
|
||||
if (prefix == "vt")
|
||||
{
|
||||
float u, v, w;
|
||||
ss >> u >> v >> w;
|
||||
TextureCoords.push_back(std::make_tuple(u, v, w));
|
||||
}
|
||||
|
||||
// Face definitions
|
||||
if (prefix == "f")
|
||||
{
|
||||
Face face;
|
||||
face.Material = m_CurrentMaterial;
|
||||
|
||||
std::string faceDefString;
|
||||
while (ss >> faceDefString)
|
||||
{
|
||||
std::stringstream ss2(faceDefString);
|
||||
FaceDefinition faceDef = { 0, 0, 0 };
|
||||
|
||||
ss2 >> faceDef.VertexIndex;
|
||||
ss2.ignore(); // Ignore first delimiter
|
||||
if (!ss2)
|
||||
continue;
|
||||
|
||||
if (ss2.peek() == '/')
|
||||
{
|
||||
ss2.ignore();
|
||||
ss2 >> faceDef.NormalIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss2 >> faceDef.TextureCoordIndex;
|
||||
ss2.ignore();
|
||||
ss2 >> faceDef.NormalIndex;
|
||||
}
|
||||
face.Definitions.push_back(faceDef);
|
||||
}
|
||||
Faces.push_back(face);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dd::OBJ::ParseMaterial()
|
||||
{
|
||||
// http://paulbourke.net/dataformats/mtl/
|
||||
std::ifstream file(m_MaterialPath.string());
|
||||
if (!file.is_open())
|
||||
{
|
||||
LOG_ERROR("Failed to open .mtl \"%s\"", m_MaterialPath.string().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
//LOG_INFO("Parsing .mtl \"%s\"", m_MaterialPath.string().c_str());
|
||||
|
||||
std::string currentMaterialName;
|
||||
MaterialInfo* currentMaterial = nullptr;
|
||||
|
||||
unsigned int currentLine = 0;
|
||||
std::string line;
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
currentLine++;
|
||||
if (line.length() == 0)
|
||||
continue;
|
||||
|
||||
std::stringstream ss(line);
|
||||
|
||||
std::string prefix;
|
||||
ss >> prefix;
|
||||
|
||||
// Create a new material definition
|
||||
if (prefix == "newmtl")
|
||||
{
|
||||
MaterialInfo mat;
|
||||
ss >> currentMaterialName;
|
||||
//LOG_INFO("Parsing material %s", currentMaterialName.c_str());
|
||||
Materials[currentMaterialName] = mat;
|
||||
currentMaterial = &Materials[currentMaterialName];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!currentMaterial)
|
||||
continue;
|
||||
|
||||
// Ambient color
|
||||
if (prefix == "Ka")
|
||||
{
|
||||
float r, g, b;
|
||||
ss >> r >> g >> b;
|
||||
currentMaterial->AmbientColor = std::make_tuple(r, g, b);
|
||||
continue;
|
||||
}
|
||||
// Diffuse color
|
||||
if (prefix == "Kd")
|
||||
{
|
||||
float r, g, b;
|
||||
ss >> r >> g >> b;
|
||||
currentMaterial->DiffuseColor = std::make_tuple(r, g, b);
|
||||
continue;
|
||||
}
|
||||
// Specular color
|
||||
if (prefix == "Ks")
|
||||
{
|
||||
float r, g, b;
|
||||
ss >> r >> g >> b;
|
||||
currentMaterial->SpecularColor = std::make_tuple(r, g, b);
|
||||
continue;
|
||||
}
|
||||
// Transmission filter
|
||||
if (prefix == "Tf")
|
||||
{
|
||||
std::stringstream ss2;
|
||||
ss2 << ss.str();
|
||||
|
||||
std::string command;
|
||||
ss2 >> command;
|
||||
if (command == "xyz")
|
||||
{
|
||||
// TODO: "The "Ks xyz" statement specifies the specular reflectivity using CIEXYZ values."
|
||||
}
|
||||
else if (command == "spectral")
|
||||
{
|
||||
// TODO: "The "Tf spectral" statement specifies the transmission filter using a spectral curve."
|
||||
}
|
||||
else
|
||||
{
|
||||
float r, g, b;
|
||||
ss >> r;
|
||||
// G and B are optional
|
||||
if (!(ss >> g >> b))
|
||||
{
|
||||
g = r;
|
||||
b = r;
|
||||
}
|
||||
currentMaterial->TransmissionFilter = std::make_tuple(r, g, b);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Optical density
|
||||
if (prefix == "Ni")
|
||||
{
|
||||
ss >> currentMaterial->OpticalDensity;
|
||||
continue;
|
||||
}
|
||||
// Alpha
|
||||
if (prefix == "d" || prefix == "Tr")
|
||||
{
|
||||
ss >> currentMaterial->Alpha;
|
||||
continue;
|
||||
}
|
||||
// Shininess
|
||||
if (prefix == "Ns")
|
||||
{
|
||||
ss >> currentMaterial->Shininess;
|
||||
continue;
|
||||
}
|
||||
// Illumination model
|
||||
if (prefix == "illum")
|
||||
{
|
||||
int illum = 0;
|
||||
ss >> illum;
|
||||
currentMaterial->IlluminationModel = illum;
|
||||
continue;
|
||||
}
|
||||
// Diffuse texture
|
||||
if (prefix == "map_Kd")
|
||||
{
|
||||
MaterialInfo::ColorMap colorMap;
|
||||
|
||||
std::string fileName;
|
||||
std::string arg;
|
||||
while (ss >> arg)
|
||||
{
|
||||
ParseColorMap(currentLine, ss, prefix, arg, colorMap);
|
||||
}
|
||||
|
||||
// HACK: Should we really have to specify the full path here?
|
||||
colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string();
|
||||
currentMaterial->DiffuseTexture = colorMap;
|
||||
continue;
|
||||
}
|
||||
// Specular map
|
||||
if (prefix == "map_Ks")
|
||||
{
|
||||
MaterialInfo::ColorMap colorMap;
|
||||
|
||||
std::string fileName;
|
||||
std::string arg;
|
||||
while (ss >> arg)
|
||||
{
|
||||
ParseColorMap(currentLine, ss, prefix, arg, colorMap);
|
||||
}
|
||||
|
||||
// HACK: Should we really have to specify the full path here?
|
||||
colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string();
|
||||
currentMaterial->SpecularMap = colorMap;
|
||||
continue;
|
||||
}
|
||||
// Normal map (bump map)
|
||||
if (prefix == "bump" || prefix == "map_Bump" )
|
||||
{
|
||||
MaterialInfo::BumpMap bumpMap;
|
||||
|
||||
std::string fileName;
|
||||
std::string arg;
|
||||
while (ss >> arg)
|
||||
{
|
||||
ParseBumpMap(currentLine, ss, prefix, arg, bumpMap);
|
||||
}
|
||||
|
||||
// HACK: Should we really have to specify the full path here?
|
||||
bumpMap.FileName = (m_MaterialPath.branch_path() / bumpMap.FileName).string();
|
||||
currentMaterial->NormalMap = bumpMap;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dd::OBJ::ParseTextureMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::TextureMap &textureMap)
|
||||
{
|
||||
if (arg == "-blendu")
|
||||
{
|
||||
std::string val;
|
||||
ss >> val;
|
||||
if (val == "off")
|
||||
textureMap.blendu = false;
|
||||
else if (val == "on")
|
||||
textureMap.blendu = true;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else if (arg == "-blendv")
|
||||
{
|
||||
std::string val;
|
||||
ss >> val;
|
||||
if (val == "off")
|
||||
textureMap.blendv = false;
|
||||
else if (val == "on")
|
||||
textureMap.blendv = true;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else if (arg == "-clamp")
|
||||
{
|
||||
std::string val;
|
||||
ss >> val;
|
||||
if (val == "off")
|
||||
textureMap.clamp = false;
|
||||
else if (val == "on")
|
||||
textureMap.clamp = true;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else if (arg == "-o")
|
||||
{
|
||||
float u, v, w;
|
||||
if (ss >> u >> v >> w)
|
||||
{
|
||||
textureMap.o = std::make_tuple(u, v, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
}
|
||||
else if (arg == "-s")
|
||||
{
|
||||
float u, v, w;
|
||||
if (ss >> u >> v >> w)
|
||||
{
|
||||
textureMap.s = std::make_tuple(u, v, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
}
|
||||
// Assume unrecognized options is part of the file name
|
||||
else
|
||||
{
|
||||
if (!textureMap.FileName.empty())
|
||||
textureMap.FileName += " ";
|
||||
textureMap.FileName += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void dd::OBJ::ParseColorMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::ColorMap &colorMap)
|
||||
{
|
||||
if (arg == "-cc")
|
||||
{
|
||||
if (prefix != "map_Kd" || prefix != "map_Ks")
|
||||
{
|
||||
LOG_ERROR("Invalid MTL argument \"%s\" to option \"%s\" on line %i", arg.c_str(), prefix.c_str(), line);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string val;
|
||||
if (ss >> val)
|
||||
{
|
||||
if (val == "off")
|
||||
colorMap.cc = false;
|
||||
else if (val == "on")
|
||||
colorMap.cc = true;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseTextureMap(line, ss, prefix, arg, colorMap);
|
||||
}
|
||||
}
|
||||
|
||||
void dd::OBJ::ParseBumpMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::BumpMap &bumpMap)
|
||||
{
|
||||
if (arg == "-bm")
|
||||
{
|
||||
if (prefix != "bump")
|
||||
{
|
||||
LOG_ERROR("Invalid MTL argument \"%s\" to option \"%s\" on line %i", arg.c_str(), prefix.c_str(), line);
|
||||
return;
|
||||
}
|
||||
|
||||
float val;
|
||||
if (ss >> val)
|
||||
bumpMap.bm = val;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseTextureMap(line, ss, prefix, arg, bumpMap);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
This file is part of Daydream Engine.
|
||||
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
|
||||
|
||||
Daydream Engine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Daydream Engine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Core/Skeleton.h"
|
||||
|
||||
int dd::Skeleton::CreateBone(int ID, int parentID, std::string name, glm::mat4 offsetMatrix)
|
||||
{
|
||||
if (m_BonesByName.find(name) != m_BonesByName.end()) {
|
||||
return m_BonesByName.at(name)->ID;
|
||||
} else {
|
||||
Bone* bone;
|
||||
|
||||
if (parentID == -1) {
|
||||
bone = new Bone(ID, nullptr, name, offsetMatrix);
|
||||
RootBone = bone;
|
||||
} else {
|
||||
Bone* parent = Bones[parentID];
|
||||
bone = new Bone(ID, parent, name, offsetMatrix);
|
||||
parent->Children.push_back(bone);
|
||||
}
|
||||
|
||||
Bones[ID] = bone;
|
||||
m_BonesByName[name] = bone;
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
|
||||
dd::Skeleton::~Skeleton()
|
||||
{
|
||||
for (auto &kv : Bones) {
|
||||
delete kv.second;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> dd::Skeleton::GetFrameBones(std::string animationName, double time, bool noRootMotion /*= false*/)
|
||||
{
|
||||
auto& animation = Animations.at(animationName);
|
||||
|
||||
// HACK: Animation wrap-around
|
||||
while (time < 0)
|
||||
time += animation.Duration;
|
||||
while (time > animation.Duration)
|
||||
time -= animation.Duration;
|
||||
|
||||
int currentKeyframeIndex = GetKeyframe(animation, time);
|
||||
|
||||
Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex];
|
||||
Animation::Keyframe& nextFrame = animation.Keyframes[currentKeyframeIndex + 1];
|
||||
float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
//auto animationFrame = Animations[""].Keyframes[frame];
|
||||
std::map<int, glm::mat4> frameBones;
|
||||
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1));
|
||||
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : frameBones) {
|
||||
finalMatrices.push_back(kv.second);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
void dd::Skeleton::AccumulateBoneTransforms(bool noRootMotion, Animation::Keyframe ¤tFrame, Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) {
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID);
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties.at(bone->ID);
|
||||
|
||||
glm::vec3 positionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
glm::quat rotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
glm::vec3 scaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
positionInterp.x = 0;
|
||||
positionInterp.z = 0;
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
boneMatrix = parentMatrix * bone->Parent->OffsetMatrix; // * glm::inverse(bone->OffsetMatrix);
|
||||
boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix;
|
||||
}
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
std::string name = child->Name;
|
||||
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
int dd::Skeleton::GetBoneID(std::string name)
|
||||
{
|
||||
if (m_BonesByName.find(name) == m_BonesByName.end()) {
|
||||
return -1;
|
||||
} else {
|
||||
return m_BonesByName.at(name)->ID;
|
||||
}
|
||||
}
|
||||
|
||||
void dd::Skeleton::PrintSkeleton()
|
||||
{
|
||||
PrintSkeleton(RootBone, 0);
|
||||
}
|
||||
|
||||
void dd::Skeleton::PrintSkeleton(Bone* bone, int depthCount)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::string(depthCount, ' ');
|
||||
ss << bone->ID << ": " << bone->Name;
|
||||
std::cout << ss.str() << std::endl;
|
||||
|
||||
depthCount++;
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
PrintSkeleton(child, depthCount);
|
||||
}
|
||||
}
|
||||
|
||||
int dd::Skeleton::GetKeyframe(Animation& animation, double time)
|
||||
{
|
||||
if (time < 0)
|
||||
time = 0;
|
||||
if (time > animation.Duration)
|
||||
return animation.Keyframes.size() - 1;
|
||||
|
||||
for (int keyframe = 0; keyframe < animation.Keyframes.size(); ++keyframe) {
|
||||
if (animation.Keyframes[keyframe].Time > time)
|
||||
return keyframe - 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -20,10 +20,6 @@
|
||||
#include "Transform/TransformSystem.h"
|
||||
#include "Core/World.h"
|
||||
|
||||
void dd::Systems::TransformSystem::Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
glm::vec3 dd::Systems::TransformSystem::AbsolutePosition(EntityID entity)
|
||||
{
|
||||
glm::vec3 absPosition;
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Core/Engine.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
dd::Engine engine(argc, argv);
|
||||
LOG_INFO("------------ Engine initialized ------------");
|
||||
while (engine.Running())
|
||||
engine.Tick();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3,7 +3,7 @@ project(tests)
|
||||
find_package(Boost REQUIRED COMPONENTS chrono thread unit_test_framework)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/include/dd
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
@@ -19,6 +19,6 @@ endif()
|
||||
|
||||
add_executable(tests ${SOURCE_FILES})
|
||||
target_link_libraries(tests
|
||||
daydream
|
||||
game
|
||||
${Boost_LIBRARIES}
|
||||
)
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ MKLINK "%DeployLocation%\Models\" "assets\Models" /J
|
||||
MKLINK "%DeployLocation%\Textures\" "assets\Textures\" /J
|
||||
MKLINK "%DeployLocation%\Sounds\" "assets\Sounds\" /J
|
||||
:: Shaders
|
||||
MKLINK "%DeployLocation%\Shaders\" "src\dd\Core\Shaders\" /J
|
||||
MKLINK "%DeployLocation%\Shaders\" "src\game\Core\Shaders\" /J
|
||||
:: Platform specific binaries
|
||||
IF "%~1"=="" GOTO :EOF
|
||||
ECHO Deploying %1 binaries to %DeployLocation%
|
||||
@@ -17,4 +17,4 @@ COPY "deps\bin\%1\x64\*.dll" "%DeployLocation%"
|
||||
::COPY "libs\assimp-3.1.1\LICENSE" "%ConfigPath%\Assimp License.txt"
|
||||
::COPY "libs\glew-1.11.0\LICENSE.txt" "%ConfigPath%\GLEW License.txt"
|
||||
::COPY "libs\glm-0.9.5.4\copying.txt" "%ConfigPath%\GLM License.txt"
|
||||
::COPY "libs\assimp-3.1.1\LICENSE" "%ConfigPath%\Assimp License.txt"
|
||||
::COPY "libs\assimp-3.1.1\LICENSE" "%ConfigPath%\Assimp License.txt"
|
||||
|
||||
Regular → Executable
+2
-2
@@ -9,9 +9,9 @@ ln -srf assets/Models ${DeployLocation}
|
||||
ln -srf assets/Textures ${DeployLocation}
|
||||
ln -srf assets/Sounds ${DeployLocation}
|
||||
# Shaders
|
||||
ln -srf src/dd/Core/Shaders ${DeployLocation}
|
||||
ln -srf src/game/Core/Shaders ${DeployLocation}
|
||||
# Platform specific binaries
|
||||
if [[ $# -eq 1 ]]; then
|
||||
echo "Deploying {$1} binaries to ${DeployLocation}"
|
||||
ln -srf deps/bin/$1/x64/*.dll ${DeployLocation}
|
||||
fi
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user