From 4d5b8353529f12656f0acae8a3ffb99057188fc4 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Wed, 20 Jan 2016 16:43:09 +0100 Subject: [PATCH 001/131] WIP triangles vs. AABB. --- .../Schema/Entities/ModelCollisionTest.xml | 49 +++++++++ src/Engine/Collision/Collision.cpp | 99 ++++++++++++++++--- src/Engine/Collision/CollisionSystem.cpp | 63 ++++++------ 3 files changed, 166 insertions(+), 45 deletions(-) create mode 100644 resources/Schema/Entities/ModelCollisionTest.xml diff --git a/resources/Schema/Entities/ModelCollisionTest.xml b/resources/Schema/Entities/ModelCollisionTest.xml new file mode 100644 index 00000000..46746264 --- /dev/null +++ b/resources/Schema/Entities/ModelCollisionTest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + ../assets/Models/Core/UnitCube.obj + + + + + + + + + + + + + + + ../assets/Models/Core/UnitCube.obj + + + + + + + + + + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index b30ae927..c351d9fa 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -199,30 +199,93 @@ bool RayVsModel(const Ray& ray, return hit; } -bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) +bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, glm::vec3& outResolutionVector) { - bool hit = false; - const glm::vec3& origin = box.Origin(); const glm::vec3& min = box.MinCorner(); const glm::vec3& max = box.MaxCorner(); + const glm::vec3& half = box.HalfSize(); - outResolutionVector.x = INFINITY; + const glm::vec3 triPos[] = { + v0, v1, v2 + }; - for (int i = 0; i < modelIndices.size(); ++i) { - glm::vec3 p = modelVertices[i].Position; + for (int ax = 0; ax < 3; ++ax) { + auto outsideMinPlane = glm::tvec3(false); + auto outsideMaxPlane = glm::tvec3(false); + for (int pos = 0; pos < 3; ++pos) { + outsideMinPlane[pos] = (min[ax] > triPos[pos][ax]); + outsideMaxPlane[pos] = (triPos[pos][ax] > max[ax]); + } + if (glm::all(outsideMinPlane) || glm::all(outsideMaxPlane)) { + return false; + } + } + return true; +} + +bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) +{ + bool hit = false; + for (int i = 0; i < modelIndices.size(); i += 3) { + glm::vec3 resVec; + hit = AABBvsTriangle( + box, + modelVertices[modelIndices[i]].Position, + modelVertices[modelIndices[i + 1]].Position, + modelVertices[modelIndices[i + 2]].Position, + resVec + ); + if (hit) { + break; + } + } + return hit; + //TODO: Remove old code. + + /* + auto hit = glm::tvec3(false); + const glm::vec3& origin = box.Origin(); + const glm::vec3& min = box.MinCorner(); + const glm::vec3& max = box.MaxCorner(); + const glm::vec3& half = box.HalfSize(); + + float minResolution = INFINITY; + outResolutionVector = glm::vec3(0.f); + //TODO: Don't need indices? Remove? + for (const auto& v : modelVertices) { + glm::vec3 p = v.Position; p = glm::vec3(modelMatrix * glm::vec4(p.x, p.y, p.z, 1)); - float distFromOrigin = glm::abs(origin.x - p.x); - float penetration = box.HalfSize().x - distFromOrigin; - if (penetration > 0 && penetration < glm::abs(outResolutionVector.x)) { - if (p.x > origin.x) { - outResolutionVector.x = -penetration; - } else { - outResolutionVector.x = penetration; + const glm::vec3 diffO = origin - p; + const glm::vec3 distO = glm::abs(diffO); + for (int axis = 0; axis < 3; ++axis) { + float penetration = half[axis] - distO[axis]; + if (penetration > 0){ + if (penetration < minResolution) { + minResolution = penetration; + outResolutionVector = glm::vec3(0.f); + if (p[axis] > origin[axis]) { + outResolutionVector[axis] = -penetration; + } else { + outResolutionVector[axis] = penetration; + } + } + hit[axis] = true; } - hit = true; } + + //float distFromOrigin = glm::abs(origin.x - p.x); + //float penetration = box.HalfSize().x - distFromOrigin; + //if (penetration > 0 && penetration < glm::abs(outResolutionVector.x)) { + // if (p.x > origin.x) { + // outResolutionVector.x = -penetration; + // } else { + // outResolutionVector.x = penetration; + // } + // hit = true; + //} + //glm::vec3 pLocal = origin - p; //for (int axis = 0; axis < 3; ++axis) { // if (p[axis] < min[axis] || p[axis] > max[axis]) { @@ -236,7 +299,13 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model //} } - return hit; + //for (int axis = 0; axis < 3; ++axis) { + // if (glm::isinf(outResolutionVector[axis])) { + // outResolutionVector[axis] = 0.f; + // } + //} + + return glm::all(hit);*/ } bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon) diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index d841c75e..58e48357 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -1,6 +1,7 @@ #include "Collision/Collision.h" #include "Collision/CollisionSystem.h" #include "Core/AABB.h" +#include "Rendering/Model.h" void CollisionSystem::UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) { @@ -22,40 +23,42 @@ void CollisionSystem::UpdateComponent(World* world, EntityWrapper& entity, Compo } // Collide against octree - std::vector octreeResult; - m_Octree->BoxesInSameRegion(*boundingBox, octreeResult); - for (auto& boxB : octreeResult) { - glm::vec3 resolutionVector; - if (Collision::IsSameBoxProbably(boxA, boxB)) { - continue; - } - if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { - (glm::vec3&)cTransform["Position"] += resolutionVector; - cPhysics["Velocity"] = glm::vec3(0, 0, 0); - } - } - - // HACK: Temporarily collide against all collidable models since they're not in the octree yet - //auto otherCollidables = world->GetComponents("Model"); - //for (auto& cModel : *otherCollidables) { - // if (cModel.EntityID == entity) { - // continue; - // } - // if (!world->HasComponent(cModel.EntityID, "Collidable")) { - // continue; - // } - - // auto absPosition = RenderQueueFactory::AbsolutePosition(world, cModel.EntityID); - // auto absOrientation = RenderQueueFactory::AbsoluteOrientation(world, cModel.EntityID); - // auto absScale = RenderQueueFactory::AbsoluteScale(world, cModel.EntityID); - // glm::mat4 modelMatrix = glm::translate(absPosition); // *glm::toMat4(absOrientation) * glm::scale(absScale); - - // auto model = ResourceManager::Load(cModel["Resource"]); + //std::vector octreeResult; + //m_Octree->BoxesInSameRegion(*boundingBox, octreeResult); + //for (auto& boxB : octreeResult) { // glm::vec3 resolutionVector; - // if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) { + // if (Collision::IsSameBoxProbably(boxA, boxB)) { + // continue; + // } + // if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { // (glm::vec3&)cTransform["Position"] += resolutionVector; + // cPhysics["Velocity"] = glm::vec3(0, 0, 0); // } //} + + // HACK: Temporarily collide against all collidable models since they're not in the octree yet + auto otherCollidables = world->GetComponents("Model"); + for (auto& cModel : *otherCollidables) { + if (cModel.EntityID == EntityID(entity)) { + continue; + } + if (!world->HasComponent(cModel.EntityID, "Collidable")) { + continue; + } + + auto absPosition = Transform::AbsolutePosition(world, cModel.EntityID); + auto absOrientation = Transform::AbsoluteOrientation(world, cModel.EntityID); + auto absScale = Transform::AbsoluteScale(world, cModel.EntityID); + glm::mat4 modelMatrix = glm::translate(absPosition); // *glm::toMat4(absOrientation) * glm::scale(absScale); + + RawModel* model = ResourceManager::Load(cModel["Resource"]); + glm::vec3 resolutionVector; + if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) { + //TODO: remove Temp. + (glm::vec3&)cTransform["Position"] = glm::vec3(2, 2, 2); + //(glm::vec3&)cTransform["Position"] += resolutionVector; + } + } } bool CollisionSystem::OnKeyUp(const Events::KeyUp & event) From de7c8e9234f89893265a6ce97a95b06268e6eb53 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Thu, 21 Jan 2016 17:10:36 +0100 Subject: [PATCH 002/131] WIP, collision detects too much, no resolving for most cases. --- include/Engine/Collision/Collision.h | 9 + include/Engine/Core/Transform.h | 1 + .../Schema/Entities/ModelCollisionTest.xml | 10 +- src/Engine/Collision/Collision.cpp | 256 ++++++++++++++++-- src/Engine/Collision/CollisionSystem.cpp | 6 +- src/Engine/Core/Transform.cpp | 4 + 6 files changed, 248 insertions(+), 38 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 148f688d..b32d190a 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -26,6 +26,15 @@ bool RayVsAABB(const Ray& ray, const AABB& box); //Return true if the ray hits the box, also outputs distance from ray origin to intersection point in [outDistance]. bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance); +//Return true if the ray hits the triangle, and the distance is less than outDistance. +bool RayVsTriangle(const Ray& ray, + const glm::vec3& v0, + const glm::vec3& v1, + const glm::vec3& v2, + float& outDistance, + float& outUCoord, + float& outVCoord, + bool trueOnNegativeDistance = false); //Return true if the ray hits any of the triangles in the model. Stops checking when a hit is detected. bool RayVsModel(const Ray& ray, const std::vector& modelVertices, diff --git a/include/Engine/Core/Transform.h b/include/Engine/Core/Transform.h index 474a7bdb..b004f047 100644 --- a/include/Engine/Core/Transform.h +++ b/include/Engine/Core/Transform.h @@ -11,6 +11,7 @@ glm::vec3 AbsolutePosition(World* world, EntityID entity); glm::quat AbsoluteOrientation(World* world, EntityID entity); glm::vec3 AbsoluteScale(World* world, EntityID entity); glm::mat4 ModelMatrix(EntityID entity, World* world); +glm::vec3 TransformPoint(const glm::vec3& point, const glm::mat4& matrix); } diff --git a/resources/Schema/Entities/ModelCollisionTest.xml b/resources/Schema/Entities/ModelCollisionTest.xml index 46746264..fd26f0c5 100644 --- a/resources/Schema/Entities/ModelCollisionTest.xml +++ b/resources/Schema/Entities/ModelCollisionTest.xml @@ -11,8 +11,8 @@ - - + + @@ -22,10 +22,10 @@ ../assets/Models/Core/UnitCube.obj + - - + @@ -39,7 +39,7 @@ ../assets/Models/Core/UnitCube.obj - + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index c351d9fa..6794f5b9 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -146,6 +146,38 @@ bool RayVsModel(const Ray& ray, return false; } +bool RayVsTriangle(const Ray& ray, + const glm::vec3& v0, + const glm::vec3& v1, + const glm::vec3& v2, + float& outDistance, + float& outUCoord, + float& outVCoord, + bool trueOnNegativeDistance) +{ + glm::vec3 e1 = v1 - v0; //v1 - v0 + glm::vec3 e2 = v2 - v0; //v2 - v0 + glm::vec3 m = ray.Origin() - v0; + glm::vec3 MxE1 = glm::cross(m, e1); + glm::vec3 DxE2 = glm::cross(ray.Direction(), e2);//pVec + float DetInv = glm::dot(e1, DxE2); + if (std::abs(DetInv) < FLT_EPSILON) { + return false; + } + DetInv = 1.0f / DetInv; + float dist = glm::dot(e2, MxE1) * DetInv; + if (dist >= outDistance) { + return false; + } + outDistance = dist; + outUCoord = glm::dot(m, DxE2) * DetInv; + outVCoord = glm::dot(ray.Direction(), MxE1) * DetInv; + + //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem + //If u and v are positive, u+v <= 1, dist is positive, and less than closest. + return (0 <= (outUCoord + 0.001f) && 0 <= (outVCoord + 0.001f) && outUCoord + outVCoord <= 1 && (trueOnNegativeDistance || 0 <= dist)); +} + bool RayVsModel(const Ray& ray, const std::vector& modelVertices, const std::vector& modelIndices, @@ -157,26 +189,12 @@ bool RayVsModel(const Ray& ray, bool hit = false; for (int i = 0; i < modelIndices.size(); ++i) { glm::vec3 v0 = modelVertices[modelIndices[i]].Position; - glm::vec3 e1 = modelVertices[modelIndices[++i]].Position - v0; //v1 - v0 - glm::vec3 e2 = modelVertices[modelIndices[++i]].Position - v0; //v2 - v0 - glm::vec3 m = ray.Origin() - v0; - glm::vec3 MxE1 = glm::cross(m, e1); - glm::vec3 DxE2 = glm::cross(ray.Direction(), e2);//pVec - float DetInv = glm::dot(e1, DxE2); - if (std::abs(DetInv) < FLT_EPSILON) { - continue; - } - DetInv = 1.0f / DetInv; - float dist = glm::dot(e2, MxE1) * DetInv; - if (dist >= outDistance) { - continue; - } - float u = glm::dot(m, DxE2) * DetInv; - float v = glm::dot(ray.Direction(), MxE1) * DetInv; - - //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem - //If u and v are positive, u+v <= 1, dist is positive, and less than closest. - if (0 <= (u + 0.001f) && 0 <= (v + 0.001f) && u + v <= 1 && 0 <= dist) { + glm::vec3 v1 = modelVertices[modelIndices[++i]].Position; + glm::vec3 v2 = modelVertices[modelIndices[++i]].Position; + float dist; + float u; + float v; + if (RayVsTriangle(ray, v0, v1, v2, dist, u, v)) { outDistance = dist; outUCoord = u; outVCoord = v; @@ -199,29 +217,205 @@ bool RayVsModel(const Ray& ray, return hit; } +constexpr inline int squareOf(float x) +{ + return x * x; +} + +constexpr inline int signNonZero(float x) +{ + return x < 0 ? -1 : 1; +} + +inline glm::vec3 signNonZero(const glm::vec3& x) +{ + glm::vec3 r; + for (int i = 0; i < 3; ++i) { + r[i] = signNonZero(x[i]); + } + return r; +} + +bool lineIntersectsBox(const AABB& box, const glm::vec3& v0, const glm::vec3& v1) +{ + const glm::vec3 edgevec = v1 - v0; + glm::vec3 edgevec_signs = signNonZero(edgevec); + + for (int i = 0; i < 3; ++i) + edgevec_signs[i] = signNonZero(edgevec[i]); + + /* + * Test the three cube faces on the v1-ward side of the cube-- + * if v0 is outside any of their planes then there is no intersection. + * Also test the three cube faces on the v0-ward side of the cube-- + * if v1 is outside any of their planes then there is no intersection. + */ + + for (int i = 0; i < 3; ++i) + { + if (v0[i] * edgevec_signs[i] > .5) return false; + if (v1[i] * edgevec_signs[i] < -.5) return false; + } + + /* + * Okay, that's the six easy faces of the rhombic dodecahedron + * out of the way. Six more to go. + * The remaining six planes bound an infinite hexagonal prism + * joining the petrie polygons (skew hexagons) of the two cubes + * centered at the endpoints. + */ + + for (int i = 0; i < 3; ++i) + { + float rhomb_normal_dot_v0, rhomb_normal_dot_cubedge; + + int iplus1 = (i + 1) % 3; + int iplus2 = (i + 2) % 3; + +#ifdef THE_EASY_TO_UNDERSTAND_WAY + + { + real rhomb_normal[3], cubedge_midpoint[3]; + + /* + * rhomb_normal = VXV3(edgevec, unit vector in direction i), + * being cavalier about which direction it's facing + */ + rhomb_normal[i] = 0; + rhomb_normal[iplus1] = edgevec[iplus2]; + rhomb_normal[iplus2] = -edgevec[iplus1]; + + /* + * We now are describing a plane parallel to + * both segment and the cube edge in question. + * if |DOT3(rhomb_normal, an arbitrary point on the segment)| > + * |DOT3(rhomb_normal, an arbitrary point on the cube edge in question| + * then the origin is outside this pair of opposite faces. + * (This is equivalent to saying that the line + * containing the segment is "outside" (i.e. further away from the + * origin than) the line containing the cube edge. + */ + + cubedge_midpoint[i] = 0; + cubedge_midpoint[iplus1] = edgevec_signs[iplus1] * .5; + cubedge_midpoint[iplus2] = -edgevec_signs[iplus2] * .5; + + rhomb_normal_dot_v0 = DOT3(rhomb_normal, v0); + rhomb_normal_dot_cubedge = DOT3(rhomb_normal, cubedge_midpoint); + } + +#else /* the efficient way */ + + rhomb_normal_dot_v0 = edgevec[iplus2] * v0[iplus1] + - edgevec[iplus1] * v0[iplus2]; + + rhomb_normal_dot_cubedge = .5 * + (edgevec[iplus2] * edgevec_signs[iplus1] + + edgevec[iplus1] * edgevec_signs[iplus2]); + +#endif /* the efficient way */ + + if (squareOf(rhomb_normal_dot_v0) > squareOf(rhomb_normal_dot_cubedge)) + return false; /* origin is outside this pair of opposite planes */ + } + return true; +} + +bool vectorHasLength(const glm::vec3& vec) +{ + return glm::all(glm::lessThan(glm::abs(vec), glm::vec3(0.0001f, 0.0001f, 0.0001f))); +} + bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, glm::vec3& outResolutionVector) { + //Check so we don't have a zero area triangle when calculating the normal. + glm::vec3 triNormal = glm::cross(v1 - v0, v2 - v0); + if (vectorHasLength(triNormal)) { + return false; + } + const glm::vec3& origin = box.Origin(); + const glm::vec3& half = box.HalfSize(); const glm::vec3& min = box.MinCorner(); const glm::vec3& max = box.MaxCorner(); - const glm::vec3& half = box.HalfSize(); const glm::vec3 triPos[] = { v0, v1, v2 }; + auto insideAllPlanes = glm::tvec3(false); + //All triangle vertex points. + //Check if the triangle is completely outside or inside the box. for (int ax = 0; ax < 3; ++ax) { auto outsideMinPlane = glm::tvec3(false); auto outsideMaxPlane = glm::tvec3(false); + auto insidePlanes = glm::tvec3(false); for (int pos = 0; pos < 3; ++pos) { outsideMinPlane[pos] = (min[ax] > triPos[pos][ax]); outsideMaxPlane[pos] = (triPos[pos][ax] > max[ax]); + insidePlanes[pos] = !(outsideMinPlane[pos] || outsideMaxPlane[pos]); } if (glm::all(outsideMinPlane) || glm::all(outsideMaxPlane)) { return false; } + insideAllPlanes[ax] = glm::all(insidePlanes); } - return true; + if (glm::all(insideAllPlanes)) { + outResolutionVector = glm::vec3(0.f); + LOG_DEBUG("Triangle collision inside"); + return true; //TODO: Resolve. + } + + glm::vec3 triPosInBoxSpace[3]; + for (int i = 0; i < 3; ++i) { + triPosInBoxSpace[i] = (triPos[i] - origin) / (2.0f * half); + } + //All triangle lines. + //Check if each line on the triangle intersects any plane on the box. + for (int l = 0; l < 3; ++l) { + if (lineIntersectsBox(box, triPosInBoxSpace[l], triPosInBoxSpace[(l + 1) % 3])) { + outResolutionVector = glm::vec3(0.f); + LOG_DEBUG("Triangle collision lines"); + return true; //TODO: Resolve. + } + } + + //None of the polygon's edges intersects the cube, finally, check if any of the four + //cube diagonals intersect the interior of the polygon. + //If the polygon does intersect any of the cube diagonals, it will + //intersect the cube diagonal that comes + //closest to being perpendicular to the plane of the polygon. + + triNormal = glm::normalize(triNormal); + glm::vec3 diagonal = signNonZero(triNormal) * half; +#define EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK +#ifdef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK + //The triangle plane contains all points P in dot(triNormal, P) == dot(triNormal, v0) + //The diagonal line contains all points P in P = origin + diagonal * t. + float t = glm::dot(triNormal, v0 - origin) / glm::dot(triNormal, diagonal); + + //If intersection point between plane and diagonal is not within the box. + if (glm::abs(t) > 1) { + return false; + } + //glm::vec3 intersection = origin + t * diagonal; +#endif + + //Check if intersection point is on the triangle. + Ray ray(origin, diagonal); + float dist = INFINITY, u, v; + if (RayVsTriangle(ray, v0, v1, v2, dist, u, v, true)) { +#ifndef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK + if (glm::abs(dist) > glm::length(diagonal)) { + return false; + } +#endif + float dist = glm::dot(triNormal, origin + diagonal - v0); + outResolutionVector = dist * triNormal; + LOG_DEBUG("Triangle collision corner"); + return true; + } + return false; } bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) @@ -229,15 +423,19 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model bool hit = false; for (int i = 0; i < modelIndices.size(); i += 3) { glm::vec3 resVec; - hit = AABBvsTriangle( + if (AABBvsTriangle( box, - modelVertices[modelIndices[i]].Position, - modelVertices[modelIndices[i + 1]].Position, - modelVertices[modelIndices[i + 2]].Position, + Transform::TransformPoint(modelVertices[modelIndices[i]].Position, modelMatrix), + Transform::TransformPoint(modelVertices[modelIndices[i + 1]].Position, modelMatrix), + Transform::TransformPoint(modelVertices[modelIndices[i + 2]].Position, modelMatrix), resVec - ); - if (hit) { - break; + )) + { + hit = true; + //If resolution distance is smaller than previous, and is non-zero. + if (glm::length(resVec) < glm::length(outResolutionVector) && vectorHasLength(resVec)) { + outResolutionVector = resVec; + } } } return hit; diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 58e48357..abddce1f 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -49,14 +49,12 @@ void CollisionSystem::UpdateComponent(World* world, EntityWrapper& entity, Compo auto absPosition = Transform::AbsolutePosition(world, cModel.EntityID); auto absOrientation = Transform::AbsoluteOrientation(world, cModel.EntityID); auto absScale = Transform::AbsoluteScale(world, cModel.EntityID); - glm::mat4 modelMatrix = glm::translate(absPosition); // *glm::toMat4(absOrientation) * glm::scale(absScale); + glm::mat4 modelMatrix = glm::translate(absPosition) * glm::toMat4(absOrientation) * glm::scale(absScale); RawModel* model = ResourceManager::Load(cModel["Resource"]); glm::vec3 resolutionVector; if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) { - //TODO: remove Temp. - (glm::vec3&)cTransform["Position"] = glm::vec3(2, 2, 2); - //(glm::vec3&)cTransform["Position"] += resolutionVector; + (glm::vec3&)cTransform["Position"] += resolutionVector; } } } diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp index cbc405a3..054b1984 100644 --- a/src/Engine/Core/Transform.cpp +++ b/src/Engine/Core/Transform.cpp @@ -50,3 +50,7 @@ glm::mat4 Transform::ModelMatrix(EntityID entity, World* world) return modelMatrix; } +glm::vec3 Transform::TransformPoint(const glm::vec3& point, const glm::mat4& matrix) +{ + return glm::vec3(matrix * glm::vec4(point.x, point.y, point.z, 1)); +} \ No newline at end of file From 52765cc85bccfc3f4eaddefefcb404350fdc125f Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 22 Jan 2016 11:22:56 +0100 Subject: [PATCH 003/131] TriangleVsBox detection seems to work in all cases, but cannot resolve all cases yet. Also added default ctor for Ray and removed compilation errors in CollisionSystem. --- include/Engine/Core/Ray.h | 4 + src/Engine/Collision/Collision.cpp | 177 ++--------------------- src/Engine/Collision/CollisionSystem.cpp | 12 +- 3 files changed, 25 insertions(+), 168 deletions(-) diff --git a/include/Engine/Core/Ray.h b/include/Engine/Core/Ray.h index a234a488..03bfa391 100644 --- a/include/Engine/Core/Ray.h +++ b/include/Engine/Core/Ray.h @@ -7,6 +7,10 @@ class Ray { public: + Ray() + : m_Origin(glm::vec3(0.f)) + , m_Direction(glm::vec3(0, 0, 1)) + {} Ray(const glm::vec3& origin, const glm::vec3& dir) : m_Origin(origin) , m_Direction(glm::normalize(dir)) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 6794f5b9..d643e8cc 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -217,11 +217,6 @@ bool RayVsModel(const Ray& ray, return hit; } -constexpr inline int squareOf(float x) -{ - return x * x; -} - constexpr inline int signNonZero(float x) { return x < 0 ? -1 : 1; @@ -236,101 +231,17 @@ inline glm::vec3 signNonZero(const glm::vec3& x) return r; } -bool lineIntersectsBox(const AABB& box, const glm::vec3& v0, const glm::vec3& v1) -{ - const glm::vec3 edgevec = v1 - v0; - glm::vec3 edgevec_signs = signNonZero(edgevec); - - for (int i = 0; i < 3; ++i) - edgevec_signs[i] = signNonZero(edgevec[i]); - - /* - * Test the three cube faces on the v1-ward side of the cube-- - * if v0 is outside any of their planes then there is no intersection. - * Also test the three cube faces on the v0-ward side of the cube-- - * if v1 is outside any of their planes then there is no intersection. - */ - - for (int i = 0; i < 3; ++i) - { - if (v0[i] * edgevec_signs[i] > .5) return false; - if (v1[i] * edgevec_signs[i] < -.5) return false; - } - - /* - * Okay, that's the six easy faces of the rhombic dodecahedron - * out of the way. Six more to go. - * The remaining six planes bound an infinite hexagonal prism - * joining the petrie polygons (skew hexagons) of the two cubes - * centered at the endpoints. - */ - - for (int i = 0; i < 3; ++i) - { - float rhomb_normal_dot_v0, rhomb_normal_dot_cubedge; - - int iplus1 = (i + 1) % 3; - int iplus2 = (i + 2) % 3; - -#ifdef THE_EASY_TO_UNDERSTAND_WAY - - { - real rhomb_normal[3], cubedge_midpoint[3]; - - /* - * rhomb_normal = VXV3(edgevec, unit vector in direction i), - * being cavalier about which direction it's facing - */ - rhomb_normal[i] = 0; - rhomb_normal[iplus1] = edgevec[iplus2]; - rhomb_normal[iplus2] = -edgevec[iplus1]; - - /* - * We now are describing a plane parallel to - * both segment and the cube edge in question. - * if |DOT3(rhomb_normal, an arbitrary point on the segment)| > - * |DOT3(rhomb_normal, an arbitrary point on the cube edge in question| - * then the origin is outside this pair of opposite faces. - * (This is equivalent to saying that the line - * containing the segment is "outside" (i.e. further away from the - * origin than) the line containing the cube edge. - */ - - cubedge_midpoint[i] = 0; - cubedge_midpoint[iplus1] = edgevec_signs[iplus1] * .5; - cubedge_midpoint[iplus2] = -edgevec_signs[iplus2] * .5; - - rhomb_normal_dot_v0 = DOT3(rhomb_normal, v0); - rhomb_normal_dot_cubedge = DOT3(rhomb_normal, cubedge_midpoint); - } - -#else /* the efficient way */ - - rhomb_normal_dot_v0 = edgevec[iplus2] * v0[iplus1] - - edgevec[iplus1] * v0[iplus2]; - - rhomb_normal_dot_cubedge = .5 * - (edgevec[iplus2] * edgevec_signs[iplus1] + - edgevec[iplus1] * edgevec_signs[iplus2]); - -#endif /* the efficient way */ - - if (squareOf(rhomb_normal_dot_v0) > squareOf(rhomb_normal_dot_cubedge)) - return false; /* origin is outside this pair of opposite planes */ - } - return true; -} bool vectorHasLength(const glm::vec3& vec) { - return glm::all(glm::lessThan(glm::abs(vec), glm::vec3(0.0001f, 0.0001f, 0.0001f))); + return glm::any(glm::greaterThan(glm::abs(vec), glm::vec3(0.0001f, 0.0001f, 0.0001f))); } bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, glm::vec3& outResolutionVector) { //Check so we don't have a zero area triangle when calculating the normal. glm::vec3 triNormal = glm::cross(v1 - v0, v2 - v0); - if (vectorHasLength(triNormal)) { + if (!vectorHasLength(triNormal)) { return false; } @@ -366,14 +277,15 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c return true; //TODO: Resolve. } - glm::vec3 triPosInBoxSpace[3]; - for (int i = 0; i < 3; ++i) { - triPosInBoxSpace[i] = (triPos[i] - origin) / (2.0f * half); - } + Ray ray; //All triangle lines. //Check if each line on the triangle intersects any plane on the box. for (int l = 0; l < 3; ++l) { - if (lineIntersectsBox(box, triPosInBoxSpace[l], triPosInBoxSpace[(l + 1) % 3])) { + glm::vec3 edge = triPos[(l + 1) % 3] - triPos[l]; + ray.SetOrigin(triPos[l]); + ray.SetDirection(edge); + float dist; + if (RayVsAABB(ray, box, dist) && dist <= glm::length(edge)) { outResolutionVector = glm::vec3(0.f); LOG_DEBUG("Triangle collision lines"); return true; //TODO: Resolve. @@ -402,7 +314,8 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c #endif //Check if intersection point is on the triangle. - Ray ray(origin, diagonal); + ray.SetOrigin(origin); + ray.SetDirection(diagonal); float dist = INFINITY, u, v; if (RayVsTriangle(ray, v0, v1, v2, dist, u, v, true)) { #ifndef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK @@ -421,6 +334,7 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) { bool hit = false; + outResolutionVector = glm::vec3(INFINITY); for (int i = 0; i < modelIndices.size(); i += 3) { glm::vec3 resVec; if (AABBvsTriangle( @@ -438,72 +352,11 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model } } } - return hit; - //TODO: Remove old code. - - /* - auto hit = glm::tvec3(false); - const glm::vec3& origin = box.Origin(); - const glm::vec3& min = box.MinCorner(); - const glm::vec3& max = box.MaxCorner(); - const glm::vec3& half = box.HalfSize(); - - float minResolution = INFINITY; - outResolutionVector = glm::vec3(0.f); - //TODO: Don't need indices? Remove? - for (const auto& v : modelVertices) { - glm::vec3 p = v.Position; - p = glm::vec3(modelMatrix * glm::vec4(p.x, p.y, p.z, 1)); - - const glm::vec3 diffO = origin - p; - const glm::vec3 distO = glm::abs(diffO); - for (int axis = 0; axis < 3; ++axis) { - float penetration = half[axis] - distO[axis]; - if (penetration > 0){ - if (penetration < minResolution) { - minResolution = penetration; - outResolutionVector = glm::vec3(0.f); - if (p[axis] > origin[axis]) { - outResolutionVector[axis] = -penetration; - } else { - outResolutionVector[axis] = penetration; - } - } - hit[axis] = true; - } - } - - //float distFromOrigin = glm::abs(origin.x - p.x); - //float penetration = box.HalfSize().x - distFromOrigin; - //if (penetration > 0 && penetration < glm::abs(outResolutionVector.x)) { - // if (p.x > origin.x) { - // outResolutionVector.x = -penetration; - // } else { - // outResolutionVector.x = penetration; - // } - // hit = true; - //} - - //glm::vec3 pLocal = origin - p; - //for (int axis = 0; axis < 3; ++axis) { - // if (p[axis] < min[axis] || p[axis] > max[axis]) { - // continue; - // } - - // if (glm::abs(pLocal[axis]) < box.HalfSize()[axis]) { - // outResolutionVector[axis] = (glm::sign(pLocal[axis]) * box.HalfSize()[axis]) - pLocal[axis]; - // hit = true; - // } - //} + //TODO: Unnecessary later, remove it. + if (glm::any(glm::isinf(outResolutionVector))) { + outResolutionVector = glm::vec3(0, 0, 0); } - - //for (int axis = 0; axis < 3; ++axis) { - // if (glm::isinf(outResolutionVector[axis])) { - // outResolutionVector[axis] = 0.f; - // } - //} - - return glm::all(hit);*/ + return hit; } bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon) diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 84608fbd..657cc90b 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -37,18 +37,18 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c //} // HACK: Temporarily collide against all collidable models since they're not in the octree yet - auto otherCollidables = world->GetComponents("Model"); + auto otherCollidables = m_World->GetComponents("Model"); for (auto& cModel : *otherCollidables) { - if (cModel.EntityID == EntityID(entity)) { + if (cModel.EntityID == entity.ID) { continue; } - if (!world->HasComponent(cModel.EntityID, "Collidable")) { + if (!m_World->HasComponent(cModel.EntityID, "Collidable")) { continue; } - auto absPosition = Transform::AbsolutePosition(world, cModel.EntityID); - auto absOrientation = Transform::AbsoluteOrientation(world, cModel.EntityID); - auto absScale = Transform::AbsoluteScale(world, cModel.EntityID); + auto absPosition = Transform::AbsolutePosition(m_World, cModel.EntityID); + auto absOrientation = Transform::AbsoluteOrientation(m_World, cModel.EntityID); + auto absScale = Transform::AbsoluteScale(m_World, cModel.EntityID); glm::mat4 modelMatrix = glm::translate(absPosition) * glm::toMat4(absOrientation) * glm::scale(absScale); RawModel* model = ResourceManager::Load(cModel["Resource"]); From 3955e1d60c1d388b39599c5eaa3c343d064bac85 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 22 Jan 2016 13:46:09 +0100 Subject: [PATCH 004/131] Can resolve collision when AABB corners cut through triangle. At least two more cases left to resolve. --- .../Schema/Entities/ModelCollisionTest.xml | 35 ++++++++++++++----- src/Engine/Collision/Collision.cpp | 8 ++--- src/Engine/Collision/CollisionSystem.cpp | 8 ++++- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/resources/Schema/Entities/ModelCollisionTest.xml b/resources/Schema/Entities/ModelCollisionTest.xml index fd26f0c5..f7a547f5 100644 --- a/resources/Schema/Entities/ModelCollisionTest.xml +++ b/resources/Schema/Entities/ModelCollisionTest.xml @@ -2,7 +2,9 @@ - + + + @@ -11,8 +13,8 @@ - - + + @@ -21,25 +23,40 @@ - ../assets/Models/Core/UnitCube.obj - + ../assets/Models/Core/UnitQuad.obj + - + + + - + + + + + ../assets/Models/Core/UnitQuad.obj + + + + + + + + + - ../assets/Models/Core/UnitCube.obj + - + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index d643e8cc..d174eb86 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -299,7 +299,7 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c //closest to being perpendicular to the plane of the polygon. triNormal = glm::normalize(triNormal); - glm::vec3 diagonal = signNonZero(triNormal) * half; + glm::vec3 diagonal = -signNonZero(triNormal) * half; #define EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK #ifdef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK //The triangle plane contains all points P in dot(triNormal, P) == dot(triNormal, v0) @@ -323,9 +323,9 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c return false; } #endif - float dist = glm::dot(triNormal, origin + diagonal - v0); - outResolutionVector = dist * triNormal; - LOG_DEBUG("Triangle collision corner"); + //Distance between triangle plane, and the diagonal corner, multiplied by the normal. + //Signed distance, positive if on the same side as the normal. + outResolutionVector = -glm::dot(triNormal, origin + diagonal - v0) * triNormal; return true; } return false; diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 657cc90b..11d2a836 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -51,7 +51,13 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c auto absScale = Transform::AbsoluteScale(m_World, cModel.EntityID); glm::mat4 modelMatrix = glm::translate(absPosition) * glm::toMat4(absOrientation) * glm::scale(absScale); - RawModel* model = ResourceManager::Load(cModel["Resource"]); + RawModel* model; + try { + model = ResourceManager::Load(cModel["Resource"]); + } catch (const std::exception&) { + continue; + } + glm::vec3 resolutionVector; if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; From 1670fb4e48f4e9aa215512a7238ec49898074ba3 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 22 Jan 2016 14:45:50 +0100 Subject: [PATCH 005/131] Moved triangle vs ray code to method. --- include/Engine/Collision/Collision.h | 6 ++++ src/Engine/Collision/Collision.cpp | 54 +++++++++++++++++----------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index b32d190a..4e764905 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -26,6 +26,12 @@ bool RayVsAABB(const Ray& ray, const AABB& box); //Return true if the ray hits the box, also outputs distance from ray origin to intersection point in [outDistance]. bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance); +//Return true if the ray hits the triangle. +bool RayVsTriangle(const Ray& ray, + const glm::vec3& v0, + const glm::vec3& v1, + const glm::vec3& v2, + bool trueOnNegativeDistance = false); //Return true if the ray hits the triangle, and the distance is less than outDistance. bool RayVsTriangle(const Ray& ray, const glm::vec3& v0, diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index d174eb86..d44c97be 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -116,30 +116,41 @@ bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation) return glm::all(axisesIntersecting); } +bool RayVsTriangle(const Ray& ray, + const glm::vec3& v0, + const glm::vec3& v1, + const glm::vec3& v2, + bool trueOnNegativeDistance) +{ + glm::vec3 e1 = v1 - v0; //v1 - v0 + glm::vec3 e2 = v2 - v0; //v2 - v0 + glm::vec3 m = ray.Origin() - v0; + glm::vec3 MxE1 = glm::cross(m, e1); + glm::vec3 DxE2 = glm::cross(ray.Direction(), e2); + float DetInv = glm::dot(e1, DxE2); + if (std::abs(DetInv) < FLT_EPSILON) { + return false; + } + DetInv = 1.0f / DetInv; + float u = glm::dot(m, DxE2) * DetInv; + float v = glm::dot(ray.Direction(), MxE1) * DetInv; + //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem + if ((u + 0.001f) < 0 || (v + 0.001f) < 0 || 1 < u + v) { + return false; + } + //Here, u and v are positive, u+v <= 1, and if distance is positive - triangle is hit. + return trueOnNegativeDistance || 0 <= glm::dot(e2, MxE1) * DetInv; +} + bool RayVsModel(const Ray& ray, const std::vector& modelVertices, const std::vector& modelIndices) { for (int i = 0; i < modelIndices.size(); ++i) { glm::vec3 v0 = modelVertices[modelIndices[i]].Position; - glm::vec3 e1 = modelVertices[modelIndices[++i]].Position - v0; //v1 - v0 - glm::vec3 e2 = modelVertices[modelIndices[++i]].Position - v0; //v2 - v0 - glm::vec3 m = ray.Origin() - v0; - glm::vec3 MxE1 = glm::cross(m, e1); - glm::vec3 DxE2 = glm::cross(ray.Direction(), e2); - float DetInv = glm::dot(e1, DxE2); - if (std::abs(DetInv) < FLT_EPSILON) { - continue; - } - DetInv = 1.0f / DetInv; - float u = glm::dot(m, DxE2) * DetInv; - float v = glm::dot(ray.Direction(), MxE1) * DetInv; - //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem - if ((u + 0.001f) < 0 || (v + 0.001f) < 0 || 1 < u + v) { - continue; - } - //Here, u and v are positive, u+v <= 1, and if distance is positive - triangle is hit. - if (0 <= glm::dot(e2, MxE1) * DetInv) { + glm::vec3 v1 = modelVertices[modelIndices[++i]].Position; + glm::vec3 v2 = modelVertices[modelIndices[++i]].Position; + if (RayVsTriangle(ray, v0, v1, v2)) { return true; } } @@ -300,7 +311,7 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c triNormal = glm::normalize(triNormal); glm::vec3 diagonal = -signNonZero(triNormal) * half; -#define EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK +#define EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK //TODO: We should probably performance test with this on/off. #ifdef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK //The triangle plane contains all points P in dot(triNormal, P) == dot(triNormal, v0) //The diagonal line contains all points P in P = origin + diagonal * t. @@ -310,15 +321,16 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c if (glm::abs(t) > 1) { return false; } - //glm::vec3 intersection = origin + t * diagonal; #endif //Check if intersection point is on the triangle. ray.SetOrigin(origin); ray.SetDirection(diagonal); +#ifdef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK + if (RayVsTriangle(ray, v0, v1, v2, true)) { +#else float dist = INFINITY, u, v; if (RayVsTriangle(ray, v0, v1, v2, dist, u, v, true)) { -#ifndef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK if (glm::abs(dist) > glm::length(diagonal)) { return false; } From 3974c649ab8297a8dbf4750643f474f761fa9182 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Sat, 23 Jan 2016 10:45:50 +0100 Subject: [PATCH 006/131] WIP on ModelBoxCollision. Octree works in Release mode. --- include/Engine/Collision/CollisionSystem.h | 7 -- include/Engine/Core/Octree.h | 2 +- .../Schema/Entities/ModelCollisionTest.xml | 6 +- src/Engine/Collision/Collision.cpp | 86 +++++++++++++------ src/Engine/Collision/CollisionSystem.cpp | 13 --- src/Engine/Core/Octree.cpp | 5 -- 6 files changed, 64 insertions(+), 55 deletions(-) diff --git a/include/Engine/Collision/CollisionSystem.h b/include/Engine/Collision/CollisionSystem.h index 5f15a3d5..93ec3d76 100644 --- a/include/Engine/Collision/CollisionSystem.h +++ b/include/Engine/Collision/CollisionSystem.h @@ -17,20 +17,13 @@ public: : System(world, eventBroker) , PureSystem("Collidable") , m_Octree(octree) - , zPress(false) { - //TODO: Debug stuff, remove later. - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &CollisionSystem::OnKeyUp); } virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override; private: Octree* m_Octree; - bool zPress; - - EventRelay m_EKeyUp; - bool OnKeyUp(const Events::KeyUp &event); }; #endif \ No newline at end of file diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index bbd27b3c..907d5736 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -111,7 +111,7 @@ struct Child std::vector& m_StaticObjectsRef; std::vector& m_DynamicObjectsRef; - inline bool hasChildren() const; + inline bool hasChildren() const { return m_Children[0] != nullptr; } int childIndexContainingPoint(const glm::vec3& point) const; std::vector childIndicesContainingBox(const AABB& box) const; }; diff --git a/resources/Schema/Entities/ModelCollisionTest.xml b/resources/Schema/Entities/ModelCollisionTest.xml index f7a547f5..f2a78549 100644 --- a/resources/Schema/Entities/ModelCollisionTest.xml +++ b/resources/Schema/Entities/ModelCollisionTest.xml @@ -23,7 +23,7 @@ - ../assets/Models/Core/UnitQuad.obj + ../assets/Models/Core/Tri.obj @@ -36,11 +36,11 @@ - ../assets/Models/Core/UnitQuad.obj + ../assets/Models/Core/Tri.obj - + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index d44c97be..f040ccd5 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -248,7 +248,12 @@ bool vectorHasLength(const glm::vec3& vec) return glm::any(glm::greaterThan(glm::abs(vec), glm::vec3(0.0001f, 0.0001f, 0.0001f))); } -bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, glm::vec3& outResolutionVector) +bool AABBvsTriangle(const AABB& box, + const glm::vec3& v0, + const glm::vec3& v1, + const glm::vec3& v2, + glm::vec3& outVector, + int& lineHit) { //Check so we don't have a zero area triangle when calculating the normal. glm::vec3 triNormal = glm::cross(v1 - v0, v2 - v0); @@ -283,23 +288,22 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c insideAllPlanes[ax] = glm::all(insidePlanes); } if (glm::all(insideAllPlanes)) { - outResolutionVector = glm::vec3(0.f); - LOG_DEBUG("Triangle collision inside"); - return true; //TODO: Resolve. + return false; //If a triangle is completely inside the box, we call it a non-intersection. } + triNormal = glm::normalize(triNormal); Ray ray; - //All triangle lines. - //Check if each line on the triangle intersects any plane on the box. + //All triangle edges. + //Check if any edge on the triangle intersects the box. for (int l = 0; l < 3; ++l) { glm::vec3 edge = triPos[(l + 1) % 3] - triPos[l]; ray.SetOrigin(triPos[l]); ray.SetDirection(edge); float dist; if (RayVsAABB(ray, box, dist) && dist <= glm::length(edge)) { - outResolutionVector = glm::vec3(0.f); - LOG_DEBUG("Triangle collision lines"); - return true; //TODO: Resolve. + outVector = triNormal; + lineHit = l; + return true; } } @@ -309,7 +313,6 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c //intersect the cube diagonal that comes //closest to being perpendicular to the plane of the polygon. - triNormal = glm::normalize(triNormal); glm::vec3 diagonal = -signNonZero(triNormal) * half; #define EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK //TODO: We should probably performance test with this on/off. #ifdef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK @@ -337,7 +340,7 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c #endif //Distance between triangle plane, and the diagonal corner, multiplied by the normal. //Signed distance, positive if on the same side as the normal. - outResolutionVector = -glm::dot(triNormal, origin + diagonal - v0) * triNormal; + outVector = -glm::dot(triNormal, origin + diagonal - v0) * triNormal; return true; } return false; @@ -345,28 +348,59 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) { + struct Triangle + { + glm::vec3 v0, v1, v2; + }; bool hit = false; - outResolutionVector = glm::vec3(INFINITY); + bool cornerHitTODO = false; + outResolutionVector = glm::vec3(0.f); + std::vector hitTriangles; + std::vector hitNormals; for (int i = 0; i < modelIndices.size(); i += 3) { - glm::vec3 resVec; - if (AABBvsTriangle( - box, - Transform::TransformPoint(modelVertices[modelIndices[i]].Position, modelMatrix), - Transform::TransformPoint(modelVertices[modelIndices[i + 1]].Position, modelMatrix), - Transform::TransformPoint(modelVertices[modelIndices[i + 2]].Position, modelMatrix), - resVec - )) + glm::vec3 outVec; + glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + glm::vec3 v2 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + int lineHit = -1; + if (AABBvsTriangle(box, v0, v1, v2, outVec, lineHit)) { hit = true; - //If resolution distance is smaller than previous, and is non-zero. - if (glm::length(resVec) < glm::length(outResolutionVector) && vectorHasLength(resVec)) { - outResolutionVector = resVec; + if (lineHit == -1) { + outResolutionVector += outVec; + //TODO: We might be able to return here instead, having only convex geometry. + cornerHitTODO = true; + //return true; + } + else { + const glm::vec3 triPos[] = { + v0, v1, v2 + }; + glm::vec3 edge = triPos[(lineHit + 1) % 3] - triPos[lineHit]; + hitTriangles.push_back({v0, v1, v2}); + hitNormals.push_back(outVec); } } } - //TODO: Unnecessary later, remove it. - if (glm::any(glm::isinf(outResolutionVector))) { - outResolutionVector = glm::vec3(0, 0, 0); + if (hitTriangles.size() > 0) { + if (cornerHitTODO) { + LOG_DEBUG("Both edges and corners was hit on the same model."); + return true; + } + for (const glm::vec3& norm : hitNormals) { + outResolutionVector += norm; + } + //Normalize. + outResolutionVector /= hitNormals.size(); + const glm::vec3& origin = box.Origin(); + const glm::vec3& half = box.HalfSize(); + float maxDist = -10; + for (const Triangle& tri : hitTriangles) { + float d = glm::dot(outResolutionVector, 0.333f * (tri.v0 + tri.v1 + tri.v2) - origin); + maxDist = std::max(maxDist, d); + } + glm::vec3 tmp = glm::clamp(2.0f * outResolutionVector, glm::vec3(-1, -1, -1), glm::vec3(1, 1, 1)); + outResolutionVector *= maxDist + glm::length(tmp * half); } return hit; } diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 11d2a836..452a73ef 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -17,11 +17,6 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c ComponentWrapper& cTransform = entity["Transform"]; AABB& boxA = *boundingBox; - //Press 'Z' to enable/disable collision. - if (zPress) { - return; - } - // Collide against octree //std::vector octreeResult; //m_Octree->ObjectsInSameRegion(*boundingBox, octreeResult); @@ -64,11 +59,3 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c } } } - -bool CollisionSystem::OnKeyUp(const Events::KeyUp & event) -{ - if (event.KeyCode == GLFW_KEY_Z) { - zPress = !zPress; - } - return false; -} diff --git a/src/Engine/Core/Octree.cpp b/src/Engine/Core/Octree.cpp index d7feba45..f6e358c8 100644 --- a/src/Engine/Core/Octree.cpp +++ b/src/Engine/Core/Octree.cpp @@ -276,9 +276,4 @@ std::vector Child::childIndicesContainingBox(const AABB& box) const } } -inline bool Child::hasChildren() const -{ - return m_Children[0] != nullptr; -} - } \ No newline at end of file From 71404c882819a10a4016cf95b032f67736911d11 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Sat, 23 Jan 2016 14:01:54 +0100 Subject: [PATCH 007/131] Special case for collision vs ground (upward facing) triangles. --- .../Schema/Entities/CollisionTestLevel.xml | 186 ++++++------------ src/Engine/Collision/Collision.cpp | 92 ++++++--- src/Engine/Collision/CollisionSystem.cpp | 1 + 3 files changed, 134 insertions(+), 145 deletions(-) diff --git a/resources/Schema/Entities/CollisionTestLevel.xml b/resources/Schema/Entities/CollisionTestLevel.xml index d5e932c2..76a3b6e6 100644 --- a/resources/Schema/Entities/CollisionTestLevel.xml +++ b/resources/Schema/Entities/CollisionTestLevel.xml @@ -1,122 +1,66 @@ - + + - - - - - - - Models/DummyScene.obj - - - - - - - - - - - Models/Core/UnitSphere.obj - - - - - - - - - - - Models/RotationWidgetX.obj - - - - - - - - - - - - - - - Models/Core/UnitCube.obj - - - - - - - - - - - - - - - - - - - - - - Models/Core/UnitRaptor.obj - - - - - - - - - - - - 20 - - - - - - - - - - - - - Models/Core/UnitCube.obj - - - - - - - - - - - - - Models/Core/UnitCube.obj - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + ../assets\Models\Test/ObstacleCourse.obj + + + + + + + + + + + 0.46000027656555176 + + + + + + + + + + + + + ../assets\Models\Core\UnitCube.obj + + + false + + + + + + + + + + + + + + ../assets\Models\Core\colorbox.obj + + + + + + + + + + + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index f040ccd5..d134a5d8 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -4,6 +4,7 @@ #include "Engine/GLM.h" #include "Core/World.h" #include "Rendering/Model.h" +#include "imgui/imgui.h" namespace Collision { @@ -248,12 +249,21 @@ bool vectorHasLength(const glm::vec3& vec) return glm::any(glm::greaterThan(glm::abs(vec), glm::vec3(0.0001f, 0.0001f, 0.0001f))); } +enum BoxTriHit +{ + Line0 = 0, + Line1, + Line2, + Ground, + Corner +}; + bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, glm::vec3& outVector, - int& lineHit) + BoxTriHit& outHit) { //Check so we don't have a zero area triangle when calculating the normal. glm::vec3 triNormal = glm::cross(v1 - v0, v2 - v0); @@ -266,6 +276,23 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& min = box.MinCorner(); const glm::vec3& max = box.MaxCorner(); + //Check if normal faces upwards, and if so, just push the box upwards on collision. + triNormal = glm::normalize(triNormal); + if (triNormal.y > 0.5f || true) { + //TODO: Optimize calculation since x, z is 0. + //Ray ray(glm::vec3(origin.x, origin.y + half.y, origin.z), glm::vec3(0, -1, 0)); + //float dist = INFINITY, u, v; + //if (RayVsTriangle(ray, v0, v1, v2, dist, u, v) && dist < 2.0f * half.y) { + Ray ray(origin, glm::vec3(0, -1, 0)); + float dist = INFINITY, u, v; + if (RayVsTriangle(ray, v0, v1, v2, dist, u, v) && dist < half.y) { + outVector = glm::vec3(0, half.y - dist, 0); + outHit = Ground; + return true; + } + //return false; //TODO: Uncomment? + } + const glm::vec3 triPos[] = { v0, v1, v2 }; @@ -291,7 +318,6 @@ bool AABBvsTriangle(const AABB& box, return false; //If a triangle is completely inside the box, we call it a non-intersection. } - triNormal = glm::normalize(triNormal); Ray ray; //All triangle edges. //Check if any edge on the triangle intersects the box. @@ -302,7 +328,7 @@ bool AABBvsTriangle(const AABB& box, float dist; if (RayVsAABB(ray, box, dist) && dist <= glm::length(edge)) { outVector = triNormal; - lineHit = l; + outHit = (BoxTriHit)l; return true; } } @@ -341,6 +367,7 @@ bool AABBvsTriangle(const AABB& box, //Distance between triangle plane, and the diagonal corner, multiplied by the normal. //Signed distance, positive if on the same side as the normal. outVector = -glm::dot(triNormal, origin + diagonal - v0) * triNormal; + outHit = Corner; return true; } return false; @@ -348,6 +375,7 @@ bool AABBvsTriangle(const AABB& box, bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) { + AABB newBox = box; struct Triangle { glm::vec3 v0, v1, v2; @@ -362,45 +390,61 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); glm::vec3 v2 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); - int lineHit = -1; - if (AABBvsTriangle(box, v0, v1, v2, outVec, lineHit)) + BoxTriHit hitCase; + if (AABBvsTriangle(newBox, v0, v1, v2, outVec, hitCase)) { hit = true; - if (lineHit == -1) { - outResolutionVector += outVec; - //TODO: We might be able to return here instead, having only convex geometry. - cornerHitTODO = true; - //return true; - } - else { - const glm::vec3 triPos[] = { - v0, v1, v2 - }; - glm::vec3 edge = triPos[(lineHit + 1) % 3] - triPos[lineHit]; + switch (hitCase) { + case Collision::Line0: + case Collision::Line1: + case Collision::Line2: + //TODO: Resolve. + //const glm::vec3 triPos[] = { + // v0, v1, v2 + //}; + //glm::vec3 edge = triPos[(hitCase + 1) % 3] - triPos[hitCase]; hitTriangles.push_back({v0, v1, v2}); hitNormals.push_back(outVec); + ImGui::Text("triangle edge collision."); + break; + case Collision::Corner: + //TODO: We might be able to return here instead, having only convex geometry. + cornerHitTODO = true; + //outResolutionVector += outVec; + //return true; + ImGui::Text("triangle corner collision."); + outResolutionVector += outVec; + newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); + break; + case Collision::Ground: + default: + outResolutionVector += outVec; + newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); + ImGui::Text("triangle ground collision."); + break; } } } if (hitTriangles.size() > 0) { if (cornerHitTODO) { - LOG_DEBUG("Both edges and corners was hit on the same model."); + ImGui::Text("Both edges and corners was hit on the same model."); return true; } + glm::vec3 lineResolve(0.f); for (const glm::vec3& norm : hitNormals) { - outResolutionVector += norm; + lineResolve += norm; } //Normalize. - outResolutionVector /= hitNormals.size(); - const glm::vec3& origin = box.Origin(); - const glm::vec3& half = box.HalfSize(); + lineResolve /= hitNormals.size(); + const glm::vec3& origin = newBox.Origin(); + const glm::vec3& half = newBox.HalfSize(); float maxDist = -10; for (const Triangle& tri : hitTriangles) { - float d = glm::dot(outResolutionVector, 0.333f * (tri.v0 + tri.v1 + tri.v2) - origin); + float d = glm::dot(lineResolve, 0.333f * (tri.v0 + tri.v1 + tri.v2) - origin); maxDist = std::max(maxDist, d); } - glm::vec3 tmp = glm::clamp(2.0f * outResolutionVector, glm::vec3(-1, -1, -1), glm::vec3(1, 1, 1)); - outResolutionVector *= maxDist + glm::length(tmp * half); + glm::vec3 tmp = glm::clamp(2.0f * lineResolve, glm::vec3(-1, -1, -1), glm::vec3(1, 1, 1)); + outResolutionVector += lineResolve * (maxDist + glm::length(tmp * half)); } return hit; } diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 452a73ef..20854c12 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -56,6 +56,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c glm::vec3 resolutionVector; if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; + cPhysics["Velocity"] = glm::vec3(0, 0, 0); } } } From 6eeb3ea5248e2a0acfa72d81f65363deb24a7038 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Sat, 23 Jan 2016 17:50:35 +0100 Subject: [PATCH 008/131] WIP, Bug fix + nitpicks + optimizations. --- resources/Schema/Entities/CollisionTestLevel.xml | 3 ++- src/Engine/Collision/Collision.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/resources/Schema/Entities/CollisionTestLevel.xml b/resources/Schema/Entities/CollisionTestLevel.xml index 76a3b6e6..5c029cf3 100644 --- a/resources/Schema/Entities/CollisionTestLevel.xml +++ b/resources/Schema/Entities/CollisionTestLevel.xml @@ -42,7 +42,8 @@ - + + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index d134a5d8..2b4b989e 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -278,8 +278,8 @@ bool AABBvsTriangle(const AABB& box, //Check if normal faces upwards, and if so, just push the box upwards on collision. triNormal = glm::normalize(triNormal); - if (triNormal.y > 0.5f || true) { - //TODO: Optimize calculation since x, z is 0. + if (triNormal.y > 0.5f) { + //TODO: Optimize calculation since x, z is 0, y is -1. //Ray ray(glm::vec3(origin.x, origin.y + half.y, origin.z), glm::vec3(0, -1, 0)); //float dist = INFINITY, u, v; //if (RayVsTriangle(ray, v0, v1, v2, dist, u, v) && dist < 2.0f * half.y) { @@ -290,7 +290,7 @@ bool AABBvsTriangle(const AABB& box, outHit = Ground; return true; } - //return false; //TODO: Uncomment? + return false; } const glm::vec3 triPos[] = { @@ -300,7 +300,8 @@ bool AABBvsTriangle(const AABB& box, auto insideAllPlanes = glm::tvec3(false); //All triangle vertex points. //Check if the triangle is completely outside or inside the box. - for (int ax = 0; ax < 3; ++ax) { + //First test x, then z, lastly y, since y is least likely to result in a early false. + for (int ax : { 0, 2, 1 }) { auto outsideMinPlane = glm::tvec3(false); auto outsideMaxPlane = glm::tvec3(false); auto insidePlanes = glm::tvec3(false); @@ -385,14 +386,13 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model outResolutionVector = glm::vec3(0.f); std::vector hitTriangles; std::vector hitNormals; - for (int i = 0; i < modelIndices.size(); i += 3) { + for (int i = 0; i < modelIndices.size(); ) { glm::vec3 outVec; glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); glm::vec3 v2 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); BoxTriHit hitCase; - if (AABBvsTriangle(newBox, v0, v1, v2, outVec, hitCase)) - { + if (AABBvsTriangle(newBox, v0, v1, v2, outVec, hitCase)) { hit = true; switch (hitCase) { case Collision::Line0: @@ -403,7 +403,7 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model // v0, v1, v2 //}; //glm::vec3 edge = triPos[(hitCase + 1) % 3] - triPos[hitCase]; - hitTriangles.push_back({v0, v1, v2}); + hitTriangles.push_back({ v0, v1, v2 }); hitNormals.push_back(outVec); ImGui::Text("triangle edge collision."); break; From e6224a4e96ab9d9d67c43810353098207927213d Mon Sep 17 00:00:00 2001 From: William Moberg Date: Sat, 23 Jan 2016 18:31:27 +0100 Subject: [PATCH 009/131] WIP (not working), attempt at separating axis theorem stuff. --- src/Engine/Collision/Collision.cpp | 96 +++++------------------------- 1 file changed, 15 insertions(+), 81 deletions(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 2b4b989e..911b87bc 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -275,103 +275,37 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& half = box.HalfSize(); const glm::vec3& min = box.MinCorner(); const glm::vec3& max = box.MaxCorner(); - - //Check if normal faces upwards, and if so, just push the box upwards on collision. - triNormal = glm::normalize(triNormal); - if (triNormal.y > 0.5f) { - //TODO: Optimize calculation since x, z is 0, y is -1. - //Ray ray(glm::vec3(origin.x, origin.y + half.y, origin.z), glm::vec3(0, -1, 0)); - //float dist = INFINITY, u, v; - //if (RayVsTriangle(ray, v0, v1, v2, dist, u, v) && dist < 2.0f * half.y) { - Ray ray(origin, glm::vec3(0, -1, 0)); - float dist = INFINITY, u, v; - if (RayVsTriangle(ray, v0, v1, v2, dist, u, v) && dist < half.y) { - outVector = glm::vec3(0, half.y - dist, 0); - outHit = Ground; - return true; - } - return false; - } - const glm::vec3 triPos[] = { v0, v1, v2 }; - auto insideAllPlanes = glm::tvec3(false); - //All triangle vertex points. - //Check if the triangle is completely outside or inside the box. - //First test x, then z, lastly y, since y is least likely to result in a early false. - for (int ax : { 0, 2, 1 }) { - auto outsideMinPlane = glm::tvec3(false); - auto outsideMaxPlane = glm::tvec3(false); - auto insidePlanes = glm::tvec3(false); - for (int pos = 0; pos < 3; ++pos) { - outsideMinPlane[pos] = (min[ax] > triPos[pos][ax]); - outsideMaxPlane[pos] = (triPos[pos][ax] > max[ax]); - insidePlanes[pos] = !(outsideMinPlane[pos] || outsideMaxPlane[pos]); - } - if (glm::all(outsideMinPlane) || glm::all(outsideMaxPlane)) { - return false; - } - insideAllPlanes[ax] = glm::all(insidePlanes); - } - if (glm::all(insideAllPlanes)) { - return false; //If a triangle is completely inside the box, we call it a non-intersection. + for (int axis : {1, 0, 2}) { + //2D Triangle. + //for axis=0,1,2: 2d point takes from xy,xz,yx. + int dim1 = axis == 2 ? 0 : 1; //0,0,1 + int dim2 = axis == 0 ? 1 : 2; //1,2,2 + glm::vec2 t0(triPos[0][dim1], triPos[0][dim2]); + glm::vec2 t1(triPos[1][dim1], triPos[1][dim2]); + glm::vec2 t2(triPos[2][dim1], triPos[2][dim2]); + //Project tri, + //Project box, + //if projections don't overlap, return false. } - Ray ray; - //All triangle edges. - //Check if any edge on the triangle intersects the box. - for (int l = 0; l < 3; ++l) { - glm::vec3 edge = triPos[(l + 1) % 3] - triPos[l]; - ray.SetOrigin(triPos[l]); - ray.SetDirection(edge); - float dist; - if (RayVsAABB(ray, box, dist) && dist <= glm::length(edge)) { - outVector = triNormal; - outHit = (BoxTriHit)l; - return true; - } - } - - //None of the polygon's edges intersects the cube, finally, check if any of the four - //cube diagonals intersect the interior of the polygon. //If the polygon does intersect any of the cube diagonals, it will //intersect the cube diagonal that comes //closest to being perpendicular to the plane of the polygon. - + triNormal = glm::normalize(triNormal); glm::vec3 diagonal = -signNonZero(triNormal) * half; -#define EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK //TODO: We should probably performance test with this on/off. -#ifdef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK //The triangle plane contains all points P in dot(triNormal, P) == dot(triNormal, v0) //The diagonal line contains all points P in P = origin + diagonal * t. float t = glm::dot(triNormal, v0 - origin) / glm::dot(triNormal, diagonal); - - //If intersection point between plane and diagonal is not within the box. + //If intersection point between plane and diagonal is within the box. if (glm::abs(t) > 1) { return false; } -#endif - - //Check if intersection point is on the triangle. - ray.SetOrigin(origin); - ray.SetDirection(diagonal); -#ifdef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK - if (RayVsTriangle(ray, v0, v1, v2, true)) { -#else - float dist = INFINITY, u, v; - if (RayVsTriangle(ray, v0, v1, v2, dist, u, v, true)) { - if (glm::abs(dist) > glm::length(diagonal)) { - return false; - } -#endif - //Distance between triangle plane, and the diagonal corner, multiplied by the normal. - //Signed distance, positive if on the same side as the normal. - outVector = -glm::dot(triNormal, origin + diagonal - v0) * triNormal; - outHit = Corner; - return true; - } - return false; + //TODO: Resolve it. + return true; } bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) From 910b3d10e4b18f20a1e1ed32430e077d3f351943 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Sun, 24 Jan 2016 15:32:10 +0100 Subject: [PATCH 010/131] WIP (false collisions), collision method expanded, not working. --- .../Schema/Entities/ModelCollisionTest.xml | 7 +- src/Engine/Collision/Collision.cpp | 184 +++++++++--------- 2 files changed, 97 insertions(+), 94 deletions(-) diff --git a/resources/Schema/Entities/ModelCollisionTest.xml b/resources/Schema/Entities/ModelCollisionTest.xml index f2a78549..c4a3f81b 100644 --- a/resources/Schema/Entities/ModelCollisionTest.xml +++ b/resources/Schema/Entities/ModelCollisionTest.xml @@ -27,9 +27,8 @@ - - - + + @@ -56,7 +55,7 @@ - + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 911b87bc..48a6a1e3 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -249,24 +249,70 @@ bool vectorHasLength(const glm::vec3& vec) return glm::any(glm::greaterThan(glm::abs(vec), glm::vec3(0.0001f, 0.0001f, 0.0001f))); } -enum BoxTriHit +bool AARectangleVsTriangle(const glm::vec2& boxMin, + const glm::vec2& boxMax, + const std::array& triPos) { - Line0 = 0, - Line1, - Line2, - Ground, - Corner -}; + //Project along box normals (coordinate axes, since it's axis-aligned). + for (int ax = 0; ax < 2; ++ax) { + float minTri = INFINITY; + float maxTri = -INFINITY; + for (const glm::vec2& t : triPos) { + minTri = std::min(t[ax], minTri); + maxTri = std::max(t[ax], maxTri); + } + if (minTri > boxMax[ax] || maxTri < boxMin[ax]) { + return false; + } + } + //Project along triangle normals. + //Put edges into normal vector, make normals in the loop. + std::array triNormals = { + triPos[1] - triPos[0], + triPos[2] - triPos[1], + triPos[0] - triPos[2] + }; + std::array boxPos = { + boxMax, + glm::vec2(boxMax.x, boxMin.y), + glm::vec2(boxMin.x, boxMax.y), + boxMin + }; + for (auto& normal : triNormals) { + //Rotate edge to a normal. + normal = glm::vec2(-normal.y, normal.x); + //Project triangle onto the normal. + float minTri = INFINITY; + float maxTri = -INFINITY; + for (const glm::vec2& point : triPos) { + float dot = glm::dot(normal, point); + minTri = std::min(dot, minTri); + maxTri = std::max(dot, maxTri); + } + //Project box onto the normal. + float minBox = INFINITY; + float maxBox = -INFINITY; + for (const glm::vec2& point : boxPos) { + float dot = glm::dot(normal, point); + minBox = std::min(dot, minTri); + maxBox = std::max(dot, maxTri); + } + if (maxBox < minTri || minBox > maxTri) { + return false; + } + } + return true; +} + +//An array containing 3 int pairs { 0, 2 }, { 0, 1 }, { 1, 2 } +constexpr std::array, 3> DimensionPairs({ std::pair(0, 2), std::pair(0, 1), std::pair(1, 2) }); bool AABBvsTriangle(const AABB& box, - const glm::vec3& v0, - const glm::vec3& v1, - const glm::vec3& v2, - glm::vec3& outVector, - BoxTriHit& outHit) + const std::array& triPos, + glm::vec3& outVector) { //Check so we don't have a zero area triangle when calculating the normal. - glm::vec3 triNormal = glm::cross(v1 - v0, v2 - v0); + glm::vec3 triNormal = glm::cross(triPos[1] - triPos[0], triPos[2] - triPos[0]); if (!vectorHasLength(triNormal)) { return false; } @@ -275,111 +321,69 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& half = box.HalfSize(); const glm::vec3& min = box.MinCorner(); const glm::vec3& max = box.MaxCorner(); - const glm::vec3 triPos[] = { - v0, v1, v2 - }; - - for (int axis : {1, 0, 2}) { + glm::tvec3 axisHit(false, false, false); + int i = 0; + for (std::pair dim : DimensionPairs) { //2D Triangle. //for axis=0,1,2: 2d point takes from xy,xz,yx. - int dim1 = axis == 2 ? 0 : 1; //0,0,1 - int dim2 = axis == 0 ? 1 : 2; //1,2,2 - glm::vec2 t0(triPos[0][dim1], triPos[0][dim2]); - glm::vec2 t1(triPos[1][dim1], triPos[1][dim2]); - glm::vec2 t2(triPos[2][dim1], triPos[2][dim2]); - //Project tri, - //Project box, + //Project triangle. + std::array t2D = { + glm::vec2(triPos[0][dim.first], triPos[0][dim.second]), + glm::vec2(triPos[1][dim.first], triPos[1][dim.second]), + glm::vec2(triPos[2][dim.first], triPos[2][dim.second]) + }; + //Project box. + glm::vec2 boxMin(min[dim.first], min[dim.second]); + glm::vec2 boxMax(max[dim.first], max[dim.second]); //if projections don't overlap, return false. + if (!AARectangleVsTriangle(boxMin, boxMax, t2D)) { + //return false; + } else { + axisHit[i] = true; + ImGui::Text("Triangle collision: Box axis %s", i == 0 ? "y" : i == 1 ? "z" : "x"); + } + ++i; } - //If the polygon does intersect any of the cube diagonals, it will + //If the triangle does intersect any of the cube diagonals, it will //intersect the cube diagonal that comes - //closest to being perpendicular to the plane of the polygon. + //closest to being perpendicular to the plane of the triangle. triNormal = glm::normalize(triNormal); glm::vec3 diagonal = -signNonZero(triNormal) * half; //The triangle plane contains all points P in dot(triNormal, P) == dot(triNormal, v0) //The diagonal line contains all points P in P = origin + diagonal * t. - float t = glm::dot(triNormal, v0 - origin) / glm::dot(triNormal, diagonal); + float t = glm::dot(triNormal, triPos[0] - origin) / glm::dot(triNormal, diagonal); //If intersection point between plane and diagonal is within the box. if (glm::abs(t) > 1) { return false; + } else { + ImGui::Text("Triangle collision: Triangle axis."); + return glm::all(axisHit); } //TODO: Resolve it. + outVector = glm::vec3(0.f); return true; } bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) { AABB newBox = box; - struct Triangle - { - glm::vec3 v0, v1, v2; - }; bool hit = false; - bool cornerHitTODO = false; outResolutionVector = glm::vec3(0.f); - std::vector hitTriangles; - std::vector hitNormals; for (int i = 0; i < modelIndices.size(); ) { + std::array triVertices = { + Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), + Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), + Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) + }; glm::vec3 outVec; - glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); - glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); - glm::vec3 v2 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); - BoxTriHit hitCase; - if (AABBvsTriangle(newBox, v0, v1, v2, outVec, hitCase)) { + if (AABBvsTriangle(newBox, triVertices, outVec)) { + ImGui::Text("Triangle collision: True."); hit = true; - switch (hitCase) { - case Collision::Line0: - case Collision::Line1: - case Collision::Line2: - //TODO: Resolve. - //const glm::vec3 triPos[] = { - // v0, v1, v2 - //}; - //glm::vec3 edge = triPos[(hitCase + 1) % 3] - triPos[hitCase]; - hitTriangles.push_back({ v0, v1, v2 }); - hitNormals.push_back(outVec); - ImGui::Text("triangle edge collision."); - break; - case Collision::Corner: - //TODO: We might be able to return here instead, having only convex geometry. - cornerHitTODO = true; - //outResolutionVector += outVec; - //return true; - ImGui::Text("triangle corner collision."); - outResolutionVector += outVec; - newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); - break; - case Collision::Ground: - default: - outResolutionVector += outVec; - newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); - ImGui::Text("triangle ground collision."); - break; - } + outResolutionVector += outVec; + newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); } } - if (hitTriangles.size() > 0) { - if (cornerHitTODO) { - ImGui::Text("Both edges and corners was hit on the same model."); - return true; - } - glm::vec3 lineResolve(0.f); - for (const glm::vec3& norm : hitNormals) { - lineResolve += norm; - } - //Normalize. - lineResolve /= hitNormals.size(); - const glm::vec3& origin = newBox.Origin(); - const glm::vec3& half = newBox.HalfSize(); - float maxDist = -10; - for (const Triangle& tri : hitTriangles) { - float d = glm::dot(lineResolve, 0.333f * (tri.v0 + tri.v1 + tri.v2) - origin); - maxDist = std::max(maxDist, d); - } - glm::vec3 tmp = glm::clamp(2.0f * lineResolve, glm::vec3(-1, -1, -1), glm::vec3(1, 1, 1)); - outResolutionVector += lineResolve * (maxDist + glm::length(tmp * half)); - } return hit; } From f1343e2f82b14a74710b8b01f5e1926851c9967d Mon Sep 17 00:00:00 2001 From: William Moberg Date: Sun, 24 Jan 2016 21:08:42 +0100 Subject: [PATCH 011/131] Collision may be working, kind of. --- src/Engine/Collision/Collision.cpp | 69 +++++++++++++++++++----------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 48a6a1e3..41ca2155 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -243,16 +243,19 @@ inline glm::vec3 signNonZero(const glm::vec3& x) return r; } - -bool vectorHasLength(const glm::vec3& vec) +template +bool vectorHasLength(const T& vec) { - return glm::any(glm::greaterThan(glm::abs(vec), glm::vec3(0.0001f, 0.0001f, 0.0001f))); + return glm::any(glm::greaterThan(glm::abs(vec), T(0.0001f))); } -bool AARectangleVsTriangle(const glm::vec2& boxMin, +bool rectangleVsTriangle(const glm::vec2& boxMin, const glm::vec2& boxMax, - const std::array& triPos) + const std::array& triPos, + glm::vec2& resolutionDirection, + float& resolutionDistance) { + resolutionDistance = INFINITY; //Project along box normals (coordinate axes, since it's axis-aligned). for (int ax = 0; ax < 2; ++ax) { float minTri = INFINITY; @@ -264,6 +267,12 @@ bool AARectangleVsTriangle(const glm::vec2& boxMin, if (minTri > boxMax[ax] || maxTri < boxMin[ax]) { return false; } + float push = std::min(maxTri - boxMin[ax], boxMax[ax] - minTri); + if (push < resolutionDistance) { + resolutionDistance = push; + resolutionDirection[1 - ax] = 0.f; + resolutionDirection[ax] = resolutionDistance; + } } //Project along triangle normals. //Put edges into normal vector, make normals in the loop. @@ -279,6 +288,9 @@ bool AARectangleVsTriangle(const glm::vec2& boxMin, boxMin }; for (auto& normal : triNormals) { + if (!vectorHasLength(normal)) { + continue; + } //Rotate edge to a normal. normal = glm::vec2(-normal.y, normal.x); //Project triangle onto the normal. @@ -294,18 +306,24 @@ bool AARectangleVsTriangle(const glm::vec2& boxMin, float maxBox = -INFINITY; for (const glm::vec2& point : boxPos) { float dot = glm::dot(normal, point); - minBox = std::min(dot, minTri); - maxBox = std::max(dot, maxTri); + minBox = std::min(dot, minBox); + maxBox = std::max(dot, maxBox); } if (maxBox < minTri || minBox > maxTri) { return false; } + //Here: maxBox > minTri && minBox < maxTri + float push = std::min(maxTri - minBox, maxBox - minTri); + if (push < resolutionDistance) { + resolutionDistance = push; + resolutionDirection = resolutionDistance * glm::normalize(normal); + } } return true; } //An array containing 3 int pairs { 0, 2 }, { 0, 1 }, { 1, 2 } -constexpr std::array, 3> DimensionPairs({ std::pair(0, 2), std::pair(0, 1), std::pair(1, 2) }); +constexpr std::array, 3> dimensionPairs({ std::pair(0, 2), std::pair(0, 1), std::pair(1, 2) }); bool AABBvsTriangle(const AABB& box, const std::array& triPos, @@ -321,11 +339,11 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& half = box.HalfSize(); const glm::vec3& min = box.MinCorner(); const glm::vec3& max = box.MaxCorner(); - glm::tvec3 axisHit(false, false, false); - int i = 0; - for (std::pair dim : DimensionPairs) { + float minimumTranslation = INFINITY; + + //For each projection in xy-, xz-, and yx-planes. + for (std::pair dim : dimensionPairs) { //2D Triangle. - //for axis=0,1,2: 2d point takes from xy,xz,yx. //Project triangle. std::array t2D = { glm::vec2(triPos[0][dim.first], triPos[0][dim.second]), @@ -335,33 +353,35 @@ bool AABBvsTriangle(const AABB& box, //Project box. glm::vec2 boxMin(min[dim.first], min[dim.second]); glm::vec2 boxMax(max[dim.first], max[dim.second]); + glm::vec2 resolutionVector; + float resolutionDist; //if projections don't overlap, return false. - if (!AARectangleVsTriangle(boxMin, boxMax, t2D)) { - //return false; - } else { - axisHit[i] = true; - ImGui::Text("Triangle collision: Box axis %s", i == 0 ? "y" : i == 1 ? "z" : "x"); + if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector, resolutionDist)) { + return false; + } else if (resolutionDist < minimumTranslation) { + outVector = glm::vec3(0.f); + outVector[dim.first] = resolutionVector.x; + outVector[dim.second] = resolutionVector.y; + minimumTranslation = resolutionDist; } - ++i; } //If the triangle does intersect any of the cube diagonals, it will //intersect the cube diagonal that comes //closest to being perpendicular to the plane of the triangle. triNormal = glm::normalize(triNormal); - glm::vec3 diagonal = -signNonZero(triNormal) * half; + glm::vec3 diagonal = signNonZero(triNormal) * half; //The triangle plane contains all points P in dot(triNormal, P) == dot(triNormal, v0) //The diagonal line contains all points P in P = origin + diagonal * t. float t = glm::dot(triNormal, triPos[0] - origin) / glm::dot(triNormal, diagonal); //If intersection point between plane and diagonal is within the box. if (glm::abs(t) > 1) { return false; - } else { - ImGui::Text("Triangle collision: Triangle axis."); - return glm::all(axisHit); } - //TODO: Resolve it. - outVector = glm::vec3(0.f); + glm::vec3 cornerResolution = (1+t) * diagonal; + if (glm::length(cornerResolution) < minimumTranslation) { + outVector = cornerResolution; + } return true; } @@ -378,7 +398,6 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model }; glm::vec3 outVec; if (AABBvsTriangle(newBox, triVertices, outVec)) { - ImGui::Text("Triangle collision: True."); hit = true; outResolutionVector += outVec; newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); From 3389b965eb888a8a5c8ebe33a91da574568a3d09 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 25 Jan 2016 10:55:05 +0100 Subject: [PATCH 012/131] Test on game level v1. --- .../Schema/Entities/LevelCollisionTest.xml | 43 ++++++++++++++++++ src/Engine/Collision/Collision.cpp | 44 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 resources/Schema/Entities/LevelCollisionTest.xml diff --git a/resources/Schema/Entities/LevelCollisionTest.xml b/resources/Schema/Entities/LevelCollisionTest.xml new file mode 100644 index 00000000..0feb9a11 --- /dev/null +++ b/resources/Schema/Entities/LevelCollisionTest.xml @@ -0,0 +1,43 @@ + + + + + + + ../assets\Models/MapVersion1.obj + + + + + + + + + + + + + ../assets/Models/Core/UnitCube.obj + + + false + + + + + + + + + + + + + + + + + + + + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 41ca2155..7e9edb31 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -403,6 +403,50 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); } } + + //outResolutionVector = glm::vec3(INFINITY); + //std::stack testBoxes; + //std::stack resolveIndices; + //std::stack resolveVectors; + //resolveVectors.push(glm::vec3(0.f)); + //resolveIndices.push(0); + //testBoxes.push(box); + //do { + // int i = resolveIndices.top(); + // resolveIndices.pop(); + // while (i < modelIndices.size()) { + // std::array triVertices = { + // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), + // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), + // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) + // }; + // glm::vec3 outVec; + // bool test = AABBvsTriangle(testBoxes.top(), triVertices, outVec); + // if (test) { + // hit = true; + // //emplace? + // resolveIndices.push(i); + // testBoxes.push(AABB::FromOriginSize(box.Origin() + outVec, box.Size())); + // resolveVectors.top() += outVec; + // } + // } + // testBoxes.pop(); + // resolveVectors.push(glm::vec3(0.f)); + //} while (!resolveIndices.empty()); + //if (hit) { + // if (!resolveVectors.empty()) { + // while (!resolveVectors.empty()) { + // if (glm::length2(resolveVectors.top()) < glm::length2(outResolutionVector)) { + // outResolutionVector = resolveVectors.top(); + // } + // resolveVectors.pop(); + // } + // } else { + // //TODO: This won't happen. + // ImGui::Text("Collision, but not resolved."); + // } + // return true; + //} return hit; } From c5b1afb0d493e14fdf7b4e22e8e7cf0514d8f642 Mon Sep 17 00:00:00 2001 From: antc13 Date: Wed, 27 Jan 2016 09:37:01 +0100 Subject: [PATCH 013/131] Exporter Fix --- assets | 2 +- tools/MayaExporter/MayaExporter/Export.cpp | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/assets b/assets index 068fbb2d..75778193 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 068fbb2d20682dd60f186c82172d7731e60ed7e9 +Subproject commit 757781933738bc4158c5c26750594b70acd537cd diff --git a/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp index d8f1abd4..2b2764b1 100644 --- a/tools/MayaExporter/MayaExporter/Export.cpp +++ b/tools/MayaExporter/MayaExporter/Export.cpp @@ -47,13 +47,24 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) for (unsigned int i = 0; i < connections.length(); i++) { if (connections[i].node().apiType() == MFn::kSkinClusterFilter) { - MGlobal::select(shape.parent(i), MGlobal::kReplaceList); - MGlobal::displayInfo(MString() + "Moving " + thisNode.name() + " to bindPose."); + shape.parent(0, &status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "shape.parent(0, &status) failed with: " + status.errorString()); + } + status = MGlobal::select(shape.parent(0), MGlobal::kReplaceList); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "Parent to " + thisNode.name() + " failed"); + } + + MFnDependencyNode tmp(shape.parent(0)); + MGlobal::displayInfo(MString() + "Moving " + tmp.name() + " to bindPose."); + status = MGlobal::executeCommand("GoToBindPose;"); if (status != MS::kSuccess) { MGlobal::displayError(MString() + "GoToBindPose: " + status.errorString()); } - MGlobal::displayInfo(MString() + "Has moved " + thisNode.name() + " to bindPose."); + + MGlobal::displayInfo(MString() + "Has moved " + tmp.name() + " to bindPose."); } } } From 6ea490e215775c1e11ae0b7bdee39396f83b543b Mon Sep 17 00:00:00 2001 From: William Moberg Date: Wed, 27 Jan 2016 10:34:26 +0100 Subject: [PATCH 014/131] Tried a horrible recursive method, extreme framedrop. --- include/Engine/Collision/Collision.h | 1 + .../Schema/Entities/LevelCollisionTest.xml | 6 +- src/Engine/Collision/Collision.cpp | 62 +++++++++++++++++-- src/Engine/Collision/CollisionSystem.cpp | 12 ++-- 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 4e764905..6e2d679e 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -65,6 +65,7 @@ bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, + const glm::vec3& boxVelocity, glm::vec3& outResolutionVector); //Return true if the boxes are intersecting. diff --git a/resources/Schema/Entities/LevelCollisionTest.xml b/resources/Schema/Entities/LevelCollisionTest.xml index 0feb9a11..ce0fe405 100644 --- a/resources/Schema/Entities/LevelCollisionTest.xml +++ b/resources/Schema/Entities/LevelCollisionTest.xml @@ -6,9 +6,7 @@ ../assets\Models/MapVersion1.obj - - - + @@ -24,7 +22,7 @@ - + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 7e9edb31..96d908ff 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -327,11 +327,14 @@ constexpr std::array, 3> dimensionPairs({ std::pair& triPos, + const glm::vec3& boxVelocity, glm::vec3& outVector) { //Check so we don't have a zero area triangle when calculating the normal. + //Also, don't check a triangle facing away from the player. + //Less checks, and we should be able to walk out from models if we are trapped inside. glm::vec3 triNormal = glm::cross(triPos[1] - triPos[0], triPos[2] - triPos[0]); - if (!vectorHasLength(triNormal)) { + if (!vectorHasLength(triNormal) || glm::dot(triNormal, boxVelocity) > 0) { return false; } @@ -385,10 +388,18 @@ bool AABBvsTriangle(const AABB& box, return true; } -bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector) +bool AABBvsTriangles(const AABB& box, + const std::vector& modelVertices, + const std::vector& modelIndices, + const glm::mat4& modelMatrix, + const glm::vec3& boxVelocity, + glm::vec3& outResolutionVector, + int startIndex, + int recursiveDepth) { - AABB newBox = box; bool hit = false; + + AABB newBox = box; outResolutionVector = glm::vec3(0.f); for (int i = 0; i < modelIndices.size(); ) { std::array triVertices = { @@ -397,13 +408,38 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) }; glm::vec3 outVec; - if (AABBvsTriangle(newBox, triVertices, outVec)) { + if (AABBvsTriangle(newBox, triVertices, boxVelocity, outVec)) { hit = true; outResolutionVector += outVec; newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); } } + //outResolutionVector = glm::vec3(INFINITY); + //if (recursiveDepth > 2) { + // return true; + //} + //for (int i = startIndex; i < modelIndices.size(); ) { + // std::array triVertices = { + // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), + // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), + // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) + // }; + // glm::vec3 outVec; + // if (AABBvsTriangle(box, triVertices, boxVelocity, outVec) && glm::length2(outVec) < glm::length2(outResolutionVector)) { + // hit = true; + // glm::vec3 potentialResolution = outVec; + // const AABB& resolvedBox = AABB::FromOriginSize(box.Origin() + potentialResolution, box.Size()); + // if (AABBvsTriangles(resolvedBox, modelVertices, modelIndices, modelMatrix, boxVelocity, outVec, i, recursiveDepth+1)) { + // potentialResolution += outVec; + // if (glm::length2(potentialResolution) > glm::length2(outResolutionVector)) { + // continue; + // } + // } + // outResolutionVector = potentialResolution; + // } + //} + //outResolutionVector = glm::vec3(INFINITY); //std::stack testBoxes; //std::stack resolveIndices; @@ -449,6 +485,24 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model //} return hit; } +bool AABBvsTriangles(const AABB& box, + const std::vector& modelVertices, + const std::vector& modelIndices, + const glm::mat4& modelMatrix, + const glm::vec3& boxVelocity, + glm::vec3& outResolutionVector) +{ + return AABBvsTriangles( + box, + modelVertices, + modelIndices, + modelMatrix, + boxVelocity, + outResolutionVector, + 0, + 0 + ); +} bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon) { diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 20854c12..612d0707 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -41,11 +41,6 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c continue; } - auto absPosition = Transform::AbsolutePosition(m_World, cModel.EntityID); - auto absOrientation = Transform::AbsoluteOrientation(m_World, cModel.EntityID); - auto absScale = Transform::AbsoluteScale(m_World, cModel.EntityID); - glm::mat4 modelMatrix = glm::translate(absPosition) * glm::toMat4(absOrientation) * glm::scale(absScale); - RawModel* model; try { model = ResourceManager::Load(cModel["Resource"]); @@ -53,8 +48,13 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c continue; } + auto absPosition = Transform::AbsolutePosition(m_World, cModel.EntityID); + auto absOrientation = Transform::AbsoluteOrientation(m_World, cModel.EntityID); + auto absScale = Transform::AbsoluteScale(m_World, cModel.EntityID); + glm::mat4 modelMatrix = glm::translate(absPosition) * glm::toMat4(absOrientation) * glm::scale(absScale); + glm::vec3 resolutionVector; - if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) { + if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, (glm::vec3&)cPhysics["Velocity"], resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; cPhysics["Velocity"] = glm::vec3(0, 0, 0); } From 5cdf6db3404904ca799bed8d65e880739d4a6d26 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 27 Jan 2016 14:46:45 +0100 Subject: [PATCH 015/131] Modified HealthSystem so it actually publishes the DeathEvent. Modified EPlayerHealthPickup. Fixed 2 tests. Started work on PlayerDeathSystem --- include/Engine/Core/EPlayerDamage.h | 1 + include/Engine/Core/EPlayerHealthPickup.h | 4 +- include/Game/Systems/HealthSystem.h | 2 +- include/Game/Systems/PlayerDeathSystem.h | 39 ++++++++ resources/Schema/Entities/GameMap.xml | 4 +- src/Game/Game.cpp | 2 + src/Game/Systems/HealthSystem.cpp | 45 ++------- src/Game/Systems/PlayerDeathSystem.cpp | 116 ++++++++++++++++++++++ src/Tests/CollisionTest.cpp | 2 +- src/Tests/HealthSystemTest.cpp | 4 +- 10 files changed, 176 insertions(+), 43 deletions(-) create mode 100644 include/Game/Systems/PlayerDeathSystem.h create mode 100644 src/Game/Systems/PlayerDeathSystem.cpp diff --git a/include/Engine/Core/EPlayerDamage.h b/include/Engine/Core/EPlayerDamage.h index a7e135ce..8ba3907e 100644 --- a/include/Engine/Core/EPlayerDamage.h +++ b/include/Engine/Core/EPlayerDamage.h @@ -9,6 +9,7 @@ namespace Events struct PlayerDamage : Event { + //NOTE: this struct is missing information on what the damageSource is EntityWrapper Player; double Damage; }; diff --git a/include/Engine/Core/EPlayerHealthPickup.h b/include/Engine/Core/EPlayerHealthPickup.h index f3158f92..46ed76db 100644 --- a/include/Engine/Core/EPlayerHealthPickup.h +++ b/include/Engine/Core/EPlayerHealthPickup.h @@ -2,15 +2,15 @@ #define EPlayerHealthPickup_h__ #include "EventBroker.h" -#include "../Core/Entity.h" +#include "../Core/EntityWrapper.h" namespace Events { struct PlayerHealthPickup : Event { + EntityWrapper Player; double HealthAmount; - EntityID PlayerHealedID; }; } diff --git a/include/Game/Systems/HealthSystem.h b/include/Game/Systems/HealthSystem.h index 3b069349..46f24630 100644 --- a/include/Game/Systems/HealthSystem.h +++ b/include/Game/Systems/HealthSystem.h @@ -26,7 +26,7 @@ private: EventRelay m_EPlayerDamage; bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e); EventRelay m_EPlayerHealthPickup; - bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e); + bool HealthSystem::OnPlayerHealthPickup(Events::PlayerHealthPickup& e); //vector which will keep track of health changes std::vector> m_DeltaHealthVector; diff --git a/include/Game/Systems/PlayerDeathSystem.h b/include/Game/Systems/PlayerDeathSystem.h new file mode 100644 index 00000000..3f7268ca --- /dev/null +++ b/include/Game/Systems/PlayerDeathSystem.h @@ -0,0 +1,39 @@ +#ifndef PlayerDeathSystem_h__ +#define PlayerDeathSystem_h__ + +#include "Core/System.h" +#include "Input/EInputCommand.h" +#include "Systems/SpawnerSystem.h" +#include "Events/ESpawnerSpawn.h" +#include "Core/EPlayerSpawned.h" +#include "Rendering/ESetCamera.h" +#include "Core/ConfigFile.h" + +#include "Core/EPlayerDeath.h" +//tests +#include "Core/EPlayerDamage.h" + +class PlayerDeathSystem : public ImpureSystem +{ +public: + PlayerDeathSystem(World* world, EventBroker* eventBroker); + + virtual void Update(double dt) override; + +private: + struct SpawnRequest + { + int PlayerID; + ComponentInfo::EnumType Team; + }; + + bool m_NetworkEnabled = false; + std::vector m_SpawnRequests; + std::map m_PlayerEntities; + + EventRelay m_OnInputCommand; + bool OnInputCommand(const Events::InputCommand& e); + EventRelay m_OnPlayerDeath; + bool OnPlayerDeath(Events::PlayerDeath& e); +}; +#endif \ No newline at end of file diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml index 97fd3f4d..b37f702d 100644 --- a/resources/Schema/Entities/GameMap.xml +++ b/resources/Schema/Entities/GameMap.xml @@ -139,7 +139,7 @@ - + @@ -201,7 +201,7 @@ - + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index d13d62d4..b0c10a74 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -7,6 +7,7 @@ #include "Systems/PlayerMovementSystem.h" #include "Systems/SpawnerSystem.h" #include "Systems/PlayerSpawnSystem.h" +#include "Systems/PlayerDeathSystem.h" #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/WeaponSystem.h" @@ -86,6 +87,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 9e118070..26d38c69 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -11,38 +11,6 @@ HealthSystem::HealthSystem(World* m_World, EventBroker* eventBroker) void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { - //if entityID of health is 9 then the players ID is also 9 (player,health are connected to the same entity) - double maxHealth = (double)component["MaxHealth"]; - - //process the DeltaHealthVector and change the entitys health accordingly - for (size_t i = m_DeltaHealthVector.size(); i > 0; i--) - { - auto deltaHP = m_DeltaHealthVector[i - 1]; - //if we have a healthchange for the current player and health is greater than 0, then apply it - if (std::get<0>(deltaHP) == component.EntityID && (double)component["Health"] > 0.0f) { - //get the deltaHP value from the tuple and make sure you dont get more than maxHealth - double newHealth = std::min((double)component["Health"] + (double)std::get<1>(deltaHP), maxHealth); - component["Health"] = newHealth; - m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + i - 1); - //check if health is <= 0 - if ((double)component["Health"] <= 0.0f) { - component["Health"] = 0.0; - //publish death event - Events::PlayerDeath e; - e.PlayerID = component.EntityID; - m_EventBroker->Publish(e); - //clear the remaining hpDeltas for the dead player - for (size_t j = m_DeltaHealthVector.size(); j > 0; j--) - { - if (std::get<0>(m_DeltaHealthVector[j - 1]) == component.EntityID) - m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + j - 1); - } - //delete the player and break the loop - m_World->DeleteEntity(entity.ID); - break; - } - } - } } bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) @@ -52,16 +20,23 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) health -= e.Damage; if (health <= 0.0) { + Events::PlayerDeath ePlayerDeath; + ePlayerDeath.PlayerID = e.Player.ID; + m_EventBroker->Publish(ePlayerDeath); + m_World->DeleteEntity(e.Player.ID); } return true; } -bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e) +bool HealthSystem::OnPlayerHealthPickup(Events::PlayerHealthPickup& e) { - //save the changed HP to a vector. it will be taken care of in UpdateComponent - m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerHealedID, e.HealthAmount)); + ComponentWrapper cHealth = e.Player["Health"]; + double& health = cHealth["Health"]; + //NOTE: its possible to get more than MaxHealth health + health += e.HealthAmount; + return true; } diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp new file mode 100644 index 00000000..dcee3a92 --- /dev/null +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -0,0 +1,116 @@ +#include "Systems/PlayerDeathSystem.h" + +PlayerDeathSystem::PlayerDeathSystem(World* m_World, EventBroker* eventBroker) + : System(m_World, eventBroker) +{ + EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerDeathSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath); + m_NetworkEnabled = ResourceManager::Load("Config.ini")->Get("Networking.StartNetwork", false); +} + +void PlayerDeathSystem::Update(double dt) +{ + auto playerSpawns = m_World->GetComponents("PlayerSpawn"); + if (playerSpawns == nullptr) { + return; + } + + for (auto& req : m_SpawnRequests) { + for (auto& cPlayerSpawn : *playerSpawns) { + EntityWrapper spawner(m_World, cPlayerSpawn.EntityID); + if (!spawner.HasComponent("Spawner")) { + continue; + } + + // If the spawner has a team affiliation, check it + if (spawner.HasComponent("Team")) { + if ((int)spawner["Team"]["Team"] != req.Team) { + continue; + } + } + + // Spawn the player! + EntityWrapper player = SpawnerSystem::Spawn(spawner); + // Set the player team affiliation + player["Team"]["Team"] = req.Team; + + // Publish a PlayerSpawned event + Events::PlayerSpawned e; + e.PlayerID = req.PlayerID; + e.Player = player; + e.Spawner = spawner; + m_EventBroker->Publish(e); + + } + } + m_SpawnRequests.clear(); +} + +bool PlayerDeathSystem::OnInputCommand(const Events::InputCommand& e) +{ + //testing: Jump -> playerdamage + if (e.Command != "Jump") { + return false; + } + + // 0 = released + if (e.Value != 0) { + return false; + } + + auto players = m_World->GetComponents("Player"); + + for (auto& cPlayer : *players) { + EntityWrapper player(m_World, cPlayer.EntityID); + Events::PlayerDamage e; + e.Player = player; + e.Damage = 50; + m_EventBroker->Publish(e); + } + + + + return true; +} + +bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) +{ + //// When a player is actually spawned (since the actual spawning is handled on the server) + + //// Check if a player already exists + //if (m_PlayerEntities.count(e.PlayerID) != 0) { + // // TODO: Disallow infinite respawning here + // m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); + //} + + //// Store the player for future reference + //m_PlayerEntities[e.PlayerID] = e.Player; + + //// Set the camera to the correct entity + //EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); + //if (cameraEntity.Valid()) { + // Events::SetCamera e; + // e.CameraEntity = cameraEntity; + // m_EventBroker->Publish(e); + //} + + //// HACK: Set the player model color to team color + //EntityWrapper playerModel = e.Player.FirstChildByName("PlayerModel"); + //if (playerModel.Valid() && e.Player.HasComponent("Team")) { + // ComponentWrapper cTeam = e.Player["Team"]; + // ComponentWrapper cModel = playerModel["Model"]; + // if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Red")) { + // cModel["Color"] = glm::vec3(1.f, 0.f, 0.f); + // } else if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Blue")) { + // cModel["Color"] = glm::vec3(0.f, 0.25f, 1.f); + // } + //} + + //// TODO: Set the player name to whatever + //EntityWrapper playerName = e.Player.FirstChildByName("PlayerName"); + //if (playerName.Valid()) { + // playerName["Text"]["Content"] = e.PlayerName; + //} + + return true; +} \ No newline at end of file diff --git a/src/Tests/CollisionTest.cpp b/src/Tests/CollisionTest.cpp index 67b6ce19..6cb6c88b 100644 --- a/src/Tests/CollisionTest.cpp +++ b/src/Tests/CollisionTest.cpp @@ -29,7 +29,7 @@ void RayTest(std::string fileName) { Ray ray(glm::vec3(-50, 0, 0), glm::vec3(1, 0, 0)); //using a - here, else we have to init the renderingsystem + //here, else we have to init the renderingsystem ResourceManager::RegisterType("RawModel"); auto unitBox = ResourceManager::Load(fileName); BOOST_REQUIRE(unitBox != nullptr); diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index bdd9ba4b..6a434a9a 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -69,8 +69,8 @@ GameHealthSystemTest::GameHealthSystemTest() m_EventBroker->Publish(e3); //damage player with 50 Events::PlayerDamage e; - e.DamageAmount = 50.0f; - e.PlayerDamagedID = healthsID; + e.Damage = 50.0f; +// e.PlayerDamagedID = healthsID; m_EventBroker->Publish(e); //heal some other player with 40 Events::PlayerHealthPickup e2; From 246f56c82363b455b9de82ad114eb921374a2759 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 27 Jan 2016 15:40:01 +0100 Subject: [PATCH 016/131] Removed brainless logic. --- src/Engine/Sound/SoundSystem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index a55c1fee..ba46379e 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -71,7 +71,6 @@ void SoundSystem::deleteInactiveEmitters() alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); m_World->DeleteEntity(it->first); - delete it->second; it = m_Sources.erase(it); } } else { From 950f3f3cf7a02a3950a74eb0445abca0af7e9568 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 27 Jan 2016 15:43:40 +0100 Subject: [PATCH 017/131] Fixed last commit. Removed the wrong thing. --- src/Engine/Sound/SoundSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index ba46379e..d0887c05 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -70,7 +70,7 @@ void SoundSystem::deleteInactiveEmitters() // Sound has been stopped / finished playing. alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); - m_World->DeleteEntity(it->first); + delete it->second; it = m_Sources.erase(it); } } else { From 8fc8d56ee10cd130030b911393287c7b18b29a37 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 27 Jan 2016 17:14:16 +0100 Subject: [PATCH 018/131] Added BoneAttachment component --- .../Engine/Rendering/BoneAttachmentSystem.h | 29 +++++ include/Engine/Rendering/Skeleton.h | 12 +- resources/Schema/Components.xsd | 1 + .../Schema/Components/BoneAttachment.xml | 10 ++ .../Schema/Components/BoneAttachment.xsd | 19 +++ resources/Schema/Entities/AnimationTests.xml | 117 ++++++++++++++++++ resources/Schema/Entities/FastWorld.xml | 8 +- resources/Schema/Entities/awdawd | 23 ++++ src/Engine/Rendering/AnimationSystem.cpp | 2 - src/Engine/Rendering/BoneAttachmentSystem.cpp | 71 +++++++++++ src/Engine/Rendering/DrawFinalPass.cpp | 13 +- src/Engine/Rendering/Skeleton.cpp | 30 +++++ src/Game/Game.cpp | 4 +- 13 files changed, 322 insertions(+), 17 deletions(-) create mode 100644 include/Engine/Rendering/BoneAttachmentSystem.h create mode 100644 resources/Schema/Components/BoneAttachment.xml create mode 100644 resources/Schema/Components/BoneAttachment.xsd create mode 100644 resources/Schema/Entities/AnimationTests.xml create mode 100644 resources/Schema/Entities/awdawd create mode 100644 src/Engine/Rendering/BoneAttachmentSystem.cpp diff --git a/include/Engine/Rendering/BoneAttachmentSystem.h b/include/Engine/Rendering/BoneAttachmentSystem.h new file mode 100644 index 00000000..93ce5119 --- /dev/null +++ b/include/Engine/Rendering/BoneAttachmentSystem.h @@ -0,0 +1,29 @@ +#ifndef BoneAttachmentSystem_h__ +#define BoneAttachmentSystem_h__ + +#include "GLM.h" + +#include "Common.h" +#include "Core/System.h" +#include "Core/ResourceManager.h" +#include "Rendering/Model.h" +#include "Rendering/Skeleton.h" + +//Needs to be a higher orderlevel than AnimationSystem +class BoneAttachmentSystem : public PureSystem +{ +public: + BoneAttachmentSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("BoneAttachment") + { + + } + ~BoneAttachmentSystem() { } + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& BoneAttachmentComponent, double dt) override; +private: + + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 3b89b89b..15749b85 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -82,17 +82,19 @@ public: int GetBoneID(std::string name); - const Animation* GetAnimation(std::string name); - std::vector GetFrameBones(const Animation& animation, double time, bool noRootMotion = false); - void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); - void PrintSkeleton(); + const Animation* GetAnimation(std::string name); + std::vector GetFrameBones(const Animation& animation, double time, bool noRootMotion = false); + void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); std::map Animations; + glm::mat4 GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix); + int GetKeyframe(const Animation& animation, double time); + private: std::map m_BonesByName; - int GetKeyframe(const Animation& animation, double time); }; #endif diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index d663f695..eeeac344 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -24,4 +24,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/BoneAttachment.xml b/resources/Schema/Components/BoneAttachment.xml new file mode 100644 index 00000000..c8a8971a --- /dev/null +++ b/resources/Schema/Components/BoneAttachment.xml @@ -0,0 +1,10 @@ + + + + + + + true + true + false + \ No newline at end of file diff --git a/resources/Schema/Components/BoneAttachment.xsd b/resources/Schema/Components/BoneAttachment.xsd new file mode 100644 index 00000000..bc1dc444 --- /dev/null +++ b/resources/Schema/Components/BoneAttachment.xsd @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/AnimationTests.xml b/resources/Schema/Entities/AnimationTests.xml new file mode 100644 index 00000000..cdb80769 --- /dev/null +++ b/resources/Schema/Entities/AnimationTests.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + + + + + + + + + + + + Models/DirectionalLightWidget.mesh + + + + + + + + + + + + Run + + 0.5 + + + Models/AssaultAnimated.mesh + + + + + + + + + + + + 12 + 0.29999995231628418 + + + + + + + + + + + + 7 + + + + + + + + + + + + L_Foot + true + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + R_Foot + true + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/FastWorld.xml b/resources/Schema/Entities/FastWorld.xml index 68d1dccb..4863f8f7 100644 --- a/resources/Schema/Entities/FastWorld.xml +++ b/resources/Schema/Entities/FastWorld.xml @@ -3,7 +3,7 @@ - + @@ -18,16 +18,14 @@ - + - Crouch Walk - - 32 + Walk Models/AssaultAnimated.mesh diff --git a/resources/Schema/Entities/awdawd b/resources/Schema/Entities/awdawd new file mode 100644 index 00000000..d8dacb54 --- /dev/null +++ b/resources/Schema/Entities/awdawd @@ -0,0 +1,23 @@ + + + + + + + L_Foot + true + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 2126362f..e164c7fb 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -41,7 +41,5 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } } - - } diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp new file mode 100644 index 00000000..82ef7764 --- /dev/null +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -0,0 +1,71 @@ +#include "Rendering/BoneAttachmentSystem.h" + +void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& BoneAttachmentComponent, double dt) +{ + + if(!entity.HasComponent("Transform")) { + return; + } + + auto parent = entity.FirstParentWithComponent("Animation"); + if (!parent.HasComponent("Model")) { + return; + } + Model* model; + try { + model = ResourceManager::Load<::Model, true>(parent["Model"]["Resource"]); + } catch (const std::exception&) { + return; + } + + + Skeleton* skeleton = model->m_RawModel->m_Skeleton; + const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["Name"]); + + if (!animation) { + return; + } + + int id = skeleton->GetBoneID(entity["BoneAttachment"]["Name"]); + + if(id == -1) { + return; + } + + int currentKeyframeIndex = skeleton->GetKeyframe(*animation, parent["Animation"]["Time"]); + + const Skeleton::Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; + const Skeleton::Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; + float alpha = ((double)parent["Animation"]["Time"] - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + + glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], currentFrame, nextFrame, alpha, glm::mat4(1)); + + + + glm::vec3 scale; + glm::quat rotation; + glm::vec3 translation; + glm::vec3 skew; + glm::vec4 perspective; + glm::decompose(boneTransform, scale, rotation, translation, skew, perspective); + + glm::vec3 angles; + angles.y = asin(-boneTransform[0][2]); + if (cos(angles.y) != 0) { + angles.x = atan2(boneTransform[1][2], boneTransform[2][2]); + angles.z = atan2(boneTransform[0][1], boneTransform[0][0]); + } else { + angles.x = atan2(-boneTransform[2][0], boneTransform[1][1]); + angles.z = 0; + } + + if ((bool)entity["BoneAttachment"]["InheritPosition"]) { + (glm::vec3&)entity["Transform"]["Position"] = translation + (glm::vec3)entity["BoneAttachment"]["PositionOffset"]; + } + if ((bool)entity["BoneAttachment"]["InheritOrientation"]) { + (glm::vec3&)entity["Transform"]["Orientation"] = angles + (glm::vec3)entity["BoneAttachment"]["OrientationOffset"]; + } + if ((bool)entity["BoneAttachment"]["InheritScale"]) { + (glm::vec3&)entity["Transform"]["Scale"] = scale * (glm::vec3)entity["BoneAttachment"]["ScaleOffset"]; + } +} diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 52c9a4a9..9d36db2e 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -94,11 +94,16 @@ void DrawFinalPass::Draw(RenderScene& scene) glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); }*/ - //TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :) - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones( *modelJob->Animation, modelJob->AnimationTime); + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); +// std::vector frameBones2 = modelJob->Skeleton->GetFrameBones(*modelJob->Skeleton->GetAnimation("Walk"), modelJob->AnimationTime); +// +// +// for (int i = 0; i < frameBones.size(); i++) { +// frameBones[i] = frameBones[i] * glm::mat4(glm::quat(glm::vec3(0.f, 0.f, 0.f)));//* frameBones2[i]; +// } + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index cebabb67..8326dea9 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -66,6 +66,8 @@ std::vector Skeleton::GetFrameBones(const Animation& animation, doubl return finalMatrices; } + + void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map &boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { glm::mat4 boneMatrix; @@ -101,6 +103,34 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf } +glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, 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; + + + boneMatrix = (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)) * parentMatrix; + } else { + if (bone->Parent) { + boneMatrix = parentMatrix; + } + } + + if(bone->Parent) { + return GetBoneTransform(bone->Parent, currentFrame, nextFrame, progress, boneMatrix); + } else { + return boneMatrix; + } + +} + int Skeleton::GetBoneID(std::string name) { if (m_BonesByName.find(name) == m_BonesByName.end()) { diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 6384297c..b22f86ff 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -10,7 +10,8 @@ #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/WeaponSystem.h" -#include "../Engine/Rendering/AnimationSystem.h" +#include "Rendering/AnimationSystem.h" +#include "Rendering/BoneAttachmentSystem.h" Game::Game(int argc, char* argv[]) { @@ -90,6 +91,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); // Collision and TriggerSystem should update after player. ++updateOrderLevel; + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); ++updateOrderLevel; From 2ec5023752da427968e7e17ccb13e756de7cb730 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 27 Jan 2016 17:27:34 +0100 Subject: [PATCH 019/131] Changed Animation and BoneAttachment "Name" field to "AnimationName" and "BoneName" --- include/Engine/Rendering/ModelJob.h | 2 +- resources/Schema/Components/Animation.xml | 2 +- resources/Schema/Components/Animation.xsd | 2 +- .../Schema/Components/BoneAttachment.xml | 2 +- .../Schema/Components/BoneAttachment.xsd | 2 +- resources/Schema/Entities/AnimationTests.xml | 20 +++++++++---------- src/Engine/Rendering/AnimationSystem.cpp | 4 ++-- src/Engine/Rendering/BoneAttachmentSystem.cpp | 4 ++-- src/Engine/Rendering/DrawFinalPass.cpp | 8 -------- 9 files changed, 19 insertions(+), 27 deletions(-) diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index df7f1aec..21f7c1ca 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -46,7 +46,7 @@ struct ModelJob : RenderJob if (world->HasComponent(Entity, "Animation") && Skeleton != nullptr) { auto animationComponent = world->GetComponent(Entity, "Animation"); - Animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["Name"]); + Animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["AnimationName"]); AnimationTime = (double)animationComponent["Time"]; } }; diff --git a/resources/Schema/Components/Animation.xml b/resources/Schema/Components/Animation.xml index 66d2865d..ab589698 100644 --- a/resources/Schema/Components/Animation.xml +++ b/resources/Schema/Components/Animation.xml @@ -1,6 +1,6 @@ - + 0 true diff --git a/resources/Schema/Components/Animation.xsd b/resources/Schema/Components/Animation.xsd index 0dd21f29..388dfc07 100644 --- a/resources/Schema/Components/Animation.xsd +++ b/resources/Schema/Components/Animation.xsd @@ -6,7 +6,7 @@ - + diff --git a/resources/Schema/Components/BoneAttachment.xml b/resources/Schema/Components/BoneAttachment.xml index c8a8971a..47df9e40 100644 --- a/resources/Schema/Components/BoneAttachment.xml +++ b/resources/Schema/Components/BoneAttachment.xml @@ -1,6 +1,6 @@ - + diff --git a/resources/Schema/Components/BoneAttachment.xsd b/resources/Schema/Components/BoneAttachment.xsd index bc1dc444..aee1868f 100644 --- a/resources/Schema/Components/BoneAttachment.xsd +++ b/resources/Schema/Components/BoneAttachment.xsd @@ -6,7 +6,7 @@ - + diff --git a/resources/Schema/Entities/AnimationTests.xml b/resources/Schema/Entities/AnimationTests.xml index cdb80769..8a757639 100644 --- a/resources/Schema/Entities/AnimationTests.xml +++ b/resources/Schema/Entities/AnimationTests.xml @@ -34,8 +34,8 @@ - Run - + Walk + 0.5 @@ -75,8 +75,8 @@ + L_Foot - L_Foot true @@ -84,9 +84,9 @@ - - - + + + @@ -94,8 +94,8 @@ + R_Foot - R_Foot true @@ -103,9 +103,9 @@ - - - + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index e164c7fb..c79b5a36 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -15,7 +15,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a Skeleton* skeleton = model->m_RawModel->m_Skeleton; - const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["Name"]); + const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]); if(animation != nullptr) { double animationSpeed = (double)animationComponent["Speed"]; @@ -29,7 +29,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a (double&)animationComponent["Speed"] = 0.0; Events::AnimationComplete e; e.Entity = entity; - e.Name = (std::string)animationComponent["Name"]; + e.Name = (std::string)animationComponent["AnimationName"]; m_EventBroker->Publish(e); } else { if (glm::abs(nextTime) > animation->Duration) { diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index 82ef7764..2a2e5c7d 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -20,13 +20,13 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp Skeleton* skeleton = model->m_RawModel->m_Skeleton; - const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["Name"]); + const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["AnimationName"]); if (!animation) { return; } - int id = skeleton->GetBoneID(entity["BoneAttachment"]["Name"]); + int id = skeleton->GetBoneID(entity["BoneAttachment"]["BoneName"]); if(id == -1) { return; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 006790cd..72329f5b 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -156,17 +156,9 @@ void DrawFinalPass::Draw(RenderScene& scene) glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); }*/ - //TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { if (modelJob->Animation != nullptr) { std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); -// std::vector frameBones2 = modelJob->Skeleton->GetFrameBones(*modelJob->Skeleton->GetAnimation("Walk"), modelJob->AnimationTime); -// -// -// for (int i = 0; i < frameBones.size(); i++) { -// frameBones[i] = frameBones[i] * glm::mat4(glm::quat(glm::vec3(0.f, 0.f, 0.f)));//* frameBones2[i]; -// } - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } From c9b982bc89cb627bae518ce0c0cbd2809f3f931d Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 27 Jan 2016 17:31:57 +0100 Subject: [PATCH 020/131] Added BoneAttachment to Entity.xsd --- resources/Schema/Types/Entity.xsd | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 99b90caa..addabff2 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -37,6 +37,7 @@ + From 7497ff39d2e3d73ed4a3d34b8345236e575b6cf9 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 27 Jan 2016 18:00:31 +0100 Subject: [PATCH 021/131] Simon added Copy method to ComponentWrapper. Its being used in PlayerDeathSystem to copy model,animation,transform. TODO: 3rd person camera, cleanup, tests --- include/Engine/Core/ComponentWrapper.h | 5 ++ include/Engine/Core/EPlayerDeath.h | 3 +- src/Game/Systems/HealthSystem.cpp | 4 +- src/Game/Systems/PlayerDeathSystem.cpp | 69 +++++++++++++++++++++++++- 4 files changed, 77 insertions(+), 4 deletions(-) diff --git a/include/Engine/Core/ComponentWrapper.h b/include/Engine/Core/ComponentWrapper.h index f09bbfe3..1ca0347d 100644 --- a/include/Engine/Core/ComponentWrapper.h +++ b/include/Engine/Core/ComponentWrapper.h @@ -43,6 +43,11 @@ struct ComponentWrapper // Specialization for string literals template void SetField(std::string name, const char(&value)[N]) { Field(name) = std::string(value); } + + void Copy(ComponentWrapper& destination) + { + memcpy(destination.Data, this->Data, Info.Stride); + } struct SubscriptProxy { diff --git a/include/Engine/Core/EPlayerDeath.h b/include/Engine/Core/EPlayerDeath.h index 00ede5ed..53dfd013 100644 --- a/include/Engine/Core/EPlayerDeath.h +++ b/include/Engine/Core/EPlayerDeath.h @@ -2,7 +2,7 @@ #define EPlayerDeath_h__ #include "EventBroker.h" -#include "../Core/Entity.h" +#include "../Core/EntityWrapper.h" namespace Events { @@ -12,6 +12,7 @@ struct PlayerDeath : Event //KilledBy,KilledByWhat is optional for now. It might be used later in the playerlog-system EntityID KilledBy; EntityID PlayerID; + EntityWrapper Player; std::string KilledByWhat; }; diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 26d38c69..102a4be6 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -22,9 +22,9 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) if (health <= 0.0) { Events::PlayerDeath ePlayerDeath; ePlayerDeath.PlayerID = e.Player.ID; + ePlayerDeath.Player = e.Player; m_EventBroker->Publish(ePlayerDeath); - - m_World->DeleteEntity(e.Player.ID); + //m_World->DeleteEntity(e.Player.ID); } return true; diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index dcee3a92..ab20dbce 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -112,5 +112,72 @@ bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) // playerName["Text"]["Content"] = e.PlayerName; //} + //m_World->DeleteEntity(e.Player.ID); + + //koppla till en kamera modell för att explodera den + + auto cameras = m_World->GetComponents("Camera"); + + for (auto& someCamera : *cameras) { + EntityWrapper entity = EntityWrapper(m_World, someCamera.EntityID); + auto cameraID = entity.ID; + auto modelID = entity.FirstChildByName("HUD"); + auto weapID = entity.FirstChildByName("Weapon").ID; + + // auto modelID = m_World->GetComponent(e.PlayerID, "Camera"); + ComponentWrapper& explosionEffect = m_World->AttachComponent(weapID, "ExplosionEffect"); + ComponentWrapper& lifeTime = m_World->AttachComponent(weapID, "Lifetime"); + (glm::vec3)explosionEffect["ExplosionOrigin"] = glm::vec3(0, 0, 0); + //explosionEffect["ExplosionOrigin"] = e.Player["Transform"]["Position"]; + (double)explosionEffect["TimeSinceDeath"] = 0.0; + (double)explosionEffect["ExplosionDuration"] = 2.0; + explosionEffect["EndColor"] = glm::vec4(0, 0, 0, 1); + (bool)explosionEffect["Randomness"] = false; + (double)explosionEffect["RandomnessScalar"] = 1.0; + (glm::vec2)explosionEffect["Velocity"] = glm::vec2(1, 1); + (bool)explosionEffect["ColorByDistance"] = false; + (bool)explosionEffect["ExponentialAccelaration"] = false; + lifeTime["Lifetime"] = 2.0; + } + + + auto t = e.Player.FirstChildByName("PlayerModel"); + auto playerEntityModel = t["Model"]; + auto playerEntityAnimation = t["Animation"]; + auto playerEntityTransform = t["Transform"]; + //auto playerEntityModel = e.Player["PlayerModel"]; +// ComponentWrapper& playerEntityModel = e.Player.FirstChildByName("PlayerModel"); + + auto newEntity = m_World->CreateEntity(); + ComponentWrapper& newEntityModel = m_World->AttachComponent(newEntity, "Model"); + ComponentWrapper& newAnimationModel = m_World->AttachComponent(newEntity, "Animation"); + ComponentWrapper& newTransformModel = m_World->AttachComponent(newEntity, "Transform"); + + //ComponentWrapper& playerEntityModel = m_World->GetComponent(e.PlayerID, "PlayerModel"); + playerEntityModel.Copy(newEntityModel); + playerEntityAnimation.Copy(newAnimationModel); + playerEntityTransform.Copy(newTransformModel); + newAnimationModel["Speed"] = (double)0.0; + auto t2 = e.Player["Transform"]["Position"]; + newTransformModel["Position"] = (glm::vec3)e.Player["Transform"]["Position"]; + newTransformModel["Scale"] = glm::vec3(5, 5, 5); + //auto tr = m_World->GetComponent(newEntityModel.EntityID, "Transform"); + //tr["Position"] = glm::vec3(0, 50, 0); + + ComponentWrapper& explosionEffect = m_World->AttachComponent(newEntityModel.EntityID, "ExplosionEffect"); + ComponentWrapper& lifeTime = m_World->AttachComponent(newEntityModel.EntityID, "Lifetime"); + (glm::vec3)explosionEffect["ExplosionOrigin"] = (glm::vec3)e.Player["Transform"]["Position"]; + //explosionEffect["ExplosionOrigin"] = e.Player["Transform"]["Position"]; + (double)explosionEffect["TimeSinceDeath"] = 0.0; + (double)explosionEffect["ExplosionDuration"] = 8.0; + explosionEffect["EndColor"] = glm::vec4(0, 0, 0, 1); + (bool)explosionEffect["Randomness"] = false; + (double)explosionEffect["RandomnessScalar"] = 1.0; + (glm::vec2)explosionEffect["Velocity"] = glm::vec2(1, 1); + (bool)explosionEffect["ColorByDistance"] = false; + (bool)explosionEffect["ExponentialAccelaration"] = false; + lifeTime["Lifetime"] = 8.0; + return true; -} \ No newline at end of file +} +//on deathanim done -> del entity From 8834d5f7a00d69e4e64bd28e40cf9f7ba87cf7f0 Mon Sep 17 00:00:00 2001 From: antc13 Date: Wed, 27 Jan 2016 18:37:56 +0100 Subject: [PATCH 022/131] Fixed Animation Export --- tools/MayaExporter/MayaExporter/Material.cpp | 4 +- tools/MayaExporter/MayaExporter/Mesh.cpp | 9 +--- tools/MayaExporter/MayaExporter/Skeleton.cpp | 46 ++++++++++++++------ 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index 03521231..0ec752f7 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -85,9 +85,6 @@ bool Material::findColorTexture(MaterialNode& material_node, MFnDependencyNode& material_node.ColorMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); material_node.ColorMapFileLength = material_node.ColorMapFile.length() + 1; - // Test - MGlobal::displayInfo(MString() + "getAbsolutePathToResources: " + workspace); - MGlobal::displayInfo(MString() + "Texture file: " + FullPath.c_str()); return true; } } @@ -209,6 +206,7 @@ std::vector* Material::DoIt(Mesh mesh) meshHasMaterial = true; MaterialStorage.IndexStart = totalIndices; MaterialStorage.IndexEnd = totalIndices + aMeshMaterial.second.size() - 1; + MGlobal::displayInfo("Oh noes, breaking in material"); break; } totalIndices += aMeshMaterial.second.size(); diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 6af8a557..43b76d55 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -87,10 +87,6 @@ std::map MeshClass::GetWeightData() } weightMap[geomIter.index()] = weightInfo; - - for (unsigned int k = 0; k!=nrOfWeights; k++) { - MGlobal::displayInfo(MString() + "influence: " + weightInfo.BoneIndices[k] + " weight: " + weightInfo.BoneWeights[k]); - } geomIter.next(); } it.next(); @@ -112,7 +108,6 @@ Mesh MeshClass::GetMeshData(MObjectArray object) MFnDependencyNode thisNode(node); MPlugArray connections; thisNode.findPlug("inMesh").connectedTo(connections, true, true); - MGlobal::displayInfo(MString() + "inMesh"); bool hasSkin = false; MPlug weightList, weights; MObject weightListObject; @@ -138,7 +133,6 @@ Mesh MeshClass::GetMeshData(MObjectArray object) } for (int pathID = 0; pathID < dagPaths.length(); pathID++) { - MGlobal::displayInfo(dagPaths[pathID].fullPathName()); MDagPath thisMeshPath(dagPaths[pathID]); MMatrix transformMatrix = thisMeshPath.inclusiveMatrix(&status); @@ -173,8 +167,7 @@ Mesh MeshClass::GetMeshData(MObjectArray object) break; } map> materialFaceIDs; - MGlobal::displayInfo(MString() + "shaderIndexList: " + shaderIndexList.length()); - MGlobal::displayInfo(MString() + "shaderList: " + shaderList.length()); + MPlugArray plugArray; for (int i = 0; i < shaderIndexList.length(); i++) { MFnDependencyNode shader(shaderList[shaderIndexList[i]]); diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index c30311b8..94031629 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -60,7 +60,7 @@ // // return m_AllSkeletons; //} -std::string attr[9] = { "scaleX", "scaleY", "scaleZ", "translateX", "translateY", "translateZ", "rotateX", "rotateY", "rotateZ" }; +static std::string attr[9] = { "scaleX", "scaleY", "scaleZ", "translateX", "translateY", "translateZ", "rotateX", "rotateY", "rotateZ" }; Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int endFrame) { @@ -80,6 +80,9 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e m_Hierarchy.push_back(jointIt.item()); MFnDependencyNode depNode(jointIt.item()); + MGlobal::displayInfo("-------- INFO ---------"); + MGlobal::displayInfo("Joint name: " + depNode.name()); + //Loop toght the attr Array to find keyframes; for (int i = 0; i < 9; i++) { MStatus tmp; @@ -94,21 +97,38 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MFnAnimCurve jointAnim(connected); + //MGlobal::displayInfo(MString() + "curve : " + jointAnim.name()); + //MGlobal::displayInfo(MString() + "curve keys : " + jointAnim.numKeys()); + //MGlobal::displayInfo(MString() + "curve keyframes : " + jointAnim.numKeyframes()); + //MGlobal::displayInfo(MString() + "startFrame : " + startFrame); + //MGlobal::displayInfo(MString() + "endFrame : " + endFrame); + unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp); if (tmp == MStatus::kFailure) MGlobal::displayInfo(MString() + "Fail :c"); - if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) { + //MGlobal::displayInfo(MString() + "Start key index : " + startKeyFrameIndex); + //MGlobal::displayInfo(MString() + "Start key time : " + jointAnim.time(startKeyFrameIndex).value()); + + + if (startFrame <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame ) { animatedJoints.push_back(jointIt.item()); i = 9; break; - } + } - unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField)); - MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex); + unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField), &tmp); + if (tmp == MStatus::kFailure) + MGlobal::displayInfo(MString() + "Fail!!!!!!!!!!!!!!!!!!!!!!!!!"); - if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) { + + //MGlobal::displayInfo(MString() + "End key index : " + endKeyFrameIndex); + //MGlobal::displayInfo(MString() + "end key time : " + jointAnim.time(endKeyFrameIndex).value()); + + /*MGlobal::displayInfo(MString() + "start keyfram index: " + startKeyFrameIndex + ". End keyfram index: " + endKeyFrameIndex + ".");*/ + + if (startFrame <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame || endKeyFrameIndex - startKeyFrameIndex > 0) { animatedJoints.push_back(jointIt.item()); i = 9; break; @@ -122,16 +142,19 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MFnMatrixData MartixFn(DataHandle.data()); MMatrix BindPoseMatrix = MartixFn.matrix(); - if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix())) + if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix(), 0.0000001f)) { MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya"); } } - } - } + }//end of connections.length() loop + } // end of int i loop jointIt.next(); - } + } // enf of while (!jointIt.isDone()) + + + int currentFrame = startFrame; while (currentFrame != endFrame + 1) { // ANDREAS @@ -251,18 +274,15 @@ std::vector Skeleton::GetBindPoses() MVector tmp = MayaJoint.transformation().getTranslation(MSpace::kObject); - MGlobal::displayError(MString() + "translation befor: " + tmp[0] + " " + tmp[1] + " " + tmp[2]); //Matrix[3][0] *= -1; //Matrix[3][2] *= -1; //Matrix[3][1] *= -1; double test[3]; MayaJoint.transformation().getScale(test, MSpace::kObject); - MGlobal::displayError(MString() + "scale: " + test[0] + " " + test[1] + " " + test[2]); MTransformationMatrix::RotationOrder order = MTransformationMatrix::RotationOrder::kXYZ; MayaJoint.transformation().getRotation(test, order); - MGlobal::displayError(MString() + "rotation: " + test[0] + " " + test[1] + " " + test[2]); //----- test From df05f1909b08b37a3e02d86e1a73730d6b2b7f5a Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 28 Jan 2016 11:43:38 +0100 Subject: [PATCH 023/131] Completed the code to trigger the 3rd person camera on death. Cleaned up PlayerDeathSystem. Fixed HealthSystemTest. Removed the test for PlayerDeathSystem --- include/Game/Systems/PlayerDeathSystem.h | 18 +-- src/Game/Systems/HealthSystem.cpp | 2 +- src/Game/Systems/PlayerDeathSystem.cpp | 191 +++++------------------ src/Tests/HealthSystemTest.cpp | 22 ++- 4 files changed, 52 insertions(+), 181 deletions(-) diff --git a/include/Game/Systems/PlayerDeathSystem.h b/include/Game/Systems/PlayerDeathSystem.h index 3f7268ca..c59aea03 100644 --- a/include/Game/Systems/PlayerDeathSystem.h +++ b/include/Game/Systems/PlayerDeathSystem.h @@ -3,15 +3,11 @@ #include "Core/System.h" #include "Input/EInputCommand.h" -#include "Systems/SpawnerSystem.h" -#include "Events/ESpawnerSpawn.h" -#include "Core/EPlayerSpawned.h" +#include "GLM.h" #include "Rendering/ESetCamera.h" #include "Core/ConfigFile.h" #include "Core/EPlayerDeath.h" -//tests -#include "Core/EPlayerDamage.h" class PlayerDeathSystem : public ImpureSystem { @@ -21,18 +17,6 @@ public: virtual void Update(double dt) override; private: - struct SpawnRequest - { - int PlayerID; - ComponentInfo::EnumType Team; - }; - - bool m_NetworkEnabled = false; - std::vector m_SpawnRequests; - std::map m_PlayerEntities; - - EventRelay m_OnInputCommand; - bool OnInputCommand(const Events::InputCommand& e); EventRelay m_OnPlayerDeath; bool OnPlayerDeath(Events::PlayerDeath& e); }; diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 102a4be6..1b747046 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -24,7 +24,7 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) ePlayerDeath.PlayerID = e.Player.ID; ePlayerDeath.Player = e.Player; m_EventBroker->Publish(ePlayerDeath); - //m_World->DeleteEntity(e.Player.ID); + //Note: we will delete the entity in PlayerDeathSystem } return true; diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index ab20dbce..7085a23f 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -3,181 +3,72 @@ PlayerDeathSystem::PlayerDeathSystem(World* m_World, EventBroker* eventBroker) : System(m_World, eventBroker) { - EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerDeathSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath); - m_NetworkEnabled = ResourceManager::Load("Config.ini")->Get("Networking.StartNetwork", false); } void PlayerDeathSystem::Update(double dt) { - auto playerSpawns = m_World->GetComponents("PlayerSpawn"); - if (playerSpawns == nullptr) { - return; - } - - for (auto& req : m_SpawnRequests) { - for (auto& cPlayerSpawn : *playerSpawns) { - EntityWrapper spawner(m_World, cPlayerSpawn.EntityID); - if (!spawner.HasComponent("Spawner")) { - continue; - } - - // If the spawner has a team affiliation, check it - if (spawner.HasComponent("Team")) { - if ((int)spawner["Team"]["Team"] != req.Team) { - continue; - } - } - - // Spawn the player! - EntityWrapper player = SpawnerSystem::Spawn(spawner); - // Set the player team affiliation - player["Team"]["Team"] = req.Team; - - // Publish a PlayerSpawned event - Events::PlayerSpawned e; - e.PlayerID = req.PlayerID; - e.Player = player; - e.Spawner = spawner; - m_EventBroker->Publish(e); - - } - } - m_SpawnRequests.clear(); -} - -bool PlayerDeathSystem::OnInputCommand(const Events::InputCommand& e) -{ - //testing: Jump -> playerdamage - if (e.Command != "Jump") { - return false; - } - - // 0 = released - if (e.Value != 0) { - return false; - } - - auto players = m_World->GetComponents("Player"); - - for (auto& cPlayer : *players) { - EntityWrapper player(m_World, cPlayer.EntityID); - Events::PlayerDamage e; - e.Player = player; - e.Damage = 50; - m_EventBroker->Publish(e); - } - - - - return true; } bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) { - //// When a player is actually spawned (since the actual spawning is handled on the server) - - //// Check if a player already exists - //if (m_PlayerEntities.count(e.PlayerID) != 0) { - // // TODO: Disallow infinite respawning here - // m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); - //} - - //// Store the player for future reference - //m_PlayerEntities[e.PlayerID] = e.Player; - - //// Set the camera to the correct entity - //EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); - //if (cameraEntity.Valid()) { - // Events::SetCamera e; - // e.CameraEntity = cameraEntity; - // m_EventBroker->Publish(e); - //} - - //// HACK: Set the player model color to team color - //EntityWrapper playerModel = e.Player.FirstChildByName("PlayerModel"); - //if (playerModel.Valid() && e.Player.HasComponent("Team")) { - // ComponentWrapper cTeam = e.Player["Team"]; - // ComponentWrapper cModel = playerModel["Model"]; - // if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Red")) { - // cModel["Color"] = glm::vec3(1.f, 0.f, 0.f); - // } else if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Blue")) { - // cModel["Color"] = glm::vec3(0.f, 0.25f, 1.f); - // } - //} - - //// TODO: Set the player name to whatever - //EntityWrapper playerName = e.Player.FirstChildByName("PlayerName"); - //if (playerName.Valid()) { - // playerName["Text"]["Content"] = e.PlayerName; - //} - - //m_World->DeleteEntity(e.Player.ID); - - //koppla till en kamera modell för att explodera den - - auto cameras = m_World->GetComponents("Camera"); - - for (auto& someCamera : *cameras) { - EntityWrapper entity = EntityWrapper(m_World, someCamera.EntityID); - auto cameraID = entity.ID; - auto modelID = entity.FirstChildByName("HUD"); - auto weapID = entity.FirstChildByName("Weapon").ID; - - // auto modelID = m_World->GetComponent(e.PlayerID, "Camera"); - ComponentWrapper& explosionEffect = m_World->AttachComponent(weapID, "ExplosionEffect"); - ComponentWrapper& lifeTime = m_World->AttachComponent(weapID, "Lifetime"); - (glm::vec3)explosionEffect["ExplosionOrigin"] = glm::vec3(0, 0, 0); - //explosionEffect["ExplosionOrigin"] = e.Player["Transform"]["Position"]; - (double)explosionEffect["TimeSinceDeath"] = 0.0; - (double)explosionEffect["ExplosionDuration"] = 2.0; - explosionEffect["EndColor"] = glm::vec4(0, 0, 0, 1); - (bool)explosionEffect["Randomness"] = false; - (double)explosionEffect["RandomnessScalar"] = 1.0; - (glm::vec2)explosionEffect["Velocity"] = glm::vec2(1, 1); - (bool)explosionEffect["ColorByDistance"] = false; - (bool)explosionEffect["ExponentialAccelaration"] = false; - lifeTime["Lifetime"] = 2.0; - } - - - auto t = e.Player.FirstChildByName("PlayerModel"); - auto playerEntityModel = t["Model"]; - auto playerEntityAnimation = t["Animation"]; - auto playerEntityTransform = t["Transform"]; - //auto playerEntityModel = e.Player["PlayerModel"]; -// ComponentWrapper& playerEntityModel = e.Player.FirstChildByName("PlayerModel"); + //current components for player that we need + auto playerModelEWrapper = e.Player.FirstChildByName("PlayerModel"); + auto playerEntityModel = playerModelEWrapper["Model"]; + auto playerEntityAnimation = playerModelEWrapper["Animation"]; + auto playerEntityTransform = playerModelEWrapper["Transform"]; + //create new entity with those components + //graphics bug: model must have an animationcomponent to be able to display it auto newEntity = m_World->CreateEntity(); ComponentWrapper& newEntityModel = m_World->AttachComponent(newEntity, "Model"); ComponentWrapper& newAnimationModel = m_World->AttachComponent(newEntity, "Animation"); ComponentWrapper& newTransformModel = m_World->AttachComponent(newEntity, "Transform"); - - //ComponentWrapper& playerEntityModel = m_World->GetComponent(e.PlayerID, "PlayerModel"); playerEntityModel.Copy(newEntityModel); playerEntityAnimation.Copy(newAnimationModel); playerEntityTransform.Copy(newTransformModel); - newAnimationModel["Speed"] = (double)0.0; - auto t2 = e.Player["Transform"]["Position"]; - newTransformModel["Position"] = (glm::vec3)e.Player["Transform"]["Position"]; - newTransformModel["Scale"] = glm::vec3(5, 5, 5); - //auto tr = m_World->GetComponent(newEntityModel.EntityID, "Transform"); - //tr["Position"] = glm::vec3(0, 50, 0); - ComponentWrapper& explosionEffect = m_World->AttachComponent(newEntityModel.EntityID, "ExplosionEffect"); - ComponentWrapper& lifeTime = m_World->AttachComponent(newEntityModel.EntityID, "Lifetime"); + //change the animation speed and make sure the explosioneffect spawns at the players position + newAnimationModel["Speed"] = (double)0.0; + newEntityModel["Color"] = glm::vec4(1, 0, 0, 1); + newTransformModel["Position"] = (glm::vec3)e.Player["Transform"]["Position"]; + newTransformModel["Scale"] = glm::vec3(1, 1, 1); + + //add the explosion with a lifetime + ComponentWrapper& explosionEffect = m_World->AttachComponent(newEntity, "ExplosionEffect"); + ComponentWrapper& lifeTime = m_World->AttachComponent(newEntity, "Lifetime"); (glm::vec3)explosionEffect["ExplosionOrigin"] = (glm::vec3)e.Player["Transform"]["Position"]; - //explosionEffect["ExplosionOrigin"] = e.Player["Transform"]["Position"]; (double)explosionEffect["TimeSinceDeath"] = 0.0; (double)explosionEffect["ExplosionDuration"] = 8.0; - explosionEffect["EndColor"] = glm::vec4(0, 0, 0, 1); + (glm::vec4)explosionEffect["EndColor"] = glm::vec4(0, 0, 0, 1); (bool)explosionEffect["Randomness"] = false; (double)explosionEffect["RandomnessScalar"] = 1.0; - (glm::vec2)explosionEffect["Velocity"] = glm::vec2(1, 1); + (glm::vec2)explosionEffect["Velocity"] = glm::vec2(0.1f, 0.1f); (bool)explosionEffect["ColorByDistance"] = false; (bool)explosionEffect["ExponentialAccelaration"] = false; - lifeTime["Lifetime"] = 8.0; + lifeTime["Lifetime"] = (double)8.0; + //create a camera (with lifetime) slightly above the player and look down at the player + auto cameraEntity = m_World->CreateEntity(); + ComponentWrapper& thirdPersonCameraLifeTime = m_World->AttachComponent(cameraEntity, "Lifetime"); + ComponentWrapper& thirdPersonCamera = m_World->AttachComponent(cameraEntity, "Camera"); + ComponentWrapper& thirdPersonCameraTransform = m_World->AttachComponent(cameraEntity, "Transform"); + auto pos = (glm::vec3)e.Player["Transform"]["Position"]; + pos.y += 10.0f; + thirdPersonCameraTransform["Position"] = (glm::vec3)pos; + //http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/ + thirdPersonCameraTransform["Orientation"] = glm::vec3(-0.7f, 1.46f, 0.8f); + thirdPersonCamera["FOV"] = 120.0; + thirdPersonCamera["NearClip"] = 0.1; + thirdPersonCamera["FarClip"] = 10000.0; + thirdPersonCameraLifeTime["Lifetime"] = (double)1.0; + + //set 3rd person camera + Events::SetCamera eSetCamera; + eSetCamera.CameraEntity = EntityWrapper(m_World, cameraEntity); + m_EventBroker->Publish(eSetCamera); + + //on deathanim done -> del entity + m_World->DeleteEntity(e.Player.ID); return true; } -//on deathanim done -> del entity diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index 6a434a9a..280b8d14 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -54,36 +54,32 @@ GameHealthSystemTest::GameHealthSystemTest() //The Test //create entity which has transform,player,model,health in it. i.e. is a player EntityID playerID = m_World->CreateEntity(); - ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform"); - ComponentWrapper model = m_World->AttachComponent(playerID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere ComponentWrapper player = m_World->AttachComponent(playerID, "Player"); ComponentWrapper health = m_World->AttachComponent(playerID, "Health"); healthsID = playerID; - double currentHealth = (double)m_World->GetComponent(healthsID, "Health")["Health"]; + + EntityID playerID2 = m_World->CreateEntity(); + ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player"); + ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health"); //heal player with 40 Events::PlayerHealthPickup e3; e3.HealthAmount = 40.0f; - e3.PlayerHealedID = healthsID; + e3.Player = EntityWrapper(m_World, player.EntityID); m_EventBroker->Publish(e3); + //damage player with 50 Events::PlayerDamage e; e.Damage = 50.0f; -// e.PlayerDamagedID = healthsID; + e.Player = EntityWrapper(m_World, player.EntityID); m_EventBroker->Publish(e); + //heal some other player with 40 Events::PlayerHealthPickup e2; e2.HealthAmount = 40.0f; - e2.PlayerHealedID = healthsID + 1; + e2.Player = EntityWrapper(m_World, player2.EntityID); m_EventBroker->Publish(e2); - EntityID playerID2 = m_World->CreateEntity(); - ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform"); - ComponentWrapper model2 = m_World->AttachComponent(playerID2, "Model"); - model2["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere - ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player"); - ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health"); //END TEST } From 51075aefc819edd09a0737f056f517970718124b Mon Sep 17 00:00:00 2001 From: viktorljung Date: Mon, 1 Feb 2016 10:24:50 +0100 Subject: [PATCH 024/131] Model that has animations is now visible when it does not play an animation (T-pose) --- include/Engine/Rendering/Skeleton.h | 2 +- resources/Schema/Entities/AnimatedArmy.xml | 4 +- resources/Schema/Entities/AnimationTests.xml | 73 ++++++++++++-------- resources/Schema/Entities/RenderingWorld.xml | 6 +- src/Engine/Rendering/DrawFinalPass.cpp | 14 ++-- src/Engine/Rendering/PickingPass.cpp | 2 +- src/Engine/Rendering/Skeleton.cpp | 23 ++++-- 7 files changed, 72 insertions(+), 52 deletions(-) diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 15749b85..dca78e4c 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -83,7 +83,7 @@ public: int GetBoneID(std::string name); const Animation* GetAnimation(std::string name); - std::vector GetFrameBones(const Animation& animation, double time, bool noRootMotion = false); + std::vector GetFrameBones(const Animation* animation, double time, bool noRootMotion = false); void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); diff --git a/resources/Schema/Entities/AnimatedArmy.xml b/resources/Schema/Entities/AnimatedArmy.xml index b711a0fe..0baa457a 100644 --- a/resources/Schema/Entities/AnimatedArmy.xml +++ b/resources/Schema/Entities/AnimatedArmy.xml @@ -91,7 +91,7 @@ - + @@ -154,7 +154,7 @@ - + diff --git a/resources/Schema/Entities/AnimationTests.xml b/resources/Schema/Entities/AnimationTests.xml index 8a757639..453a18cb 100644 --- a/resources/Schema/Entities/AnimationTests.xml +++ b/resources/Schema/Entities/AnimationTests.xml @@ -12,8 +12,7 @@ Models/Core/UnitPlane.mesh - - + @@ -34,16 +33,15 @@ - Walk - - 0.5 + Run + + 1 Models/AssaultAnimated.mesh - - + @@ -84,34 +82,51 @@ - - - - - - - - - - - R_Foot - - true - - - Models/Core/UnitCube.mesh - - - - - - + + + + + + + Walk + + 1 + + + Models/AssaultAnimated.mesh + + + + + + + + + + + Crouch Walk + + 1 + + + + + + Models/AssaultAnimated.mesh + + + + + + + + diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 20301d5f..1ac95a3b 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -52,11 +52,11 @@ - 0.65990006923675537 + Models/Core/UnitHexagon.mesh @@ -161,7 +161,7 @@ - + @@ -308,7 +308,7 @@ - Models/Assault.mesh + Models/AssaultAnimated.mesh diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 72329f5b..b5808117 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -88,11 +88,8 @@ void DrawFinalPass::Draw(RenderScene& scene) GLERROR("DrawFinalPass::ExplosionEffect: 2"); if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (explosionEffectJob->Animation != nullptr) { - std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animation, explosionEffectJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } //TODO: Renderer: bättre textur felhantering samt fler texturer stöd @@ -157,10 +154,9 @@ void DrawFinalPass::Draw(RenderScene& scene) }*/ if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } glBindVertexArray(modelJob->Model->VAO); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 3a7d5bfd..b509bd3d 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -91,7 +91,7 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 8326dea9..150fad7d 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -39,20 +39,29 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name) } } -std::vector Skeleton::GetFrameBones(const Animation& animation, double time, bool noRootMotion /*= false*/) +std::vector Skeleton::GetFrameBones(const Animation* animation, double time, bool noRootMotion /*= false*/) { + if(animation == nullptr) { + std::vector finalMatrices; + for(auto& b : Bones) { + finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); + } + return finalMatrices; + } + + // HACK: Animation wrap-around while (time < 0) { - time += animation.Duration; + time += animation->Duration; } - while (time > animation.Duration) { - time -= animation.Duration; + while (time > animation->Duration) { + time -= animation->Duration; } - int currentKeyframeIndex = GetKeyframe(animation, time); + int currentKeyframeIndex = GetKeyframe(*animation, time); - const Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex]; - const Animation::Keyframe& nextFrame = animation.Keyframes[(currentKeyframeIndex + 1) % animation.Keyframes.size()]; + const Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; + const Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); //auto animationFrame = Animations[""].Keyframes[frame]; From 6ba87d2942c50d7310c9b87da90b88df82ddf359 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Mon, 1 Feb 2016 10:42:23 +0100 Subject: [PATCH 025/131] Fixed, Crash when trying to animate a model that doesn't contain animations --- include/Engine/Rendering/ModelJob.h | 1 + resources/Schema/Entities/AnimationTests.xml | 29 +++++++++++++------- src/Engine/Rendering/AnimationSystem.cpp | 6 ++++ src/Engine/Rendering/DrawFinalPass.cpp | 1 - src/Engine/Rendering/PickingPass.cpp | 3 -- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 21f7c1ca..6598b950 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -42,6 +42,7 @@ struct ModelJob : RenderJob FillColor = fillColor; FillPercentage = fillPercentage; + Skeleton = Model->m_RawModel->m_Skeleton; if (world->HasComponent(Entity, "Animation") && Skeleton != nullptr) { diff --git a/resources/Schema/Entities/AnimationTests.xml b/resources/Schema/Entities/AnimationTests.xml index 453a18cb..578db574 100644 --- a/resources/Schema/Entities/AnimationTests.xml +++ b/resources/Schema/Entities/AnimationTests.xml @@ -12,7 +12,8 @@ Models/Core/UnitPlane.mesh - + + @@ -34,7 +35,7 @@ Run - + 1 @@ -82,9 +83,9 @@ - - - + + + @@ -95,7 +96,7 @@ Walk - + 1 @@ -111,12 +112,9 @@ Crouch Walk - + 1 - - - Models/AssaultAnimated.mesh @@ -127,6 +125,17 @@ + + + + Models/Core/UnitCube.mesh + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index c79b5a36..9c1e68cf 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -15,6 +15,12 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a Skeleton* skeleton = model->m_RawModel->m_Skeleton; + + if(skeleton == nullptr) { + return; + } + + const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]); if(animation != nullptr) { diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index b5808117..66c4d52b 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -156,7 +156,6 @@ void DrawFinalPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } glBindVertexArray(modelJob->Model->VAO); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index b509bd3d..4c39bfc9 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -89,11 +89,8 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (modelJob->Animation != nullptr) { std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } } glBindVertexArray(modelJob->Model->VAO); From 76274c326e66beeae725b6638fd46b1d2814e364 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 1 Feb 2016 13:34:39 +0100 Subject: [PATCH 026/131] Fixed going through flat large triangles. Velocity affected by collision. --- include/Engine/Collision/Collision.h | 2 +- .../Schema/Entities/CollisionSpawnTest.xml | 164 ++++++++++++++ resources/Schema/Entities/GameMap.xml | 1 + .../Schema/Entities/LevelCollisionTest.xml | 4 +- src/Engine/Collision/Collision.cpp | 203 +++++++++--------- src/Engine/Collision/CollisionSystem.cpp | 5 +- 6 files changed, 267 insertions(+), 112 deletions(-) create mode 100644 resources/Schema/Entities/CollisionSpawnTest.xml diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index b8625b73..dfc71496 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -66,7 +66,7 @@ bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, - const glm::vec3& boxVelocity, + glm::vec3& boxVelocity, glm::vec3& outResolutionVector); //Return true if the boxes are intersecting. diff --git a/resources/Schema/Entities/CollisionSpawnTest.xml b/resources/Schema/Entities/CollisionSpawnTest.xml new file mode 100644 index 00000000..331beae6 --- /dev/null +++ b/resources/Schema/Entities/CollisionSpawnTest.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + ../assets/Models/Test/ObstacleCourse.mesh + + + + + + + + + + + 0.46000027656555176 + + + + + + + + + + + + + ../assets/Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml index 97fd3f4d..e206d31f 100644 --- a/resources/Schema/Entities/GameMap.xml +++ b/resources/Schema/Entities/GameMap.xml @@ -8,6 +8,7 @@ + Models\MapVersion1.mesh diff --git a/resources/Schema/Entities/LevelCollisionTest.xml b/resources/Schema/Entities/LevelCollisionTest.xml index ce0fe405..3c3f3bab 100644 --- a/resources/Schema/Entities/LevelCollisionTest.xml +++ b/resources/Schema/Entities/LevelCollisionTest.xml @@ -4,7 +4,7 @@ - ../assets\Models/MapVersion1.obj + ../assets/Models/MapVersion1.mesh @@ -15,7 +15,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh false diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 96d908ff..8134bab7 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -253,8 +253,10 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, const glm::vec2& boxMax, const std::array& triPos, glm::vec2& resolutionDirection, - float& resolutionDistance) + float& resolutionDistance, + bool& pushedFromTriNormal) { + pushedFromTriNormal = false; resolutionDistance = INFINITY; //Project along box normals (coordinate axes, since it's axis-aligned). for (int ax = 0; ax < 2; ++ax) { @@ -264,14 +266,20 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, minTri = std::min(t[ax], minTri); maxTri = std::max(t[ax], maxTri); } - if (minTri > boxMax[ax] || maxTri < boxMin[ax]) { + if (boxMax[ax] <= minTri || maxTri <= boxMin[ax]) { return false; } - float push = std::min(maxTri - boxMin[ax], boxMax[ax] - minTri); - if (push < resolutionDistance) { - resolutionDistance = push; + + //Here: maxBox > minTri && minBox < maxTri + //Left is negative. + float leftRes = minTri - boxMax[ax]; + float rightRes = maxTri - boxMin[ax]; + float push = rightRes < -leftRes ? rightRes : leftRes; + float absPush = abs(push); + if (absPush < resolutionDistance) { + resolutionDistance = absPush; resolutionDirection[1 - ax] = 0.f; - resolutionDirection[ax] = resolutionDistance; + resolutionDirection[ax] = push; } } //Project along triangle normals. @@ -292,7 +300,7 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, continue; } //Rotate edge to a normal. - normal = glm::vec2(-normal.y, normal.x); + normal = glm::normalize(glm::vec2(-normal.y, normal.x)); //Project triangle onto the normal. float minTri = INFINITY; float maxTri = -INFINITY; @@ -309,14 +317,20 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, minBox = std::min(dot, minBox); maxBox = std::max(dot, maxBox); } - if (maxBox < minTri || minBox > maxTri) { + if (maxBox <= minTri || maxTri <= minBox) { return false; } + //Here: maxBox > minTri && minBox < maxTri - float push = std::min(maxTri - minBox, maxBox - minTri); - if (push < resolutionDistance) { - resolutionDistance = push; - resolutionDirection = resolutionDistance * glm::normalize(normal); + //Left is negative. + float leftRes = minTri - maxBox; + float rightRes = maxTri - minBox; + float push = rightRes < -leftRes ? rightRes : leftRes; + float absPush = abs(push); + if (absPush < resolutionDistance) { + resolutionDistance = absPush; + resolutionDirection = push * normal; + pushedFromTriNormal = true; } } return true; @@ -326,18 +340,26 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, constexpr std::array, 3> dimensionPairs({ std::pair(0, 2), std::pair(0, 1), std::pair(1, 2) }); bool AABBvsTriangle(const AABB& box, - const std::array& triPos, - const glm::vec3& boxVelocity, + const std::array& triPos, + const glm::vec3& wantDirection, + glm::vec3& boxVelocity, glm::vec3& outVector) { //Check so we don't have a zero area triangle when calculating the normal. //Also, don't check a triangle facing away from the player. //Less checks, and we should be able to walk out from models if we are trapped inside. glm::vec3 triNormal = glm::cross(triPos[1] - triPos[0], triPos[2] - triPos[0]); - if (!vectorHasLength(triNormal) || glm::dot(triNormal, boxVelocity) > 0) { + if (!vectorHasLength(triNormal) || (glm::dot(triNormal, boxVelocity) > 0) && vectorHasLength(boxVelocity)) { return false; } + enum BoxTriResolveCase + { + Vertex, + Line, + Corner + } resolveCase; + const glm::vec3& origin = box.Origin(); const glm::vec3& half = box.HalfSize(); const glm::vec3& min = box.MinCorner(); @@ -358,14 +380,16 @@ bool AABBvsTriangle(const AABB& box, glm::vec2 boxMax(max[dim.first], max[dim.second]); glm::vec2 resolutionVector; float resolutionDist; + bool pushedFromTriangleLine; //if projections don't overlap, return false. - if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector, resolutionDist)) { + if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector, resolutionDist, pushedFromTriangleLine)) { return false; } else if (resolutionDist < minimumTranslation) { outVector = glm::vec3(0.f); outVector[dim.first] = resolutionVector.x; outVector[dim.second] = resolutionVector.y; minimumTranslation = resolutionDist; + resolveCase = pushedFromTriangleLine ? Line : Vertex; } } @@ -384,6 +408,56 @@ bool AABBvsTriangle(const AABB& box, glm::vec3 cornerResolution = (1+t) * diagonal; if (glm::length(cornerResolution) < minimumTranslation) { outVector = cornerResolution; + resolveCase = Corner; + } + + bool groundCollision = triNormal.y > 0.5f; + //ImGui::Text(groundCollision ? "Ground" : "Slope"); + + glm::vec3 projNorm; + switch (resolveCase) { + case Vertex: + { + int maxD = 0; + float maxResolution = 0.f; + for (int d = 0; d < 3; ++d) { + float resolve = glm::abs(outVector[d]); + if (resolve > maxResolution) { + maxResolution = resolve; + maxD = d; + } + } + boxVelocity[maxD] = 0.f; + return true; + } + case Line: + projNorm = glm::normalize(outVector); + break; + case Corner: + projNorm = triNormal; + break; + default: + break; + } + + //Project the velocity onto the normal of the hit line/face. + //w = v - *n, |n|==1. + boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; + if (groundCollision) { + float len = glm::length2(boxVelocity); + if (len > 0.0001f) { + len = glm::sqrt(len); + boxVelocity = len * glm::normalize(wantDirection); + } + + len = glm::length(outVector); + float ang = glm::half_pi() - glm::acos(outVector.y / len); + if (len > 0.0000001f && ang > 0.0000001f) { + //ImGui::Text("ang=%f, len=%f, acos=%f, outY=%f", ang, len, glm::acos(outVector.y / len), outVector.y); + outVector.x = 0; + outVector.y = len / glm::sin(ang); + outVector.z = 0; + } } return true; } @@ -392,15 +466,16 @@ bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, - const glm::vec3& boxVelocity, - glm::vec3& outResolutionVector, - int startIndex, - int recursiveDepth) + glm::vec3& boxVelocity, + glm::vec3& outResolutionVector) { bool hit = false; AABB newBox = box; outResolutionVector = glm::vec3(0.f); + glm::vec3 wantDirection(boxVelocity); + wantDirection.y = 0; + wantDirection = glm::normalize(wantDirection); for (int i = 0; i < modelIndices.size(); ) { std::array triVertices = { Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), @@ -408,101 +483,15 @@ bool AABBvsTriangles(const AABB& box, Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) }; glm::vec3 outVec; - if (AABBvsTriangle(newBox, triVertices, boxVelocity, outVec)) { + if (AABBvsTriangle(newBox, triVertices, wantDirection, boxVelocity, outVec)) { hit = true; outResolutionVector += outVec; newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); } } - //outResolutionVector = glm::vec3(INFINITY); - //if (recursiveDepth > 2) { - // return true; - //} - //for (int i = startIndex; i < modelIndices.size(); ) { - // std::array triVertices = { - // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), - // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), - // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) - // }; - // glm::vec3 outVec; - // if (AABBvsTriangle(box, triVertices, boxVelocity, outVec) && glm::length2(outVec) < glm::length2(outResolutionVector)) { - // hit = true; - // glm::vec3 potentialResolution = outVec; - // const AABB& resolvedBox = AABB::FromOriginSize(box.Origin() + potentialResolution, box.Size()); - // if (AABBvsTriangles(resolvedBox, modelVertices, modelIndices, modelMatrix, boxVelocity, outVec, i, recursiveDepth+1)) { - // potentialResolution += outVec; - // if (glm::length2(potentialResolution) > glm::length2(outResolutionVector)) { - // continue; - // } - // } - // outResolutionVector = potentialResolution; - // } - //} - - //outResolutionVector = glm::vec3(INFINITY); - //std::stack testBoxes; - //std::stack resolveIndices; - //std::stack resolveVectors; - //resolveVectors.push(glm::vec3(0.f)); - //resolveIndices.push(0); - //testBoxes.push(box); - //do { - // int i = resolveIndices.top(); - // resolveIndices.pop(); - // while (i < modelIndices.size()) { - // std::array triVertices = { - // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), - // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), - // Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) - // }; - // glm::vec3 outVec; - // bool test = AABBvsTriangle(testBoxes.top(), triVertices, outVec); - // if (test) { - // hit = true; - // //emplace? - // resolveIndices.push(i); - // testBoxes.push(AABB::FromOriginSize(box.Origin() + outVec, box.Size())); - // resolveVectors.top() += outVec; - // } - // } - // testBoxes.pop(); - // resolveVectors.push(glm::vec3(0.f)); - //} while (!resolveIndices.empty()); - //if (hit) { - // if (!resolveVectors.empty()) { - // while (!resolveVectors.empty()) { - // if (glm::length2(resolveVectors.top()) < glm::length2(outResolutionVector)) { - // outResolutionVector = resolveVectors.top(); - // } - // resolveVectors.pop(); - // } - // } else { - // //TODO: This won't happen. - // ImGui::Text("Collision, but not resolved."); - // } - // return true; - //} return hit; } -bool AABBvsTriangles(const AABB& box, - const std::vector& modelVertices, - const std::vector& modelIndices, - const glm::mat4& modelMatrix, - const glm::vec3& boxVelocity, - glm::vec3& outResolutionVector) -{ - return AABBvsTriangles( - box, - modelVertices, - modelIndices, - modelMatrix, - boxVelocity, - outResolutionVector, - 0, - 0 - ); -} bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon) { diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 8d43534c..81e76410 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -54,9 +54,10 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c glm::mat4 modelMatrix = glm::translate(absPosition) * glm::toMat4(absOrientation) * glm::scale(absScale); glm::vec3 resolutionVector; - if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, (glm::vec3&)cPhysics["Velocity"], resolutionVector)) { + glm::vec3 newVelocity = (glm::vec3)cPhysics["Velocity"]; + if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, newVelocity, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; - cPhysics["Velocity"] = glm::vec3(0, 0, 0); + cPhysics["Velocity"] = newVelocity; } } } From 25b3c02d29bb8fdc4161867ad42899c4c9229416 Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 1 Feb 2016 14:32:01 +0100 Subject: [PATCH 027/131] Adding sounds for: jump, walk, shoot --- assets | 2 +- include/Engine/Sound/SoundSystem.h | 39 ++++- resources/Schema/Entities/aim_rays.xml | 210 +++++++++++++++++++++++++ src/Engine/Sound/SoundSystem.cpp | 129 ++++++++++++++- 4 files changed, 368 insertions(+), 12 deletions(-) create mode 100644 resources/Schema/Entities/aim_rays.xml diff --git a/assets b/assets index e4dc9529..9b4f9ab2 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e4dc9529f2178d373808ddf487165fa50a641a78 +Subproject commit 9b4f9ab2e67fc09863f35b33bb0a61ce75ef6aa8 diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index b9cc2589..5d57d5b6 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -20,6 +20,10 @@ #include "Sound/EStopSound.h" #include "Sound/ESetBGMGain.h" #include "Sound/ESetSFXGain.h" +#include "Core/EShoot.h" +#include "Core/EPlayerSpawned.h" +#include "Input/EInputCommand.h" +#include "Core/ECaptured.h" enum class SoundType { SFX, @@ -55,18 +59,24 @@ private: // Logic void initOpenAL(); - void updateEmitters(double dt); - void updateListener(double dt); - void deleteInactiveEmitters(); void addNewEmitters(double dt); - Source* createSource(std::string filePath); - void playSound(Source* source); - void stopSound(Source* source); + void updateEmitters(double dt); + void deleteInactiveEmitters(); void stopEmitters(); + void updateListener(double dt); + Source* createSource(std::string filePath); ALenum getSourceState(ALuint source); void setGain(Source* source, float gain); void setSoundProperties(ALuint source, ComponentWrapper* soundComponent); + // Specific logic + void playSound(Source* source); + void stopSound(Source* source); + void playerDamaged(); + void playerShot(); + void playerJumps(); + void playerStep(double dt); + // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; ALCcontext* m_ALCcontext = nullptr; @@ -75,9 +85,14 @@ private: World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; std::unordered_map m_Sources; - float m_BGMVolumeChannel = 1.0f; + float m_BGMVolumeChannel = 1.f; float m_SFXVolumeChannel = 1.f; bool m_EditorEnabled = false; + const double m_PlayerFootstepInterval = 0.5; + double m_TimeSinceLastFootstep = 0; + // TEMP + EntityID m_LocalPlayer = EntityID_Invalid; + bool m_LeftFoot = false; // Events EventRelay m_EPlaySoundOnEntity; @@ -96,6 +111,16 @@ private: bool OnSetBGMGain(const Events::SetBGMGain &e); // Not tested EventRelay m_ESetSFXGain; bool OnSetSFXGain(const Events::SetSFXGain &e); // Not tested + + EventRelay m_EShoot; + bool OnShoot(const Events::Shoot &e); + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(const Events::PlayerSpawned &e); + EventRelay m_EInputCommand; + bool OnInputCommand(const Events::InputCommand &e); + EventRelay m_ECaptured; + bool OnCaptured(const Events::Captured &e); + }; #endif \ No newline at end of file diff --git a/resources/Schema/Entities/aim_rays.xml b/resources/Schema/Entities/aim_rays.xml new file mode 100644 index 00000000..c488ca51 --- /dev/null +++ b/resources/Schema/Entities/aim_rays.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index d0887c05..dbabb32d 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -20,6 +20,10 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundSystem::OnContinueSound); EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundSystem::OnSetBGMGain); EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundSystem::OnSetSFXGain); + EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundSystem::OnShoot); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); } SoundSystem::~SoundSystem() @@ -48,19 +52,20 @@ void SoundSystem::stopEmitters() } void SoundSystem::Update(double dt) -{ +{ m_EventBroker->Process(); + playerStep(dt); addNewEmitters(dt); // can be optimized with "EEntityCreated" deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" - updateEmitters( dt); - updateListener( dt); + updateEmitters(dt); + updateListener(dt); } void SoundSystem::deleteInactiveEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end();) { - if (m_World->ValidEntity(it->first) + if (m_World->ValidEntity(it->first) && m_World->HasComponent(it->first, "SoundEmitter")) { if (getSourceState(it->second->ALsource) != AL_STOPPED) { // Nothing to see here, move along @@ -70,6 +75,7 @@ void SoundSystem::deleteInactiveEmitters() // Sound has been stopped / finished playing. alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); + m_World->DeleteEntity(it->first); delete it->second; it = m_Sources.erase(it); } @@ -174,6 +180,58 @@ void SoundSystem::stopSound(Source* source) alSourceStop(source->ALsource); } +void SoundSystem::playerDamaged() +{ + +} + +void SoundSystem::playerShot() +{ } + +void SoundSystem::playerJumps() +{ + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; + if (vel.y > 1) { + Source* source = createSource("Audio/jump/jump1.wav"); + auto emitterID = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(emitterID, "Transform"); + m_World->AttachComponent(emitterID, "SoundEmitter"); + source->Type = SoundType::SFX; + m_Sources[emitterID] = source; + playSound(source); + } +} + +void SoundSystem::playerStep(double dt) +{ + if (m_LocalPlayer == EntityID_Invalid) { + return; + } + m_TimeSinceLastFootstep += dt; + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; + float playerSpeed = glm::length(vel); + bool isAirborne = vel.y != 0; + if (playerSpeed > 1 && !isAirborne) { + // Player is walking + if (m_TimeSinceLastFootstep > m_PlayerFootstepInterval) { + // Create footstep sound + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + Events::PlaySoundOnEntity e; + e.EmitterID = child; + if (m_LeftFoot) { + e.FilePath = "Audio/footstep/footstep2.wav"; + } else { + e.FilePath = "Audio/footstep/footstep3.wav"; + } + m_LeftFoot = !m_LeftFoot; + m_EventBroker->Publish(e); + m_TimeSinceLastFootstep = 0; + } + } +} + bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) { Source* source = createSource(e.FilePath); @@ -251,6 +309,69 @@ bool SoundSystem::OnSetSFXGain(const Events::SetSFXGain & e) return true; } +bool SoundSystem::OnShoot(const Events::Shoot & e) +{ + Source* source = createSource("Audio/laser/laser1.wav"); + auto emitterID = m_World->CreateEntity(e.Player.ID); + m_World->AttachComponent(emitterID, "Transform"); + auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); + source->Type = SoundType::SFX; + m_Sources[emitterID] = source; + playSound(source); + return true; +} + +bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned & e) +{ + if (e.PlayerID == -1) { // Local player + m_World->AttachComponent(e.Player.ID, "Listener"); + m_LocalPlayer = e.Player.ID; + EntityID child = m_World->CreateEntity(e.Player.ID); + m_World->AttachComponent(child, "SoundEmitter"); // Temp + m_World->AttachComponent(child, "Transform"); // Temp + Events::PlaySoundOnEntity event; + event.EmitterID = child; + event.FilePath = "Audio/announcer/go.wav"; + m_EventBroker->Publish(event); + } + return true; +} + +bool SoundSystem::OnInputCommand(const Events::InputCommand & e) +{ + if (e.Player.ID == EntityID_Invalid) { + //return false; + } + if (e.Command == "Jump" && e.Value > 0) { + if (e.PlayerID == -1) { // local player + //bool airBorne = ((glm::vec3)m_World->GetComponent(e.Player.ID, "Physics")["Velocity"]).y != 0; + //if (!airBorne) { + playerJumps(); + //} + return true; + } + } + return false; +} + +bool SoundSystem::OnCaptured(const Events::Captured & e) +{ + int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "CapturePoint")["HomePointForTeam"]; + int team = (int)m_World->GetComponent(m_LocalPlayer, "Team")["Team"]; + Events::PlaySoundOnEntity ev; + if (team == homeTeam) { + ev.FilePath = "Audio/announcer/objective_achieved.wav"; + } else { + ev.FilePath = "Audio/announcer/objective_failed.wav"; + } + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + ev.EmitterID = child; + m_EventBroker->Publish(ev); + return false; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector. From 3cfbbbbf54c0365bb0244d1f7289970cea4efddb Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 1 Feb 2016 16:13:48 +0100 Subject: [PATCH 028/131] CollisionSystem now utilizes Octree for collision detection. --- resources/Schema/Components/AABB.xsd | 4 +-- resources/Schema/Entities/GameMap.xml | 3 ++ src/Engine/Collision/CollisionSystem.cpp | 44 +++++++++++------------- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/resources/Schema/Components/AABB.xsd b/resources/Schema/Components/AABB.xsd index daa633a6..7dec510f 100644 --- a/resources/Schema/Components/AABB.xsd +++ b/resources/Schema/Components/AABB.xsd @@ -7,10 +7,10 @@ - Middle point of the bounding box + Middle point of the bounding box, in model space - Size of the bounding box + Size of the bounding box, in model space diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml index e206d31f..4d0a2716 100644 --- a/resources/Schema/Entities/GameMap.xml +++ b/resources/Schema/Entities/GameMap.xml @@ -8,6 +8,9 @@ + + + Models\MapVersion1.mesh diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 382238e7..846d38a7 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -1,6 +1,7 @@ #include "Collision/Collision.h" #include "Collision/CollisionSystem.h" #include "Core/AABB.h" +#include "Rendering/Model.h" void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { @@ -25,33 +26,28 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c continue; } - if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { + if (boxB.Entity.HasComponent("Model") && Collision::AABBVsAABB(boxA, boxB)) { + //Here we know boxB is a entity with Collideable, AABB, and Model. + RawModel* model; + try { + model = ResourceManager::Load(boxB.Entity["Model"]["Resource"]); + } catch (const std::exception&) { + continue; + } + + glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity); + + glm::vec3 newVelocity = (glm::vec3)cPhysics["Velocity"]; + if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, newVelocity, resolutionVector)) { + (glm::vec3&)cTransform["Position"] += resolutionVector; + cPhysics["Velocity"] = newVelocity; + } + } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { + //Enter here if boxB has no Model. (glm::vec3&)cTransform["Position"] += resolutionVector; if (resolutionVector.y > 0) { ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; } } } - - // HACK: Temporarily collide against all collidable models since they're not in the octree yet - //auto otherCollidables = world->GetComponents("Model"); - //for (auto& cModel : *otherCollidables) { - // if (cModel.EntityID == entity) { - // continue; - // } - // if (!world->HasComponent(cModel.EntityID, "Collidable")) { - // continue; - // } - - // auto absPosition = RenderQueueFactory::AbsolutePosition(world, cModel.EntityID); - // auto absOrientation = RenderQueueFactory::AbsoluteOrientation(world, cModel.EntityID); - // auto absScale = RenderQueueFactory::AbsoluteScale(world, cModel.EntityID); - // glm::mat4 modelMatrix = glm::translate(absPosition); // *glm::toMat4(absOrientation) * glm::scale(absScale); - - // auto model = ResourceManager::Load(cModel["Resource"]); - // glm::vec3 resolutionVector; - // if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) { - // (glm::vec3&)cTransform["Position"] += resolutionVector; - // } - //} -} \ No newline at end of file +} From 5a45f778e68498933486e77a5b2108170318938d Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 1 Feb 2016 17:01:58 +0100 Subject: [PATCH 029/131] Fixed so players don't teleport to (NaN, NaN, NaN) on spawning. --- include/Engine/Core/MemoryPool.h | 2 +- src/Engine/Collision/Collision.cpp | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/Engine/Core/MemoryPool.h b/include/Engine/Core/MemoryPool.h index 3a1cc069..f4073294 100644 --- a/include/Engine/Core/MemoryPool.h +++ b/include/Engine/Core/MemoryPool.h @@ -102,7 +102,7 @@ public: m_ExtraMemory.push_back((char*)malloc(m_Stride)); //We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead. if (!DisableMemoryPool::Value) { - LOG_WARNING("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size()); + LOG_DEBUG("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size()); } return m_ExtraMemory.back(); } diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 67ed6c99..a17e347c 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -412,7 +412,6 @@ bool AABBvsTriangle(const AABB& box, } bool groundCollision = triNormal.y > 0.5f; - //ImGui::Text(groundCollision ? "Ground" : "Slope"); glm::vec3 projNorm; switch (resolveCase) { @@ -446,14 +445,12 @@ bool AABBvsTriangle(const AABB& box, if (groundCollision) { float len = glm::length2(boxVelocity); if (len > 0.0001f) { - len = glm::sqrt(len); - boxVelocity = len * glm::normalize(wantDirection); + boxVelocity = glm::sqrt(len) * wantDirection; } len = glm::length(outVector); float ang = glm::half_pi() - glm::acos(outVector.y / len); if (len > 0.0000001f && ang > 0.0000001f) { - //ImGui::Text("ang=%f, len=%f, acos=%f, outY=%f", ang, len, glm::acos(outVector.y / len), outVector.y); outVector.x = 0; outVector.y = len / glm::sin(ang); outVector.z = 0; @@ -475,7 +472,9 @@ bool AABBvsTriangles(const AABB& box, outResolutionVector = glm::vec3(0.f); glm::vec3 wantDirection(boxVelocity); wantDirection.y = 0; - wantDirection = glm::normalize(wantDirection); + if (vectorHasLength(wantDirection)) { + wantDirection = glm::normalize(wantDirection); + } for (int i = 0; i < modelIndices.size(); ) { std::array triVertices = { Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), From 4ccda5ee43950a251449769dbdece96e50c02a88 Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 1 Feb 2016 17:03:41 +0100 Subject: [PATCH 030/131] WIP --- include/Engine/Sound/SoundSystem.h | 11 ++++++++ src/Engine/Sound/SoundSystem.cpp | 43 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 5d57d5b6..4ceed60f 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -24,6 +24,9 @@ #include "Core/EPlayerSpawned.h" #include "Input/EInputCommand.h" #include "Core/ECaptured.h" +#include "Core/EPlayerDamage.h" +#include "Core/EPlayerDeath.h" +#include "Core/EPlayerHealthPickup.h" enum class SoundType { SFX, @@ -120,6 +123,14 @@ private: bool OnInputCommand(const Events::InputCommand &e); EventRelay m_ECaptured; bool OnCaptured(const Events::Captured &e); + EventRelay m_EPlayerDamage; + bool OnPlayerDamage(const Events::PlayerDamage &e); + EventRelay m_EPlayerDeath; + bool OnPlayerDeath(const Events::PlayerDeath &e); + EventRelay m_EPlayerHealthPickup; + bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); + + }; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index dbabb32d..b4de9d31 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -122,6 +122,7 @@ void SoundSystem::updateEmitters(double dt) setSourceVel(it->second->ALsource, velocity); float gain; (bool)(it->second->Type) ? gain = m_SFXVolumeChannel : gain = m_BGMVolumeChannel; + auto emitter = m_World->GetComponent(it->first, "SoundEmitter"); setSoundProperties(it->second->ALsource, &emitter); @@ -372,6 +373,48 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) return false; } +bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) +{ + if (e.Player.ID == m_LocalPlayer) { + Events::PlaySoundOnEntity ev; + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + ev.EmitterID = child; + ev.FilePath = "Audio/hurt/hurt3.wav"; // random between a bunch + m_EventBroker->Publish(ev); + } + return false; +} + +bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) +{ + if (e.PlayerID == m_LocalPlayer) { + Events::PlaySoundOnEntity ev; + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + ev.EmitterID = child; + ev.FilePath = "Audio/die/die2.wav"; // random between a bunch + m_EventBroker->Publish(ev); + } + return false; +} + +bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) +{ + if (e.PlayerHealedID == m_LocalPlayer) { + Events::PlaySoundOnEntity ev; + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + ev.EmitterID = child; + ev.FilePath = "Audio/pickup/pickup2.wav"; + m_EventBroker->Publish(ev); + } + return false; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector. From 4dcf5a8fa089a19e220667c193f0903704139a18 Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 1 Feb 2016 17:05:15 +0100 Subject: [PATCH 031/131] #68 fixed warning. --- src/Engine/Sound/SoundSystem.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index b4de9d31..89798516 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -121,7 +121,11 @@ void SoundSystem::updateEmitters(double dt) setSourcePos(it->second->ALsource, nextPos); setSourceVel(it->second->ALsource, velocity); float gain; - (bool)(it->second->Type) ? gain = m_SFXVolumeChannel : gain = m_BGMVolumeChannel; + if (it->second->Type == SoundType::SFX) { + gain = m_SFXVolumeChannel; + } else if (it->second->Type == SoundType::BGM) { + gain = m_BGMVolumeChannel; + } auto emitter = m_World->GetComponent(it->first, "SoundEmitter"); setSoundProperties(it->second->ALsource, &emitter); From 4d19158600b1a01e19a0decf551e4162c842ba88 Mon Sep 17 00:00:00 2001 From: Teejoon Date: Mon, 1 Feb 2016 18:04:16 +0100 Subject: [PATCH 032/131] No longer need to key frame joins for exporting. Also don't save animations between exports --- tools/MayaExporter/MayaExporter/Export.cpp | 2 + tools/MayaExporter/MayaExporter/Menu.cpp | 2 - tools/MayaExporter/MayaExporter/Skeleton.cpp | 157 +++++++++++++------ tools/MayaExporter/MayaExporter/Skeleton.h | 1 + 4 files changed, 113 insertions(+), 49 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp index d8f1abd4..d516d058 100644 --- a/tools/MayaExporter/MayaExporter/Export.cpp +++ b/tools/MayaExporter/MayaExporter/Export.cpp @@ -109,6 +109,8 @@ bool Export::Materials(std::string pathName) bool Export::Animations(std::string pathName, std::vector animInfo) { + allAnimations.clear(); + allBindPoses.clear(); if (MAnimControl::currentTime().unit() != MTime::kNTSCField) { MGlobal::displayError(MString() + "Please change to 60 FPS under Preferences/Settings!"); diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 9cc6de91..02810018 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -60,8 +60,6 @@ Menu::Menu(QDialog* dialog) m_ExportPath = new QLineEdit; m_FileDialog = new QFileDialog; - QString tmpPath("C:/Users/Nickelodion/Desktop/workspace/tacticalZ/assets/models/"); - m_ExportPath->setText(tmpPath); QLabel* exportLabel = new QLabel; exportLabel->setText("Export Path:"); QLabel* nameLabel = new QLabel; diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index c30311b8..780466fa 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -74,67 +74,130 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e returnData.nameLength = animationName.size() + 1; returnData.Duration = (endFrame - startFrame) * oneDivSixty; + std::map, 4>> joinCheckMap; + std::map exportJoint; + MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); - while (!jointIt.isDone()) + for (unsigned int i = startFrame; i <= endFrame; i++) { - m_Hierarchy.push_back(jointIt.item()); - - MFnDependencyNode depNode(jointIt.item()); - for (int i = 0; i < 9; i++) + MAnimControl::setCurrentTime(MTime(i, MTime::kNTSCField)); + while (!jointIt.isDone()) { - MStatus tmp; - MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp); + m_Hierarchy.push_back(jointIt.item()); - MPlugArray connections; - plug.connectedTo(connections, true, false, 0); - for (int j = 0; j != connections.length(); j++) { - MObject connected = connections[j].node(); + MFnTransform MayaJoint(jointIt.item()); + MMatrix transformationMatrix = MayaJoint.transformationMatrix(); - if (connected.hasFn(MFn::kAnimCurve)) { + if (i == startFrame) + { + double doubleMat[4][4]; + transformationMatrix.get(doubleMat); - MFnAnimCurve jointAnim(connected); + joinCheckMap[MayaJoint.name().asChar()][0][0] = doubleMat[0][0]; + joinCheckMap[MayaJoint.name().asChar()][0][1] = doubleMat[0][1]; + joinCheckMap[MayaJoint.name().asChar()][0][2] = doubleMat[0][2]; + joinCheckMap[MayaJoint.name().asChar()][0][3] = doubleMat[0][3]; + joinCheckMap[MayaJoint.name().asChar()][1][0] = doubleMat[1][0]; + joinCheckMap[MayaJoint.name().asChar()][1][1] = doubleMat[1][1]; + joinCheckMap[MayaJoint.name().asChar()][1][2] = doubleMat[1][2]; + joinCheckMap[MayaJoint.name().asChar()][1][3] = doubleMat[1][3]; + joinCheckMap[MayaJoint.name().asChar()][2][0] = doubleMat[2][0]; + joinCheckMap[MayaJoint.name().asChar()][2][1] = doubleMat[2][1]; + joinCheckMap[MayaJoint.name().asChar()][2][2] = doubleMat[2][2]; + joinCheckMap[MayaJoint.name().asChar()][2][3] = doubleMat[2][3]; + joinCheckMap[MayaJoint.name().asChar()][3][0] = doubleMat[3][0]; + joinCheckMap[MayaJoint.name().asChar()][3][1] = doubleMat[3][1]; + joinCheckMap[MayaJoint.name().asChar()][3][2] = doubleMat[3][2]; + joinCheckMap[MayaJoint.name().asChar()][3][3] = doubleMat[3][3]; - unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp); + exportJoint[MayaJoint.name().asChar()] = false; + } + else if(!exportJoint[MayaJoint.name().asChar()])//!exportJoint[MayaJoint.name().asChar()]) + { + double doubleMat[4][4]; - if (tmp == MStatus::kFailure) - MGlobal::displayInfo(MString() + "Fail :c"); + doubleMat[0][0] = joinCheckMap[MayaJoint.name().asChar()][0][0]; + doubleMat[0][1] = joinCheckMap[MayaJoint.name().asChar()][0][1]; + doubleMat[0][2] = joinCheckMap[MayaJoint.name().asChar()][0][2]; + doubleMat[0][3] = joinCheckMap[MayaJoint.name().asChar()][0][3]; + doubleMat[1][0] = joinCheckMap[MayaJoint.name().asChar()][1][0]; + doubleMat[1][1] = joinCheckMap[MayaJoint.name().asChar()][1][1]; + doubleMat[1][2] = joinCheckMap[MayaJoint.name().asChar()][1][2]; + doubleMat[1][3] = joinCheckMap[MayaJoint.name().asChar()][1][3]; + doubleMat[2][0] = joinCheckMap[MayaJoint.name().asChar()][2][0]; + doubleMat[2][1] = joinCheckMap[MayaJoint.name().asChar()][2][1]; + doubleMat[2][2] = joinCheckMap[MayaJoint.name().asChar()][2][2]; + doubleMat[2][3] = joinCheckMap[MayaJoint.name().asChar()][2][3]; + doubleMat[3][0] = joinCheckMap[MayaJoint.name().asChar()][3][0]; + doubleMat[3][1] = joinCheckMap[MayaJoint.name().asChar()][3][1]; + doubleMat[3][2] = joinCheckMap[MayaJoint.name().asChar()][3][2]; + doubleMat[3][3] = joinCheckMap[MayaJoint.name().asChar()][3][3]; - if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) { - animatedJoints.push_back(jointIt.item()); - i = 9; - break; - } - - unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField)); - MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex); - - if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) { - animatedJoints.push_back(jointIt.item()); - i = 9; - break; - } - - MFnTransform MayaJoint(jointIt.item()); - - MPlug BindPose = MayaJoint.findPlug("bindPose"); - MDataHandle DataHandle; - BindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix BindPoseMatrix = MartixFn.matrix(); - - if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix())) - { - MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya"); - } + MMatrix tmp(doubleMat); + if (!tmp.isEquivalent(transformationMatrix)) { + MGlobal::displayInfo(MString() + MayaJoint.name() + " is exported"); + exportJoint[MayaJoint.name().asChar()] = true; + animatedJoints.push_back(MayaJoint.object()); } } - } - jointIt.next(); + /*for (int i = 0; i < 9; i++) + { + MStatus tmp; + MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp); + + MPlugArray connections; + plug.connectedTo(connections, true, false, 0); + for (int j = 0; j != connections.length(); j++) { + MObject connected = connections[j].node(); + + if (connected.hasFn(MFn::kAnimCurve)) { + + MFnAnimCurve jointAnim(connected); + + unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp); + + if (tmp == MStatus::kFailure) + MGlobal::displayInfo(MString() + "Fail :c"); + + if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) { + animatedJoints.push_back(jointIt.item()); + i = 9; + break; + } + + unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField)); + MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex); + + if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) { + animatedJoints.push_back(jointIt.item()); + i = 9; + break; + } + + MFnTransform MayaJoint(jointIt.item()); + + MPlug BindPose = MayaJoint.findPlug("bindPose"); + MDataHandle DataHandle; + BindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix BindPoseMatrix = MartixFn.matrix(); + + if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix())) + { + MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya"); + } + } + } + }*/ + + jointIt.next(); + } + jointIt.reset(); } int currentFrame = startFrame; - while (currentFrame != endFrame + 1) { // ANDREAS + while (currentFrame <= endFrame) { // ANDREAS Animation::Keyframe thisKeyFrame; thisKeyFrame.Index = currentFrame - startFrame; thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; @@ -219,7 +282,7 @@ std::vector Skeleton::GetBindPoses() MFnTransform MayaJoint(jointIt.currentItem()); BindPoseSkeletonNode::BindPoseJoint NewJoint; - if (MFnDependencyNode(MayaJoint.parent(0)).name() == "world") { + if (MFnDependencyNode(MayaJoint.parent(0)).object().apiType() != MFn::kJoint) { if (SkeletonStorage.Joints.size() != 0) { m_AllSkeletons.push_back(SkeletonStorage); diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index 6a288c8a..9033441d 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "MayaIncludes.h" #include "OutputData.h" From 30b1dab7640406c180de7f2ce5ef6c53de0319b4 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 1 Feb 2016 18:06:28 +0100 Subject: [PATCH 033/131] More efficient collision resolution case + comments. --- src/Engine/Collision/Collision.cpp | 43 +++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index a17e347c..edb6c9a9 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -336,6 +336,11 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, return true; } +constexpr float SlopeConstant(float degrees) +{ + return (1.0 - degrees / 90.f); +} + //An array containing 3 int pairs { 0, 2 }, { 0, 1 }, { 1, 2 } constexpr std::array, 3> dimensionPairs({ std::pair(0, 2), std::pair(0, 1), std::pair(1, 2) }); @@ -355,9 +360,11 @@ bool AABBvsTriangle(const AABB& box, enum BoxTriResolveCase { - Vertex, - Line, - Corner + ResolveDimX, + ResolveDimY, + ResolveDimZ, + Line, //Box edge colliding with triangle line. + Corner //Box corner colliding with the triangle face. } resolveCase; const glm::vec3& origin = box.Origin(); @@ -389,7 +396,9 @@ bool AABBvsTriangle(const AABB& box, outVector[dim.first] = resolutionVector.x; outVector[dim.second] = resolutionVector.y; minimumTranslation = resolutionDist; - resolveCase = pushedFromTriangleLine ? Line : Vertex; + //If we pushed away from triangle line (edge), or if we + //move the player along one coordinate axis (pick the dimension that isn't zero). + resolveCase = pushedFromTriangleLine ? Line : static_cast((abs(outVector[dim.first]) < 0.0001f) ? dim.second : dim.first); } } @@ -411,22 +420,15 @@ bool AABBvsTriangle(const AABB& box, resolveCase = Corner; } - bool groundCollision = triNormal.y > 0.5f; - glm::vec3 projNorm; switch (resolveCase) { - case Vertex: + case ResolveDimX: + case ResolveDimY: + case ResolveDimZ: { - int maxD = 0; - float maxResolution = 0.f; - for (int d = 0; d < 3; ++d) { - float resolve = glm::abs(outVector[d]); - if (resolve > maxResolution) { - maxResolution = resolve; - maxD = d; - } - } - boxVelocity[maxD] = 0.f; + //If we get here, the resolution is along one coordinate axis. + //set velocity to 0 in that dimension. + boxVelocity[resolveCase] = 0.f; return true; } case Line: @@ -442,12 +444,17 @@ bool AABBvsTriangle(const AABB& box, //Project the velocity onto the normal of the hit line/face. //w = v - *n, |n|==1. boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; - if (groundCollision) { + //If the collision was not on steep wall or similarly (e.g. walking on the ground), do special treatment. + //Magic value that makes condition correspond to: + //if the angle between horizon and the collision surface is less than 45 degrees. + if (projNorm.y > SlopeConstant(45.0f)) { + //Make sure the player keeps moving in their desired direction, just slower. float len = glm::length2(boxVelocity); if (len > 0.0001f) { boxVelocity = glm::sqrt(len) * wantDirection; } + //Ensure that the player always is moved upwards, instead of sliding down. len = glm::length(outVector); float ang = glm::half_pi() - glm::acos(outVector.y / len); if (len > 0.0000001f && ang > 0.0000001f) { From 9573958a86f35ab3f950ea45eb8d5a167fa92539 Mon Sep 17 00:00:00 2001 From: Teejoon Date: Tue, 2 Feb 2016 10:19:00 +0100 Subject: [PATCH 034/131] Fixed Git's shitty merge in Skeleton.cpp and The Exporter now Exports meshes with and without skins --- tools/MayaExporter/MayaExporter/Mesh.cpp | 10 +++--- tools/MayaExporter/MayaExporter/Mesh.h | 20 ++++++++--- tools/MayaExporter/MayaExporter/Skeleton.cpp | 38 ++++++++++---------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 43b76d55..01737683 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -108,7 +108,6 @@ Mesh MeshClass::GetMeshData(MObjectArray object) MFnDependencyNode thisNode(node); MPlugArray connections; thisNode.findPlug("inMesh").connectedTo(connections, true, true); - bool hasSkin = false; MPlug weightList, weights; MObject weightListObject; for (unsigned int i = 0; i < connections.length(); i++) { @@ -117,7 +116,7 @@ Mesh MeshClass::GetMeshData(MObjectArray object) weightList = skinCluster.findPlug("weightList", &status); weightListObject = weightList.attribute(); weights = skinCluster.findPlug("weights"); - hasSkin = true; + newMesh.hasSkin = true; break; } } @@ -301,7 +300,8 @@ Mesh MeshClass::GetMeshData(MObjectArray object) thisVertex.Uv[1] = UV[1]; - if (hasSkin) { + if (newMesh.hasSkin) { + thisVertex.useWeights = true; float totalWeight = 0.0f; unsigned int totalBones = 0; MIntArray jointIDs /* ??? */; @@ -319,7 +319,9 @@ Mesh MeshClass::GetMeshData(MObjectArray object) for (unsigned int i = 0; i < 4; i++) { thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight; } - } + } else { + thisVertex.useWeights = false; + } //float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3]; //if (totalWeight > 0.0001f) { diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index 11f6bcf8..affc4320 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -11,6 +11,7 @@ class VertexLayout : public OutputData { public: + bool useWeights = true; float Pos[3]{ 0 }; float Normal[3]{ 0 }; float Tangent[3]{ 0 }; @@ -26,8 +27,10 @@ public: out.write((char*)&Tangent, sizeof(float) * 3); out.write((char*)&BiNormal, sizeof(float) * 3); out.write((char*)&Uv, sizeof(float) * 2); - out.write((char*)&BoneIndices, sizeof(float) * 4); - out.write((char*)&BoneWeights, sizeof(float) * 4); + if (useWeights) { + out.write((char*)&BoneIndices, sizeof(float) * 4); + out.write((char*)&BoneWeights, sizeof(float) * 4); + } } virtual void WriteASCII(std::ostream& out) const @@ -37,8 +40,10 @@ public: out << Tangent[0] << " " << Tangent[1] << " " << Tangent[2] << endl; out << BiNormal[0] << " " << BiNormal[1] << " " << BiNormal[2] << endl; out << Uv[0] << " " << Uv[1] << endl; - out << BoneIndices[0] << " " << BoneIndices[1] << " " << BoneIndices[2] << " " << BoneIndices[3] << endl; - out << BoneWeights[0] << " " << BoneWeights[1] << " " << BoneWeights[2] << " " << BoneWeights[3] << endl; + if (useWeights) { + out << BoneIndices[0] << " " << BoneIndices[1] << " " << BoneIndices[2] << " " << BoneIndices[3] << endl; + out << BoneWeights[0] << " " << BoneWeights[1] << " " << BoneWeights[2] << " " << BoneWeights[3] << endl; + } } bool operator==(const VertexLayout& right) @@ -57,6 +62,7 @@ public: class Mesh : public OutputData { public: + bool hasSkin = false; unsigned int NumVertices; unsigned int NumIndices; std::vector Vertices; @@ -64,6 +70,7 @@ public: virtual void WriteBinary(std::ostream& out) { + out.write((char*)&hasSkin, sizeof(bool)); out.write((char*)&NumVertices, sizeof(int)); out.write((char*)&NumIndices, sizeof(int)); for (auto aVertex : Vertices) { @@ -79,6 +86,11 @@ public: virtual void WriteASCII(std::ostream& out) const { out << "New Mesh _ not in binary" << endl; + out << "hasSkin: "; + if(hasSkin) + out << "true" << endl; + else + out << "false" << endl; out << "Number of vertices: " << NumVertices << endl; out << "number of indices: " << NumIndices << endl; int vertexNumber = 0; diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index bde87247..bb8c10d3 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -186,29 +186,29 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e /*MGlobal::displayInfo(MString() + "start keyfram index: " + startKeyFrameIndex + ". End keyfram index: " + endKeyFrameIndex + ".");*/ - if (startFrame <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame || endKeyFrameIndex - startKeyFrameIndex > 0) { - animatedJoints.push_back(jointIt.item()); - i = 9; - break; - } + // if (startFrame <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame || endKeyFrameIndex - startKeyFrameIndex > 0) { + // animatedJoints.push_back(jointIt.item()); + // i = 9; + // break; + // } - MFnTransform MayaJoint(jointIt.item()); + // MFnTransform MayaJoint(jointIt.item()); - MPlug BindPose = MayaJoint.findPlug("bindPose"); - MDataHandle DataHandle; - BindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix BindPoseMatrix = MartixFn.matrix(); + // MPlug BindPose = MayaJoint.findPlug("bindPose"); + // MDataHandle DataHandle; + // BindPose.getValue(DataHandle); + // MFnMatrixData MartixFn(DataHandle.data()); + // MMatrix BindPoseMatrix = MartixFn.matrix(); - if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix())) - { - MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya"); - } - } - } - }*/ + // if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix())) + // { + // MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya"); + // } + // } + // } + // } - } // end of int i loop + //} // end of int i loop jointIt.next(); } jointIt.reset(); From 563fd4082e090cb46e5eebc23095a2c86154e323 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 2 Feb 2016 12:10:39 +0100 Subject: [PATCH 035/131] Updated movement test for model collisions --- resources/Schema/Entities/MovementTest.xml | 67 ++-------------------- 1 file changed, 5 insertions(+), 62 deletions(-) diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 1378f623..f5197830 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -6,22 +6,6 @@ - - - - - - Models/Core/UnitCube.mesh - - false - - - - - - - - @@ -81,6 +65,10 @@ + + + + Models/Test/ObstacleCourse.mesh @@ -88,51 +76,6 @@ - - - - - - Models/Core/UnitCube.mesh - false - - - - - - - - - - - - - - Models/Core/UnitCube.mesh - false - - - - - - - - - - - - - - Models/Core/UnitCube.mesh - false - - - - - - - - @@ -197,7 +140,7 @@ - + From cb0feb0b84acd312f5ea8a145819e7de6ef702c7 Mon Sep 17 00:00:00 2001 From: stiffly Date: Tue, 2 Feb 2016 13:25:25 +0100 Subject: [PATCH 036/131] Tested hurt event. Randomizes between several different ones. --- assets | 2 +- include/Engine/Sound/SoundSystem.h | 9 +++-- src/Engine/Sound/SoundSystem.cpp | 55 +++++++++++++++++++----------- src/Game/Game.cpp | 3 +- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/assets b/assets index 9b4f9ab2..5bf03ccd 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 9b4f9ab2e67fc09863f35b33bb0a61ce75ef6aa8 +Subproject commit 5bf03ccd54bed358d525840635573f931adf584e diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 4ceed60f..e161af77 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -2,6 +2,7 @@ #define SoundSystem_h__ #include +#include #include "glm/common.hpp" #include "glm/gtx/rotate_vector.hpp" // Calculate Up vector @@ -27,6 +28,7 @@ #include "Core/EPlayerDamage.h" #include "Core/EPlayerDeath.h" #include "Core/EPlayerHealthPickup.h" +#include "Core/EComponentAttached.h" enum class SoundType { SFX, @@ -70,7 +72,7 @@ private: Source* createSource(std::string filePath); ALenum getSourceState(ALuint source); void setGain(Source* source, float gain); - void setSoundProperties(ALuint source, ComponentWrapper* soundComponent); + void setSoundProperties(Source* source, ComponentWrapper* soundComponent); // Specific logic void playSound(Source* source); @@ -91,11 +93,12 @@ private: float m_BGMVolumeChannel = 1.f; float m_SFXVolumeChannel = 1.f; bool m_EditorEnabled = false; - const double m_PlayerFootstepInterval = 0.5; + const double m_PlayerFootstepInterval = 1.0; double m_TimeSinceLastFootstep = 0; // TEMP EntityID m_LocalPlayer = EntityID_Invalid; bool m_LeftFoot = false; + std::default_random_engine generator; // Events EventRelay m_EPlaySoundOnEntity; @@ -129,6 +132,8 @@ private: bool OnPlayerDeath(const Events::PlayerDeath &e); EventRelay m_EPlayerHealthPickup; bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); + EventRelay m_EComponentAttached; + bool OnComponentAttached(const Events::ComponentAttached &e); diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 89798516..d08232ec 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -22,6 +22,7 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundSystem::OnSetSFXGain); EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundSystem::OnShoot); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); } @@ -120,15 +121,9 @@ void SoundSystem::updateEmitters(double dt) glm::vec3 velocity = glm::vec3(nextPos - previousPos) / (float)dt; setSourcePos(it->second->ALsource, nextPos); setSourceVel(it->second->ALsource, velocity); - float gain; - if (it->second->Type == SoundType::SFX) { - gain = m_SFXVolumeChannel; - } else if (it->second->Type == SoundType::BGM) { - gain = m_BGMVolumeChannel; - } auto emitter = m_World->GetComponent(it->first, "SoundEmitter"); - setSoundProperties(it->second->ALsource, &emitter); + setSoundProperties(it->second, &emitter); // To make an emitter play when spawned in editor mode if (m_EditorEnabled) { @@ -196,7 +191,7 @@ void SoundSystem::playerShot() void SoundSystem::playerJumps() { glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; - if (vel.y > 1) { + if (vel.y == 0) { Source* source = createSource("Audio/jump/jump1.wav"); auto emitterID = m_World->CreateEntity(m_LocalPlayer); m_World->AttachComponent(emitterID, "Transform"); @@ -205,6 +200,7 @@ void SoundSystem::playerJumps() m_Sources[emitterID] = source; playSound(source); } + } void SoundSystem::playerStep(double dt) @@ -218,7 +214,7 @@ void SoundSystem::playerStep(double dt) bool isAirborne = vel.y != 0; if (playerSpeed > 1 && !isAirborne) { // Player is walking - if (m_TimeSinceLastFootstep > m_PlayerFootstepInterval) { + if (m_TimeSinceLastFootstep * playerSpeed > m_PlayerFootstepInterval) { // Create footstep sound EntityID child = m_World->CreateEntity(m_LocalPlayer); m_World->AttachComponent(child, "Transform"); @@ -351,11 +347,19 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) if (e.PlayerID == -1) { // local player //bool airBorne = ((glm::vec3)m_World->GetComponent(e.Player.ID, "Physics")["Velocity"]).y != 0; //if (!airBorne) { - playerJumps(); + playerJumps(); //} return true; } } + if (e.Command == "TakeDamage" && e.Value > 0) { + if (e.PlayerID == -1) { //Local Player + Events::PlayerDamage ePlayerDamage; + ePlayerDamage.Damage = 1; + ePlayerDamage.Player = EntityWrapper(m_World, e.Player.ID); + m_EventBroker->Publish(ePlayerDamage); + } + } return false; } @@ -379,15 +383,17 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) { - if (e.Player.ID == m_LocalPlayer) { + //if (e.Player.ID == m_LocalPlayer) { Events::PlaySoundOnEntity ev; EntityID child = m_World->CreateEntity(m_LocalPlayer); m_World->AttachComponent(child, "Transform"); m_World->AttachComponent(child, "SoundEmitter"); ev.EmitterID = child; - ev.FilePath = "Audio/hurt/hurt3.wav"; // random between a bunch + std::uniform_int_distribution dist(1, 12); + int rand = dist(generator); + ev.FilePath = "Audio/hurt/hurt" + std::to_string(rand) + ".wav"; m_EventBroker->Publish(ev); - } + //} return false; } @@ -419,6 +425,14 @@ bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) return false; } +bool SoundSystem::OnComponentAttached(const Events::ComponentAttached & e) +{ + if (e.Component.Info.Name == "SoundEmitter") { + + } + return false; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector. @@ -448,14 +462,15 @@ void SoundSystem::setGain(Source * source, float gain) alSourcef(source->ALsource, AL_GAIN, gain); } -void SoundSystem::setSoundProperties(ALuint source, ComponentWrapper* soundComponent) +void SoundSystem::setSoundProperties(Source* source, ComponentWrapper* soundComponent) { - alSourcef(source, AL_GAIN, (float)(double)(*soundComponent)["Gain"]); - alSourcef(source, AL_PITCH, (float)(double)(*soundComponent)["Pitch"]); - alSourcei(source, AL_LOOPING, (int)(bool)(*soundComponent)["Loop"]); // YOLO - alSourcef(source, AL_MAX_DISTANCE, (float)(double)(*soundComponent)["MaxDistance"]); - alSourcef(source, AL_ROLLOFF_FACTOR, (float)(double)(*soundComponent)["RollOffFactor"]); - alSourcef(source, AL_REFERENCE_DISTANCE, (float)(double)(*soundComponent)["ReferenceDistance"]); + float gain = (source->Type == SoundType::SFX) ? m_SFXVolumeChannel : m_BGMVolumeChannel; + alSourcef(source->ALsource, AL_GAIN, (float)(double)(*soundComponent)["Gain"] * gain); + alSourcef(source->ALsource, AL_PITCH, (float)(double)(*soundComponent)["Pitch"]); + alSourcei(source->ALsource, AL_LOOPING, (int)(bool)(*soundComponent)["Loop"]); // YOLO + alSourcef(source->ALsource, AL_MAX_DISTANCE, (float)(double)(*soundComponent)["MaxDistance"]); + alSourcef(source->ALsource, AL_ROLLOFF_FACTOR, (float)(double)(*soundComponent)["RollOffFactor"]); + alSourcef(source->ALsource, AL_REFERENCE_DISTANCE, (float)(double)(*soundComponent)["ReferenceDistance"]); } void SoundSystem::initOpenAL() diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 515540bf..e0e7f611 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -154,12 +154,13 @@ void Game::Tick() if (m_IsClientOrServer) { m_ClientOrServer->Update(); } + m_SoundSystem->Update(dt); + // Iterate through systems and update world! m_EventBroker->Process(); m_SystemPipeline->Update(dt); debugTick(dt); m_Renderer->Update(dt); - m_SoundSystem->Update(dt); GLERROR("Game::Tick m_RenderQueueFactory->Update"); m_Renderer->Draw(*m_RenderFrame); m_RenderFrame->Clear(); From 83281fdaf14cc5ff3151841e81b60fd4d41df728 Mon Sep 17 00:00:00 2001 From: stiffly Date: Tue, 2 Feb 2016 13:39:11 +0100 Subject: [PATCH 037/131] Changed model in player.xml --- resources/Schema/Entities/Player.xml | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index e81ec5aa..15198dcb 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -2,14 +2,15 @@ - + + - + 5 @@ -20,7 +21,8 @@ - + + @@ -30,12 +32,14 @@ + + Fonts/DroidSans.ttf,100 @@ -102,11 +106,11 @@ - Models/AssaultWeapon.mesh + Models/AssaultWeaponBlue.mesh - + @@ -141,7 +145,7 @@ Hold Pos - + 1 @@ -180,6 +184,13 @@ + + + + + + + From e8186a706294d3af016f130427d07128e7d23b6e Mon Sep 17 00:00:00 2001 From: antc13 Date: Tue, 2 Feb 2016 14:47:22 +0100 Subject: [PATCH 038/131] Changed the way we're exporting animations. --- include/Engine/Rendering/RawModelCustom.h | 2 +- src/Engine/Rendering/RawModelCustom.cpp | 16 +- tools/MayaExporter/MayaExporter/Skeleton.cpp | 460 ++++++++++--------- tools/MayaExporter/MayaExporter/Skeleton.h | 8 +- 4 files changed, 267 insertions(+), 219 deletions(-) diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index f1bc0e24..167d2ec1 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -89,7 +89,7 @@ private: void ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize); void ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips); void ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex); - void ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfJoints, Skeleton::Animation& animation); + void ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, Skeleton::Animation& animation); //void CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID); }; diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 83f6e703..83c68e47 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -327,22 +327,16 @@ void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileDat unsigned int nrOfKeyframes = *(unsigned int*)(fileData + offset); offset += sizeof(unsigned int); - if (offset + sizeof(unsigned int) > fileByteSize) { - throw Resource::FailedLoadingException("Reading AnimationClip NrOfJoints failed"); - } - unsigned int nrOfJoints = *(unsigned int*)(fileData + offset); - offset += sizeof(unsigned int); - newAnimation.Keyframes.reserve(nrOfKeyframes); for (unsigned int i = 0; i < nrOfKeyframes; i++) { - ReadAnimationKeyFrame(offset, fileData, fileByteSize, nrOfJoints, newAnimation); + ReadAnimationKeyFrame(offset, fileData, fileByteSize, newAnimation); } m_Skeleton->Animations[newAnimation.Name] = newAnimation; #else #endif } -void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int nrOfJoints, Skeleton::Animation& animation) +void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, Skeleton::Animation& animation) { Skeleton::Animation::Keyframe newKeyFrame; @@ -358,6 +352,12 @@ void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, newKeyFrame.Time = *(float*)(fileData + offset); offset += sizeof(float); + if (offset + sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationKeyFrame NrOfJoints failed"); + } + unsigned int nrOfJoints = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + if (offset + sizeof(Skeleton::Animation::Keyframe::BoneProperty) * nrOfJoints> fileByteSize) { throw Resource::FailedLoadingException("Reading AnimationKeyFrame joints failed"); } diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index bde87247..a6ee5897 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -68,92 +68,92 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e std::vector animatedJoints; std::vector m_Hierarchy; - Animation returnData; - double oneDivSixty = 1 / 60.0; - returnData.Name = animationName; + Animation returnData; + double oneDivSixty = 1 / 60.0; + returnData.Name = animationName; returnData.nameLength = animationName.size() + 1; - returnData.Duration = (endFrame - startFrame) * oneDivSixty; + returnData.Duration = (endFrame - startFrame) * oneDivSixty; - std::map, 4>> joinCheckMap; - std::map exportJoint; + std::map, 4>> joinCheckMap; + std::map exportJoint; - MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); - for (unsigned int i = startFrame; i <= endFrame; i++) - { - MAnimControl::setCurrentTime(MTime(i, MTime::kNTSCField)); - while (!jointIt.isDone()) - { - m_Hierarchy.push_back(jointIt.item()); + //MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); + //for (unsigned int i = startFrame; i <= endFrame; i++) + //{ + // MAnimControl::setCurrentTime(MTime(i, MTime::kNTSCField)); + // while (!jointIt.isDone()) + // { + // m_Hierarchy.push_back(jointIt.item()); - MFnTransform MayaJoint(jointIt.item()); - MMatrix transformationMatrix = MayaJoint.transformationMatrix(); + // MFnTransform MayaJoint(jointIt.item()); + // MMatrix transformationMatrix = MayaJoint.transformationMatrix(); - if (i == startFrame) - { - double doubleMat[4][4]; - transformationMatrix.get(doubleMat); + // if (i == startFrame) + // { + // double doubleMat[4][4]; + // transformationMatrix.get(doubleMat); - joinCheckMap[MayaJoint.name().asChar()][0][0] = doubleMat[0][0]; - joinCheckMap[MayaJoint.name().asChar()][0][1] = doubleMat[0][1]; - joinCheckMap[MayaJoint.name().asChar()][0][2] = doubleMat[0][2]; - joinCheckMap[MayaJoint.name().asChar()][0][3] = doubleMat[0][3]; - joinCheckMap[MayaJoint.name().asChar()][1][0] = doubleMat[1][0]; - joinCheckMap[MayaJoint.name().asChar()][1][1] = doubleMat[1][1]; - joinCheckMap[MayaJoint.name().asChar()][1][2] = doubleMat[1][2]; - joinCheckMap[MayaJoint.name().asChar()][1][3] = doubleMat[1][3]; - joinCheckMap[MayaJoint.name().asChar()][2][0] = doubleMat[2][0]; - joinCheckMap[MayaJoint.name().asChar()][2][1] = doubleMat[2][1]; - joinCheckMap[MayaJoint.name().asChar()][2][2] = doubleMat[2][2]; - joinCheckMap[MayaJoint.name().asChar()][2][3] = doubleMat[2][3]; - joinCheckMap[MayaJoint.name().asChar()][3][0] = doubleMat[3][0]; - joinCheckMap[MayaJoint.name().asChar()][3][1] = doubleMat[3][1]; - joinCheckMap[MayaJoint.name().asChar()][3][2] = doubleMat[3][2]; - joinCheckMap[MayaJoint.name().asChar()][3][3] = doubleMat[3][3]; + // joinCheckMap[MayaJoint.name().asChar()][0][0] = doubleMat[0][0]; + // joinCheckMap[MayaJoint.name().asChar()][0][1] = doubleMat[0][1]; + // joinCheckMap[MayaJoint.name().asChar()][0][2] = doubleMat[0][2]; + // joinCheckMap[MayaJoint.name().asChar()][0][3] = doubleMat[0][3]; + // joinCheckMap[MayaJoint.name().asChar()][1][0] = doubleMat[1][0]; + // joinCheckMap[MayaJoint.name().asChar()][1][1] = doubleMat[1][1]; + // joinCheckMap[MayaJoint.name().asChar()][1][2] = doubleMat[1][2]; + // joinCheckMap[MayaJoint.name().asChar()][1][3] = doubleMat[1][3]; + // joinCheckMap[MayaJoint.name().asChar()][2][0] = doubleMat[2][0]; + // joinCheckMap[MayaJoint.name().asChar()][2][1] = doubleMat[2][1]; + // joinCheckMap[MayaJoint.name().asChar()][2][2] = doubleMat[2][2]; + // joinCheckMap[MayaJoint.name().asChar()][2][3] = doubleMat[2][3]; + // joinCheckMap[MayaJoint.name().asChar()][3][0] = doubleMat[3][0]; + // joinCheckMap[MayaJoint.name().asChar()][3][1] = doubleMat[3][1]; + // joinCheckMap[MayaJoint.name().asChar()][3][2] = doubleMat[3][2]; + // joinCheckMap[MayaJoint.name().asChar()][3][3] = doubleMat[3][3]; - exportJoint[MayaJoint.name().asChar()] = false; - } - else if(!exportJoint[MayaJoint.name().asChar()])//!exportJoint[MayaJoint.name().asChar()]) - { - double doubleMat[4][4]; + // exportJoint[MayaJoint.name().asChar()] = false; + // } + // else if(!exportJoint[MayaJoint.name().asChar()])//!exportJoint[MayaJoint.name().asChar()]) + // { + // double doubleMat[4][4]; - doubleMat[0][0] = joinCheckMap[MayaJoint.name().asChar()][0][0]; - doubleMat[0][1] = joinCheckMap[MayaJoint.name().asChar()][0][1]; - doubleMat[0][2] = joinCheckMap[MayaJoint.name().asChar()][0][2]; - doubleMat[0][3] = joinCheckMap[MayaJoint.name().asChar()][0][3]; - doubleMat[1][0] = joinCheckMap[MayaJoint.name().asChar()][1][0]; - doubleMat[1][1] = joinCheckMap[MayaJoint.name().asChar()][1][1]; - doubleMat[1][2] = joinCheckMap[MayaJoint.name().asChar()][1][2]; - doubleMat[1][3] = joinCheckMap[MayaJoint.name().asChar()][1][3]; - doubleMat[2][0] = joinCheckMap[MayaJoint.name().asChar()][2][0]; - doubleMat[2][1] = joinCheckMap[MayaJoint.name().asChar()][2][1]; - doubleMat[2][2] = joinCheckMap[MayaJoint.name().asChar()][2][2]; - doubleMat[2][3] = joinCheckMap[MayaJoint.name().asChar()][2][3]; - doubleMat[3][0] = joinCheckMap[MayaJoint.name().asChar()][3][0]; - doubleMat[3][1] = joinCheckMap[MayaJoint.name().asChar()][3][1]; - doubleMat[3][2] = joinCheckMap[MayaJoint.name().asChar()][3][2]; - doubleMat[3][3] = joinCheckMap[MayaJoint.name().asChar()][3][3]; + // doubleMat[0][0] = joinCheckMap[MayaJoint.name().asChar()][0][0]; + // doubleMat[0][1] = joinCheckMap[MayaJoint.name().asChar()][0][1]; + // doubleMat[0][2] = joinCheckMap[MayaJoint.name().asChar()][0][2]; + // doubleMat[0][3] = joinCheckMap[MayaJoint.name().asChar()][0][3]; + // doubleMat[1][0] = joinCheckMap[MayaJoint.name().asChar()][1][0]; + // doubleMat[1][1] = joinCheckMap[MayaJoint.name().asChar()][1][1]; + // doubleMat[1][2] = joinCheckMap[MayaJoint.name().asChar()][1][2]; + // doubleMat[1][3] = joinCheckMap[MayaJoint.name().asChar()][1][3]; + // doubleMat[2][0] = joinCheckMap[MayaJoint.name().asChar()][2][0]; + // doubleMat[2][1] = joinCheckMap[MayaJoint.name().asChar()][2][1]; + // doubleMat[2][2] = joinCheckMap[MayaJoint.name().asChar()][2][2]; + // doubleMat[2][3] = joinCheckMap[MayaJoint.name().asChar()][2][3]; + // doubleMat[3][0] = joinCheckMap[MayaJoint.name().asChar()][3][0]; + // doubleMat[3][1] = joinCheckMap[MayaJoint.name().asChar()][3][1]; + // doubleMat[3][2] = joinCheckMap[MayaJoint.name().asChar()][3][2]; + // doubleMat[3][3] = joinCheckMap[MayaJoint.name().asChar()][3][3]; - MMatrix tmp(doubleMat); - if (!tmp.isEquivalent(transformationMatrix)) { - MGlobal::displayInfo(MString() + MayaJoint.name() + " is exported"); - exportJoint[MayaJoint.name().asChar()] = true; - animatedJoints.push_back(MayaJoint.object()); - } - } + // MMatrix tmp(doubleMat); + // if (!tmp.isEquivalent(transformationMatrix)) { + // MGlobal::displayInfo(MString() + MayaJoint.name() + " is exported"); + // exportJoint[MayaJoint.name().asChar()] = true; + // animatedJoints.push_back(MayaJoint.object()); + // } + // } - /*for (int i = 0; i < 9; i++) - { - MStatus tmp; - MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp); + /*for (int i = 0; i < 9; i++) + { + MStatus tmp; + MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp); - MPlugArray connections; - plug.connectedTo(connections, true, false, 0); - for (int j = 0; j != connections.length(); j++) { - MObject connected = connections[j].node(); + MPlugArray connections; + plug.connectedTo(connections, true, false, 0); + for (int j = 0; j != connections.length(); j++) { + MObject connected = connections[j].node(); - if (connected.hasFn(MFn::kAnimCurve)) { + if (connected.hasFn(MFn::kAnimCurve)) { - MFnAnimCurve jointAnim(connected); + MFnAnimCurve jointAnim(connected); //MGlobal::displayInfo(MString() + "curve : " + jointAnim.name()); //MGlobal::displayInfo(MString() + "curve keys : " + jointAnim.numKeys()); @@ -161,89 +161,133 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e //MGlobal::displayInfo(MString() + "startFrame : " + startFrame); //MGlobal::displayInfo(MString() + "endFrame : " + endFrame); - unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp); + unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp); - if (tmp == MStatus::kFailure) - MGlobal::displayInfo(MString() + "Fail :c"); + if (tmp == MStatus::kFailure) + MGlobal::displayInfo(MString() + "Fail :c"); - if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) { + if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) { //MGlobal::displayInfo(MString() + "Start key time : " + jointAnim.time(startKeyFrameIndex).value()); - if (startFrame <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame ) { - animatedJoints.push_back(jointIt.item()); - i = 9; - break; - } + if (startFrame <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame ) { + animatedJoints.push_back(jointIt.item()); + i = 9; + break; + } - unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField)); - MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex); + unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField)); + MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex); MGlobal::displayInfo(MString() + "Fail!!!!!!!!!!!!!!!!!!!!!!!!!"); - if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) { + if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) { //MGlobal::displayInfo(MString() + "End key index : " + endKeyFrameIndex); //MGlobal::displayInfo(MString() + "end key time : " + jointAnim.time(endKeyFrameIndex).value()); - /*MGlobal::displayInfo(MString() + "start keyfram index: " + startKeyFrameIndex + ". End keyfram index: " + endKeyFrameIndex + ".");*/ + /*MGlobal::displayInfo(MString() + "start keyfram index: " + startKeyFrameIndex + ". End keyfram index: " + endKeyFrameIndex + ".");*/ - if (startFrame <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame || endKeyFrameIndex - startKeyFrameIndex > 0) { - animatedJoints.push_back(jointIt.item()); - i = 9; - break; - } + /*if (startFrame <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame || endKeyFrameIndex - startKeyFrameIndex > 0) { + animatedJoints.push_back(jointIt.item()); + i = 9; + break; + } - MFnTransform MayaJoint(jointIt.item()); + MFnTransform MayaJoint(jointIt.item()); - MPlug BindPose = MayaJoint.findPlug("bindPose"); - MDataHandle DataHandle; - BindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix BindPoseMatrix = MartixFn.matrix(); + MPlug BindPose = MayaJoint.findPlug("bindPose"); + MDataHandle DataHandle; + BindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix BindPoseMatrix = MartixFn.matrix(); - if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix())) - { - MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya"); - } - } - } - }*/ + if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix())) + { + MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya"); + } + } + } + } - } // end of int i loop - jointIt.next(); - } - jointIt.reset(); - } + } // end of int i loop*/ + /* jointIt.next(); + } + jointIt.reset(); + }*/ - int currentFrame = startFrame; - while (currentFrame <= endFrame) { // ANDREAS - Animation::Keyframe thisKeyFrame; - thisKeyFrame.Index = currentFrame - startFrame; - thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; + int currentFrame = startFrame; + while (currentFrame <= endFrame) { // ANDREAS + Animation::Keyframe thisKeyFrame; + thisKeyFrame.Index = currentFrame - startFrame; + thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; - MAnimControl::setCurrentTime(MTime(currentFrame, MTime::kNTSCField)); - MTime time = MAnimControl::currentTime(); + MAnimControl::setCurrentTime(MTime(currentFrame, MTime::kNTSCField)); + MTime time = MAnimControl::currentTime(); - for (auto aJoint : animatedJoints){ - MFnTransform thisJoint(aJoint); - Animation::Keyframe::JointProperty joint; + MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); + unsigned int jointID = 0; + while (!jointIt.isDone()) { + MFnTransform thisJoint(jointIt.currentItem()); + MMatrix transformationMatrix = thisJoint.transformationMatrix(); + + double doubleMat[4][4]; - auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), thisJoint.object()); - if (it != m_Hierarchy.end()) { - joint.ID = it - m_Hierarchy.begin(); - } - else { - MGlobal::displayError(MString() + "Could not find joint ID for: " + thisJoint.name()); - } - - MTransformationMatrix Matrix = thisJoint.transformation(); + if (currentFrame != startFrame){ + Animation::Keyframe::JointProperty joint; + + doubleMat[0][0] = joinCheckMap[thisJoint.name().asChar()][0][0]; + doubleMat[0][1] = joinCheckMap[thisJoint.name().asChar()][0][1]; + doubleMat[0][2] = joinCheckMap[thisJoint.name().asChar()][0][2]; + doubleMat[0][3] = joinCheckMap[thisJoint.name().asChar()][0][3]; + doubleMat[1][0] = joinCheckMap[thisJoint.name().asChar()][1][0]; + doubleMat[1][1] = joinCheckMap[thisJoint.name().asChar()][1][1]; + doubleMat[1][2] = joinCheckMap[thisJoint.name().asChar()][1][2]; + doubleMat[1][3] = joinCheckMap[thisJoint.name().asChar()][1][3]; + doubleMat[2][0] = joinCheckMap[thisJoint.name().asChar()][2][0]; + doubleMat[2][1] = joinCheckMap[thisJoint.name().asChar()][2][1]; + doubleMat[2][2] = joinCheckMap[thisJoint.name().asChar()][2][2]; + doubleMat[2][3] = joinCheckMap[thisJoint.name().asChar()][2][3]; + doubleMat[3][0] = joinCheckMap[thisJoint.name().asChar()][3][0]; + doubleMat[3][1] = joinCheckMap[thisJoint.name().asChar()][3][1]; + doubleMat[3][2] = joinCheckMap[thisJoint.name().asChar()][3][2]; + doubleMat[3][3] = joinCheckMap[thisJoint.name().asChar()][3][3]; + + MMatrix LastJointMatrix(doubleMat); + //Is same as last KeyFrame + if (LastJointMatrix.isEquivalent(transformationMatrix)) { + jointID++; + jointIt.next(); + continue; + } + } + + transformationMatrix.get(doubleMat); + + joinCheckMap[thisJoint.name().asChar()][0][0] = doubleMat[0][0]; + joinCheckMap[thisJoint.name().asChar()][0][1] = doubleMat[0][1]; + joinCheckMap[thisJoint.name().asChar()][0][2] = doubleMat[0][2]; + joinCheckMap[thisJoint.name().asChar()][0][3] = doubleMat[0][3]; + joinCheckMap[thisJoint.name().asChar()][1][0] = doubleMat[1][0]; + joinCheckMap[thisJoint.name().asChar()][1][1] = doubleMat[1][1]; + joinCheckMap[thisJoint.name().asChar()][1][2] = doubleMat[1][2]; + joinCheckMap[thisJoint.name().asChar()][1][3] = doubleMat[1][3]; + joinCheckMap[thisJoint.name().asChar()][2][0] = doubleMat[2][0]; + joinCheckMap[thisJoint.name().asChar()][2][1] = doubleMat[2][1]; + joinCheckMap[thisJoint.name().asChar()][2][2] = doubleMat[2][2]; + joinCheckMap[thisJoint.name().asChar()][2][3] = doubleMat[2][3]; + joinCheckMap[thisJoint.name().asChar()][3][0] = doubleMat[3][0]; + joinCheckMap[thisJoint.name().asChar()][3][1] = doubleMat[3][1]; + joinCheckMap[thisJoint.name().asChar()][3][2] = doubleMat[3][2]; + joinCheckMap[thisJoint.name().asChar()][3][3] = doubleMat[3][3]; + + MTransformationMatrix Matrix = thisJoint.transformation(); MPlug BindPose = thisJoint.findPlug("bindPose"); MDataHandle DataHandle; BindPose.getValue(DataHandle); MFnMatrixData MartixFn(DataHandle.data()); MMatrix BindPoseMatrix = MartixFn.matrix(); Matrix = Matrix.asMatrix(); - + MObject jointOrientObj = thisJoint.attribute("jointOrient"); MFnNumericAttribute jointOrient(jointOrientObj); double jointOrientDouble[3]; @@ -257,79 +301,83 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MEulerRotation joEuler(jointOrientDouble[0], jointOrientDouble[1], jointOrientDouble[2]); MQuaternion jo = joEuler.asQuaternion(); - double tmp[4]; + double tmp[4]; Matrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); MQuaternion rotation(tmp); rotation = rotation * jo; rotation.get(tmp); - joint.Rotation[0] = tmp[0]; - joint.Rotation[1] = tmp[1]; - joint.Rotation[2] = tmp[2]; - joint.Rotation[3] = tmp[3]; - Matrix.getTranslation(MSpace::kTransform).get(tmp); - joint.Position[0] = tmp[0]; - joint.Position[1] = tmp[1]; - joint.Position[2] = tmp[2]; - Matrix.getScale(tmp, MSpace::kTransform); - joint.Scale[0] = tmp[0]; - joint.Scale[1] = tmp[1]; - joint.Scale[2] = tmp[2]; + Animation::Keyframe::JointProperty joint; + joint.ID = jointID; - thisKeyFrame.JointProperties.push_back(joint); - } - returnData.Keyframes.push_back(thisKeyFrame); - currentFrame++; - } + joint.Rotation[0] = tmp[0]; + joint.Rotation[1] = tmp[1]; + joint.Rotation[2] = tmp[2]; + joint.Rotation[3] = tmp[3]; + Matrix.getTranslation(MSpace::kTransform).get(tmp); + joint.Position[0] = tmp[0]; + joint.Position[1] = tmp[1]; + joint.Position[2] = tmp[2]; + Matrix.getScale(tmp, MSpace::kTransform); + joint.Scale[0] = tmp[0]; + joint.Scale[1] = tmp[1]; + joint.Scale[2] = tmp[2]; + + thisKeyFrame.JointProperties.push_back(joint); + + jointID++; + jointIt.next(); + } + thisKeyFrame.NumberOfJoints = thisKeyFrame.JointProperties.size(); + returnData.Keyframes.push_back(thisKeyFrame); + currentFrame++; + } returnData.NumKeyFrames = returnData.Keyframes.size(); - returnData.NumberOfJoints = animatedJoints.size(); - return returnData; + return returnData; } std::vector Skeleton::GetBindPoses() { MStatus status; - std::vector m_AllSkeletons; - std::vector m_Hierarchy; + std::vector m_AllSkeletons; + std::vector m_Hierarchy; - MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); - BindPoseSkeletonNode SkeletonStorage; - while (!jointIt.isDone()) { - MFnTransform MayaJoint(jointIt.currentItem()); - BindPoseSkeletonNode::BindPoseJoint NewJoint; + MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); + BindPoseSkeletonNode SkeletonStorage; + while (!jointIt.isDone()) { + MFnTransform MayaJoint(jointIt.currentItem()); + BindPoseSkeletonNode::BindPoseJoint NewJoint; - if (MFnDependencyNode(MayaJoint.parent(0)).object().apiType() != MFn::kJoint) { - if (SkeletonStorage.Joints.size() != 0) { - m_AllSkeletons.push_back(SkeletonStorage); + if (MFnDependencyNode(MayaJoint.parent(0)).object().apiType() != MFn::kJoint) { + if (SkeletonStorage.Joints.size() != 0) { + m_AllSkeletons.push_back(SkeletonStorage); - SkeletonStorage.Joints.clear(); - SkeletonStorage.Name.clear(); - } - SkeletonStorage.Name = std::string(MayaJoint.name().asChar()); - NewJoint.ParentID = -1; // This joint is root - } - else { - auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), MayaJoint.parent(0)); - if (it != m_Hierarchy.end()) { - NewJoint.ParentID = it - m_Hierarchy.begin(); - } - else { - MGlobal::displayError(MString() + "Could not find joint parent for: " + MayaJoint.name()); - } - } - m_Hierarchy.push_back(MayaJoint.object()); + SkeletonStorage.Joints.clear(); + SkeletonStorage.Name.clear(); + } + SkeletonStorage.Name = std::string(MayaJoint.name().asChar()); + NewJoint.ParentID = -1; // This joint is root + } else { + auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), MayaJoint.parent(0)); + if (it != m_Hierarchy.end()) { + NewJoint.ParentID = it - m_Hierarchy.begin(); + } else { + MGlobal::displayError(MString() + "Could not find joint parent for: " + MayaJoint.name()); + } + } + m_Hierarchy.push_back(MayaJoint.object()); - MPlug BindPose = MayaJoint.findPlug("bindPose", &status); - if (status != MS::kSuccess) { + MPlug BindPose = MayaJoint.findPlug("bindPose", &status); + if (status != MS::kSuccess) { MGlobal::displayError(MString() + "Could not find bindPose plug: " + status.errorString()); } - MDataHandle DataHandle; - BindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix Matrix = MartixFn.matrix(); + MDataHandle DataHandle; + BindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix Matrix = MartixFn.matrix(); MVector tmp = MayaJoint.transformation().getTranslation(MSpace::kObject); @@ -342,7 +390,7 @@ std::vector Skeleton::GetBindPoses() MTransformationMatrix::RotationOrder order = MTransformationMatrix::RotationOrder::kXYZ; MayaJoint.transformation().getRotation(test, order); - + //----- test @@ -389,33 +437,33 @@ std::vector Skeleton::GetBindPoses() Matrix = Matrix.inverse(); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; - } - } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; + } + } - NewJoint.Name = MayaJoint.name().asChar(); + NewJoint.Name = MayaJoint.name().asChar(); NewJoint.NameLength = MayaJoint.name().length() + 1; NewJoint.ID = SkeletonStorage.Joints.size(); - //double tmp[3]; - //((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp); - //NewJoint.Rotation[0] = tmp[0]; - //NewJoint.Rotation[1] = tmp[1]; - //NewJoint.Rotation[2] = tmp[2]; - //((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform); - //NewJoint.Scale[0] = tmp[0]; - //NewJoint.Scale[1] = tmp[1]; - //NewJoint.Scale[2] = tmp[2]; - //((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp); - //NewJoint.Translation[0] = tmp[0]; - //NewJoint.Translation[1] = tmp[1]; - //NewJoint.Translation[2] = tmp[2]; - SkeletonStorage.Joints.push_back(NewJoint); + //double tmp[3]; + //((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp); + //NewJoint.Rotation[0] = tmp[0]; + //NewJoint.Rotation[1] = tmp[1]; + //NewJoint.Rotation[2] = tmp[2]; + //((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform); + //NewJoint.Scale[0] = tmp[0]; + //NewJoint.Scale[1] = tmp[1]; + //NewJoint.Scale[2] = tmp[2]; + //((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp); + //NewJoint.Translation[0] = tmp[0]; + //NewJoint.Translation[1] = tmp[1]; + //NewJoint.Translation[2] = tmp[2]; + SkeletonStorage.Joints.push_back(NewJoint); SkeletonStorage.numBones++; - jointIt.next(); - } - m_AllSkeletons.push_back(SkeletonStorage); + jointIt.next(); + } + m_AllSkeletons.push_back(SkeletonStorage); - return m_AllSkeletons; + return m_AllSkeletons; } \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index 9033441d..47ae6f4c 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -22,6 +22,7 @@ public: int Index = 0; float Time = 0; + int NumberOfJoints; std::vector JointProperties; }; @@ -29,7 +30,6 @@ public: int nameLength = 0; float Duration = 0; int NumKeyFrames = 0; - int NumberOfJoints = 0; std::vector Keyframes; virtual void WriteBinary(std::ostream& out) @@ -38,11 +38,11 @@ public: out.write(Name.c_str(), Name.size() + 1); out.write((char*)&Duration, sizeof(float)); out.write((char*)&NumKeyFrames, sizeof(int)); - out.write((char*)&NumberOfJoints, sizeof(int)); //Här under loopas alla key frames igenom for (auto aKeyframe : Keyframes) { out.write((char*)&aKeyframe.Index, sizeof(int)); out.write((char*)&aKeyframe.Time, sizeof(float)); + out.write((char*)&aKeyframe.NumberOfJoints, sizeof(int)); for (auto aJoint : aKeyframe.JointProperties) { out.write((char*)&aJoint.ID, sizeof(int)); out.write((char*)aJoint.Position, sizeof(float) * 3); @@ -56,11 +56,11 @@ public: { out << "Animation Name: " << Name << endl; out << "Duration: " << Duration << endl; - out << "Number of KeyFrames: " << NumKeyFrames << endl; - out << "Number of Joints: " << NumberOfJoints << endl; + out << "Number of KeyFrames: " << NumKeyFrames << endl; for (auto aKeyframe : Keyframes) { out << "Frame: " << aKeyframe.Index << endl; out << "Time: " << aKeyframe.Time << endl; + out << "Number of Joints: " << aKeyframe.NumberOfJoints << endl; for (auto aJoint : aKeyframe.JointProperties) { out << "Joint ID: " << aJoint.ID << endl; out << aJoint.Position[0] << " " << aJoint.Position[1] << " " << aJoint.Position[2] << endl; From dba2fbdc0cbe2b2947ca45ab58108c1ef5bcbdc5 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 2 Feb 2016 14:52:31 +0100 Subject: [PATCH 039/131] WIP --- include/Engine/Rendering/AnimationSystem.h | 6 +- include/Engine/Rendering/Skeleton.h | 1 + resources/Schema/Entities/AnimationTests.xml | 394 ++++++++++++++---- resources/Schema/Entities/AnimationTests2.xml | 341 +++++++++++++++ resources/Schema/Entities/BoneMarker | 22 + resources/Schema/Entities/FastWorld.xml | 4 +- resources/Schema/Entities/Testingu | 45 ++ src/Engine/Rendering/AnimationSystem.cpp | 112 ++++- src/Engine/Rendering/RenderSystem.cpp | 12 +- src/Engine/Rendering/Skeleton.cpp | 9 +- src/Game/Systems/PlayerMovementSystem.cpp | 8 +- 11 files changed, 842 insertions(+), 112 deletions(-) create mode 100644 resources/Schema/Entities/AnimationTests2.xml create mode 100644 resources/Schema/Entities/BoneMarker create mode 100644 resources/Schema/Entities/Testingu diff --git a/include/Engine/Rendering/AnimationSystem.h b/include/Engine/Rendering/AnimationSystem.h index fcdcbc92..15dbe39d 100644 --- a/include/Engine/Rendering/AnimationSystem.h +++ b/include/Engine/Rendering/AnimationSystem.h @@ -9,6 +9,7 @@ #include "Rendering/Model.h" #include "Rendering/EAnimationComplete.h" #include "Rendering/Skeleton.h" +#include class AnimationSystem : public PureSystem { @@ -22,8 +23,9 @@ public: ~AnimationSystem() { } virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt) override; private: - - + float angle = 0.f; + bool b_forward = false; + char bone[100]; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index dca78e4c..8ae3d487 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -41,6 +41,7 @@ public: std::string Name; glm::mat4 OffsetMatrix; + glm::mat4 ModificationMatrix = glm::mat4(1); int ID; Bone* Parent; diff --git a/resources/Schema/Entities/AnimationTests.xml b/resources/Schema/Entities/AnimationTests.xml index 578db574..77c87e64 100644 --- a/resources/Schema/Entities/AnimationTests.xml +++ b/resources/Schema/Entities/AnimationTests.xml @@ -34,108 +34,344 @@ - Run - + Crouch + 1 - Models/AssaultAnimated.mesh + Models/Asstest.mesh - + - - - - - 12 - 0.29999995231628418 - - - - - - - - - - - - 7 - - - - - - - - + - L_Foot + R_Leg_Top - true Models/Core/UnitCube.mesh - - - + + + + + + + + + + + R_Leg_Bottom + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Foot + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Foot + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Leg_Bottom + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Leg_Top + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Hip + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_1 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_2 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_3 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Neck + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Shoulder + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Arm + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Elbow + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Hand + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Chin + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Hand + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Elbow + + + + Models/Core/UnitCube.mesh + + + + + + - - - - Walk - - 1 - - - Models/AssaultAnimated.mesh - - - - - - - - - - - Crouch Walk - - 1 - - - Models/AssaultAnimated.mesh - - - - - - - - - - - - Models/Core/UnitCube.mesh - - - - - - - diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml new file mode 100644 index 00000000..23fc0548 --- /dev/null +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -0,0 +1,341 @@ + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + + + + + + + + + + + + Models/DirectionalLightWidget.mesh + + + + + + + + + + + + Run + + 1 + + + Models/Asstest.mesh + + + + + + + + + + R_Leg_Top + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Leg_Bottom + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Foot + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Foot + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Leg_Bottom + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Leg_Top + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Hip + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_1 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_2 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_3 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Neck + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Shoulder + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Arm + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Elbow + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Hand + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Chin + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/BoneMarker b/resources/Schema/Entities/BoneMarker new file mode 100644 index 00000000..eda56d56 --- /dev/null +++ b/resources/Schema/Entities/BoneMarker @@ -0,0 +1,22 @@ + + + + + + R_Leg_Top + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + diff --git a/resources/Schema/Entities/FastWorld.xml b/resources/Schema/Entities/FastWorld.xml index 4863f8f7..94df077d 100644 --- a/resources/Schema/Entities/FastWorld.xml +++ b/resources/Schema/Entities/FastWorld.xml @@ -25,7 +25,9 @@ - Walk + Crouch Walk + + 8 Models/AssaultAnimated.mesh diff --git a/resources/Schema/Entities/Testingu b/resources/Schema/Entities/Testingu new file mode 100644 index 00000000..145550f4 --- /dev/null +++ b/resources/Schema/Entities/Testingu @@ -0,0 +1,45 @@ + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 9c1e68cf..93d52787 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -23,29 +23,109 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]); - if(animation != nullptr) { - double animationSpeed = (double)animationComponent["Speed"]; + if (animation == nullptr) { + return; + } - if (animationSpeed != 0.0) { - double nextTime = (double)animationComponent["Time"] + animationSpeed * dt; + double animationSpeed = (double)animationComponent["Speed"]; + + if (animationSpeed != 0.0) { + double nextTime = (double)animationComponent["Time"] + animationSpeed * dt; - if (!(bool)animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) { - (double&)animationComponent["Time"] = glm::sign(nextTime) * animation->Duration; - (double&)animationComponent["Speed"] = 0.0; - Events::AnimationComplete e; - e.Entity = entity; - e.Name = (std::string)animationComponent["AnimationName"]; - m_EventBroker->Publish(e); + if (!(bool)animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) { + (double&)animationComponent["Time"] = glm::sign(nextTime) * animation->Duration; + (double&)animationComponent["Speed"] = 0.0; + Events::AnimationComplete e; + e.Entity = entity; + e.Name = (std::string)animationComponent["AnimationName"]; + m_EventBroker->Publish(e); + } else { + if (glm::abs(nextTime) > animation->Duration) { + (double&)animationComponent["Time"] = glm::abs(nextTime) - animation->Duration; } else { - if (glm::abs(nextTime) > animation->Duration) { - (double&)animationComponent["Time"] = glm::abs(nextTime) - animation->Duration; - } else { - (double&)animationComponent["Time"] = nextTime; - } + (double&)animationComponent["Time"] = nextTime; } } } + + + + ImGui::SliderFloat("Angle", &angle, -180.f, 180.f); + + int id = skeleton->GetBoneID("Spine_2"); + auto it = skeleton->Bones.find(id); + if (it != skeleton->Bones.end()) { + int currentKeyframeIndex = skeleton->GetKeyframe(*animation, entity["Animation"]["Time"]); + + const Skeleton::Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; + const Skeleton::Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; + float alpha = ((double)entity["Animation"]["Time"] - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + + glm::mat4 parentBoneTransform = skeleton->GetBoneTransform(it->second->Parent, currentFrame, nextFrame, alpha, glm::mat4(1)); + + + + glm::vec3 scale; + glm::quat rotation; + glm::vec3 translation; + glm::vec3 skew; + glm::vec4 perspective; + glm::decompose(parentBoneTransform, scale, rotation, translation, skew, perspective); + + + + glm::vec3 rot; + rot = glm::vec3(1, 0, 0); + rot = glm::normalize(rot) * glm::radians(angle); + glm::mat4 modmat = glm::mat4(glm::quat(rot)) * glm::inverse(glm::mat4(rotation)); + + + it->second->ModificationMatrix = modmat; + } + + + +/* + + { + int id = skeleton->GetBoneID("Neck"); + auto it = skeleton->Bones.find(id); + if (it != skeleton->Bones.end()) { + it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); + } + } + + { + int id = skeleton->GetBoneID("Spine_2"); + auto it = skeleton->Bones.find(id); + if (it != skeleton->Bones.end()) { + it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/4.f), 0.f, 0.f))); + } + } + { + int id = skeleton->GetBoneID("R_Shoulder"); + auto it = skeleton->Bones.find(id); + if (it != skeleton->Bones.end()) { + it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); + } + } + { + int id = skeleton->GetBoneID("L_Shoulder"); + auto it = skeleton->Bones.find(id); + if (it != skeleton->Bones.end()) { + it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); + } + }*/ + + if (entity.HasComponent("Player")) { + EntityWrapper cameraEntity = entity.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; + + + } + } } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index f9114350..1998c3d7 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -61,14 +61,14 @@ void RenderSystem::fillModels(std::list>& jobs) EntityWrapper entity(m_World, cModel.EntityID); // Only render children of a camera if that camera is currently active - if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { - continue; - } +// if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { +// continue; +// } DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS // Hide things parented to local player if they have the HiddenFromLocalPlayer component - if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { - continue; - } +// if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { +// continue; +// } DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS Model* model; try { diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 150fad7d..7fe36319 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -95,12 +95,13 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf positionInterp.z = 0; } + - boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; } else { if (bone->Parent) { - boneMatrix = parentMatrix; // * glm::inverse(bone->OffsetMatrix); + boneMatrix = parentMatrix;// *glm::inverse(bone->OffsetMatrix); } boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix; } @@ -125,7 +126,7 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe glm::vec3 scaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; - boneMatrix = (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)) * parentMatrix; + boneMatrix = (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)) * bone->ModificationMatrix * parentMatrix; } else { if (bone->Parent) { boneMatrix = parentMatrix; diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 6eab02c5..36dbcbd0 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -97,18 +97,18 @@ void PlayerMovementSystem::Update(double dt) float movementLength = glm::length(groundVelocity); if (glm::length(controller->Movement()) > 0.f) { if (controller->Crouching()) { - cAnimation["Name"] = "Crouch Walk"; + cAnimation["AnimationName"] = "Crouch Walk"; (double&)cAnimation["Speed"] = 1.f * -glm::sign(controller->Movement().z); } else { - cAnimation["Name"] = "Run"; + cAnimation["AnimationName"] = "Run"; (double&)cAnimation["Speed"] = 2.f * -glm::sign(controller->Movement().z); } } else { if (controller->Crouching()) { - cAnimation["Name"] = "Crouch"; + cAnimation["AnimationName"] = "Crouch"; (double&)cAnimation["Speed"] = 1.f; } else { - cAnimation["Name"] = "Hold Pos"; + cAnimation["AnimationName"] = "Hold Pos"; (double&)cAnimation["Speed"] = 1.f; } } From 88ad127d8de062991ac047afbbf48908ea4224d3 Mon Sep 17 00:00:00 2001 From: stiffly Date: Tue, 2 Feb 2016 14:57:03 +0100 Subject: [PATCH 040/131] plays notification on captured/lost point --- resources/Schema/Entities/aim_rays.xml | 51 ++++++++++++++++++++++++++ src/Engine/Sound/SoundSystem.cpp | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/resources/Schema/Entities/aim_rays.xml b/resources/Schema/Entities/aim_rays.xml index c488ca51..c8dac9a3 100644 --- a/resources/Schema/Entities/aim_rays.xml +++ b/resources/Schema/Entities/aim_rays.xml @@ -205,6 +205,57 @@ + + + + + + + + + + Models\Core\UnitCube.mesh + + + + + + + + + + + + + + + + + + + + + + + 1 + + + Models\Core\UnitCube.mesh + + + + + + + + + + + + + + + diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index d08232ec..e5684ac3 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -365,7 +365,7 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) bool SoundSystem::OnCaptured(const Events::Captured & e) { - int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "CapturePoint")["HomePointForTeam"]; + int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"]; int team = (int)m_World->GetComponent(m_LocalPlayer, "Team")["Team"]; Events::PlaySoundOnEntity ev; if (team == homeTeam) { From 5e472cd69c9a24bc090211c7c15daf10ea6ee0bc Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Tue, 2 Feb 2016 17:18:12 +0100 Subject: [PATCH 041/131] DeathExplosion is now an XML file, changed PlayerDeathSystem accordingly. The effect should show as soon as the explosioneffect-fix is merged into master. TODO: remove the test --- include/Engine/Core/EPlayerDeath.h | 2 - include/Game/Systems/PlayerDeathSystem.h | 8 ++ .../PlayerDeathExplosionWithCamera.xml | 48 +++++++++ src/Game/Systems/HealthSystem.cpp | 1 - src/Game/Systems/PlayerDeathSystem.cpp | 102 +++++++++--------- src/Tests/CapturePointTest.cpp | 8 +- 6 files changed, 114 insertions(+), 55 deletions(-) create mode 100644 resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml diff --git a/include/Engine/Core/EPlayerDeath.h b/include/Engine/Core/EPlayerDeath.h index 53dfd013..363745a6 100644 --- a/include/Engine/Core/EPlayerDeath.h +++ b/include/Engine/Core/EPlayerDeath.h @@ -10,8 +10,6 @@ namespace Events struct PlayerDeath : Event { //KilledBy,KilledByWhat is optional for now. It might be used later in the playerlog-system - EntityID KilledBy; - EntityID PlayerID; EntityWrapper Player; std::string KilledByWhat; }; diff --git a/include/Game/Systems/PlayerDeathSystem.h b/include/Game/Systems/PlayerDeathSystem.h index c59aea03..4734947e 100644 --- a/include/Game/Systems/PlayerDeathSystem.h +++ b/include/Game/Systems/PlayerDeathSystem.h @@ -7,7 +7,11 @@ #include "Rendering/ESetCamera.h" #include "Core/ConfigFile.h" +#include "Core/EntityFile.h" +#include "Core/EntityFileParser.h" + #include "Core/EPlayerDeath.h" +#include "Core/EPlayerDamage.h" class PlayerDeathSystem : public ImpureSystem { @@ -19,5 +23,9 @@ public: private: EventRelay m_OnPlayerDeath; bool OnPlayerDeath(Events::PlayerDeath& e); + + EventRelay m_OnInputCommand; + bool OnInputCommand(const Events::InputCommand& e); + }; #endif \ No newline at end of file diff --git a/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml b/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml new file mode 100644 index 00000000..bdebbfe7 --- /dev/null +++ b/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml @@ -0,0 +1,48 @@ + + + + + + Hold Pos + + 0 + + + 8 + + + 0 + 8 + + + + Models/AssaultAnimated.mesh + + true + + + + + + + + + + + 1 + + + 120 + 0.1 + 10000 + + + + + + + + + + + diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 1b747046..18a15828 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -21,7 +21,6 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) if (health <= 0.0) { Events::PlayerDeath ePlayerDeath; - ePlayerDeath.PlayerID = e.Player.ID; ePlayerDeath.Player = e.Player; m_EventBroker->Publish(ePlayerDeath); //Note: we will delete the entity in PlayerDeathSystem diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index 7085a23f..d57caefc 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -3,69 +3,75 @@ PlayerDeathSystem::PlayerDeathSystem(World* m_World, EventBroker* eventBroker) : System(m_World, eventBroker) { + EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerDeathSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath); } +bool PlayerDeathSystem::OnInputCommand(const Events::InputCommand& e) +{ + //testing: Jump > playerdamage + if (e.Command != "Jump") { + return false; + + } + + // 0 = released + if (e.Value != 0) { + return false; + + } + + auto players = m_World->GetComponents("Player"); + + for (auto& cPlayer : *players) { + EntityWrapper player(m_World, cPlayer.EntityID); + Events::PlayerDamage e; + e.Player = player; + e.Damage = 50; + m_EventBroker->Publish(e); + + } + + + + return true; +} + void PlayerDeathSystem::Update(double dt) { } bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) { - //current components for player that we need - auto playerModelEWrapper = e.Player.FirstChildByName("PlayerModel"); - auto playerEntityModel = playerModelEWrapper["Model"]; - auto playerEntityAnimation = playerModelEWrapper["Animation"]; - auto playerEntityTransform = playerModelEWrapper["Transform"]; + //LOAD THE XML + auto deathEffect = ResourceManager::Load("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); - //create new entity with those components - //graphics bug: model must have an animationcomponent to be able to display it - auto newEntity = m_World->CreateEntity(); - ComponentWrapper& newEntityModel = m_World->AttachComponent(newEntity, "Model"); - ComponentWrapper& newAnimationModel = m_World->AttachComponent(newEntity, "Animation"); - ComponentWrapper& newTransformModel = m_World->AttachComponent(newEntity, "Transform"); - playerEntityModel.Copy(newEntityModel); - playerEntityAnimation.Copy(newAnimationModel); - playerEntityTransform.Copy(newTransformModel); + EntityFileParser parser(deathEffect); + EntityID deathEffectID = parser.MergeEntities(m_World); + EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID); + + //current components for player that we need + auto playerModelEW = e.Player.FirstChildByName("PlayerModel"); + auto playerEntityModel = playerModelEW["Model"]; + auto playerEntityTransform = playerModelEW["Transform"]; + + //copy the data from player to new playermodel + playerEntityModel.Copy(deathEffectEW["Model"]); + playerEntityTransform.Copy(deathEffectEW["Transform"]); //change the animation speed and make sure the explosioneffect spawns at the players position - newAnimationModel["Speed"] = (double)0.0; - newEntityModel["Color"] = glm::vec4(1, 0, 0, 1); - newTransformModel["Position"] = (glm::vec3)e.Player["Transform"]["Position"]; - newTransformModel["Scale"] = glm::vec3(1, 1, 1); - - //add the explosion with a lifetime - ComponentWrapper& explosionEffect = m_World->AttachComponent(newEntity, "ExplosionEffect"); - ComponentWrapper& lifeTime = m_World->AttachComponent(newEntity, "Lifetime"); - (glm::vec3)explosionEffect["ExplosionOrigin"] = (glm::vec3)e.Player["Transform"]["Position"]; - (double)explosionEffect["TimeSinceDeath"] = 0.0; - (double)explosionEffect["ExplosionDuration"] = 8.0; - (glm::vec4)explosionEffect["EndColor"] = glm::vec4(0, 0, 0, 1); - (bool)explosionEffect["Randomness"] = false; - (double)explosionEffect["RandomnessScalar"] = 1.0; - (glm::vec2)explosionEffect["Velocity"] = glm::vec2(0.1f, 0.1f); - (bool)explosionEffect["ColorByDistance"] = false; - (bool)explosionEffect["ExponentialAccelaration"] = false; - lifeTime["Lifetime"] = (double)8.0; - - //create a camera (with lifetime) slightly above the player and look down at the player - auto cameraEntity = m_World->CreateEntity(); - ComponentWrapper& thirdPersonCameraLifeTime = m_World->AttachComponent(cameraEntity, "Lifetime"); - ComponentWrapper& thirdPersonCamera = m_World->AttachComponent(cameraEntity, "Camera"); - ComponentWrapper& thirdPersonCameraTransform = m_World->AttachComponent(cameraEntity, "Transform"); - auto pos = (glm::vec3)e.Player["Transform"]["Position"]; - pos.y += 10.0f; - thirdPersonCameraTransform["Position"] = (glm::vec3)pos; //http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/ - thirdPersonCameraTransform["Orientation"] = glm::vec3(-0.7f, 1.46f, 0.8f); - thirdPersonCamera["FOV"] = 120.0; - thirdPersonCamera["NearClip"] = 0.1; - thirdPersonCamera["FarClip"] = 10000.0; - thirdPersonCameraLifeTime["Lifetime"] = (double)1.0; + auto playerPosition = (glm::vec3)e.Player["Transform"]["Position"]; + deathEffectEW["Transform"]["Position"] = playerPosition; + deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = playerPosition; - //set 3rd person camera + //camera (with lifetime) slightly above the player and looking down at the player + //camera will be positioned just above the player + glm::vec3 cameraPosition = glm::vec3(0, 10, 0); + auto cam = deathEffectEW.FirstChildByName("Camera"); + cam["Transform"]["Position"] = cameraPosition; Events::SetCamera eSetCamera; - eSetCamera.CameraEntity = EntityWrapper(m_World, cameraEntity); + eSetCamera.CameraEntity = cam; m_EventBroker->Publish(eSetCamera); //on deathanim done -> del entity diff --git a/src/Tests/CapturePointTest.cpp b/src/Tests/CapturePointTest.cpp index ffb01030..2c7bf430 100644 --- a/src/Tests/CapturePointTest.cpp +++ b/src/Tests/CapturePointTest.cpp @@ -255,14 +255,14 @@ void CapturePointTest::TestSetup8() } void CapturePointTest::DoTouchEvent(EntityID whoDidSomething, EntityID onWhatObject) { Events::TriggerTouch touchEvent; - touchEvent.Entity = whoDidSomething; - touchEvent.Trigger = onWhatObject; + touchEvent.Entity = EntityWrapper(m_World, whoDidSomething); + touchEvent.Trigger = EntityWrapper(m_World, onWhatObject); m_EventBroker->Publish(touchEvent); } void CapturePointTest::DoLeaveEvent(EntityID whoDidSomething, EntityID onWhatObject) { Events::TriggerLeave leaveEvent; - leaveEvent.Entity = whoDidSomething; - leaveEvent.Trigger = onWhatObject; + leaveEvent.Entity = EntityWrapper(m_World, whoDidSomething); + leaveEvent.Trigger = EntityWrapper(m_World, onWhatObject); m_EventBroker->Publish(leaveEvent); } void CapturePointTest::TestSuccess1() { From bb4a65a1db70c66c1bd33c9c9f0d4b86bdc6b793 Mon Sep 17 00:00:00 2001 From: Teejoon Date: Tue, 2 Feb 2016 17:18:42 +0100 Subject: [PATCH 042/131] Non-skined mesh WIP --- include/Engine/Rendering/Model.h | 5 +-- include/Engine/Rendering/RawModelCustom.h | 41 +++++++++++++++++------ src/Engine/Collision/Collision.cpp | 3 +- src/Engine/Rendering/Model.cpp | 27 +++++++++++---- src/Engine/Rendering/RawModelCustom.cpp | 28 ++++++++++++---- 5 files changed, 78 insertions(+), 26 deletions(-) diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index f751a8cc..aeb13e2f 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -16,8 +16,9 @@ public: ~Model(); const std::vector& MaterialGroups() const { return m_RawModel->MaterialGroups; } const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; } - const std::vector& Vertices() const { return m_RawModel->m_Vertices; } - + const RawModel::Vertex* Vertices() const { return m_RawModel->Vertices(); } + unsigned int NumberOfVertices() const { return m_RawModel->NumVertices(); } + bool isSkined() const { return m_RawModel->isSkined; } GLuint VAO; GLuint ElementBuffer; RawModel* m_RawModel; diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index f1bc0e24..ef7a28e5 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -33,17 +33,20 @@ protected: public: ~RawModelCustom(); - struct Vertex - { - glm::vec3 Position; - glm::vec3 Normal; - glm::vec3 Tangent; - glm::vec3 BiNormal; - glm::vec2 TextureCoords; + struct Vertex + { + glm::vec3 Position; + glm::vec3 Normal; + glm::vec3 Tangent; + glm::vec3 BiNormal; + glm::vec2 TextureCoords; + }; + + struct SkinedVertex : public Vertex { glm::vec4 BoneIndices; glm::vec4 BoneWeights; }; - + struct MaterialGroup { float SpecularExponent; @@ -64,15 +67,33 @@ public: std::shared_ptr<::Texture> IncandescenceMap; }; - std::vector MaterialGroups; + const Vertex* Vertices() const { + if (isSkined) { + return m_SkinedVertices.data(); + } else { + return m_Vertices.data(); + } + }; + + unsigned int NumVertices() const { + if (isSkined) { + return m_SkinedVertices.size(); + } else { + return m_Vertices.size(); + } + }; + + std::vector MaterialGroups; + bool isSkined; - std::vector m_Vertices; std::vector m_Indices; Skeleton* m_Skeleton = nullptr; glm::mat4 m_Matrix; private: + std::vector m_Vertices; + std::vector m_SkinedVertices; void ReadMeshFile(std::string filePath); void ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize); diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index b30ae927..4a9c77a0 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -269,7 +269,8 @@ bool attachAABBComponentFromModel(World* world, EntityID id) glm::vec3 mini = glm::vec3(INFINITY, INFINITY, INFINITY); glm::vec3 maxi = glm::vec3(-INFINITY, -INFINITY, -INFINITY); - for (const auto& v : modelRes->Vertices()) { + for (unsigned int i = 0; i < modelRes->NumberOfVertices(); i++) { + const auto& v = modelRes->Vertices()[i]; const auto& wPos = modelMatrix * glm::vec4(v.Position.x, v.Position.y, v.Position.z, 1); maxi.x = std::max(wPos.x, maxi.x); maxi.y = std::max(wPos.y, maxi.y); diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index cf4923a3..129b77fa 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -24,7 +24,12 @@ Model::Model(std::string fileName) GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, m_RawModel->m_Vertices.size() * sizeof(RawModel::Vertex), &m_RawModel->m_Vertices[0], GL_STATIC_DRAW); + + if (m_RawModel->isSkined) { + glBufferData(GL_ARRAY_BUFFER, m_RawModel->NumVertices() * sizeof(RawModel::SkinedVertex), m_RawModel->Vertices(), GL_STATIC_DRAW); + } else { + glBufferData(GL_ARRAY_BUFFER, m_RawModel->NumVertices() * sizeof(RawModel::Vertex), m_RawModel->Vertices(), GL_STATIC_DRAW); + } glGenBuffers(1, &ElementBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer); @@ -35,7 +40,13 @@ Model::Model(std::string fileName) GLERROR("GLEW: BufferFail4"); glBindBuffer(GL_ARRAY_BUFFER, buffer); - std::vector structSizes = { 3, 3, 3, 3, 2, 4, 4 }; + std::vector structSizes; + if (m_RawModel->isSkined) { + structSizes = { 3, 3, 3, 3, 2, 4, 4 }; + } else { + structSizes = { 3, 3, 3, 3, 2 }; + } + int stride = 0; for (int size : structSizes) { stride += size; @@ -49,8 +60,10 @@ Model::Model(std::string fileName) 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++; + if (m_RawModel->isSkined) { + 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"); @@ -59,8 +72,10 @@ Model::Model(std::string fileName) glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); - glEnableVertexAttribArray(5); - glEnableVertexAttribArray(6); + if (m_RawModel->isSkined) { + glEnableVertexAttribArray(5); + glEnableVertexAttribArray(6); + } GLERROR("GLEW: BufferFail5"); //CreateBuffers(); diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 83f6e703..5d3c3fb0 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -40,7 +40,14 @@ void RawModelCustom::ReadMeshFile(std::string filePath) void RawModelCustom::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - m_Vertices.resize(*(unsigned int*)(fileData + offset)); + isSkined = *(unsigned int*)(fileData + offset); + offset += sizeof(bool); + if (isSkined) { + m_SkinedVertices.resize(*(unsigned int*)(fileData + offset)); + } + else { + m_Vertices.resize(*(unsigned int*)(fileData + offset)); + } offset += sizeof(unsigned int); m_Indices.resize(*(unsigned int*)(fileData + offset)); offset += sizeof(unsigned int); @@ -57,12 +64,19 @@ void RawModelCustom::ReadMesh(unsigned int& offset, char* fileData, unsigned int void RawModelCustom::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) { - throw Resource::FailedLoadingException("Reading vertices failed"); - } - - memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(Vertex)); - offset += m_Vertices.size() * sizeof(Vertex); + if (isSkined) { + if (offset + m_SkinedVertices.size() * sizeof(SkinedVertex) > fileByteSize) { + throw Resource::FailedLoadingException("Reading skined vertices failed"); + } + memcpy(&m_SkinedVertices[0], fileData + offset, m_Vertices.size() * sizeof(SkinedVertex)); + offset += m_SkinedVertices.size() * sizeof(SkinedVertex); + } else { + if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) { + throw Resource::FailedLoadingException("Reading vertices failed"); + } + memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(Vertex)); + offset += m_Vertices.size() * sizeof(Vertex); + } #else #endif } From affcc5305bc032b27eb3e50ac222144a0820bfc3 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 2 Feb 2016 17:19:59 +0100 Subject: [PATCH 043/131] Collision affects velocity correctly, no wierd ice cream sliding along walls. --- src/Engine/Collision/Collision.cpp | 48 +++++++++++++++++++----------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index edb6c9a9..81949cb5 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -344,9 +344,10 @@ constexpr float SlopeConstant(float degrees) //An array containing 3 int pairs { 0, 2 }, { 0, 1 }, { 1, 2 } constexpr std::array, 3> dimensionPairs({ std::pair(0, 2), std::pair(0, 1), std::pair(1, 2) }); +//TODO: Prefer to move in y - if the resolution is small enough, value in physics comp. +//TODO: Walking down slopes correctly. bool AABBvsTriangle(const AABB& box, const std::array& triPos, - const glm::vec3& wantDirection, glm::vec3& boxVelocity, glm::vec3& outVector) { @@ -354,7 +355,7 @@ bool AABBvsTriangle(const AABB& box, //Also, don't check a triangle facing away from the player. //Less checks, and we should be able to walk out from models if we are trapped inside. glm::vec3 triNormal = glm::cross(triPos[1] - triPos[0], triPos[2] - triPos[0]); - if (!vectorHasLength(triNormal) || (glm::dot(triNormal, boxVelocity) > 0) && vectorHasLength(boxVelocity)) { + if (!vectorHasLength(triNormal) || (glm::dot(triNormal, boxVelocity) > 0)) { return false; } @@ -428,40 +429,56 @@ bool AABBvsTriangle(const AABB& box, { //If we get here, the resolution is along one coordinate axis. //set velocity to 0 in that dimension. + //projNorm = glm::vec3(0.f); + //projNorm[resolveCase] = 1; + //ImGui::Text(("Axis " + std::string(projNorm.y > SlopeConstant(45.0f) ? "Ground" : "Slope") + "collision proj=(%f,%f,%f)").c_str(), projNorm.x, projNorm.y, projNorm.z); boxVelocity[resolveCase] = 0.f; return true; } case Line: projNorm = glm::normalize(outVector); + //ImGui::Text(("Line " + std::string(projNorm.y > SlopeConstant(45.0f) ? "Ground" : "Slope") + "collision proj=(%f,%f,%f)").c_str(), projNorm.x, projNorm.y, projNorm.z); break; case Corner: projNorm = triNormal; + //ImGui::Text(("Corner " + std::string(projNorm.y > SlopeConstant(45.0f) ? "Ground" : "Slope") + "collision proj=(%f,%f,%f)").c_str(), projNorm.x, projNorm.y, projNorm.z); break; default: break; } - //Project the velocity onto the normal of the hit line/face. - //w = v - *n, |n|==1. - boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; //If the collision was not on steep wall or similarly (e.g. walking on the ground), do special treatment. //Magic value that makes condition correspond to: //if the angle between horizon and the collision surface is less than 45 degrees. if (projNorm.y > SlopeConstant(45.0f)) { - //Make sure the player keeps moving in their desired direction, just slower. - float len = glm::length2(boxVelocity); - if (len > 0.0001f) { - boxVelocity = glm::sqrt(len) * wantDirection; - } - //Ensure that the player always is moved upwards, instead of sliding down. - len = glm::length(outVector); + //Also zero the vertical velocity. + float len = glm::length(outVector); float ang = glm::half_pi() - glm::acos(outVector.y / len); if (len > 0.0000001f && ang > 0.0000001f) { outVector.x = 0; outVector.y = len / glm::sin(ang); outVector.z = 0; + boxVelocity.y = 0.f; } + } else if (projNorm.y > 0) { + //Enter here if the triangle is a steep slope, and it is not facing downwards. + //Project the velocity onto the normal of the hit line/face. + //w = v - *n, |n|==1. + boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; + + //Ensure that the player will be pushed in the xz-plane. + //glm::vec3 moveDir(outVector); + //moveDir.y = 0; + //if (vectorHasLength(moveDir)) { + // moveDir = glm::normalize(moveDir); + // float len = glm::length(outVector); + // float dotMoveOut = moveDir.x * outVector.x + moveDir.z * outVector.z; + // float ang = glm::half_pi() - glm::acos(dotMoveOut / len); + // if (len > 0.0000001f && ang > 0.0000001f) { + // outVector = (len / glm::sin(ang)) * moveDir; + // } + //} } return true; } @@ -477,11 +494,6 @@ bool AABBvsTriangles(const AABB& box, AABB newBox = box; outResolutionVector = glm::vec3(0.f); - glm::vec3 wantDirection(boxVelocity); - wantDirection.y = 0; - if (vectorHasLength(wantDirection)) { - wantDirection = glm::normalize(wantDirection); - } for (int i = 0; i < modelIndices.size(); ) { std::array triVertices = { Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), @@ -489,7 +501,7 @@ bool AABBvsTriangles(const AABB& box, Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) }; glm::vec3 outVec; - if (AABBvsTriangle(newBox, triVertices, wantDirection, boxVelocity, outVec)) { + if (AABBvsTriangle(newBox, triVertices, boxVelocity, outVec)) { hit = true; outResolutionVector += outVec; newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); From 9cb41fcebe5a76747b2d468d54bbe8a5ac445c9c Mon Sep 17 00:00:00 2001 From: antc13 Date: Tue, 2 Feb 2016 17:21:51 +0100 Subject: [PATCH 044/131] Fixed the exported animation matrices --- assets | 2 +- tools/MayaExporter/MayaExporter/Skeleton.cpp | 37 +++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/assets b/assets index 9b2fa74a..c4898d82 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 9b2fa74a6d535d512c13429997385f7aa3fb50f5 +Subproject commit c4898d8281b5584d89b1caf14dab8e5fac120321 diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index a6ee5897..f44b9306 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -216,7 +216,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e int currentFrame = startFrame; - while (currentFrame <= endFrame) { // ANDREAS + while (currentFrame < endFrame) { // ANDREAS Animation::Keyframe thisKeyFrame; thisKeyFrame.Index = currentFrame - startFrame; thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; @@ -280,13 +280,32 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e joinCheckMap[thisJoint.name().asChar()][3][2] = doubleMat[3][2]; joinCheckMap[thisJoint.name().asChar()][3][3] = doubleMat[3][3]; - MTransformationMatrix Matrix = thisJoint.transformation(); - MPlug BindPose = thisJoint.findPlug("bindPose"); + MPlug thisJointBindPose = thisJoint.findPlug("bindPose"); MDataHandle DataHandle; - BindPose.getValue(DataHandle); + thisJointBindPose.getValue(DataHandle); MFnMatrixData MartixFn(DataHandle.data()); - MMatrix BindPoseMatrix = MartixFn.matrix(); - Matrix = Matrix.asMatrix(); + MMatrix thisJointBindPoseMatrix = MartixFn.matrix(); + + MFnTransform Parent(thisJoint.parent(0), &status); + if (status == MS::kSuccess && thisJoint.parent(0).apiType() == MFn::kJoint) { + MTransformationMatrix Matrix = Parent.transformation(); + MPlug parentBindPose = Parent.findPlug("bindPose"); + MDataHandle DataHandle; + parentBindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix parentBindPoseMatrix = MartixFn.matrix(); + + thisJointBindPoseMatrix = thisJointBindPoseMatrix * parentBindPoseMatrix.inverse(); + } + + MTransformationMatrix TransformationMatrix = thisJoint.transformation(); + + if (thisJointBindPoseMatrix.isEquivalent(TransformationMatrix.asMatrix())) { + jointID++; + jointIt.next(); + MGlobal::displayError(MString() + thisJoint.name() + " is in bindPose"); + continue; + } MObject jointOrientObj = thisJoint.attribute("jointOrient"); MFnNumericAttribute jointOrient(jointOrientObj); @@ -302,7 +321,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MQuaternion jo = joEuler.asQuaternion(); double tmp[4]; - Matrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); + TransformationMatrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); MQuaternion rotation(tmp); rotation = rotation * jo; @@ -315,11 +334,11 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e joint.Rotation[1] = tmp[1]; joint.Rotation[2] = tmp[2]; joint.Rotation[3] = tmp[3]; - Matrix.getTranslation(MSpace::kTransform).get(tmp); + TransformationMatrix.getTranslation(MSpace::kTransform).get(tmp); joint.Position[0] = tmp[0]; joint.Position[1] = tmp[1]; joint.Position[2] = tmp[2]; - Matrix.getScale(tmp, MSpace::kTransform); + TransformationMatrix.getScale(tmp, MSpace::kTransform); joint.Scale[0] = tmp[0]; joint.Scale[1] = tmp[1]; joint.Scale[2] = tmp[2]; From 214dad2afc23be62a5fee10e71374667daa32830 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 2 Feb 2016 17:25:59 +0100 Subject: [PATCH 045/131] Removed commented code. --- src/Engine/Collision/Collision.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 81949cb5..083af229 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -429,19 +429,14 @@ bool AABBvsTriangle(const AABB& box, { //If we get here, the resolution is along one coordinate axis. //set velocity to 0 in that dimension. - //projNorm = glm::vec3(0.f); - //projNorm[resolveCase] = 1; - //ImGui::Text(("Axis " + std::string(projNorm.y > SlopeConstant(45.0f) ? "Ground" : "Slope") + "collision proj=(%f,%f,%f)").c_str(), projNorm.x, projNorm.y, projNorm.z); boxVelocity[resolveCase] = 0.f; return true; } case Line: projNorm = glm::normalize(outVector); - //ImGui::Text(("Line " + std::string(projNorm.y > SlopeConstant(45.0f) ? "Ground" : "Slope") + "collision proj=(%f,%f,%f)").c_str(), projNorm.x, projNorm.y, projNorm.z); break; case Corner: projNorm = triNormal; - //ImGui::Text(("Corner " + std::string(projNorm.y > SlopeConstant(45.0f) ? "Ground" : "Slope") + "collision proj=(%f,%f,%f)").c_str(), projNorm.x, projNorm.y, projNorm.z); break; default: break; @@ -466,19 +461,6 @@ bool AABBvsTriangle(const AABB& box, //Project the velocity onto the normal of the hit line/face. //w = v - *n, |n|==1. boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; - - //Ensure that the player will be pushed in the xz-plane. - //glm::vec3 moveDir(outVector); - //moveDir.y = 0; - //if (vectorHasLength(moveDir)) { - // moveDir = glm::normalize(moveDir); - // float len = glm::length(outVector); - // float dotMoveOut = moveDir.x * outVector.x + moveDir.z * outVector.z; - // float ang = glm::half_pi() - glm::acos(dotMoveOut / len); - // if (len > 0.0000001f && ang > 0.0000001f) { - // outVector = (len / glm::sin(ang)) * moveDir; - // } - //} } return true; } From da49dc35eef8bf1da4bc6625923006e7dda59bea Mon Sep 17 00:00:00 2001 From: Teejoon Date: Tue, 2 Feb 2016 17:31:19 +0100 Subject: [PATCH 046/131] Added stuff to .gitignore file --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0df2db42..23056510 100755 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ tools/MayaExporter/x64/Debug/ tools/MayaExporter/MayaExporter/Debug/ tools/MayaExporter/MayaExporter/GeneratedFiles/ + +tools/MayaExporter/MayaExporter/x64/* +tools/MayaExporter/x64/* From a64d227cab6889e127f97d2022776176ce228d2f Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 3 Feb 2016 10:17:53 +0100 Subject: [PATCH 047/131] Assured the volume channels were working. Playing around with drumloop --- assets | 2 +- include/Engine/Sound/SoundSystem.h | 13 ++++++--- src/Engine/Sound/SoundSystem.cpp | 42 +++++++++++++++++++++++------- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/assets b/assets index 5bf03ccd..cde9a430 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 5bf03ccd54bed358d525840635573f931adf584e +Subproject commit cde9a43029fe674a01ede2b74a1987cd57f1074a diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index e161af77..9e636c95 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -9,6 +9,8 @@ #include "OpenAL/al.h" #include "OpenAL/alc.h" +#include "imgui/imgui.h" + #include "Core/World.h" #include "Core/EventBroker.h" #include "Core/Transform.h" // Absolute transform @@ -29,6 +31,7 @@ #include "Core/EPlayerDeath.h" #include "Core/EPlayerHealthPickup.h" #include "Core/EComponentAttached.h" +#include "Collision/ETrigger.h" enum class SoundType { SFX, @@ -90,8 +93,11 @@ private: World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; std::unordered_map m_Sources; - float m_BGMVolumeChannel = 1.f; - float m_SFXVolumeChannel = 1.f; + + + + float m_BGMVolumeChannel = 1.0f; + float m_SFXVolumeChannel = 1.0f; bool m_EditorEnabled = false; const double m_PlayerFootstepInterval = 1.0; double m_TimeSinceLastFootstep = 0; @@ -117,7 +123,6 @@ private: bool OnSetBGMGain(const Events::SetBGMGain &e); // Not tested EventRelay m_ESetSFXGain; bool OnSetSFXGain(const Events::SetSFXGain &e); // Not tested - EventRelay m_EShoot; bool OnShoot(const Events::Shoot &e); EventRelay m_EPlayerSpawned; @@ -134,6 +139,8 @@ private: bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); EventRelay m_EComponentAttached; bool OnComponentAttached(const Events::ComponentAttached &e); + EventRelay m_ETriggerTouch; + bool OnTriggerTouch(const Events::TriggerTouch &e); diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index e5684ac3..08e5c0a8 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -25,6 +25,7 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); } SoundSystem::~SoundSystem() @@ -60,6 +61,10 @@ void SoundSystem::Update(double dt) deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" updateEmitters(dt); updateListener(dt); + + // Editor debug info + ImGui::SliderFloat("BGM", &m_BGMVolumeChannel, 0.0f, 1.0f, "%.3f", 1.0f); + ImGui::SliderFloat("SFX", &m_SFXVolumeChannel, 0.0f, 1.0f, "%.3f", 1.0f); } void SoundSystem::deleteInactiveEmitters() @@ -287,11 +292,12 @@ bool SoundSystem::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { auto emitterChild = m_World->CreateEntity((*it).EntityID); auto emitter = m_World->AttachComponent(emitterChild, "SoundEmitter"); - (bool&)emitter["Loop"] = true; + (bool&)emitter["Loop"] = false; (std::string&)emitter["FilePath"] = e.FilePath; m_World->AttachComponent(emitterChild, "Transform"); Source* source = createSource(e.FilePath); source->Type = SoundType::BGM; + setSoundProperties(source, &emitter); m_Sources[emitterChild] = source; playSound(source); } @@ -334,6 +340,12 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned & e) event.EmitterID = child; event.FilePath = "Audio/announcer/go.wav"; m_EventBroker->Publish(event); + // TEMP: starts bgm + { + Events::PlayBackgroundMusic ev; + ev.FilePath = "Audio/bgm/ambient.wav"; + m_EventBroker->Publish(ev); + } } return true; } @@ -384,15 +396,15 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) { //if (e.Player.ID == m_LocalPlayer) { - Events::PlaySoundOnEntity ev; - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; - std::uniform_int_distribution dist(1, 12); - int rand = dist(generator); - ev.FilePath = "Audio/hurt/hurt" + std::to_string(rand) + ".wav"; - m_EventBroker->Publish(ev); + Events::PlaySoundOnEntity ev; + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + ev.EmitterID = child; + std::uniform_int_distribution dist(1, 12); + int rand = dist(generator); + ev.FilePath = "Audio/hurt/hurt" + std::to_string(rand) + ".wav"; + m_EventBroker->Publish(ev); //} return false; } @@ -433,6 +445,16 @@ bool SoundSystem::OnComponentAttached(const Events::ComponentAttached & e) return false; } +bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) +{ + if (m_World->HasComponent(e.Trigger.ID, "CapturePoint")) { + Events::PlayBackgroundMusic ev; + ev.FilePath = "Audio/bgm/drumstest.wav"; + m_EventBroker->Publish(ev); + } + return false; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector. From 455e59a04f01b71e0317a83447fdb7f9d970ab38 Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 3 Feb 2016 11:39:18 +0100 Subject: [PATCH 048/131] Made the TEMPORARY capture point boxes transparent. --- src/Game/Systems/CapturePointSystem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Game/Systems/CapturePointSystem.cpp b/src/Game/Systems/CapturePointSystem.cpp index d26dde5f..a943e234 100644 --- a/src/Game/Systems/CapturePointSystem.cpp +++ b/src/Game/Systems/CapturePointSystem.cpp @@ -57,7 +57,7 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp int blueTeamPlayersStandingInside = 0; if (capturePointEntity.HasComponent("Model")) { //Now sets team color to the capturepoint, or white if it is uncaptured. - capturePointEntity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 1) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 1) : glm::vec4(1, 1, 1, 1); + capturePointEntity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 0.3) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 0.3) : glm::vec4(1, 1, 1, 0.3); } //calculate next possible capturePoint for both teams @@ -106,10 +106,10 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp //colorize next possible capturepoint if (nextPossibleCapturePoint["Red"] == capturePointNumber) { - capturePointEntity["Model"]["Color"] = glm::vec4(1, 1, 0, 1); + capturePointEntity["Model"]["Color"] = glm::vec4(1, 1, 0, 0.3); } if (nextPossibleCapturePoint["Blue"] == capturePointNumber) { - capturePointEntity["Model"]["Color"] = glm::vec4(0, 1, 1, 1); + capturePointEntity["Model"]["Color"] = glm::vec4(0, 1, 1, 0.3); } //check how many players are standing inside and are healthy From 2961f198b3e71546405343e34f7fa0e4a7175b4c Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 3 Feb 2016 11:48:22 +0100 Subject: [PATCH 049/131] PlayerDeathSystem is now working well. Changed so the model is oriented correctly. Changed so camera is behind the player. Copied the current animation and froze it. --- .../PlayerDeathExplosionWithCamera.xml | 5 ++- src/Game/Systems/PlayerDeathSystem.cpp | 37 ++++++++++--------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml b/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml index bdebbfe7..ff33476d 100644 --- a/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml +++ b/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml @@ -8,12 +8,13 @@ 0 - 8 + 4 0 - 8 + 4 + Models/AssaultAnimated.mesh diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index d57caefc..d6680928 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -43,38 +43,39 @@ void PlayerDeathSystem::Update(double dt) bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) { - //LOAD THE XML + //load the explosioneffect XML auto deathEffect = ResourceManager::Load("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); EntityFileParser parser(deathEffect); EntityID deathEffectID = parser.MergeEntities(m_World); EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID); - - //current components for player that we need - auto playerModelEW = e.Player.FirstChildByName("PlayerModel"); - auto playerEntityModel = playerModelEW["Model"]; - auto playerEntityTransform = playerModelEW["Transform"]; - //copy the data from player to new playermodel + //components that we need from player + auto playerCamera = e.Player.FirstChildByName("Camera"); + auto playerEntityModel = e.Player.FirstChildByName("PlayerModel")["Model"]; + auto playerEntityAnimation = e.Player.FirstChildByName("PlayerModel")["Animation"]; + + //copy the data from player to explisioneffectmodel playerEntityModel.Copy(deathEffectEW["Model"]); - playerEntityTransform.Copy(deathEffectEW["Transform"]); + playerEntityAnimation.Copy(deathEffectEW["Animation"]); + //freeze the animation + deathEffectEW["Animation"]["Speed"] = 0.0; - //change the animation speed and make sure the explosioneffect spawns at the players position - //http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/ - auto playerPosition = (glm::vec3)e.Player["Transform"]["Position"]; - deathEffectEW["Transform"]["Position"] = playerPosition; - deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = playerPosition; + //copy the models position,orientation + deathEffectEW["Transform"]["Position"] = (glm::vec3)e.Player["Transform"]["Position"]; + deathEffectEW["Transform"]["Orientation"] = (glm::vec3)e.Player["Transform"]["Orientation"]; + //effect,camera is relative to playersPosition + deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = glm::vec3(0, 0, 0); - //camera (with lifetime) slightly above the player and looking down at the player - //camera will be positioned just above the player - glm::vec3 cameraPosition = glm::vec3(0, 10, 0); + //camera (with lifetime) behind the player auto cam = deathEffectEW.FirstChildByName("Camera"); - cam["Transform"]["Position"] = cameraPosition; + cam["Transform"]["Position"] = glm::vec3(0, 2.5f, 1.8f); + cam["Transform"]["Orientation"] = glm::vec3(5.655f, 0, 0); Events::SetCamera eSetCamera; eSetCamera.CameraEntity = cam; m_EventBroker->Publish(eSetCamera); - //on deathanim done -> del entity + //done -> del entity m_World->DeleteEntity(e.Player.ID); return true; } From 7bae2d08730c646aad8e2813aaa080885ac9e441 Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 3 Feb 2016 11:58:06 +0100 Subject: [PATCH 050/131] Added a ShieldComponent and a test area in QA map for defender shield --- include/Engine/Rendering/DrawFinalPass.h | 1 + resources/Schema/Components.xsd | 1 + .../Schema/Components/ShieldComponent.xml | 3 + .../Schema/Components/ShieldComponent.xsd | 7 + .../Schema/Entities/QualityAssurance.xml | 309 ++++++++++++++++-- 5 files changed, 302 insertions(+), 19 deletions(-) create mode 100644 resources/Schema/Components/ShieldComponent.xml create mode 100644 resources/Schema/Components/ShieldComponent.xsd diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 74f505fe..4b2bcf1f 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -30,6 +30,7 @@ public: private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const; + void DrawModelRenderQueues(std::list>& job, RenderScene& scene); void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index bb1fd770..24af1f47 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -30,4 +30,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/ShieldComponent.xml b/resources/Schema/Components/ShieldComponent.xml new file mode 100644 index 00000000..855ead48 --- /dev/null +++ b/resources/Schema/Components/ShieldComponent.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/ShieldComponent.xsd b/resources/Schema/Components/ShieldComponent.xsd new file mode 100644 index 00000000..0076477d --- /dev/null +++ b/resources/Schema/Components/ShieldComponent.xsd @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index e057cf38..90c52820 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -188,7 +188,7 @@ - + @@ -586,7 +586,7 @@ true - + @@ -683,7 +683,7 @@ - + @@ -730,7 +730,7 @@ - + @@ -790,7 +790,7 @@ - + @@ -837,7 +837,7 @@ - + @@ -883,7 +883,7 @@ - + @@ -930,7 +930,7 @@ - + @@ -977,7 +977,7 @@ - + @@ -1038,7 +1038,7 @@ Models/Core/UnitCube.mesh - + true @@ -1088,7 +1088,8 @@ Models/Core/UnitCube.mesh - + + true @@ -1131,6 +1132,7 @@ Models/Core/UnitCube.mesh + true @@ -1177,7 +1179,8 @@ Models/Core/UnitCube.mesh - + + true @@ -1225,7 +1228,7 @@ Models/Core/UnitCube.mesh - + true @@ -1374,7 +1377,7 @@ - + @@ -1383,7 +1386,7 @@ true - 0.75008034908941568 + 0.7502397033169681 3.7999999523162842 true @@ -1430,7 +1433,7 @@ - + @@ -1439,7 +1442,7 @@ - 1.1999860997035228 + 1.2001454539310752 Models/Assault.mesh @@ -1482,7 +1485,7 @@ - + @@ -1497,7 +1500,7 @@ true - 0.68343188336345406 + 0.68359123759100648 true @@ -1553,6 +1556,274 @@ + + + + + + + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Camera.mesh + false + + + + + + + + + + + + + + + + + + + 1 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Models/CrosshairQuad.mesh + + + + + + + + + + + + + true + + 3.7999999523162842 + + true + + + Models/AssaultWeaponRed.mesh + + + + + + + + + + + + + + + + + + + + + + + + + Models/Camera.mesh + false + + + + + + + + + + + + Hold Pos + + 1 + + + + Models/AssaultAnimated.mesh + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + + + + + + + + + Models/Log.mesh + + + + + + + + + + + + Models/BushAlive.mesh + + + + + + + + + + + + + + + Defender Shield Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + From 83713b3b6d3bb9a949cb2cce464d3a97351f3a2b Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 3 Feb 2016 13:27:46 +0100 Subject: [PATCH 051/131] Renamde ShieldComponent since Component should not be in the name. Added Shielded component that will be put on objects that should be hidden behind shields. --- resources/Schema/Components.xsd | 3 ++- resources/Schema/Components/Shield.xml | 3 +++ .../Schema/Components/{ShieldComponent.xsd => Shield.xsd} | 2 +- resources/Schema/Components/ShieldComponent.xml | 3 --- resources/Schema/Components/Shielded.xml | 3 +++ resources/Schema/Components/Shielded.xsd | 7 +++++++ resources/Schema/Entities/QualityAssurance.xml | 2 +- 7 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 resources/Schema/Components/Shield.xml rename resources/Schema/Components/{ShieldComponent.xsd => Shield.xsd} (83%) delete mode 100644 resources/Schema/Components/ShieldComponent.xml create mode 100644 resources/Schema/Components/Shielded.xml create mode 100644 resources/Schema/Components/Shielded.xsd diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 24af1f47..368de22c 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -30,5 +30,6 @@ - + + \ No newline at end of file diff --git a/resources/Schema/Components/Shield.xml b/resources/Schema/Components/Shield.xml new file mode 100644 index 00000000..161f09bc --- /dev/null +++ b/resources/Schema/Components/Shield.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/ShieldComponent.xsd b/resources/Schema/Components/Shield.xsd similarity index 83% rename from resources/Schema/Components/ShieldComponent.xsd rename to resources/Schema/Components/Shield.xsd index 0076477d..9831cbfc 100644 --- a/resources/Schema/Components/ShieldComponent.xsd +++ b/resources/Schema/Components/Shield.xsd @@ -2,6 +2,6 @@ - + \ No newline at end of file diff --git a/resources/Schema/Components/ShieldComponent.xml b/resources/Schema/Components/ShieldComponent.xml deleted file mode 100644 index 855ead48..00000000 --- a/resources/Schema/Components/ShieldComponent.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/resources/Schema/Components/Shielded.xml b/resources/Schema/Components/Shielded.xml new file mode 100644 index 00000000..0d95fb0a --- /dev/null +++ b/resources/Schema/Components/Shielded.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/Shielded.xsd b/resources/Schema/Components/Shielded.xsd new file mode 100644 index 00000000..b2348cf5 --- /dev/null +++ b/resources/Schema/Components/Shielded.xsd @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index 90c52820..b15e9309 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -1568,7 +1568,7 @@ Models/Core/UnitHexagon.mesh - + From 7ffbd8455f435f5cbd8aeec8e312a93981bed9fd Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 3 Feb 2016 13:53:57 +0100 Subject: [PATCH 052/131] Added Queues for the models with shield and shielded components. --- include/Engine/Rendering/RenderQueue.h | 28 +++++++++++++++-------- include/Engine/Rendering/RenderSystem.h | 2 +- src/Engine/Editor/EditorRenderSystem.cpp | 6 ++--- src/Engine/Rendering/DrawFinalPass.cpp | 4 ++-- src/Engine/Rendering/LightCullingPass.cpp | 6 ++--- src/Engine/Rendering/PickingPass.cpp | 4 ++-- src/Engine/Rendering/RenderSystem.cpp | 19 +++++++-------- src/Engine/Rendering/Renderer.cpp | 2 +- src/Engine/Rendering/TextPass.cpp | 2 +- 9 files changed, 41 insertions(+), 32 deletions(-) diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index af9d928e..5cc6fd78 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -19,22 +19,30 @@ struct RenderScene { ::Camera* Camera = nullptr; - std::list> OpaqueObjects; - std::list> TransparentObjects; - std::list> PointLightJobs; - std::list> TextJobs; - std::list> DirectionalLightJobs; + struct Queues { + std::list> OpaqueObjects; + std::list> TransparentObjects; + std::list> OpaqueShieldedObjects; + std::list> TransparentShieldedObjects; + std::list> ShieldObjects; + std::list> PointLight; + std::list> Text; + std::list> DirectionalLight; + } Jobs; + Rectangle Viewport; bool ClearDepth = false; glm::vec4 AmbientColor; void Clear() { - OpaqueObjects.clear(); - TransparentObjects.clear(); - PointLightJobs.clear(); - TextJobs.clear(); - DirectionalLightJobs.clear(); + Jobs.OpaqueObjects.clear(); + Jobs.TransparentObjects.clear(); + Jobs.OpaqueShieldedObjects.clear(); + Jobs.TransparentShieldedObjects.clear(); + Jobs.ShieldObjects.clear(); + Jobs.Text.clear(); + Jobs.DirectionalLight.clear(); } }; diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index d64147b9..5845d9d3 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -40,7 +40,7 @@ private: EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(Events::PlayerSpawned& e); - void fillModels(std::list>& opaqueJobs, std::list>& transparentJobs); + void fillModels(RenderScene::Queues &jobs); void fillText(std::list>& jobs, World* world); void fillPointLights(std::list>& jobs, World* world); void fillDirectionalLights(std::list>& jobs, World* world); diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp index 4d65e9d3..c5e90865 100644 --- a/src/Engine/Editor/EditorRenderSystem.cpp +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -56,9 +56,9 @@ void EditorRenderSystem::Update(double dt) for (auto matGroup : model->MaterialGroups()) { std::shared_ptr modelJob = std::make_shared(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f); if (cModel["Transparent"]) { - scene.TransparentObjects.push_back(modelJob); + scene.Jobs.TransparentObjects.push_back(modelJob); } else { - scene.OpaqueObjects.push_back(modelJob); + scene.Jobs.OpaqueObjects.push_back(modelJob); } } } @@ -75,7 +75,7 @@ void EditorRenderSystem::Update(double dt) EntityWrapper entity(m_World, cPointLight.EntityID); ComponentWrapper& cTransform = entity["Transform"]; std::shared_ptr pointLightJob = std::make_shared(cTransform, cPointLight, entity.World); - scene.PointLightJobs.push_back(pointLightJob); + scene.Jobs.PointLight.push_back(pointLightJob); } } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 8247797e..8e015373 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -66,9 +66,9 @@ void DrawFinalPass::Draw(RenderScene& scene) glClear(GL_DEPTH_BUFFER_BIT); } - DrawModelRenderQueues(scene.OpaqueObjects, scene); + DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); GLERROR("OpaqueObjects"); - DrawModelRenderQueues(scene.TransparentObjects, scene); + DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); GLERROR("TransparentObjects"); delete state; diff --git a/src/Engine/Rendering/LightCullingPass.cpp b/src/Engine/Rendering/LightCullingPass.cpp index 5e6da64d..0ae359db 100644 --- a/src/Engine/Rendering/LightCullingPass.cpp +++ b/src/Engine/Rendering/LightCullingPass.cpp @@ -16,7 +16,7 @@ LightCullingPass::~LightCullingPass() void LightCullingPass::GenerateNewFrustum(RenderScene& scene) { - if (scene.PointLightJobs.size() == 0) + if (scene.Jobs.PointLight.size() == 0) return; GLERROR("CalculateFrustum Error: Pre"); @@ -83,7 +83,7 @@ void LightCullingPass::FillLightList(RenderScene& scene) { m_LightSources.clear(); - for(auto &job : scene.PointLightJobs) { + for(auto &job : scene.Jobs.PointLight) { auto pointLightjob = std::dynamic_pointer_cast(job); if (pointLightjob) { LightSource p; @@ -97,7 +97,7 @@ void LightCullingPass::FillLightList(RenderScene& scene) m_LightSources.push_back(p); } } - for(auto &job : scene.DirectionalLightJobs) { + for(auto &job : scene.Jobs.DirectionalLight) { auto directionalLightJob = std::dynamic_pointer_cast(job); if(directionalLightJob) { LightSource p; diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index abc79f2e..3baf2b2a 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -56,7 +56,7 @@ void PickingPass::Draw(RenderScene& scene) } m_Camera = scene.Camera; - for (auto &job : scene.OpaqueObjects) { + for (auto &job : scene.Jobs.OpaqueObjects) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { @@ -102,7 +102,7 @@ void PickingPass::Draw(RenderScene& scene) } } - for (auto &job : scene.TransparentObjects) { + for (auto &job : scene.Jobs.TransparentObjects) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index eaecf99e..9711cea1 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -40,7 +40,7 @@ bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity) return entity == m_CurrentCamera || entity.IsChildOf(m_CurrentCamera); } -void RenderSystem::fillModels(std::list>& opaqueJobs, std::list>& transparentJobs) +void RenderSystem::fillModels(RenderScene::Queues &Jobs) { auto models = m_World->GetComponents("Model"); if (models == nullptr) { @@ -106,14 +106,15 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, fillColor, fillPercentage )); + if(explosionEffectJob->Color.a != 1.f || explosionEffectJob->EndColor.a != 1.f || explosionEffectJob->DiffuseColor.a != 1.f) { cModel["Transparent"] = true; } if (cModel["Transparent"]) { - transparentJobs.push_back(explosionEffectJob); + Jobs.TransparentObjects.push_back(explosionEffectJob); } else { - opaqueJobs.push_back(explosionEffectJob); + Jobs.OpaqueObjects.push_back(explosionEffectJob); } } else { std::shared_ptr modelJob = std::shared_ptr(new ModelJob( @@ -130,9 +131,9 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, cModel["Transparent"] = true; } if (cModel["Transparent"]) { - transparentJobs.push_back(modelJob); + Jobs.TransparentObjects.push_back(modelJob); } else { - opaqueJobs.push_back(modelJob); + Jobs.OpaqueObjects.push_back(modelJob); } } } @@ -251,10 +252,10 @@ void RenderSystem::Update(double dt) scene.AmbientColor = (glm::vec4)(*cSceneLight->begin())["AmbientColor"]; } - fillModels(scene.OpaqueObjects, scene.TransparentObjects); - fillPointLights(scene.PointLightJobs, m_World); - fillDirectionalLights(scene.DirectionalLightJobs, m_World); - fillText(scene.TextJobs, m_World); + fillModels(scene.Jobs); + fillPointLights(scene.Jobs.PointLight, m_World); + fillDirectionalLights(scene.Jobs.DirectionalLight, m_World); + fillText(scene.Jobs.Text, m_World); m_RenderFrame->Add(scene); } \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index a63e02a0..fa3d1709 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -154,7 +154,7 @@ void Renderer::InitializeTextures() void Renderer::SortRenderJobsByDepth(RenderScene &scene) { //Sort all forward jobs so transparency is good. - scene.TransparentObjects.sort(Renderer::DepthSort); + scene.Jobs.TransparentObjects.sort(Renderer::DepthSort); } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) diff --git a/src/Engine/Rendering/TextPass.cpp b/src/Engine/Rendering/TextPass.cpp index 1e3d5941..9583fcfd 100644 --- a/src/Engine/Rendering/TextPass.cpp +++ b/src/Engine/Rendering/TextPass.cpp @@ -35,7 +35,7 @@ void TextPass::Draw(RenderScene& scene, FrameBuffer& frameBuffer) { GLERROR("Derp1"); TextPassState* state = new TextPassState(frameBuffer.GetHandle()); - for (auto &job : scene.TextJobs) { + for (auto &job : scene.Jobs.Text) { auto textJob = std::dynamic_pointer_cast(job); if (textJob) { From 5665c0f298d2b1e4b65b2842b180843b50543fab Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 3 Feb 2016 14:20:47 +0100 Subject: [PATCH 053/131] Models with Shield and shielded component now added to queues --- .../Schema/Entities/QualityAssurance.xml | 32 +++++----- src/Engine/Rendering/RenderSystem.cpp | 58 +++++++++++++++---- 2 files changed, 63 insertions(+), 27 deletions(-) diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index b15e9309..cb75b7b3 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -40,7 +40,7 @@ - + @@ -188,7 +188,7 @@ - + @@ -683,7 +683,7 @@ - + @@ -730,7 +730,7 @@ - + @@ -790,7 +790,7 @@ - + @@ -837,7 +837,7 @@ - + @@ -883,7 +883,7 @@ - + @@ -930,7 +930,7 @@ - + @@ -977,7 +977,7 @@ - + @@ -1377,7 +1377,7 @@ - + @@ -1386,7 +1386,7 @@ true - 0.7502397033169681 + 0.75055150002244431 3.7999999523162842 true @@ -1433,7 +1433,7 @@ - + @@ -1442,7 +1442,7 @@ - 1.2001454539310752 + 1.2004572506365514 Models/Assault.mesh @@ -1485,7 +1485,7 @@ - + @@ -1500,7 +1500,7 @@ true - 0.68359123759100648 + 0.68390303429648269 true @@ -1581,6 +1581,7 @@ Models/Core/UnitCube.mesh + @@ -1690,6 +1691,7 @@ true + 0.0003117967054762083 3.7999999523162842 true diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 9711cea1..623e7101 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -92,7 +92,9 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) } glm::mat4 modelMatrix = Transform::ModelMatrix(cModel.EntityID, m_World); + //Loop through all materialgroups of a model for (auto matGroup : model->MaterialGroups()) { + //If the model has an explosioneffect component, we will add an explosioneffectjob if (m_World->HasComponent(cModel.EntityID, "ExplosionEffect")) { auto explosionEffectComponent = m_World->GetComponent(cModel.EntityID, "ExplosionEffect"); std::shared_ptr explosionEffectJob = std::shared_ptr(new ExplosionEffectJob( @@ -106,15 +108,30 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) fillColor, fillPercentage )); + if (m_World->HasComponent(cModel.EntityID, "Shield")){ + Jobs.ShieldObjects.push_back(explosionEffectJob); + } else if (m_World->HasComponent(cModel.EntityID, "Shielded") + || m_World->HasComponent(cModel.EntityID, "Player")) { - if(explosionEffectJob->Color.a != 1.f || explosionEffectJob->EndColor.a != 1.f || explosionEffectJob->DiffuseColor.a != 1.f) { - cModel["Transparent"] = true; - } + if (explosionEffectJob->Color.a != 1.f || explosionEffectJob->EndColor.a != 1.f || explosionEffectJob->DiffuseColor.a != 1.f) { + cModel["Transparent"] = true; + } - if (cModel["Transparent"]) { - Jobs.TransparentObjects.push_back(explosionEffectJob); + if (cModel["Transparent"]) { + Jobs.TransparentShieldedObjects.push_back(explosionEffectJob); + } else { + Jobs.OpaqueShieldedObjects.push_back(explosionEffectJob); + } } else { - Jobs.OpaqueObjects.push_back(explosionEffectJob); + if (explosionEffectJob->Color.a != 1.f || explosionEffectJob->EndColor.a != 1.f || explosionEffectJob->DiffuseColor.a != 1.f) { + cModel["Transparent"] = true; + } + + if (cModel["Transparent"]) { + Jobs.TransparentObjects.push_back(explosionEffectJob); + } else { + Jobs.OpaqueObjects.push_back(explosionEffectJob); + } } } else { std::shared_ptr modelJob = std::shared_ptr(new ModelJob( @@ -127,13 +144,30 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) fillColor, fillPercentage )); - if (modelJob->Color.a != 1.f || modelJob->DiffuseColor.a != 1.f) { - cModel["Transparent"] = true; - } - if (cModel["Transparent"]) { - Jobs.TransparentObjects.push_back(modelJob); + if (m_World->HasComponent(cModel.EntityID, "Shield")) { + Jobs.ShieldObjects.push_back(modelJob); + } else if (m_World->HasComponent(cModel.EntityID, "Shielded") + || m_World->HasComponent(cModel.EntityID, "Player")) { + + if (modelJob->Color.a != 1.f || modelJob->DiffuseColor.a != 1.f) { + cModel["Transparent"] = true; + } + + if (cModel["Transparent"]) { + Jobs.TransparentShieldedObjects.push_back(modelJob); + } else { + Jobs.OpaqueShieldedObjects.push_back(modelJob); + } } else { - Jobs.OpaqueObjects.push_back(modelJob); + if (modelJob->Color.a != 1.f || modelJob->DiffuseColor.a != 1.f) { + cModel["Transparent"] = true; + } + + if (cModel["Transparent"]) { + Jobs.TransparentObjects.push_back(modelJob); + } else { + Jobs.OpaqueObjects.push_back(modelJob); + } } } } From 938caa6ba2809023cbfb9bd096f5f8481ae394c3 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 3 Feb 2016 15:48:25 +0100 Subject: [PATCH 054/131] Now uses OnComponentAttached event. Can now queue sound on a source. --- assets | 2 +- include/Engine/Sound/SoundSystem.h | 17 ++++- src/Engine/Sound/SoundSystem.cpp | 101 +++++++++++++++++++---------- 3 files changed, 81 insertions(+), 39 deletions(-) diff --git a/assets b/assets index cde9a430..29f8e123 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit cde9a43029fe674a01ede2b74a1987cd57f1074a +Subproject commit 29f8e1234661f93ffba656c031d037a9ca484660 diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 9e636c95..20d58933 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -31,7 +31,13 @@ #include "Core/EPlayerDeath.h" #include "Core/EPlayerHealthPickup.h" #include "Core/EComponentAttached.h" +#include "Core/EComponentDeleted.h" +#include "Core/EEntityDeleted.h" #include "Collision/ETrigger.h" +#include "Core/EPause.h" + + +typedef std::pair> QueuedBuffers; enum class SoundType { SFX, @@ -67,7 +73,6 @@ private: // Logic void initOpenAL(); - void addNewEmitters(double dt); void updateEmitters(double dt); void deleteInactiveEmitters(); void stopEmitters(); @@ -79,6 +84,8 @@ private: // Specific logic void playSound(Source* source); + // Need to be the same format (sample rate etc) + void playQueue(QueuedBuffers qb); void stopSound(Source* source); void playerDamaged(); void playerShot(); @@ -94,8 +101,6 @@ private: EventBroker* m_EventBroker = nullptr; std::unordered_map m_Sources; - - float m_BGMVolumeChannel = 1.0f; float m_SFXVolumeChannel = 1.0f; bool m_EditorEnabled = false; @@ -139,8 +144,14 @@ private: bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); EventRelay m_EComponentAttached; bool OnComponentAttached(const Events::ComponentAttached &e); + EventRelay m_EComponentDeleted; + bool OnComponentDeleted(const Events::ComponentDeleted &e); EventRelay m_ETriggerTouch; bool OnTriggerTouch(const Events::TriggerTouch &e); + EventRelay m_EPause; + bool OnPause(const Events::Pause &e); + EventRelay m_EResume; + bool OnResume(const Events::Resume &e); diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 08e5c0a8..ab4c5fce 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -26,6 +26,9 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); + EVENT_SUBSCRIBE_MEMBER(m_EPause, &SoundSystem::OnPause); + EVENT_SUBSCRIBE_MEMBER(m_EResume, &SoundSystem::OnResume); + EVENT_SUBSCRIBE_MEMBER(m_EComponentAttached, &SoundSystem::OnComponentAttached); } SoundSystem::~SoundSystem() @@ -57,7 +60,6 @@ void SoundSystem::Update(double dt) { m_EventBroker->Process(); playerStep(dt); - addNewEmitters(dt); // can be optimized with "EEntityCreated" deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" updateEmitters(dt); updateListener(dt); @@ -87,7 +89,7 @@ void SoundSystem::deleteInactiveEmitters() } } else { // Entity / Component has been removed - stopSound((*it).second); + stopSound(it->second); alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); delete it->second; @@ -96,28 +98,14 @@ void SoundSystem::deleteInactiveEmitters() } } -void SoundSystem::addNewEmitters(double dt) -{ - auto emitterComponents = m_World->GetComponents("SoundEmitter"); - if (emitterComponents == nullptr) { - return; - } - for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { - EntityID emitter = (*it).EntityID; - std::unordered_map::iterator source; - source = m_Sources.find(emitter); - if (source == m_Sources.end()) { // Did not exist, add it - Source* source = createSource((std::string)(*it)["FilePath"]); - m_Sources[emitter] = source; - } - } -} - void SoundSystem::updateEmitters(double dt) { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { // Get previous pos + if (!m_World->ValidEntity(it->first)) { + return; + } glm::vec3 previousPos; alGetSource3f(it->second->ALsource, AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get next pos @@ -180,6 +168,15 @@ void SoundSystem::playSound(Source* source) alSourcePlay(source->ALsource); } +void SoundSystem::playQueue(QueuedBuffers qb) +{ + for (int i = 0; i < qb.second.size(); i++) { + alSourceQueueBuffers(qb.first, 1, &qb.second[i]); + } + alSourcePlay(qb.first); +} + + void SoundSystem::stopSound(Source* source) { alSourceStop(source->ALsource); @@ -210,9 +207,13 @@ void SoundSystem::playerJumps() void SoundSystem::playerStep(double dt) { + if (!m_World->ValidEntity(m_LocalPlayer)) { + return; + } if (m_LocalPlayer == EntityID_Invalid) { return; } + m_TimeSinceLastFootstep += dt; glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; float playerSpeed = glm::length(vel); @@ -260,8 +261,6 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) (float&)(double)emitter["MaxDistance"] = e.MaxDistance; (float&)(double)emitter["RollOffFactor"] = e.RollOffFactor; (float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance; - auto model = m_World->AttachComponent(emitterID, "Model"); - (std::string&)model["Resource"] = "Models/Core/UnitCube.mesh"; // 360NoScope UnitCube source->Type = SoundType::SFX; m_Sources[emitterID] = source; playSound(source); @@ -352,24 +351,20 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned & e) bool SoundSystem::OnInputCommand(const Events::InputCommand & e) { - if (e.Player.ID == EntityID_Invalid) { - //return false; - } if (e.Command == "Jump" && e.Value > 0) { if (e.PlayerID == -1) { // local player - //bool airBorne = ((glm::vec3)m_World->GetComponent(e.Player.ID, "Physics")["Velocity"]).y != 0; - //if (!airBorne) { playerJumps(); - //} return true; } } + // TEMP: testing purpose (obviously) if (e.Command == "TakeDamage" && e.Value > 0) { if (e.PlayerID == -1) { //Local Player Events::PlayerDamage ePlayerDamage; ePlayerDamage.Damage = 1; ePlayerDamage.Player = EntityWrapper(m_World, e.Player.ID); m_EventBroker->Publish(ePlayerDamage); + return true; } } return false; @@ -383,7 +378,7 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) if (team == homeTeam) { ev.FilePath = "Audio/announcer/objective_achieved.wav"; } else { - ev.FilePath = "Audio/announcer/objective_failed.wav"; + ev.FilePath = "Audio/announcer/objective_failed.wav"; // have not been tested } EntityID child = m_World->CreateEntity(m_LocalPlayer); m_World->AttachComponent(child, "Transform"); @@ -395,17 +390,27 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) { - //if (e.Player.ID == m_LocalPlayer) { - Events::PlaySoundOnEntity ev; + // Should check for only local players here... EntityID child = m_World->CreateEntity(m_LocalPlayer); m_World->AttachComponent(child, "Transform"); m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + std::uniform_int_distribution dist(1, 12); int rand = dist(generator); - ev.FilePath = "Audio/hurt/hurt" + std::to_string(rand) + ".wav"; - m_EventBroker->Publish(ev); - //} + Source* source = createSource("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); + source->Type = SoundType::SFX; + m_Sources[child] = source; + //playSound(source); + + // breathe + std::vector buffers; + buffers.push_back(source->SoundResource->Buffer()); + int ammountOfbreaths = (e.Damage / 10) + 2; // TEMP: Idk something stupid like this shit + for (int i = 0; i < ammountOfbreaths; i++) { + buffers.push_back(ResourceManager::Load("Audio/exhausted/breath.wav")->Buffer()); + } + playQueue(QueuedBuffers(std::make_pair(source->ALsource, buffers))); + return false; } @@ -417,7 +422,7 @@ bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) m_World->AttachComponent(child, "Transform"); m_World->AttachComponent(child, "SoundEmitter"); ev.EmitterID = child; - ev.FilePath = "Audio/die/die2.wav"; // random between a bunch + ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch m_EventBroker->Publish(ev); } return false; @@ -440,6 +445,16 @@ bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) bool SoundSystem::OnComponentAttached(const Events::ComponentAttached & e) { if (e.Component.Info.Name == "SoundEmitter") { + auto component = m_World->GetComponent(e.Entity.ID, "SoundEmitter"); + Source* source = createSource(component["FilePath"]); + m_Sources[e.Entity.ID] = source; + } + return false; +} + +bool SoundSystem::OnComponentDeleted(const Events::ComponentDeleted & e) +{ + if (e.ComponentType == "SoundEmitter") { } return false; @@ -455,6 +470,22 @@ bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) return false; } +bool SoundSystem::OnPause(const Events::Pause & e) +{ + for (auto it = m_Sources.begin(); it != m_Sources.end(); it++) { + alSourcePause(it->second->ALsource); + } + return false; +} + +bool SoundSystem::OnResume(const Events::Resume &e) +{ + for (auto it = m_Sources.begin(); it != m_Sources.end(); it++) { + alSourcePlay(it->second->ALsource); + } + return false; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector. From c2833b10c40d9ade38f5548ae97e9323bb948010 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 3 Feb 2016 15:55:32 +0100 Subject: [PATCH 055/131] Hard coded (read retarded) improvements added to player walk logic --- src/Engine/Sound/SoundSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index ab4c5fce..86f3a34b 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -220,7 +220,7 @@ void SoundSystem::playerStep(double dt) bool isAirborne = vel.y != 0; if (playerSpeed > 1 && !isAirborne) { // Player is walking - if (m_TimeSinceLastFootstep * playerSpeed > m_PlayerFootstepInterval) { + if (m_TimeSinceLastFootstep * std::min(playerSpeed, 2) > m_PlayerFootstepInterval) { // Create footstep sound EntityID child = m_World->CreateEntity(m_LocalPlayer); m_World->AttachComponent(child, "Transform"); From bc01e147c27f6a58937a7fd2498f37fcf2bd450e Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 3 Feb 2016 18:09:44 +0100 Subject: [PATCH 056/131] Some state stuff, some draw stuff, some QA map stuff --- include/Engine/Rendering/DrawFinalPass.h | 5 +- include/Engine/Rendering/DrawFinalPassState.h | 7 + include/Engine/Rendering/RenderState.h | 1 + .../Schema/Entities/QualityAssurance.xml | 185 ++++++++++++++---- resources/Schema/Types/Entity.xsd | 2 + resources/Shaders/ShieldStencil.frag.glsl | 15 ++ resources/Shaders/ShieldStencil.vert.glsl | 19 ++ src/Engine/Rendering/DrawFinalPass.cpp | 144 +++++++++++++- src/Engine/Rendering/DrawFinalPassState.cpp | 16 ++ src/Engine/Rendering/RenderState.cpp | 14 ++ 10 files changed, 369 insertions(+), 39 deletions(-) create mode 100644 resources/Shaders/ShieldStencil.frag.glsl create mode 100644 resources/Shaders/ShieldStencil.vert.glsl diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 4b2bcf1f..740c6ef6 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -31,7 +31,9 @@ private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const; - void DrawModelRenderQueues(std::list>& job, RenderScene& scene); + void DrawModelRenderQueues(std::list>& jobs, RenderScene& scene); + void DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene); + void DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene); void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); void BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); @@ -54,6 +56,7 @@ private: ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; + ShaderProgram* m_ShieldToStencilProgram; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/DrawFinalPassState.h b/include/Engine/Rendering/DrawFinalPassState.h index 10b840e9..91fc4cf4 100644 --- a/include/Engine/Rendering/DrawFinalPassState.h +++ b/include/Engine/Rendering/DrawFinalPassState.h @@ -12,4 +12,11 @@ private: }; +class DrawStencilState : public RenderState +{ +public: + DrawStencilState(GLuint frameBuffer); + ~DrawStencilState(); +}; + #endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index 688ef520..ae43c013 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -19,6 +19,7 @@ public: bool BindFramebuffer(GLint framebuffer); bool BlendEquation(GLenum mode); bool BlendFunc(GLenum sfactor, GLenum dfactor); + bool StencilFunc(GLenum sfail, GLenum dpfail, GLenum dppass); bool DepthMask(GLboolean flag); private: diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index cb75b7b3..11fbaf99 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -40,7 +40,7 @@ - + @@ -105,7 +105,7 @@ - + @@ -122,7 +122,7 @@ Run - + 1 @@ -138,7 +138,7 @@ Walk - + 1 @@ -188,7 +188,7 @@ - + @@ -196,7 +196,7 @@ Run - + 1 @@ -237,7 +237,7 @@ - + @@ -301,7 +301,7 @@ - + @@ -333,7 +333,7 @@ - + @@ -683,7 +683,7 @@ - + @@ -730,7 +730,7 @@ - + @@ -790,7 +790,7 @@ - + @@ -837,7 +837,7 @@ - + @@ -883,7 +883,7 @@ - + @@ -930,7 +930,7 @@ - + @@ -977,7 +977,7 @@ - + @@ -1350,6 +1350,19 @@ + + + + ExplosionEffect Test + Fonts/DroidSans.ttf,64 + + + + + + + + @@ -1377,7 +1390,7 @@ - + @@ -1386,7 +1399,7 @@ true - 0.75055150002244431 + 1.3668564709912516 3.7999999523162842 true @@ -1433,7 +1446,7 @@ - + @@ -1442,7 +1455,7 @@ - 1.2004572506365514 + 0.316796204374441 Models/Assault.mesh @@ -1485,7 +1498,7 @@ - + @@ -1493,14 +1506,14 @@ Walk - + 1 true - 0.68390303429648269 + 0.316796204374441 true @@ -1518,18 +1531,120 @@ - + - - ExplosionEffect Test - Fonts/DroidSans.ttf,64 - + + Models/Core/UnitCylinder.mesh + + - - + - + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + true + + + 0.95015514958004132 + 10 + + 3 + true + + + Models/Core/UnitSphere.mesh + + true + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + true + + + 1.3501834109561059 + true + 5 + true + + + Models/Assault.mesh + + true + + + + + + + + + + @@ -1597,7 +1712,7 @@ - + 5 @@ -1608,7 +1723,7 @@ - + @@ -1691,7 +1806,7 @@ true - 0.0003117967054762083 + 1.3668564709912516 3.7999999523162842 true @@ -1736,7 +1851,7 @@ Hold Pos - + 1 diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 028af9e6..972a45e1 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -38,6 +38,8 @@ + + diff --git a/resources/Shaders/ShieldStencil.frag.glsl b/resources/Shaders/ShieldStencil.frag.glsl new file mode 100644 index 00000000..43a067c0 --- /dev/null +++ b/resources/Shaders/ShieldStencil.frag.glsl @@ -0,0 +1,15 @@ +#version 430 + +in VertexData{ + vec3 Position; +}Input; + + +out vec4 fragmentColor; + +void main() +{ + fragmentColor = vec4(0.5, 0.5, 0.5, 1.0); +} + + diff --git a/resources/Shaders/ShieldStencil.vert.glsl b/resources/Shaders/ShieldStencil.vert.glsl new file mode 100644 index 00000000..b6669f2c --- /dev/null +++ b/resources/Shaders/ShieldStencil.vert.glsl @@ -0,0 +1,19 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; + + +out VertexData{ + vec3 Position; +}Output; + +void main() +{ + gl_Position = P * V * M * vec4(Position, 1.0); + + Output.Position = Position; +} \ No newline at end of file diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 8e015373..d2d22514 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -55,6 +55,14 @@ void DrawFinalPass::InitializeShaderPrograms() m_ExplosionEffectProgram->BindFragDataLocation(1, "bloomColor"); m_ExplosionEffectProgram->Link(); GLERROR("Creating explosion program"); + + m_ShieldToStencilProgram = ResourceManager::Load("#ShieldToStencilProgram"); + m_ShieldToStencilProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ShieldStencil.vert.glsl"))); + m_ShieldToStencilProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ShieldStencil.frag.glsl"))); + m_ShieldToStencilProgram->Compile(); + m_ShieldToStencilProgram->Link(); + GLERROR("Creating Shield program"); + } void DrawFinalPass::Draw(RenderScene& scene) @@ -65,14 +73,30 @@ void DrawFinalPass::Draw(RenderScene& scene) if (scene.ClearDepth) { glClear(GL_DEPTH_BUFFER_BIT); } + //might need to clear stencil here DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); GLERROR("OpaqueObjects"); DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); GLERROR("TransparentObjects"); - delete state; + + DrawStencilState* stencilState = new DrawStencilState(m_FinalPassFrameBuffer.GetHandle()); + glClear(GL_STENCIL_BUFFER_BIT); + //Draw shields to stencil pass + DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene); + GLERROR("StencilPass"); + + //Draw Opaque shielded objects + DrawShieldedModelRenderQueue(scene.Jobs.OpaqueShieldedObjects, scene); + GLERROR("Shielded Opaque object"); + + //Draw Transparen Shielded objects + //DrawShieldedModelRenderQueue(scene.Jobs.TransparentShieldedObjects, scene); + GLERROR("Shielded Transparent objects"); + GLERROR("END"); + delete stencilState; } @@ -110,7 +134,7 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm: GLERROR("MipMap Texture initialization failed"); } -void DrawFinalPass::DrawModelRenderQueues(std::list>& job, RenderScene& scene) +void DrawFinalPass::DrawModelRenderQueues(std::list>& jobs, RenderScene& scene) { GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); GLERROR("forwardHandle"); @@ -121,7 +145,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); - for(auto &job : job) + for(auto &job : jobs) { auto explosionEffectJob = std::dynamic_pointer_cast(job); if(explosionEffectJob) { @@ -201,6 +225,120 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } + +void DrawFinalPass::DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene) +{ + m_ShieldToStencilProgram->Bind(); + GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle(); + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + + for (auto &job : jobs) { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); + if (GLERROR("models end")) { + continue; + } + } + } +} + +void DrawFinalPass::DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene) +{ + GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); + GLERROR("forwardHandle"); + GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle(); + GLERROR("explosionHandle"); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); + + for (auto &job : jobs) { + auto explosionEffectJob = std::dynamic_pointer_cast(job); + if (explosionEffectJob) { + //Bind program + if (GLERROR("Prebind")) { + continue; + } + m_ExplosionEffectProgram->Bind(); + if (GLERROR("BindProgram")) { + continue; + } + + glDisable(GL_CULL_FACE); + + //Bind uniforms + BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); + if (GLERROR("BindExplosionUniforms")) { + continue; + } + + if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { + + if (explosionEffectJob->Animation != nullptr) { + std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + if (GLERROR("Animation")) { + continue; + } + + //bind textures + BindExplosionTextures(explosionEffectJob); + if (GLERROR("BindExplosionTextures")) { + continue; + } + //draw + glBindVertexArray(explosionEffectJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int))); + glEnable(GL_CULL_FACE); + if (GLERROR("explosion effect end")) { + continue; + } + + } else { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + //bind forward program + m_ForwardPlusProgram->Bind(); + glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + + //bind uniforms + BindModelUniforms(forwardHandle, modelJob, scene); + + //bind textures + BindModelTextures(modelJob); + + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + + //draw + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); + if (GLERROR("models end")) { + continue; + } + } + } + } +} + void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) { glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); diff --git a/src/Engine/Rendering/DrawFinalPassState.cpp b/src/Engine/Rendering/DrawFinalPassState.cpp index 3ebe320d..d85d476c 100644 --- a/src/Engine/Rendering/DrawFinalPassState.cpp +++ b/src/Engine/Rendering/DrawFinalPassState.cpp @@ -1,6 +1,7 @@ #include "Rendering/DrawFinalPassState.h" + DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer) { BindFramebuffer(frameBuffer); @@ -15,3 +16,18 @@ DrawFinalPassState::~DrawFinalPassState() { } + +DrawStencilState::DrawStencilState(GLuint frameBuffer) +{ + BindFramebuffer(frameBuffer); + Enable(GL_STENCIL_TEST); + StencilFunc(GL_KEEP, GL_KEEP, GL_REPLACE); + Enable(GL_DEPTH_TEST); + ClearColor(glm::vec4(0.f)); +} + +DrawStencilState::~DrawStencilState() +{ + +} + diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 1da2f0b1..d85b2b43 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -85,6 +85,20 @@ bool RenderState::BlendFunc(GLenum sfactor, GLenum dfactor) return !GLERROR("RenderState::BlendFunc"); } + +bool RenderState::StencilFunc(GLenum sfail, GLenum dpfail, GLenum dppass) +{ + GLint originalSFail; + glGetIntegerv(GL_STENCIL_FAIL, &originalSFail); + GLint originalDPFail; + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &originalDPFail); + GLint originalDPPass; + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &originalDPPass); + m_ResetFunctions.push_back(std::bind(glStencilOp, originalSFail, originalDPFail, originalDPPass)); + glStencilOp(sfail, dpfail, dppass); + return !GLERROR("StencilFunc"); +} + bool RenderState::DepthMask(GLboolean flag) { GLboolean original; From 0bbaf1d57678e6e7745d4fe55466b3330a2f2afe Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 4 Feb 2016 10:04:44 +0100 Subject: [PATCH 057/131] Oops! Removed DebugCode... --- include/Game/Systems/PlayerDeathSystem.h | 5 ---- src/Game/Systems/PlayerDeathSystem.cpp | 31 ------------------------ 2 files changed, 36 deletions(-) diff --git a/include/Game/Systems/PlayerDeathSystem.h b/include/Game/Systems/PlayerDeathSystem.h index 4734947e..7d989dbf 100644 --- a/include/Game/Systems/PlayerDeathSystem.h +++ b/include/Game/Systems/PlayerDeathSystem.h @@ -11,7 +11,6 @@ #include "Core/EntityFileParser.h" #include "Core/EPlayerDeath.h" -#include "Core/EPlayerDamage.h" class PlayerDeathSystem : public ImpureSystem { @@ -23,9 +22,5 @@ public: private: EventRelay m_OnPlayerDeath; bool OnPlayerDeath(Events::PlayerDeath& e); - - EventRelay m_OnInputCommand; - bool OnInputCommand(const Events::InputCommand& e); - }; #endif \ No newline at end of file diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index d6680928..f7fe1ab5 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -3,40 +3,9 @@ PlayerDeathSystem::PlayerDeathSystem(World* m_World, EventBroker* eventBroker) : System(m_World, eventBroker) { - EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerDeathSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath); } -bool PlayerDeathSystem::OnInputCommand(const Events::InputCommand& e) -{ - //testing: Jump > playerdamage - if (e.Command != "Jump") { - return false; - - } - - // 0 = released - if (e.Value != 0) { - return false; - - } - - auto players = m_World->GetComponents("Player"); - - for (auto& cPlayer : *players) { - EntityWrapper player(m_World, cPlayer.EntityID); - Events::PlayerDamage e; - e.Player = player; - e.Damage = 50; - m_EventBroker->Publish(e); - - } - - - - return true; -} - void PlayerDeathSystem::Update(double dt) { } From 0a8ee1623fae4cec72b1973c52f446f12e4a48f4 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 4 Feb 2016 10:47:30 +0100 Subject: [PATCH 058/131] Merge remote-tracking branch 'origin/master' into Sound # Conflicts: # assets --- assets | 2 +- include/Engine/Sound/SoundSystem.h | 3 +++ include/Game/Events/EDoubleJump.h | 16 ++++++++++++++++ include/Game/Systems/PlayerMovementSystem.h | 1 + src/Engine/Sound/SoundSystem.cpp | 14 +++++++++++++- src/Game/Systems/PlayerMovementSystem.cpp | 2 ++ 6 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 include/Game/Events/EDoubleJump.h diff --git a/assets b/assets index 29f8e123..a7387630 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 29f8e1234661f93ffba656c031d037a9ca484660 +Subproject commit a73876309264a0751e3a46f15020dd46d5a67f98 diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 20d58933..597aca22 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -35,6 +35,7 @@ #include "Core/EEntityDeleted.h" #include "Collision/ETrigger.h" #include "Core/EPause.h" +#include "Game/Events/EDoubleJump.h" typedef std::pair> QueuedBuffers; @@ -152,6 +153,8 @@ private: bool OnPause(const Events::Pause &e); EventRelay m_EResume; bool OnResume(const Events::Resume &e); + EventRelay m_EDoubleJump; + bool OnDoubleJump(const Events::DoubleJump &e); diff --git a/include/Game/Events/EDoubleJump.h b/include/Game/Events/EDoubleJump.h new file mode 100644 index 00000000..767d5b39 --- /dev/null +++ b/include/Game/Events/EDoubleJump.h @@ -0,0 +1,16 @@ +#ifndef Events_DoubleJump_h__ +#define Events_DoubleJump_h__ + +#include "Core/Event.h" + +namespace Events +{ + +struct DoubleJump : public Event +{ + +}; + +} + +#endif diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index f39740ec..4d98990a 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -4,6 +4,7 @@ #include "Core/EPlayerSpawned.h" #include "Input/FirstPersonInputController.h" #include +#include "Events/EDoubleJump.h" class PlayerMovementSystem : public ImpureSystem, PureSystem { diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 92ea5142..847230d9 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -29,6 +29,7 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode EVENT_SUBSCRIBE_MEMBER(m_EPause, &SoundSystem::OnPause); EVENT_SUBSCRIBE_MEMBER(m_EResume, &SoundSystem::OnResume); EVENT_SUBSCRIBE_MEMBER(m_EComponentAttached, &SoundSystem::OnComponentAttached); + EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump); } SoundSystem::~SoundSystem() @@ -400,7 +401,6 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) Source* source = createSource("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); source->Type = SoundType::SFX; m_Sources[child] = source; - //playSound(source); // breathe std::vector buffers; @@ -486,6 +486,18 @@ bool SoundSystem::OnResume(const Events::Resume &e) return false; } +bool SoundSystem::OnDoubleJump(const Events::DoubleJump & e) +{ + Events::PlaySoundOnEntity ev; + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + ev.EmitterID = child; + ev.FilePath = "Audio/jump/jump2.wav"; + m_EventBroker->Publish(ev); + return false; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector. diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 72900d7a..498c3765 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -82,6 +82,8 @@ void PlayerMovementSystem::Update(double dt) } else { controller->SetDoubleJumping(true); + Events::DoubleJump e; + m_EventBroker->Publish(e); } velocity.y += 4.f; } From 379d2118328f2946bc09687a985ae30775b5c7e0 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 4 Feb 2016 11:13:26 +0100 Subject: [PATCH 059/131] some fixes with the stencil states and implemented stencil func/stencilop/stencilmask to renderstate --- include/Engine/Rendering/RenderState.h | 4 +- .../Schema/Entities/aaaatestremoveme.xml | 39 ++++++++++++++++ src/Engine/Rendering/DrawFinalPass.cpp | 14 +++--- src/Engine/Rendering/DrawFinalPassState.cpp | 8 +++- src/Engine/Rendering/RenderState.cpp | 45 +++++++++++++++---- 5 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 resources/Schema/Entities/aaaatestremoveme.xml diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index ae43c013..e8ace433 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -19,7 +19,9 @@ public: bool BindFramebuffer(GLint framebuffer); bool BlendEquation(GLenum mode); bool BlendFunc(GLenum sfactor, GLenum dfactor); - bool StencilFunc(GLenum sfail, GLenum dpfail, GLenum dppass); + bool StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass); + bool StencilFunc(GLenum func, GLint ref, GLuint mask); + bool StencilMask(GLuint mask); bool DepthMask(GLboolean flag); private: diff --git a/resources/Schema/Entities/aaaatestremoveme.xml b/resources/Schema/Entities/aaaatestremoveme.xml new file mode 100644 index 00000000..8da40b58 --- /dev/null +++ b/resources/Schema/Entities/aaaatestremoveme.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + Models/Core/Unithexagon.mesh + + + + + + + + + + + + + + + + + + + 2.2000000476837158 + + + + + + + + diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index d2d22514..f571389f 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -73,22 +73,23 @@ void DrawFinalPass::Draw(RenderScene& scene) if (scene.ClearDepth) { glClear(GL_DEPTH_BUFFER_BIT); } - //might need to clear stencil here + //TODO: Do we need check for this or will it be per scene always? + glClear(GL_STENCIL_BUFFER_BIT); DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); GLERROR("OpaqueObjects"); DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); GLERROR("TransparentObjects"); - delete state; - DrawStencilState* stencilState = new DrawStencilState(m_FinalPassFrameBuffer.GetHandle()); - glClear(GL_STENCIL_BUFFER_BIT); + //DrawStencilState* stencilState = new DrawStencilState(m_FinalPassFrameBuffer.GetHandle()); //Draw shields to stencil pass + state->StencilFunc(GL_ALWAYS, 1, 0xFF); + state->StencilMask(0xFF); DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene); GLERROR("StencilPass"); //Draw Opaque shielded objects - DrawShieldedModelRenderQueue(scene.Jobs.OpaqueShieldedObjects, scene); + //DrawShieldedModelRenderQueue(scene.Jobs.OpaqueShieldedObjects, scene); GLERROR("Shielded Opaque object"); //Draw Transparen Shielded objects @@ -96,7 +97,8 @@ void DrawFinalPass::Draw(RenderScene& scene) GLERROR("Shielded Transparent objects"); GLERROR("END"); - delete stencilState; + delete state; + //delete stencilState; } diff --git a/src/Engine/Rendering/DrawFinalPassState.cpp b/src/Engine/Rendering/DrawFinalPassState.cpp index d85d476c..a1cd445c 100644 --- a/src/Engine/Rendering/DrawFinalPassState.cpp +++ b/src/Engine/Rendering/DrawFinalPassState.cpp @@ -9,6 +9,10 @@ DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer) BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); + Enable(GL_STENCIL_TEST); + StencilFunc(GL_NOTEQUAL, 1, 0xFF); + StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + StencilMask(0x00); ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f)); } @@ -21,7 +25,9 @@ DrawStencilState::DrawStencilState(GLuint frameBuffer) { BindFramebuffer(frameBuffer); Enable(GL_STENCIL_TEST); - StencilFunc(GL_KEEP, GL_KEEP, GL_REPLACE); + StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + StencilFunc(GL_ALWAYS, 1, 0xFF); + StencilMask(0xFF); Enable(GL_DEPTH_TEST); ClearColor(glm::vec4(0.f)); } diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index d85b2b43..1bacda18 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -6,9 +6,10 @@ bool RenderState::Enable(GLenum cap) //LOG_WARNING("Trying to enable somthing that is already enabled."); return false; } + m_ResetFunctions.push_back(std::bind(glDisable, cap)); glEnable(cap); - return !GLERROR("RenderState::Enable"); + return !GLERROR("Enable"); } bool RenderState::Disable(GLenum cap) @@ -16,9 +17,10 @@ bool RenderState::Disable(GLenum cap) if (!glIsEnabled(cap)) { return false; } + m_ResetFunctions.push_back(std::bind(glEnable, cap)); glDisable(cap); - return !GLERROR("RenderState::Disable"); + return !GLERROR("Disable"); } bool RenderState::CullFace(GLenum mode) @@ -32,7 +34,7 @@ bool RenderState::CullFace(GLenum mode) glGetIntegerv(GL_CULL_FACE_MODE, &original); m_ResetFunctions.push_back(std::bind(glCullFace, original)); glCullFace(mode); - return !GLERROR("RenderState::CullFace"); + return !GLERROR("CullFace"); } bool RenderState::ClearColor(glm::vec4 color) @@ -41,7 +43,7 @@ bool RenderState::ClearColor(glm::vec4 color) glGetFloatv(GL_COLOR_CLEAR_VALUE, &original[0]); m_ResetFunctions.push_back(std::bind(glClearColor, original[0], original[1], original[2], original[3])); glClearColor(color.r, color.g, color.b, color.a); - return !GLERROR("RenderState::ClearColor"); + return !GLERROR("ClearColor"); } bool RenderState::BindFramebuffer(GLint framebuffer) @@ -55,7 +57,7 @@ bool RenderState::BindFramebuffer(GLint framebuffer) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, originalDraw); }); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - return !GLERROR("RenderState::BindBuffer"); + return !GLERROR("BindBuffer"); } @@ -67,7 +69,7 @@ bool RenderState::BlendEquation(GLenum mode) glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &originalAlpha); m_ResetFunctions.push_back(std::bind(glBlendEquationSeparate, originalRGB, originalAlpha)); glBlendEquation(mode); - return !GLERROR("RenderState::BlendEquation"); + return !GLERROR("BlendEquation"); } bool RenderState::BlendFunc(GLenum sfactor, GLenum dfactor) @@ -82,11 +84,11 @@ bool RenderState::BlendFunc(GLenum sfactor, GLenum dfactor) glGetIntegerv(GL_BLEND_DST_ALPHA, &originalDestAlpha); m_ResetFunctions.push_back(std::bind(glBlendFuncSeparate, originalSrcRGB, originalSrcAlpha, originalDestRGB, originalDestAlpha)); glBlendFunc(sfactor, dfactor); - return !GLERROR("RenderState::BlendFunc"); + return !GLERROR("BlendFunc"); } -bool RenderState::StencilFunc(GLenum sfail, GLenum dpfail, GLenum dppass) +bool RenderState::StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) { GLint originalSFail; glGetIntegerv(GL_STENCIL_FAIL, &originalSFail); @@ -96,16 +98,41 @@ bool RenderState::StencilFunc(GLenum sfail, GLenum dpfail, GLenum dppass) glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &originalDPPass); m_ResetFunctions.push_back(std::bind(glStencilOp, originalSFail, originalDPFail, originalDPPass)); glStencilOp(sfail, dpfail, dppass); + return !GLERROR("StencilOp"); +} + + +bool RenderState::StencilFunc(GLenum func, GLint ref, GLuint mask) +{ + GLint originalFunc; + glGetIntegerv(GL_STENCIL_FUNC, &originalFunc); + GLint originalRef; + glGetIntegerv(GL_STENCIL_REF, &originalRef); + GLint originalMask; + glGetIntegerv(GL_STENCIL_VALUE_MASK, &originalMask); + m_ResetFunctions.push_back(std::bind(glStencilFunc, originalFunc, originalRef, originalMask)); + glStencilFunc(func, ref, mask); return !GLERROR("StencilFunc"); } + + +bool RenderState::StencilMask(GLuint mask) +{ + GLint originalMask; + glGetIntegerv(GL_STENCIL_WRITEMASK, &originalMask); + m_ResetFunctions.push_back(std::bind(glStencilMask, mask)); + glStencilMask(mask); + return !GLERROR("StencilMask"); +} + bool RenderState::DepthMask(GLboolean flag) { GLboolean original; glGetBooleanv(GL_DEPTH_WRITEMASK, &original); m_ResetFunctions.push_back(std::bind(glDepthMask, original)); glDepthMask(flag); - return !GLERROR("RenderState::DepthMask"); + return !GLERROR("DepthMask"); } RenderState::~RenderState() From 6aec7555cce58e19560dbc03d12c8aedd3a65208 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 4 Feb 2016 11:13:33 +0100 Subject: [PATCH 060/131] WIP Waiting for importer --- include/Engine/Rendering/Skeleton.h | 12 +- resources/Schema/Entities/AnimationTests2.xml | 5 +- src/Engine/Rendering/AnimationSystem.cpp | 5 +- src/Engine/Rendering/BoneAttachmentSystem.cpp | 3 +- src/Engine/Rendering/DrawFinalPass.cpp | 9 +- src/Engine/Rendering/PickingPass.cpp | 2 +- src/Engine/Rendering/RawModelCustom.cpp | 7 + src/Engine/Rendering/Skeleton.cpp | 137 +++++++++++++++++- 8 files changed, 162 insertions(+), 18 deletions(-) diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 8ae3d487..9c7242d3 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -55,19 +55,23 @@ public: struct BoneProperty { int ID; - glm::vec3 Position; - glm::quat Rotation; + glm::vec3 Position; + glm::quat Rotation; glm::vec3 Scale = glm::vec3(1); }; int Index = 0; double Time = 0.0; std::map BoneProperties; + //Keyframe::BoneProperty boneProperty; }; std::string Name; double Duration; + // unsigned int KeyFrameAmount; std::vector Keyframes; + //std::map> BoneKeyFrames; + }; Skeleton() { } @@ -86,6 +90,10 @@ public: const Animation* GetAnimation(std::string name); std::vector GetFrameBones(const Animation* animation, double time, bool noRootMotion = false); void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + + void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + void AccumulateBoneTransforms2(bool noRootMotion, const Animation* animation, int keyframeIndex, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); std::map Animations; diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 23fc0548..baff7413 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -10,6 +10,7 @@ Models/Core/UnitPlane.mesh + false @@ -34,8 +35,8 @@ - Run - + Ru + 1 diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 93d52787..517fbf5c 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -51,6 +51,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a +/* ImGui::SliderFloat("Angle", &angle, -180.f, 180.f); @@ -86,6 +87,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } +*/ /* @@ -117,7 +119,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a if (it != skeleton->Bones.end()) { it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); } - }*/ + }* if (entity.HasComponent("Player")) { EntityWrapper cameraEntity = entity.FirstChildByName("Camera"); @@ -127,5 +129,6 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } } + */ } diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index 2a2e5c7d..1f98c28e 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -2,6 +2,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& BoneAttachmentComponent, double dt) { +/* if(!entity.HasComponent("Transform")) { return; @@ -67,5 +68,5 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp } if ((bool)entity["BoneAttachment"]["InheritScale"]) { (glm::vec3&)entity["Transform"]["Scale"] = scale * (glm::vec3)entity["BoneAttachment"]["ScaleOffset"]; - } + }*/ } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 48ea4144..005249ed 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -130,7 +130,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { if (explosionEffectJob->Animation != nullptr) { - std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); + std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animation, explosionEffectJob->AnimationTime); glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } @@ -155,11 +155,8 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindModelTextures(modelJob); if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } //draw diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index d0518ee8..58723a43 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -134,7 +134,7 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 83c68e47..1f9e104d 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -332,6 +332,7 @@ void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileDat ReadAnimationKeyFrame(offset, fileData, fileByteSize, newAnimation); } m_Skeleton->Animations[newAnimation.Name] = newAnimation; + //m_Skeleton->Animations[newAnimation.Name].KeyFrameAmount = nrOfKeyframes; #else #endif } @@ -363,12 +364,18 @@ void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, } Skeleton::Animation::Keyframe::BoneProperty newBone; + for (unsigned int i = 0; i < nrOfJoints; i++) { memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty)); offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty); newKeyFrame.BoneProperties[newBone.ID] = newBone; } animation.Keyframes.push_back(newKeyFrame); + // memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty)); + //newKeyFrame.boneProperty = newBone; + + // animation.BoneKeyFrames[newBone.ID].push_back(newKeyFrame); + } RawModelCustom::~RawModelCustom() diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 7fe36319..590cd9a4 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -66,7 +66,9 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl //auto animationFrame = Animations[""].Keyframes[frame]; std::map frameBones; - AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); + //AccumulateBoneTransforms(noRootMotion, animation, time, frameBones, RootBone, glm::mat4(1)); + AccumulateBoneTransforms2(noRootMotion, animation, currentKeyframeIndex, time, frameBones, RootBone, glm::mat4(1)); + //AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); std::vector finalMatrices; for (auto &kv : frameBones) { @@ -81,7 +83,14 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf { glm::mat4 boneMatrix; - if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) { + + + float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + + + 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); @@ -89,6 +98,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf 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; @@ -97,13 +107,13 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf - boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); - boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + boneMatrix = parentMatrix * bone->ModificationMatrix *(glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } else { if (bone->Parent) { boneMatrix = parentMatrix;// *glm::inverse(bone->OffsetMatrix); } - boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix; + boneMatrices[bone->ID] = boneMatrix;// *bone->OffsetMatrix; } for (auto &child : bone->Children) { @@ -113,6 +123,123 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf } + +void Skeleton::AccumulateBoneTransforms2(bool noRootMotion, const Animation* animation, int keyframeIndex, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +{ + glm::mat4 boneMatrix = glm::mat4(1); + + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; + + int currentFrameIndex = keyframeIndex; + + while (true) { + std::map boneProperties = animation->Keyframes[currentFrameIndex].BoneProperties; + if (boneProperties.find(bone->ID) != boneProperties.end()) { + currentFrame = animation->Keyframes[keyframeIndex]; + break; + } else { + + if(currentFrameIndex > 0) { + currentFrameIndex--; + } else { + break; + } + } + } + + + + if ( != animation->BoneKeyFrames.end()) { // find the bone keyframes that surrounds the current frame + std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); + for (auto frame : boneKeyFrames) { + if (frame.Time <= time) { + currentFrame = &frame; + } else if (frame.Time > time) { + nextFrame = &frame; + } + } + + //if(currentFrame == nullptr) cant happen + + if (nextFrame == nullptr) { + std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); + nextFrame = &boneKeyFrames.front(); + } + +} + + + + +void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +{ + +/* + glm::mat4 boneMatrix = glm::mat4(1); + + Animation::Keyframe* currentFrame = nullptr; + Animation::Keyframe* nextFrame = nullptr; + + if(animation->BoneKeyFrames.find(bone->ID) != animation->BoneKeyFrames.end()) { // find the bone keyframes that surrounds the current frame + std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); + for (auto frame : boneKeyFrames) { + if(frame.Time <= time) { + currentFrame = &frame; + } else if (frame.Time > time) { + nextFrame = &frame; + } + } + + //if(currentFrame == nullptr) cant happen + + if (nextFrame == nullptr) { + std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); + nextFrame = &boneKeyFrames.front(); + } + + + + if (currentFrame != nextFrame) { + + float progress = (time - currentFrame->Time) / (nextFrame->Time - currentFrame->Time); + + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame->boneProperty; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame->boneProperty; + + 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 * bone->ModificationMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + + } else {// if (currentFrame == nextFrame) { + boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(currentFrame->boneProperty.Position) * glm::toMat4(currentFrame->boneProperty.Rotation) * glm::scale(currentFrame->boneProperty.Scale)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } + } else { +// if (bone->Parent) { // dont think this is needed +// boneMatrix = parentMatrix * bone->ModificationMatrix; +// } + + boneMatrix = parentMatrix * bone->ModificationMatrix; + boneMatrices[bone->ID] = boneMatrix;// *bone->OffsetMatrix; + // } + } + + for (auto &child : bone->Children) { + std::string name = child->Name; + AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, child, boneMatrix); + }*/ +} + glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix) { glm::mat4 boneMatrix; From 356cf72b0ff8e5d5eca877c5ba54bad974c6cc82 Mon Sep 17 00:00:00 2001 From: antc13 Date: Thu, 4 Feb 2016 11:25:31 +0100 Subject: [PATCH 061/131] Changed the structure of the Animation Data in both Exporter & Importer. --- include/Engine/Rendering/RawModelCustom.h | 2 +- include/Engine/Rendering/Skeleton.h | 17 +- src/Engine/Rendering/RawModelCustom.cpp | 62 ++++--- src/Engine/Rendering/Skeleton.cpp | 82 ++++----- tools/MayaExporter/MayaExporter/Mesh.h | 2 +- tools/MayaExporter/MayaExporter/Skeleton.cpp | 171 ++++++++++++------- tools/MayaExporter/MayaExporter/Skeleton.h | 81 +++++---- 7 files changed, 251 insertions(+), 166 deletions(-) diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index fe00d89c..e2595ba3 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -110,7 +110,7 @@ private: void ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize); void ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips); void ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex); - void ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, Skeleton::Animation& animation); + void ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, std::vector& animation); //void CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID); }; diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 3b89b89b..52fc02d0 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -53,20 +53,21 @@ public: { struct BoneProperty { - int ID; glm::vec3 Position; glm::quat Rotation; glm::vec3 Scale = glm::vec3(1); }; - int Index = 0; - double Time = 0.0; - std::map BoneProperties; + int Index = 0; + double Time = 0.0; + BoneProperty BoneProperties; }; - - std::string Name; - double Duration; - std::vector Keyframes; + std::string Name; + double Duration; + std::map> JointAnimations; + + + }; Skeleton() { } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index c1939bdf..936c7b7b 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -11,6 +11,7 @@ RawModelCustom::RawModelCustom(std::string fileName) ReadMeshFile(fileName); ReadMaterialFile(fileName); ReadAnimationFile(fileName); + int k = 0; } void RawModelCustom::ReadMeshFile(std::string filePath) @@ -40,8 +41,8 @@ void RawModelCustom::ReadMeshFile(std::string filePath) void RawModelCustom::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - isSkined = *(unsigned int*)(fileData + offset); - offset += sizeof(bool); + isSkined = true;//*(unsigned int*)(fileData + offset); + //offset += sizeof(bool); if (isSkined) { m_SkinedVertices.resize(*(unsigned int*)(fileData + offset)); } @@ -331,26 +332,42 @@ void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileDat if (offset + sizeof(float) > fileByteSize) { throw Resource::FailedLoadingException("Reading AnimationClip duration failed"); } - newAnimation.Duration = *(float*)(fileData + offset); offset += sizeof(float); if (offset + sizeof(unsigned int) > fileByteSize) { - throw Resource::FailedLoadingException("Reading AnimationClip NrOfKeyframes failed"); + throw Resource::FailedLoadingException("Reading AnimationClip numberOfJointFrames failed"); } - unsigned int nrOfKeyframes = *(unsigned int*)(fileData + offset); + unsigned int numberOfJointFrames = *(unsigned int*)(fileData + offset); offset += sizeof(unsigned int); - newAnimation.Keyframes.reserve(nrOfKeyframes); - for (unsigned int i = 0; i < nrOfKeyframes; i++) { - ReadAnimationKeyFrame(offset, fileData, fileByteSize, newAnimation); + for (unsigned int i = 0; i < numberOfJointFrames; i++) { + if (offset + sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationClip JointID failed"); + } + int jointID = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + + if (offset + sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationClip numberOFKeyFrames failed"); + } + unsigned int numberOFKeyFrames = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + + if (numberOFKeyFrames > 0) { + newAnimation.JointAnimations[jointID].reserve(numberOFKeyFrames); + + for (unsigned int j = 0; j < numberOFKeyFrames; j++) { + ReadAnimationKeyFrame(offset, fileData, fileByteSize, newAnimation.JointAnimations[jointID]); + } + } } m_Skeleton->Animations[newAnimation.Name] = newAnimation; #else #endif } -void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, Skeleton::Animation& animation) +void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, std::vector& animation) { Skeleton::Animation::Keyframe newKeyFrame; @@ -366,23 +383,26 @@ void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, newKeyFrame.Time = *(float*)(fileData + offset); offset += sizeof(float); - if (offset + sizeof(unsigned int) > fileByteSize) { - throw Resource::FailedLoadingException("Reading AnimationKeyFrame NrOfJoints failed"); + if (offset + sizeof(float) * 3 > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationKeyFrame Position failed"); } - unsigned int nrOfJoints = *(unsigned int*)(fileData + offset); - offset += sizeof(unsigned int); + memcpy(&newKeyFrame.BoneProperties.Position[0], fileData + offset, sizeof(float) * 3); + offset += sizeof(float) * 3; - if (offset + sizeof(Skeleton::Animation::Keyframe::BoneProperty) * nrOfJoints> fileByteSize) { - throw Resource::FailedLoadingException("Reading AnimationKeyFrame joints failed"); + if (offset + sizeof(float) * 4 > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationKeyFrame Rotation failed"); } + memcpy(&newKeyFrame.BoneProperties.Rotation[0], fileData + offset, sizeof(float) * 4); + offset += sizeof(float) * 4; - Skeleton::Animation::Keyframe::BoneProperty newBone; - for (unsigned int i = 0; i < nrOfJoints; i++) { - memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty)); - offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty); - newKeyFrame.BoneProperties[newBone.ID] = newBone; + if (offset + sizeof(float) * 3 > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationKeyFrame Scale failed"); } - animation.Keyframes.push_back(newKeyFrame); + memcpy(&newKeyFrame.BoneProperties.Scale[0], fileData + offset, sizeof(float) * 3); + offset += sizeof(float) * 3; + + + animation.push_back(newKeyFrame); } RawModelCustom::~RawModelCustom() diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index cebabb67..b9488dda 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -49,15 +49,15 @@ std::vector Skeleton::GetFrameBones(const Animation& animation, doubl time -= animation.Duration; } - int currentKeyframeIndex = GetKeyframe(animation, time); + //int currentKeyframeIndex = GetKeyframe(animation, time); - const Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex]; - const Animation::Keyframe& nextFrame = animation.Keyframes[(currentKeyframeIndex + 1) % animation.Keyframes.size()]; - float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + //const Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex]; + //const Animation::Keyframe& nextFrame = animation.Keyframes[(currentKeyframeIndex + 1) % animation.Keyframes.size()]; + //float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - //auto animationFrame = Animations[""].Keyframes[frame]; + ////auto animationFrame = Animations[""].Keyframes[frame]; std::map frameBones; - AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); + //AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); std::vector finalMatrices; for (auto &kv : frameBones) { @@ -68,36 +68,36 @@ std::vector Skeleton::GetFrameBones(const Animation& animation, doubl void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map &boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { - glm::mat4 boneMatrix; + // 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); + //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; + // 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; - } + // // 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 { - if (bone->Parent) { - boneMatrix = parentMatrix; // * glm::inverse(bone->OffsetMatrix); - } - boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix; - } + // boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + // boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + //} else { + // if (bone->Parent) { + // boneMatrix = parentMatrix; // * 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); - } + //for (auto &child : bone->Children) { + // std::string name = child->Name; + // AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix); + //} } @@ -134,18 +134,18 @@ void Skeleton::PrintSkeleton(const Bone* bone, int depthCount) int Skeleton::GetKeyframe(const Animation& animation, double time) { - if (time < 0) { - time = 0; - } - if (time >= animation.Duration) { - return animation.Keyframes.size() - 1; - } + //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) % animation.Keyframes.size(); - } - } + //for (int keyframe = 0; keyframe < animation.Keyframes.size(); ++keyframe) { + // if (animation.Keyframes[keyframe].Time > time) { + // return (keyframe - 1) % animation.Keyframes.size(); + // } + //} return 0; } diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index affc4320..87e0ce19 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -70,7 +70,7 @@ public: virtual void WriteBinary(std::ostream& out) { - out.write((char*)&hasSkin, sizeof(bool)); + //out.write((char*)&hasSkin, sizeof(bool)); out.write((char*)&NumVertices, sizeof(int)); out.write((char*)&NumIndices, sizeof(int)); for (auto aVertex : Vertices) { diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index f44b9306..900ed9b2 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -214,26 +214,28 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e jointIt.reset(); }*/ + MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); + unsigned int jointID = 0; - int currentFrame = startFrame; - while (currentFrame < endFrame) { // ANDREAS - Animation::Keyframe thisKeyFrame; - thisKeyFrame.Index = currentFrame - startFrame; - thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; + while (!jointIt.isDone()) { + int currentFrame = startFrame; + Animation::JointAnimation thisJointAnimation; + bool haxBool = false; + while (currentFrame < endFrame) { + Animation::JointAnimation::KeyFrame thisKeyFrame; + //thisKeyFrame.Index = currentFrame - startFrame; + //thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; - MAnimControl::setCurrentTime(MTime(currentFrame, MTime::kNTSCField)); - MTime time = MAnimControl::currentTime(); + MAnimControl::setCurrentTime(MTime(currentFrame, MTime::kNTSCField)); + MTime time = MAnimControl::currentTime(); - MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); - unsigned int jointID = 0; - while (!jointIt.isDone()) { MFnTransform thisJoint(jointIt.currentItem()); MMatrix transformationMatrix = thisJoint.transformationMatrix(); - + double doubleMat[4][4]; - if (currentFrame != startFrame){ - Animation::Keyframe::JointProperty joint; + if (currentFrame != startFrame) { + //Animation::JointAnimation joint; doubleMat[0][0] = joinCheckMap[thisJoint.name().asChar()][0][0]; doubleMat[0][1] = joinCheckMap[thisJoint.name().asChar()][0][1]; @@ -255,9 +257,53 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MMatrix LastJointMatrix(doubleMat); //Is same as last KeyFrame if (LastJointMatrix.isEquivalent(transformationMatrix)) { - jointID++; - jointIt.next(); + //jointID++; + //jointIt.next(); + currentFrame++; + haxBool = false; continue; + } else if(!haxBool){ + haxBool = true; + MTransformationMatrix TransformationMatrix = LastJointMatrix; + MObject jointOrientObj = thisJoint.attribute("jointOrient"); + MFnNumericAttribute jointOrient(jointOrientObj); + double jointOrientDouble[3]; + jointOrient.getDefault(jointOrientDouble[0], jointOrientDouble[1], jointOrientDouble[2]); + //MGlobal::displayError(MString() + "Joint Matrix: "); + //MGlobal::displayError(MString() + Matrix.asMatrix()[0][0] + " " + Matrix.asMatrix()[0][1] + " " + Matrix.asMatrix()[0][2] + " " + Matrix.asMatrix()[0][3]); + //MGlobal::displayError(MString() + Matrix.asMatrix()[1][0] + " " + Matrix.asMatrix()[1][1] + " " + Matrix.asMatrix()[1][2] + " " + Matrix.asMatrix()[1][3]); + //MGlobal::displayError(MString() + Matrix.asMatrix()[2][0] + " " + Matrix.asMatrix()[2][1] + " " + Matrix.asMatrix()[2][2] + " " + Matrix.asMatrix()[2][3]); + //MGlobal::displayError(MString() + Matrix.asMatrix()[3][0] + " " + Matrix.asMatrix()[3][1] + " " + Matrix.asMatrix()[3][2] + " " + Matrix.asMatrix()[3][3]); + + MEulerRotation joEuler(jointOrientDouble[0], jointOrientDouble[1], jointOrientDouble[2]); + MQuaternion jo = joEuler.asQuaternion(); + + double tmp[4]; + TransformationMatrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); + MQuaternion rotation(tmp); + + rotation = rotation * jo; + rotation.get(tmp); + + //Animation::JointAnimation::KeyFrame keyframe; + Animation::JointAnimation::KeyFrame previousKeyFrame; + previousKeyFrame.Index = currentFrame - startFrame - 1; + previousKeyFrame.Time = previousKeyFrame.Index * oneDivSixty; + + previousKeyFrame.Rotation[0] = tmp[0]; + previousKeyFrame.Rotation[1] = tmp[1]; + previousKeyFrame.Rotation[2] = tmp[2]; + previousKeyFrame.Rotation[3] = tmp[3]; + TransformationMatrix.getTranslation(MSpace::kTransform).get(tmp); + previousKeyFrame.Position[0] = tmp[0]; + previousKeyFrame.Position[1] = tmp[1]; + previousKeyFrame.Position[2] = tmp[2]; + TransformationMatrix.getScale(tmp, MSpace::kTransform); + previousKeyFrame.Scale[0] = tmp[0]; + previousKeyFrame.Scale[1] = tmp[1]; + previousKeyFrame.Scale[2] = tmp[2]; + + thisJointAnimation.m_KeyFrames.push_back(previousKeyFrame); } } @@ -280,31 +326,35 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e joinCheckMap[thisJoint.name().asChar()][3][2] = doubleMat[3][2]; joinCheckMap[thisJoint.name().asChar()][3][3] = doubleMat[3][3]; - MPlug thisJointBindPose = thisJoint.findPlug("bindPose"); - MDataHandle DataHandle; - thisJointBindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix thisJointBindPoseMatrix = MartixFn.matrix(); - - MFnTransform Parent(thisJoint.parent(0), &status); - if (status == MS::kSuccess && thisJoint.parent(0).apiType() == MFn::kJoint) { - MTransformationMatrix Matrix = Parent.transformation(); - MPlug parentBindPose = Parent.findPlug("bindPose"); - MDataHandle DataHandle; - parentBindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix parentBindPoseMatrix = MartixFn.matrix(); - - thisJointBindPoseMatrix = thisJointBindPoseMatrix * parentBindPoseMatrix.inverse(); - } - MTransformationMatrix TransformationMatrix = thisJoint.transformation(); - if (thisJointBindPoseMatrix.isEquivalent(TransformationMatrix.asMatrix())) { - jointID++; - jointIt.next(); - MGlobal::displayError(MString() + thisJoint.name() + " is in bindPose"); - continue; + if (currentFrame == startFrame) { + MPlug thisJointBindPose = thisJoint.findPlug("bindPose"); + MDataHandle DataHandle; + thisJointBindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix thisJointBindPoseMatrix = MartixFn.matrix(); + + MFnTransform Parent(thisJoint.parent(0), &status); + if (status == MS::kSuccess && thisJoint.parent(0).apiType() == MFn::kJoint) { + MTransformationMatrix Matrix = Parent.transformation(); + MPlug parentBindPose = Parent.findPlug("bindPose"); + MDataHandle DataHandle; + parentBindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix parentBindPoseMatrix = MartixFn.matrix(); + + thisJointBindPoseMatrix = thisJointBindPoseMatrix * parentBindPoseMatrix.inverse(); + } + + if (thisJointBindPoseMatrix.isEquivalent(TransformationMatrix.asMatrix())) { + //jointID++; + //jointIt.next(); + currentFrame++; + MGlobal::displayError(MString() + thisJoint.name() + " is in bindPose"); + continue; + } + haxBool = true; } MObject jointOrientObj = thisJoint.attribute("jointOrient"); @@ -327,34 +377,35 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e rotation = rotation * jo; rotation.get(tmp); - Animation::Keyframe::JointProperty joint; - joint.ID = jointID; + //Animation::JointAnimation::KeyFrame keyframe; + thisKeyFrame.Index = currentFrame - startFrame; + thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; - joint.Rotation[0] = tmp[0]; - joint.Rotation[1] = tmp[1]; - joint.Rotation[2] = tmp[2]; - joint.Rotation[3] = tmp[3]; + thisKeyFrame.Rotation[0] = tmp[0]; + thisKeyFrame.Rotation[1] = tmp[1]; + thisKeyFrame.Rotation[2] = tmp[2]; + thisKeyFrame.Rotation[3] = tmp[3]; TransformationMatrix.getTranslation(MSpace::kTransform).get(tmp); - joint.Position[0] = tmp[0]; - joint.Position[1] = tmp[1]; - joint.Position[2] = tmp[2]; + thisKeyFrame.Position[0] = tmp[0]; + thisKeyFrame.Position[1] = tmp[1]; + thisKeyFrame.Position[2] = tmp[2]; TransformationMatrix.getScale(tmp, MSpace::kTransform); - joint.Scale[0] = tmp[0]; - joint.Scale[1] = tmp[1]; - joint.Scale[2] = tmp[2]; + thisKeyFrame.Scale[0] = tmp[0]; + thisKeyFrame.Scale[1] = tmp[1]; + thisKeyFrame.Scale[2] = tmp[2]; - thisKeyFrame.JointProperties.push_back(joint); - - jointID++; - jointIt.next(); + thisJointAnimation.m_KeyFrames.push_back(thisKeyFrame); + + currentFrame++; } - thisKeyFrame.NumberOfJoints = thisKeyFrame.JointProperties.size(); - returnData.Keyframes.push_back(thisKeyFrame); - currentFrame++; + //thisKeyFrame.NumberOfJoints = thisKeyFrame.JointProperties.size(); + thisJointAnimation.numberOFKeyFrames = thisJointAnimation.m_KeyFrames.size(); + returnData.JointsFrameMap[jointID] = (thisJointAnimation); + + jointID++; + jointIt.next(); } - - returnData.NumKeyFrames = returnData.Keyframes.size(); - + returnData.NumOfJointFrames = returnData.JointsFrameMap.size(); return returnData; } diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index 47ae6f4c..3dfbe8a5 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -10,44 +10,56 @@ class Animation : public OutputData { public: - struct Keyframe - { - struct JointProperty - { - int ID = 0; + //struct Keyframe + //{ + // struct JointProperty + // { + // int ID = 0; + // float Position[3]{ 0 }; + // float Rotation[4]{ 0 }; + // float Scale[3]{ 0 }; + // }; + + // int Index = 0; + // float Time = 0; + // int NumberOfJoints; + // std::vector JointProperties; + //}; + + struct JointAnimation { + struct KeyFrame { + int Index = 0; + float Time = 0; float Position[3]{ 0 }; float Rotation[4]{ 0 }; float Scale[3]{ 0 }; - }; - - int Index = 0; - float Time = 0; - int NumberOfJoints; - std::vector JointProperties; - }; + }; + unsigned int numberOFKeyFrames = 0; + std::vector m_KeyFrames; + }; std::string Name; int nameLength = 0; float Duration = 0; - int NumKeyFrames = 0; - std::vector Keyframes; + int NumOfJointFrames = 0; + std::map JointsFrameMap; virtual void WriteBinary(std::ostream& out) { out.write((char*)&nameLength, sizeof(int)); out.write(Name.c_str(), Name.size() + 1); out.write((char*)&Duration, sizeof(float)); - out.write((char*)&NumKeyFrames, sizeof(int)); + out.write((char*)&NumOfJointFrames, sizeof(int)); //Här under loopas alla key frames igenom - for (auto aKeyframe : Keyframes) { - out.write((char*)&aKeyframe.Index, sizeof(int)); - out.write((char*)&aKeyframe.Time, sizeof(float)); - out.write((char*)&aKeyframe.NumberOfJoints, sizeof(int)); - for (auto aJoint : aKeyframe.JointProperties) { - out.write((char*)&aJoint.ID, sizeof(int)); - out.write((char*)aJoint.Position, sizeof(float) * 3); - out.write((char*)aJoint.Rotation, sizeof(float) * 4); - out.write((char*)aJoint.Scale, sizeof(float) * 3); + for (auto aJointAnimation : JointsFrameMap) { + out.write((char*)&aJointAnimation.first, sizeof(int)); + out.write((char*)&aJointAnimation.second.numberOFKeyFrames, sizeof(int)); + for (auto aJointKeyFrame : aJointAnimation.second.m_KeyFrames) { + out.write((char*)&aJointKeyFrame.Index, sizeof(int)); + out.write((char*)&aJointKeyFrame.Time, sizeof(float)); + out.write((char*)&aJointKeyFrame.Position, sizeof(float) * 3); + out.write((char*)&aJointKeyFrame.Rotation, sizeof(float) * 4); + out.write((char*)&aJointKeyFrame.Scale, sizeof(float) * 3); } } } @@ -56,16 +68,17 @@ public: { out << "Animation Name: " << Name << endl; out << "Duration: " << Duration << endl; - out << "Number of KeyFrames: " << NumKeyFrames << endl; - for (auto aKeyframe : Keyframes) { - out << "Frame: " << aKeyframe.Index << endl; - out << "Time: " << aKeyframe.Time << endl; - out << "Number of Joints: " << aKeyframe.NumberOfJoints << endl; - for (auto aJoint : aKeyframe.JointProperties) { - out << "Joint ID: " << aJoint.ID << endl; - out << aJoint.Position[0] << " " << aJoint.Position[1] << " " << aJoint.Position[2] << endl; - out << aJoint.Rotation[0] << " " << aJoint.Rotation[1] << " " << aJoint.Rotation[2] << " " << aJoint.Rotation[3] << endl; - out << aJoint.Scale[0] << " " << aJoint.Scale[1] << " " << aJoint.Scale[2] << endl; + out << "Number of KeyFrames: " << NumOfJointFrames << endl; + for (auto aJointAnimation : JointsFrameMap) { + out << "Bone: " << aJointAnimation.first << endl; + //out << "Time: " << aJointAnimation.Time << endl; + //out << "Number of Joints: " << aKeyframe.NumberOfJoints << endl; + for (auto aJointKeyFrame : aJointAnimation.second.m_KeyFrames) { + //out << "Joint ID: " << aJoint.ID << endl; + out << "Time: " << aJointKeyFrame.Time << endl; + out << aJointKeyFrame.Position[0] << " " << aJointKeyFrame.Position[1] << " " << aJointKeyFrame.Position[2] << endl; + out << aJointKeyFrame.Rotation[0] << " " << aJointKeyFrame.Rotation[1] << " " << aJointKeyFrame.Rotation[2] << " " << aJointKeyFrame.Rotation[3] << endl; + out << aJointKeyFrame.Scale[0] << " " << aJointKeyFrame.Scale[1] << " " << aJointKeyFrame.Scale[2] << endl; } } From 84499665d0c1583b12be07b98306117eab437145 Mon Sep 17 00:00:00 2001 From: antc13 Date: Thu, 4 Feb 2016 11:53:17 +0100 Subject: [PATCH 062/131] Changed vertices to skinnedVertices in RawModelCustom.cpp --- src/Engine/Rendering/RawModelCustom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 936c7b7b..7852f54b 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -69,7 +69,7 @@ void RawModelCustom::ReadVertices(unsigned int& offset, char* fileData, unsigned if (offset + m_SkinedVertices.size() * sizeof(SkinedVertex) > fileByteSize) { throw Resource::FailedLoadingException("Reading skined vertices failed"); } - memcpy(&m_SkinedVertices[0], fileData + offset, m_Vertices.size() * sizeof(SkinedVertex)); + memcpy(&m_SkinedVertices[0], fileData + offset, m_SkinedVertices.size() * sizeof(SkinedVertex)); offset += m_SkinedVertices.size() * sizeof(SkinedVertex); } else { if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) { From 35376178b1801d0bbc9065f647747421d80f50c5 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 4 Feb 2016 11:54:13 +0100 Subject: [PATCH 063/131] WIP --- include/Engine/Rendering/Skeleton.h | 1 - src/Engine/Rendering/Skeleton.cpp | 71 ++++++----------------------- 2 files changed, 13 insertions(+), 59 deletions(-) diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 811cd42f..a428b7f3 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -90,7 +90,6 @@ public: void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); - void AccumulateBoneTransforms2(bool noRootMotion, const Animation* animation, int keyframeIndex, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 590cd9a4..86d1cb20 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -41,7 +41,8 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name) std::vector Skeleton::GetFrameBones(const Animation* animation, double time, bool noRootMotion /*= false*/) { - if(animation == nullptr) { + if(true){ + // if(animation == nullptr) { std::vector finalMatrices; for(auto& b : Bones) { finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); @@ -60,14 +61,13 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl int currentKeyframeIndex = GetKeyframe(*animation, time); - const Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; - const Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; - float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); +// const Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; +// const Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; +// float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); //auto animationFrame = Animations[""].Keyframes[frame]; std::map frameBones; - //AccumulateBoneTransforms(noRootMotion, animation, time, frameBones, RootBone, glm::mat4(1)); - AccumulateBoneTransforms2(noRootMotion, animation, currentKeyframeIndex, time, frameBones, RootBone, glm::mat4(1)); + AccumulateBoneTransforms(noRootMotion, animation, time, frameBones, RootBone, glm::mat4(1)); //AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); std::vector finalMatrices; @@ -81,7 +81,7 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map &boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { - glm::mat4 boneMatrix; + /* glm::mat4 boneMatrix; @@ -120,58 +120,11 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf std::string name = child->Name; AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix); } +*/ } -void Skeleton::AccumulateBoneTransforms2(bool noRootMotion, const Animation* animation, int keyframeIndex, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) -{ - glm::mat4 boneMatrix = glm::mat4(1); - - Animation::Keyframe currentFrame; - Animation::Keyframe nextFrame; - - int currentFrameIndex = keyframeIndex; - - while (true) { - std::map boneProperties = animation->Keyframes[currentFrameIndex].BoneProperties; - if (boneProperties.find(bone->ID) != boneProperties.end()) { - currentFrame = animation->Keyframes[keyframeIndex]; - break; - } else { - - if(currentFrameIndex > 0) { - currentFrameIndex--; - } else { - break; - } - } - } - - - - if ( != animation->BoneKeyFrames.end()) { // find the bone keyframes that surrounds the current frame - std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); - for (auto frame : boneKeyFrames) { - if (frame.Time <= time) { - currentFrame = &frame; - } else if (frame.Time > time) { - nextFrame = &frame; - } - } - - //if(currentFrame == nullptr) cant happen - - if (nextFrame == nullptr) { - std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); - nextFrame = &boneKeyFrames.front(); - } - -} - - - - void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { @@ -242,7 +195,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix) { - glm::mat4 boneMatrix; + /* 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); @@ -264,8 +217,8 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe return GetBoneTransform(bone->Parent, currentFrame, nextFrame, progress, boneMatrix); } else { return boneMatrix; - } - + }*/ + return parentMatrix; } int Skeleton::GetBoneID(std::string name) @@ -301,6 +254,7 @@ void Skeleton::PrintSkeleton(const Bone* bone, int depthCount) int Skeleton::GetKeyframe(const Animation& animation, double time) { +/* if (time < 0) { time = 0; } @@ -313,6 +267,7 @@ int Skeleton::GetKeyframe(const Animation& animation, double time) return (keyframe - 1) % animation.Keyframes.size(); } } +*/ return 0; } From 7c582898f47e36d0138635fd599776b24f83a270 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 4 Feb 2016 14:33:39 +0100 Subject: [PATCH 064/131] Working stencil buffer for the shield. --- include/Engine/Rendering/DrawFinalPass.h | 1 + include/Engine/Rendering/RenderState.h | 1 + .../Schema/Entities/QualityAssurance.xml | 44 ++++++++++--------- resources/Shaders/ShieldStencil.frag.glsl | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 13 ++++-- src/Engine/Rendering/DrawFinalPassState.cpp | 2 +- src/Engine/Rendering/FrameBuffer.cpp | 8 ++-- src/Engine/Rendering/RenderState.cpp | 2 +- 8 files changed, 41 insertions(+), 32 deletions(-) diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 740c6ef6..64d5563e 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -50,6 +50,7 @@ private: GLuint m_BloomTexture; GLuint m_SceneTexture; GLuint m_DepthBuffer; + GLuint m_StencilBuffer; const IRenderer* m_Renderer; const LightCullingPass* m_LightCullingPass; diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index e8ace433..c1886247 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -2,6 +2,7 @@ #define RenderState_h__ #include +#include #include "../Common.h" #include "../OpenGL.h" #include "../GLM.h" diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index 11fbaf99..980cb39c 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -188,7 +188,7 @@ - + @@ -683,7 +683,7 @@ - + @@ -730,7 +730,7 @@ - + @@ -790,7 +790,7 @@ - + @@ -837,7 +837,7 @@ - + @@ -883,7 +883,7 @@ - + @@ -930,7 +930,7 @@ - + @@ -977,7 +977,7 @@ - + @@ -1390,7 +1390,7 @@ - + @@ -1399,7 +1399,7 @@ true - 1.3668564709912516 + 1.3671759474185377 3.7999999523162842 true @@ -1446,7 +1446,7 @@ - + @@ -1455,7 +1455,7 @@ - 0.316796204374441 + 0.31711568080172703 Models/Assault.mesh @@ -1498,7 +1498,7 @@ - + @@ -1513,7 +1513,7 @@ true - 0.316796204374441 + 0.31711568080172703 true @@ -1558,7 +1558,7 @@ - + @@ -1568,7 +1568,7 @@ true - 0.95015514958004132 + 0.95047462600732735 10 3 @@ -1616,7 +1616,7 @@ - + @@ -1626,7 +1626,7 @@ true - 1.3501834109561059 + 1.350502887383392 true 5 true @@ -1712,7 +1712,8 @@ - + + false 5 @@ -1723,7 +1724,7 @@ - + @@ -1806,7 +1807,7 @@ true - 1.3668564709912516 + 1.3671759474185377 3.7999999523162842 true @@ -1859,6 +1860,7 @@ Models/AssaultAnimated.mesh + diff --git a/resources/Shaders/ShieldStencil.frag.glsl b/resources/Shaders/ShieldStencil.frag.glsl index 43a067c0..bc114fc9 100644 --- a/resources/Shaders/ShieldStencil.frag.glsl +++ b/resources/Shaders/ShieldStencil.frag.glsl @@ -9,7 +9,7 @@ out vec4 fragmentColor; void main() { - fragmentColor = vec4(0.5, 0.5, 0.5, 1.0); + fragmentColor = vec4(0.5, 0.5, 0.5, 0.2); } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index f571389f..106f9aa5 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -21,17 +21,18 @@ void DrawFinalPass::InitializeFrameBuffers() { glGenRenderbuffers(1, &m_DepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_FLOAT, 4); - m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT))); + m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_STENCIL_ATTACHMENT))); m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SceneTexture, GL_COLOR_ATTACHMENT0))); m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_BloomTexture, GL_COLOR_ATTACHMENT1))); m_FinalPassFrameBuffer.Generate(); + GLERROR("FBO generation"); } @@ -74,8 +75,10 @@ void DrawFinalPass::Draw(RenderScene& scene) glClear(GL_DEPTH_BUFFER_BIT); } //TODO: Do we need check for this or will it be per scene always? + glClearStencil(0x00); glClear(GL_STENCIL_BUFFER_BIT); + state->StencilMask(0x00); DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); GLERROR("OpaqueObjects"); DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); @@ -89,11 +92,13 @@ void DrawFinalPass::Draw(RenderScene& scene) GLERROR("StencilPass"); //Draw Opaque shielded objects - //DrawShieldedModelRenderQueue(scene.Jobs.OpaqueShieldedObjects, scene); + state->StencilFunc(GL_NOTEQUAL, 1, 0xFF); + glStencilMask(0x00); + DrawShieldedModelRenderQueue(scene.Jobs.OpaqueShieldedObjects, scene); GLERROR("Shielded Opaque object"); //Draw Transparen Shielded objects - //DrawShieldedModelRenderQueue(scene.Jobs.TransparentShieldedObjects, scene); + DrawShieldedModelRenderQueue(scene.Jobs.TransparentShieldedObjects, scene); GLERROR("Shielded Transparent objects"); GLERROR("END"); diff --git a/src/Engine/Rendering/DrawFinalPassState.cpp b/src/Engine/Rendering/DrawFinalPassState.cpp index a1cd445c..8b5ddc8b 100644 --- a/src/Engine/Rendering/DrawFinalPassState.cpp +++ b/src/Engine/Rendering/DrawFinalPassState.cpp @@ -12,7 +12,7 @@ DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer) Enable(GL_STENCIL_TEST); StencilFunc(GL_NOTEQUAL, 1, 0xFF); StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - StencilMask(0x00); + StencilMask(0xFF); ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f)); } diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 9677f50e..5df1a5f1 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -57,17 +57,17 @@ void FrameBuffer::Generate() break; } - - if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) { + if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT || (*it)->m_Attachment != GL_STENCIL_ATTACHMENT || (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { attachments.push_back((*it)->m_Attachment); } } - + GLenum* bufferTextures = &attachments[0]; glDrawBuffers(attachments.size(), bufferTextures); if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); + GLERROR("Framebuffer incomplete"); + //LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); exit(EXIT_FAILURE); } } diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 1bacda18..26ba18a1 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -137,7 +137,7 @@ bool RenderState::DepthMask(GLboolean flag) RenderState::~RenderState() { - for (auto& f : m_ResetFunctions) { + for (auto& f : boost::adaptors::reverse(m_ResetFunctions)) { f(); } } From 336b058c9f517aab0ce8672869f011e2f87db4f9 Mon Sep 17 00:00:00 2001 From: Teejoon Date: Thu, 4 Feb 2016 14:58:46 +0100 Subject: [PATCH 065/131] WIP, commit to be able to pull stuff down --- include/Engine/Rendering/Model.h | 2 +- include/Engine/Rendering/RawModelCustom.h | 19 ++- src/Engine/Rendering/Model.cpp | 12 +- src/Engine/Rendering/RawModelCustom.cpp | 6 +- tools/MayaExporter/MayaExporter/Material.cpp | 56 ++++++-- tools/MayaExporter/MayaExporter/Material.h | 124 +++++++++++++----- .../MayaExporter/MayaExporter.vcxproj | 8 +- tools/MayaExporter/MayaExporter/Skeleton.cpp | 50 +++---- 8 files changed, 188 insertions(+), 89 deletions(-) diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index aeb13e2f..34d8462f 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -18,7 +18,7 @@ public: const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; } const RawModel::Vertex* Vertices() const { return m_RawModel->Vertices(); } unsigned int NumberOfVertices() const { return m_RawModel->NumVertices(); } - bool isSkined() const { return m_RawModel->isSkined; } + bool isSkined() const { return m_RawModel->isSkined(); } GLuint VAO; GLuint ElementBuffer; RawModel* m_RawModel; diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index fe00d89c..2b0172dd 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -68,30 +68,41 @@ public: }; const Vertex* Vertices() const { - if (isSkined) { + if (hasSkin) { return m_SkinedVertices.data(); } else { return m_Vertices.data(); } }; + unsigned int VertexSize() const { + if (hasSkin) { + return sizeof(SkinedVertex); + } + else { + return sizeof(Vertex); + } + }; + unsigned int NumVertices() const { - if (isSkined) { + if (hasSkin) { return m_SkinedVertices.size(); } else { return m_Vertices.size(); } }; + bool isSkined() const { return hasSkin; }; + std::vector MaterialGroups; - bool isSkined; + std::vector m_Indices; Skeleton* m_Skeleton = nullptr; glm::mat4 m_Matrix; private: - + bool hasSkin; std::vector m_Vertices; std::vector m_SkinedVertices; diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index 129b77fa..bf264b5a 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -25,11 +25,7 @@ Model::Model(std::string fileName) glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); - if (m_RawModel->isSkined) { - glBufferData(GL_ARRAY_BUFFER, m_RawModel->NumVertices() * sizeof(RawModel::SkinedVertex), m_RawModel->Vertices(), GL_STATIC_DRAW); - } else { - glBufferData(GL_ARRAY_BUFFER, m_RawModel->NumVertices() * sizeof(RawModel::Vertex), m_RawModel->Vertices(), GL_STATIC_DRAW); - } + glBufferData(GL_ARRAY_BUFFER, m_RawModel->NumVertices() * m_RawModel->VertexSize(), m_RawModel->Vertices(), GL_STATIC_DRAW); glGenBuffers(1, &ElementBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer); @@ -41,7 +37,7 @@ Model::Model(std::string fileName) glBindBuffer(GL_ARRAY_BUFFER, buffer); std::vector structSizes; - if (m_RawModel->isSkined) { + if (m_RawModel->isSkined()) { structSizes = { 3, 3, 3, 3, 2, 4, 4 }; } else { structSizes = { 3, 3, 3, 3, 2 }; @@ -60,7 +56,7 @@ Model::Model(std::string fileName) 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++; - if (m_RawModel->isSkined) { + if (m_RawModel->isSkined()) { 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++; } @@ -72,7 +68,7 @@ Model::Model(std::string fileName) glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); - if (m_RawModel->isSkined) { + if (m_RawModel->isSkined()) { glEnableVertexAttribArray(5); glEnableVertexAttribArray(6); } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index c1939bdf..e22b69d1 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -40,9 +40,9 @@ void RawModelCustom::ReadMeshFile(std::string filePath) void RawModelCustom::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - isSkined = *(unsigned int*)(fileData + offset); + hasSkin = *(bool*)(fileData + offset); offset += sizeof(bool); - if (isSkined) { + if (hasSkin) { m_SkinedVertices.resize(*(unsigned int*)(fileData + offset)); } else { @@ -64,7 +64,7 @@ void RawModelCustom::ReadMesh(unsigned int& offset, char* fileData, unsigned int void RawModelCustom::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - if (isSkined) { + if (hasSkin) { if (offset + m_SkinedVertices.size() * sizeof(SkinedVertex) > fileByteSize) { throw Resource::FailedLoadingException("Reading skined vertices failed"); } diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index 0ec752f7..e487d87f 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -82,9 +82,16 @@ bool Material::findColorTexture(MaterialNode& material_node, MFnDependencyNode& workspace); FullPath = FullPath.substr(workspace.length()); FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); - material_node.ColorMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); - material_node.ColorMapFileLength = material_node.ColorMapFile.length() + 1; + MaterialNode::Texture newTexture; + + newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + newTexture.FileNameLength = newTexture.FileName.length() + 1; + + newTexture.UVTiling[0] = TextureNode.findPlug("RepeatU").asFloat(); + newTexture.UVTiling[1] = TextureNode.findPlug("RepeatV").asFloat(); + + material_node.ColorMaps.push_back(newTexture); return true; } } @@ -117,8 +124,16 @@ bool Material::findNormalTexture(MaterialNode& material_node, MFnDependencyNode& workspace); FullPath = FullPath.substr(workspace.length()); FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); - material_node.NormalMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); - material_node.NormalMapFileLength = material_node.NormalMapFile.length() + 1; + + MaterialNode::Texture newTexture; + + newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + newTexture.FileNameLength = newTexture.FileName.length() + 1; + + newTexture.UVTiling[0] = TextureNode.findPlug("RepeatU").asFloat(); + newTexture.UVTiling[1] = TextureNode.findPlug("RepeatV").asFloat(); + + material_node.NormalMaps.push_back(newTexture); return true; } } @@ -147,8 +162,16 @@ bool Material::findSpecularTexture(MaterialNode& material_node, MFnDependencyNod workspace); FullPath = FullPath.substr(workspace.length()); FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); - material_node.SpecularMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); - material_node.SpecularMapFileLength = material_node.SpecularMapFile.length() + 1; + + MaterialNode::Texture newTexture; + + newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + newTexture.FileNameLength = newTexture.FileName.length() + 1; + + newTexture.UVTiling[0] = TextureNode.findPlug("RepeatU").asFloat(); + newTexture.UVTiling[1] = TextureNode.findPlug("RepeatV").asFloat(); + + material_node.SpecularMaps.push_back(newTexture); return true; } } @@ -165,7 +188,7 @@ bool Material::findIncandescenceTexture(MaterialNode& material_node, MFnDependen for (int i = 0; i < AllConnections.length(); i++) { if (AllConnections[i].node().hasFn(MFn::kFileTexture)) { MFnDependencyNode TextureNode(AllConnections[i].node()); - + std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); m_TexturePaths.push_back(FullPath); @@ -174,14 +197,29 @@ bool Material::findIncandescenceTexture(MaterialNode& material_node, MFnDependen workspace); FullPath = FullPath.substr(workspace.length()); FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); - material_node.IncandescenceMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); - material_node.IncandescenceMapFileLength = material_node.IncandescenceMapFile.length() + 1; + + MaterialNode::Texture newTexture; + + newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + newTexture.FileNameLength = newTexture.FileName.length() + 1; + + newTexture.UVTiling[0] = TextureNode.findPlug("RepeatU").asFloat(); + newTexture.UVTiling[1] = TextureNode.findPlug("RepeatV").asFloat(); + + material_node.IncandescenceMaps.push_back(newTexture); return true; + + } else if (AllConnections[i].node().hasFn(MFn::kLayeredTexture)) { + return findSplatTextures(material_node.IncandescenceMaps, MFnDependencyNode(AllConnections[i].node())); } } return false; } +bool Material::findSplatTextures(std::vector& textureVector, MFnDependencyNode& node) { + return false; +} + // Returns the absolute path for all textures. Use for copying texture files. std::vector* Material::TexturePaths() { diff --git a/tools/MayaExporter/MayaExporter/Material.h b/tools/MayaExporter/MayaExporter/Material.h index e405dd07..844b3876 100644 --- a/tools/MayaExporter/MayaExporter/Material.h +++ b/tools/MayaExporter/MayaExporter/Material.h @@ -11,51 +11,87 @@ #include "OutputData.h" #include "Mesh.h" + +//#define ColorMapSplat 1 +//#define SpecularMapSplat 1 << 1 +//#define NormalMapSplat 1 << 2 +//#define IncandescenceMapSplat 1 << 3 + class MaterialNode : public OutputData { public: + class Texture : public OutputData { + public: + unsigned int FileNameLength = 0; + std::string FileName; + float UVTiling[2]{ 1.0f, 1.0f }; + + virtual void WriteBinary(std::ostream& out) + { + out.write((char*)&FileNameLength, sizeof(unsigned int)); + out.write(FileName.c_str(), FileNameLength); + out.write((char*)&UVTiling, sizeof(float) * 2); + } + + virtual void WriteASCII(std::ostream& out) const + { + out << "FileNameLength: " << FileNameLength << endl; + out << "FileName: " << FileName << endl; + out << "UV tiling: " << UVTiling[0] << " " << UVTiling[1] << endl; + } + }; + std::string Name; float ReflectionFactor; float SpecularExponent; - float DiffuseColor[3]{ 1.0f, 1.0f, 1.0f }; - unsigned int ColorMapFileLength = 0; - std::string ColorMapFile; + float DiffuseColor[3]{ 1.0f, 1.0f, 1.0f }; + float SpecularColor[3]{ 1.0f, 1.0f, 1.0f }; + float IncandescenceColor[3]{ 1.0f, 1.0f, 1.0f }; - float SpecularColor[3]{ 1.0f, 1.0f, 1.0f }; - unsigned int SpecularMapFileLength = 0; - std::string SpecularMapFile; + unsigned int IndexStart; + unsigned int IndexEnd; - unsigned int NormalMapFileLength = 0; - std::string NormalMapFile; + char NumColormaps = 0; + char NumSpecularMap = 0; + char NumNormalMap = 0; + char NumIncandescenceMap = 0; - float IncandescenceColor[3]{ 1.0f, 1.0f, 1.0f }; - unsigned int IncandescenceMapFileLength = 0; - std::string IncandescenceMapFile; - - unsigned int IndexStart; - unsigned int IndexEnd; + std::vector ColorMaps; + std::vector SpecularMaps; + std::vector NormalMaps; + std::vector IncandescenceMaps; virtual void WriteBinary(std::ostream& out) { - out.write((char*)&ColorMapFileLength, sizeof(unsigned int)); - out.write((char*)&NormalMapFileLength, sizeof(unsigned int)); - out.write((char*)&SpecularMapFileLength, sizeof(unsigned int)); - out.write((char*)&IncandescenceMapFileLength, sizeof(unsigned int)); - out.write((char*)&SpecularExponent, sizeof(float)); out.write((char*)&ReflectionFactor, sizeof(float)); + out.write((char*)&DiffuseColor, sizeof(float) * 3); out.write((char*)&SpecularColor, sizeof(float) * 3); out.write((char*)&IncandescenceColor, sizeof(float) * 3); + out.write((char*)&IndexStart, sizeof(unsigned int)); out.write((char*)&IndexEnd, sizeof(unsigned int)); - out.write(ColorMapFile.c_str(), ColorMapFileLength); - out.write(NormalMapFile.c_str(), NormalMapFileLength); - out.write(SpecularMapFile.c_str(), SpecularMapFileLength); - out.write(IncandescenceMapFile.c_str(), IncandescenceMapFileLength); + out.write((char*)&NumColormaps, sizeof(char)); + out.write((char*)&NumSpecularMap, sizeof(char)); + out.write((char*)&NumNormalMap, sizeof(char)); + out.write((char*)&NumIncandescenceMap, sizeof(char)); + + for(auto aTexture : ColorMaps) { + aTexture.WriteBinary(out); + } + for (auto aTexture : SpecularMaps) { + aTexture.WriteBinary(out); + } + for (auto aTexture : NormalMaps) { + aTexture.WriteBinary(out); + } + for (auto aTexture : IncandescenceMaps) { + aTexture.WriteBinary(out); + } } virtual void WriteASCII(std::ostream& out) const @@ -63,11 +99,6 @@ public: out << "New Material _ not in binary" << endl; out << "number of indices: " << Name << " _ not in binary" << endl; - out << "ColorMapFile length: " << ColorMapFileLength << endl; - out << "NormalMapFile length: " << NormalMapFileLength << endl; - out << "SpecularMapFile length: " << SpecularMapFileLength << endl; - out << "IncandescenceMapFile length: " << IncandescenceMapFileLength << endl; - out << "SpecularExponent: " << SpecularExponent << endl; out << "ReflectionFactor: " << ReflectionFactor << endl; out << "DiffuseColor: " << DiffuseColor[0] << " " << DiffuseColor[1] << " " << DiffuseColor[2] << endl; @@ -76,17 +107,37 @@ public: out << "IndexStart: " << IndexStart << endl; out << "IndexEnd: " << IndexEnd << endl; - if (ColorMapFileLength > 0) - out << "ColorMapFile: " << ColorMapFile << endl; + if (NumColormaps > 0) + out << "NumColormaps: " << NumColormaps << endl; - if (NormalMapFileLength > 0) - out << "NormalMapFile: " << NormalMapFile << endl; + if (NumSpecularMap > 0) + out << "NumSpecularMap: " << NumSpecularMap << endl; - if (SpecularMapFileLength > 0) - out << "SpecularMapFile: " << SpecularMapFile << endl; + if (NumNormalMap > 0) + out << "NumNormalMap: " << NumNormalMap << endl; - if (IncandescenceMapFileLength > 0) - out << "IncandescenceMapFile: " << IncandescenceMapFile << endl; + if (NumIncandescenceMap > 0) + out << "NumIncandescenceMap: " << NumIncandescenceMap << endl; + + out << "ColorMaps _ not in binary " << endl; + for (auto aTexture : ColorMaps) { + aTexture.WriteASCII(out); + } + + out << "SpecularMaps _ not in binary " << endl; + for (auto aTexture : SpecularMaps) { + aTexture.WriteASCII(out); + } + + out << "NormalMaps _ not in binary " << endl; + for (auto aTexture : NormalMaps) { + aTexture.WriteASCII(out); + } + + out << "IncandescenceMaps _ not in binary " << endl; + for (auto aTexture : IncandescenceMaps) { + aTexture.WriteASCII(out); + } } }; @@ -107,6 +158,7 @@ private: bool findNormalTexture(MaterialNode& material_node, MFnDependencyNode& node); bool findSpecularTexture(MaterialNode& material_node, MFnDependencyNode& node); bool findIncandescenceTexture(MaterialNode& material_node, MFnDependencyNode& node); + bool findSplatTextures(std::vector& textureVector, MFnDependencyNode& node); void grabLambertProperties(MaterialNode& material_node, MFnDependencyNode& node); void grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node); void grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node); diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index 4a7ac07e..b9384a45 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -40,8 +40,9 @@ v140 - Application + DynamicLibrary v140 + Unicode @@ -77,6 +78,7 @@ $(SolutionDir)$(Platform)\$(Configuration)\ + .mll @@ -135,7 +137,7 @@ NDEBUG;QT_DLL;QT_NO_DEBUG;QT_NO_IMPORT_QT47_QML;UNICODE;WIN32;%(PreprocessorDefinitions) - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories) + C:\Program Files\Autodesk\Maya2016\include;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories) MultiThreadedDLL @@ -144,7 +146,7 @@ Windows - $(OutDir)\$(ProjectName).exe + $(OutDir)$(TargetName)$(TargetExt) $(QTDIR)\lib;%(AdditionalLibraryDirectories) false qtmain.lib;%(AdditionalDependencies) diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index f44b9306..5553dcdd 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -228,8 +228,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e unsigned int jointID = 0; while (!jointIt.isDone()) { MFnTransform thisJoint(jointIt.currentItem()); - MMatrix transformationMatrix = thisJoint.transformationMatrix(); - + MTransformationMatrix TransformationMatrix = thisJoint.transformationMatrix(); double doubleMat[4][4]; if (currentFrame != startFrame){ @@ -263,6 +262,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e transformationMatrix.get(doubleMat); + //Save transformationMatrix to joinCheckMap joinCheckMap[thisJoint.name().asChar()][0][0] = doubleMat[0][0]; joinCheckMap[thisJoint.name().asChar()][0][1] = doubleMat[0][1]; joinCheckMap[thisJoint.name().asChar()][0][2] = doubleMat[0][2]; @@ -280,32 +280,32 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e joinCheckMap[thisJoint.name().asChar()][3][2] = doubleMat[3][2]; joinCheckMap[thisJoint.name().asChar()][3][3] = doubleMat[3][3]; - MPlug thisJointBindPose = thisJoint.findPlug("bindPose"); - MDataHandle DataHandle; - thisJointBindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix thisJointBindPoseMatrix = MartixFn.matrix(); + if (currentFrame == startFrame) { + MPlug thisJointBindPose = thisJoint.findPlug("bindPose"); + MDataHandle DataHandle; + thisJointBindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix thisJointBindPoseMatrix = MartixFn.matrix(); - MFnTransform Parent(thisJoint.parent(0), &status); - if (status == MS::kSuccess && thisJoint.parent(0).apiType() == MFn::kJoint) { - MTransformationMatrix Matrix = Parent.transformation(); - MPlug parentBindPose = Parent.findPlug("bindPose"); - MDataHandle DataHandle; - parentBindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix parentBindPoseMatrix = MartixFn.matrix(); + MFnTransform Parent(thisJoint.parent(0), &status); + if (status == MS::kSuccess && thisJoint.parent(0).apiType() == MFn::kJoint) { + MTransformationMatrix Matrix = Parent.transformation(); + MPlug parentBindPose = Parent.findPlug("bindPose"); + MDataHandle DataHandle; + parentBindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix parentBindPoseMatrix = MartixFn.matrix(); - thisJointBindPoseMatrix = thisJointBindPoseMatrix * parentBindPoseMatrix.inverse(); - } + thisJointBindPoseMatrix = thisJointBindPoseMatrix * parentBindPoseMatrix.inverse(); + } - MTransformationMatrix TransformationMatrix = thisJoint.transformation(); - - if (thisJointBindPoseMatrix.isEquivalent(TransformationMatrix.asMatrix())) { - jointID++; - jointIt.next(); - MGlobal::displayError(MString() + thisJoint.name() + " is in bindPose"); - continue; - } + if (thisJointBindPoseMatrix.isEquivalent(TransformationMatrix.asMatrix())) { + jointID++; + jointIt.next(); + MGlobal::displayError(MString() + thisJoint.name() + " is in bindPose"); + continue; + } + } MObject jointOrientObj = thisJoint.attribute("jointOrient"); MFnNumericAttribute jointOrient(jointOrientObj); From d50caa176321a70a53348be7e8ca01731fc16002 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 4 Feb 2016 16:14:50 +0100 Subject: [PATCH 066/131] Gain events tested. works as intended --- include/Engine/Sound/SoundSystem.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 597aca22..d0b1a3dd 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -126,9 +126,9 @@ private: EventRelay m_EContinueSound; bool OnContinueSound(const Events::ContinueSound &e); EventRelay m_ESetBGMGain; - bool OnSetBGMGain(const Events::SetBGMGain &e); // Not tested + bool OnSetBGMGain(const Events::SetBGMGain &e); EventRelay m_ESetSFXGain; - bool OnSetSFXGain(const Events::SetSFXGain &e); // Not tested + bool OnSetSFXGain(const Events::SetSFXGain &e); EventRelay m_EShoot; bool OnShoot(const Events::Shoot &e); EventRelay m_EPlayerSpawned; From 6a23a987b36e4f0785b4ea07a3455781c8135a3c Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 4 Feb 2016 17:43:45 +0100 Subject: [PATCH 067/131] Started PickupSpawnSystem, added 2 events and a system --- include/Engine/Core/EPickupSpawned.h | 18 ++++++++++++++++++ include/Engine/Core/EPickupTaken.h | 19 +++++++++++++++++++ include/Game/Systems/PickupSpawnSystem.h | 17 +++++++++++++++++ resources/Schema/Components.xsd | 1 + resources/Schema/Components/PickupSpawn.xml | 2 ++ resources/Schema/Components/PickupSpawn.xsd | 11 +++++++++++ src/Game/Systems/PickupSpawnSystem.cpp | 1 + 7 files changed, 69 insertions(+) create mode 100644 include/Engine/Core/EPickupSpawned.h create mode 100644 include/Engine/Core/EPickupTaken.h create mode 100644 include/Game/Systems/PickupSpawnSystem.h create mode 100644 resources/Schema/Components/PickupSpawn.xml create mode 100644 resources/Schema/Components/PickupSpawn.xsd create mode 100644 src/Game/Systems/PickupSpawnSystem.cpp diff --git a/include/Engine/Core/EPickupSpawned.h b/include/Engine/Core/EPickupSpawned.h new file mode 100644 index 00000000..acb6776e --- /dev/null +++ b/include/Engine/Core/EPickupSpawned.h @@ -0,0 +1,18 @@ +#ifndef EPickupSpawned_h__ +#define EPickupSpawned_h__ + +#include "Core/Event.h" +#include "Core/EntityWrapper.h" + +namespace Events +{ + +struct PickupSpawned : Event +{ + EntityID PickupID; + EntityWrapper Spawner; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Core/EPickupTaken.h b/include/Engine/Core/EPickupTaken.h new file mode 100644 index 00000000..e06fd974 --- /dev/null +++ b/include/Engine/Core/EPickupTaken.h @@ -0,0 +1,19 @@ +#ifndef EPickupTaken_h__ +#define EPickupTaken_h__ + +#include "Core/Event.h" +#include "Core/EntityWrapper.h" + +namespace Events +{ + +struct PickupTaken : Event +{ + EntityID PickupID; + EntityWrapper Spawner; + EntityWrapper Player; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Game/Systems/PickupSpawnSystem.h b/include/Game/Systems/PickupSpawnSystem.h new file mode 100644 index 00000000..99dad0aa --- /dev/null +++ b/include/Game/Systems/PickupSpawnSystem.h @@ -0,0 +1,17 @@ +#ifndef PickupSpawnSystem_h__ +#define PickupSpawnSystem_h__ + +#include "Core/System.h" +#include "Input/EInputCommand.h" +#include "Systems/SpawnerSystem.h" +#include "Events/ESpawnerSpawn.h" +#include "Core/EPlayerSpawned.h" +#include "Rendering/ESetCamera.h" +#include "Core/ConfigFile.h" +#include "Core/EPickupSpawned.h" + +class PickupSpawnSystem : public ImpureSystem +{ + +}; +#endif diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index ab46b0ea..445d96e7 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -29,4 +29,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/PickupSpawn.xml b/resources/Schema/Components/PickupSpawn.xml new file mode 100644 index 00000000..f8ce1225 --- /dev/null +++ b/resources/Schema/Components/PickupSpawn.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/Schema/Components/PickupSpawn.xsd b/resources/Schema/Components/PickupSpawn.xsd new file mode 100644 index 00000000..7ab90407 --- /dev/null +++ b/resources/Schema/Components/PickupSpawn.xsd @@ -0,0 +1,11 @@ + + + + + + + + Combined with a Spawner, defines a spawn point for a pickup + + + diff --git a/src/Game/Systems/PickupSpawnSystem.cpp b/src/Game/Systems/PickupSpawnSystem.cpp new file mode 100644 index 00000000..3b758764 --- /dev/null +++ b/src/Game/Systems/PickupSpawnSystem.cpp @@ -0,0 +1 @@ +#include "Systems/PickupSpawnSystem.h" From c526a7af55eae698e670d6d4ee4fd6ac81f97d28 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 4 Feb 2016 17:58:36 +0100 Subject: [PATCH 068/131] WIP stencil stuff --- include/Engine/Rendering/DrawFinalPass.h | 8 ++++- src/Engine/Rendering/DrawFinalPass.cpp | 43 ++++++++++++++++++++++-- src/Engine/Rendering/FrameBuffer.cpp | 17 ++++++++-- src/Engine/Rendering/Renderer.cpp | 10 ++++-- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 64d5563e..bacc7a8c 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -22,9 +22,13 @@ public: //Return the texture that is used in later stages to apply the bloom effect GLuint BloomTexture() const { return m_BloomTexture; } + GLuint BloomTextureLowRes() const { return m_BloomTextureLowRes; } //Return the texture with diffuse and lighting of the scene. GLuint SceneTexture() const { return m_SceneTexture; } + GLuint SceneTextureLowRes() const { return m_SceneTextureLowRes; } + //Return the framebuffer used in the scene rendering stage. FrameBuffer* FinalPassFrameBuffer() { return &m_FinalPassFrameBuffer; } + FrameBuffer* FinalPassFrameBufferLowRes() { return &m_FinalPassFrameBufferLowRes; } private: @@ -47,10 +51,12 @@ private: Texture* m_GreyTexture; FrameBuffer m_FinalPassFrameBuffer; + FrameBuffer m_FinalPassFrameBufferLowRes; GLuint m_BloomTexture; GLuint m_SceneTexture; + GLuint m_BloomTextureLowRes; + GLuint m_SceneTextureLowRes; GLuint m_DepthBuffer; - GLuint m_StencilBuffer; const IRenderer* m_Renderer; const LightCullingPass* m_LightCullingPass; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 106f9aa5..0a5c626b 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -22,18 +22,33 @@ void DrawFinalPass::InitializeFrameBuffers() glGenRenderbuffers(1, &m_DepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + GLERROR("RenderBuffer generation"); GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_FLOAT, 4); + //GenerateTexture(&m_StencilTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_STENCIL, GL_STENCIL_INDEX8, GL_INT); m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_STENCIL_ATTACHMENT))); + //m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_StencilTexture, GL_STENCIL_ATTACHMENT))); m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SceneTexture, GL_COLOR_ATTACHMENT0))); m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_BloomTexture, GL_COLOR_ATTACHMENT1))); m_FinalPassFrameBuffer.Generate(); GLERROR("FBO generation"); + GenerateTexture(&m_SceneTextureLowRes, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width/16, m_Renderer->GetViewportSize().Height/16), GL_RGB16F, GL_RGB, GL_FLOAT); + //GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + GenerateTexture(&m_BloomTextureLowRes, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width/16, m_Renderer->GetViewportSize().Height/16), GL_RGB16F, GL_RGB, GL_FLOAT); + //GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_FLOAT, 4); + //GenerateTexture(&m_StencilTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_STENCIL, GL_STENCIL_INDEX8, GL_INT); + + m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_STENCIL_ATTACHMENT))); + //m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_StencilTexture, GL_STENCIL_ATTACHMENT))); + m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_SceneTextureLowRes, GL_COLOR_ATTACHMENT0))); + m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_BloomTextureLowRes, GL_COLOR_ATTACHMENT1))); + m_FinalPassFrameBufferLowRes.Generate(); + GLERROR("FBO2 generation"); } void DrawFinalPass::InitializeShaderPrograms() @@ -93,7 +108,7 @@ void DrawFinalPass::Draw(RenderScene& scene) //Draw Opaque shielded objects state->StencilFunc(GL_NOTEQUAL, 1, 0xFF); - glStencilMask(0x00); + state->StencilMask(0x00); DrawShieldedModelRenderQueue(scene.Jobs.OpaqueShieldedObjects, scene); GLERROR("Shielded Opaque object"); @@ -103,7 +118,26 @@ void DrawFinalPass::Draw(RenderScene& scene) GLERROR("END"); delete state; - //delete stencilState; + + + DrawFinalPassState* stateLowRes = new DrawFinalPassState(m_FinalPassFrameBufferLowRes.GetHandle()); + //Draw the lowres texture that will be shown behind the shield. + if (scene.ClearDepth) { + glClear(GL_DEPTH_BUFFER_BIT); + } + //TODO: Do we need check for this or will it be per scene always? + //glClearStencil(0x00); + //glClear(GL_STENCIL_BUFFER_BIT); + + //state->StencilMask(0x00); + //state->StencilFunc(GL_ALWAYS, 1, 0xFF); + state->Disable(GL_STENCIL_TEST); + state->Disable(GL_DEPTH_TEST); + DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); + GLERROR("OpaqueObjects"); + DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); + GLERROR("TransparentObjects"); + delete stateLowRes; } @@ -113,6 +147,11 @@ void DrawFinalPass::ClearBuffer() glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_FinalPassFrameBuffer.Unbind(); + + m_FinalPassFrameBufferLowRes.Bind(); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_FinalPassFrameBufferLowRes.Unbind(); } void DrawFinalPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 5df1a5f1..c0be4cb1 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -39,10 +39,13 @@ void FrameBuffer::AddResource(std::shared_ptr resource) void FrameBuffer::Generate() { + GLERROR("PRE"); + std::vector attachments; glGenFramebuffers(1, &m_BufferHandle); glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle); + GLERROR("1"); for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) { switch ((*it)->m_ResourceType) { @@ -56,20 +59,30 @@ void FrameBuffer::Generate() GLERROR("FrameBuffer generate: glFramebufferRenderbuffer"); break; } - - if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT || (*it)->m_Attachment != GL_STENCIL_ATTACHMENT || (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { + GLERROR("2"); + + if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT && (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { attachments.push_back((*it)->m_Attachment); } + GLERROR("Attachment"); + } + GLERROR("3"); + GLenum* bufferTextures = &attachments[0]; glDrawBuffers(attachments.size(), bufferTextures); + if(GLERROR("4")) { + printf("hello"); + } if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { GLERROR("Framebuffer incomplete"); //LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); exit(EXIT_FAILURE); } + GLERROR("END"); + } void FrameBuffer::Bind() diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index fa3d1709..15554ab1 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -93,7 +93,7 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderFrame& frame) { - ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking"); + ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0SceneLowRes\0BloomLowRes\0Gaussian\0Picking"); //clear buffer 0 glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -129,9 +129,15 @@ void Renderer::Draw(RenderFrame& frame) m_DrawScreenQuadPass->Draw(m_DrawFinalPass->BloomTexture()); } if (m_DebugTextureToDraw == 3) { - m_DrawScreenQuadPass->Draw(m_DrawBloomPass->GaussianTexture()); + m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTextureLowRes()); } if (m_DebugTextureToDraw == 4) { + m_DrawScreenQuadPass->Draw(m_DrawFinalPass->BloomTextureLowRes()); + } + if (m_DebugTextureToDraw == 5) { + m_DrawScreenQuadPass->Draw(m_DrawBloomPass->GaussianTexture()); + } + if (m_DebugTextureToDraw == 6) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); } From b6e0332574fc0b94233db74fcc975704a2a591b8 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 5 Feb 2016 10:07:22 +0100 Subject: [PATCH 069/131] Fixed support for new animation structure, not done yet --- include/Engine/Rendering/Skeleton.h | 3 - resources/Schema/Entities/AnimationTests2.xml | 6 +- src/Engine/Rendering/AnimationSystem.cpp | 63 ++------ src/Engine/Rendering/Skeleton.cpp | 135 +++++------------- 4 files changed, 55 insertions(+), 152 deletions(-) diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index a428b7f3..f1ef22c7 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -62,7 +62,6 @@ public: int Index = 0; double Time = 0.0; BoneProperty BoneProperties; - //Keyframe::BoneProperty boneProperty; }; std::string Name; double Duration; @@ -87,8 +86,6 @@ public: const Animation* GetAnimation(std::string name); std::vector GetFrameBones(const Animation* animation, double time, bool noRootMotion = false); - void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); - void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); void PrintSkeleton(); diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index baff7413..a116803f 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -10,7 +10,7 @@ Models/Core/UnitPlane.mesh - false + @@ -35,8 +35,8 @@ - Ru - + Run + 1 diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 517fbf5c..c78aafd9 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -20,6 +20,15 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a return; } + ImGui::SliderFloat("Angle", &angle, -100.f, 100.f); + { + int id = skeleton->GetBoneID("Spine_3"); + auto it = skeleton->Bones.find(id); + if (it != skeleton->Bones.end()) { + it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle), 0.f, 0.f))); + } + } + const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]); @@ -51,55 +60,10 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a -/* - - ImGui::SliderFloat("Angle", &angle, -180.f, 180.f); - - int id = skeleton->GetBoneID("Spine_2"); - auto it = skeleton->Bones.find(id); - if (it != skeleton->Bones.end()) { - int currentKeyframeIndex = skeleton->GetKeyframe(*animation, entity["Animation"]["Time"]); - - const Skeleton::Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; - const Skeleton::Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; - float alpha = ((double)entity["Animation"]["Time"] - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - - glm::mat4 parentBoneTransform = skeleton->GetBoneTransform(it->second->Parent, currentFrame, nextFrame, alpha, glm::mat4(1)); - glm::vec3 scale; - glm::quat rotation; - glm::vec3 translation; - glm::vec3 skew; - glm::vec4 perspective; - glm::decompose(parentBoneTransform, scale, rotation, translation, skew, perspective); - - - - glm::vec3 rot; - rot = glm::vec3(1, 0, 0); - rot = glm::normalize(rot) * glm::radians(angle); - glm::mat4 modmat = glm::mat4(glm::quat(rot)) * glm::inverse(glm::mat4(rotation)); - - - it->second->ModificationMatrix = modmat; - } - - -*/ - -/* - - { - int id = skeleton->GetBoneID("Neck"); - auto it = skeleton->Bones.find(id); - if (it != skeleton->Bones.end()) { - it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); - } - } - - { + /* { int id = skeleton->GetBoneID("Spine_2"); auto it = skeleton->Bones.find(id); if (it != skeleton->Bones.end()) { @@ -119,8 +83,9 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a if (it != skeleton->Bones.end()) { it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); } - }* + }*/ +/* if (entity.HasComponent("Player")) { EntityWrapper cameraEntity = entity.FirstChildByName("Camera"); if (cameraEntity.Valid()) { @@ -128,7 +93,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } - } - */ + }*/ + } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 86d1cb20..5ae6a264 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -41,17 +41,17 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name) std::vector Skeleton::GetFrameBones(const Animation* animation, double time, bool noRootMotion /*= false*/) { - if(true){ - // if(animation == nullptr) { + if(animation == nullptr) { std::vector finalMatrices; for(auto& b : Bones) { - finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); + finalMatrices.push_back(b.second->ModificationMatrix);//b.second->OffsetMatrix); } return finalMatrices; } // HACK: Animation wrap-around + while (time < 0) { time += animation->Duration; } @@ -59,12 +59,6 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl time -= animation->Duration; } - int currentKeyframeIndex = GetKeyframe(*animation, time); - -// const Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; -// const Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; -// float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - //auto animationFrame = Animations[""].Keyframes[frame]; std::map frameBones; AccumulateBoneTransforms(noRootMotion, animation, time, frameBones, RootBone, glm::mat4(1)); @@ -79,86 +73,33 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl -void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map &boneMatrices, const Bone* bone, glm::mat4 parentMatrix) -{ - /* glm::mat4 boneMatrix; - - - - float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - - - 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 * bone->ModificationMatrix *(glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } else { - if (bone->Parent) { - boneMatrix = parentMatrix;// *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); - } -*/ - -} - void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { + glm::mat4 boneMatrix;// = glm::mat4(1); -/* - glm::mat4 boneMatrix = glm::mat4(1); + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; - Animation::Keyframe* currentFrame = nullptr; - Animation::Keyframe* nextFrame = nullptr; - - if(animation->BoneKeyFrames.find(bone->ID) != animation->BoneKeyFrames.end()) { // find the bone keyframes that surrounds the current frame - std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); - for (auto frame : boneKeyFrames) { - if(frame.Time <= time) { - currentFrame = &frame; - } else if (frame.Time > time) { - nextFrame = &frame; + if(animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { // find the bone keyframes that surrounds the current frame + std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); + + if(boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone + for (int index = boneKeyFrames.size()-1; index >= 0; index--) { + if (time >= boneKeyFrames.at(index).Time) { + currentFrame = boneKeyFrames.at(index); + nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); + break; + } } - } - //if(currentFrame == nullptr) cant happen - - if (nextFrame == nullptr) { - std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); - nextFrame = &boneKeyFrames.front(); - } - - - - if (currentFrame != nextFrame) { - - float progress = (time - currentFrame->Time) / (nextFrame->Time - currentFrame->Time); - - Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame->boneProperty; - Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame->boneProperty; + float progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu + if(progress > 1.0f || progress < 0.0f) { + LOG_INFO("Progress %f", progress); + progress = 0.f; + } + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; glm::vec3 positionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; glm::quat rotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); @@ -171,26 +112,24 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim } boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - - } else {// if (currentFrame == nextFrame) { - boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(currentFrame->boneProperty.Position) * glm::toMat4(currentFrame->boneProperty.Rotation) * glm::scale(currentFrame->boneProperty.Scale)); - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } - } else { -// if (bone->Parent) { // dont think this is needed -// boneMatrix = parentMatrix * bone->ModificationMatrix; -// } + boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + + } else { // 1 keyframes for the current bone + currentFrame = boneKeyFrames.at(0); + boneMatrix = parentMatrix * bone->ModificationMatrix *(glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); + boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + } + } else { // 0 keyframes for the current bone + boneMatrix = parentMatrix * bone->ModificationMatrix; + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + - boneMatrix = parentMatrix * bone->ModificationMatrix; - boneMatrices[bone->ID] = boneMatrix;// *bone->OffsetMatrix; - // } } for (auto &child : bone->Children) { std::string name = child->Name; AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, child, boneMatrix); - }*/ + } } glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix) @@ -254,12 +193,13 @@ void Skeleton::PrintSkeleton(const Bone* bone, int depthCount) int Skeleton::GetKeyframe(const Animation& animation, double time) { + /* if (time < 0) { time = 0; } if (time >= animation.Duration) { - return animation.Keyframes.size() - 1; + return animation..size() - 1; } for (int keyframe = 0; keyframe < animation.Keyframes.size(); ++keyframe) { @@ -269,5 +209,6 @@ int Skeleton::GetKeyframe(const Animation& animation, double time) } */ + return 0; } From 71a86cab114f0cdcb9c6f1805dc79c9cce88b596 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 5 Feb 2016 10:07:56 +0100 Subject: [PATCH 070/131] removed event that's not being used --- include/Engine/Sound/SoundSystem.h | 5 ----- src/Engine/Sound/SoundSystem.cpp | 11 +---------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index d0b1a3dd..51f80427 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -31,8 +31,6 @@ #include "Core/EPlayerDeath.h" #include "Core/EPlayerHealthPickup.h" #include "Core/EComponentAttached.h" -#include "Core/EComponentDeleted.h" -#include "Core/EEntityDeleted.h" #include "Collision/ETrigger.h" #include "Core/EPause.h" #include "Game/Events/EDoubleJump.h" @@ -107,7 +105,6 @@ private: bool m_EditorEnabled = false; const double m_PlayerFootstepInterval = 1.0; double m_TimeSinceLastFootstep = 0; - // TEMP EntityID m_LocalPlayer = EntityID_Invalid; bool m_LeftFoot = false; std::default_random_engine generator; @@ -145,8 +142,6 @@ private: bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); EventRelay m_EComponentAttached; bool OnComponentAttached(const Events::ComponentAttached &e); - EventRelay m_EComponentDeleted; - bool OnComponentDeleted(const Events::ComponentDeleted &e); EventRelay m_ETriggerTouch; bool OnTriggerTouch(const Events::TriggerTouch &e); EventRelay m_EPause; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 847230d9..3045b1f4 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -177,7 +177,6 @@ void SoundSystem::playQueue(QueuedBuffers qb) alSourcePlay(qb.first); } - void SoundSystem::stopSound(Source* source) { alSourceStop(source->ALsource); @@ -402,7 +401,7 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) source->Type = SoundType::SFX; m_Sources[child] = source; - // breathe + // Breathe std::vector buffers; buffers.push_back(source->SoundResource->Buffer()); int ammountOfbreaths = (static_cast(e.Damage) / 10) + 2; // TEMP: Idk something stupid like this shit @@ -452,14 +451,6 @@ bool SoundSystem::OnComponentAttached(const Events::ComponentAttached & e) return false; } -bool SoundSystem::OnComponentDeleted(const Events::ComponentDeleted & e) -{ - if (e.ComponentType == "SoundEmitter") { - - } - return false; -} - bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) { if (m_World->HasComponent(e.Trigger.ID, "CapturePoint")) { From d61e6050938b751f82b7bfd1b58cd1f5628bf358 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 5 Feb 2016 10:56:34 +0100 Subject: [PATCH 071/131] Can walk up "stair-steps". Cleanup WIP. Better performance in RectanglevsTriangle check. Added IsOnGround flag and VerticalStepHeight in Physics. Lotsa commented code saved for historical reasons, remove later. --- include/Engine/Collision/Collision.h | 2 + resources/Schema/Components/Physics.xml | 2 + resources/Schema/Components/Physics.xsd | 4 + src/Engine/Collision/Collision.cpp | 226 +++++++++++++++++----- src/Engine/Collision/CollisionSystem.cpp | 30 ++- src/Game/Systems/PlayerMovementSystem.cpp | 18 +- 6 files changed, 221 insertions(+), 61 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 183c800c..6e4858b2 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -68,6 +68,8 @@ bool AABBvsTriangles(const AABB& box, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& boxVelocity, + float verticalStepHeight, + bool& isOnGround, glm::vec3& outResolutionVector); //Return true if the boxes are intersecting. diff --git a/resources/Schema/Components/Physics.xml b/resources/Schema/Components/Physics.xml index 9d1638fb..6cb73c75 100644 --- a/resources/Schema/Components/Physics.xml +++ b/resources/Schema/Components/Physics.xml @@ -2,4 +2,6 @@ true + false + 0.33 diff --git a/resources/Schema/Components/Physics.xsd b/resources/Schema/Components/Physics.xsd index 72037f48..7fed1fb5 100644 --- a/resources/Schema/Components/Physics.xsd +++ b/resources/Schema/Components/Physics.xsd @@ -13,6 +13,10 @@ m/s^2 + + + The largest height of a "stair-step" that can be walked over + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 083af229..7bb0d3c4 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -238,7 +238,7 @@ inline glm::vec3 signNonZero(const glm::vec3& x) { glm::vec3 r; for (int i = 0; i < 3; ++i) { - r[i] = signNonZero(x[i]); + r[i] = (float)signNonZero(x[i]); } return r; } @@ -253,11 +253,11 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, const glm::vec2& boxMax, const std::array& triPos, glm::vec2& resolutionDirection, - float& resolutionDistance, + float& resolutionDistanceSq, bool& pushedFromTriNormal) { pushedFromTriNormal = false; - resolutionDistance = INFINITY; + resolutionDistanceSq = INFINITY; //Project along box normals (coordinate axes, since it's axis-aligned). for (int ax = 0; ax < 2; ++ax) { float minTri = INFINITY; @@ -275,9 +275,11 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, float leftRes = minTri - boxMax[ax]; float rightRes = maxTri - boxMin[ax]; float push = rightRes < -leftRes ? rightRes : leftRes; - float absPush = abs(push); - if (absPush < resolutionDistance) { - resolutionDistance = absPush; + float absPushSq = abs(push); + absPushSq *= absPushSq; + + if (absPushSq < resolutionDistanceSq) { + resolutionDistanceSq = absPushSq; resolutionDirection[1 - ax] = 0.f; resolutionDirection[ax] = push; } @@ -326,9 +328,11 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, float leftRes = minTri - maxBox; float rightRes = maxTri - minBox; float push = rightRes < -leftRes ? rightRes : leftRes; - float absPush = abs(push); - if (absPush < resolutionDistance) { - resolutionDistance = absPush; + float absPushSq = abs(push); + absPushSq *= absPushSq; + + if (absPushSq < resolutionDistanceSq) { + resolutionDistanceSq = absPushSq; resolutionDirection = push * normal; pushedFromTriNormal = true; } @@ -338,26 +342,35 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, constexpr float SlopeConstant(float degrees) { - return (1.0 - degrees / 90.f); + return (1.0f - degrees / 90.f); +} + +//Returns true if the angle between horizon and the collision surface is less than 45 degrees. +constexpr bool FaceIsGround(float faceNormalY) +{ + //TODO: Perhaps the 45 degrees could be saved in a component or in the config.. + return faceNormalY > SlopeConstant(45.0f); } //An array containing 3 int pairs { 0, 2 }, { 0, 1 }, { 1, 2 } constexpr std::array, 3> dimensionPairs({ std::pair(0, 2), std::pair(0, 1), std::pair(1, 2) }); -//TODO: Prefer to move in y - if the resolution is small enough, value in physics comp. -//TODO: Walking down slopes correctly. bool AABBvsTriangle(const AABB& box, const std::array& triPos, + const glm::vec3& originalBoxVelocity, + float verticalStepHeight, + bool& isOnGround, glm::vec3& boxVelocity, - glm::vec3& outVector) + glm::vec3& outResolution) { //Check so we don't have a zero area triangle when calculating the normal. //Also, don't check a triangle facing away from the player. //Less checks, and we should be able to walk out from models if we are trapped inside. glm::vec3 triNormal = glm::cross(triPos[1] - triPos[0], triPos[2] - triPos[0]); - if (!vectorHasLength(triNormal) || (glm::dot(triNormal, boxVelocity) > 0)) { + if (!vectorHasLength(triNormal) || (glm::dot(triNormal, originalBoxVelocity) > 0)) { return false; } + triNormal = glm::normalize(triNormal); enum BoxTriResolveCase { @@ -366,13 +379,29 @@ bool AABBvsTriangle(const AABB& box, ResolveDimZ, Line, //Box edge colliding with triangle line. Corner //Box corner colliding with the triangle face. - } resolveCase; + }; + struct Resolution + { + Resolution() + : DistanceSq(INFINITY) + , Vector(0.f) + {} + BoxTriResolveCase Case; + float DistanceSq; + glm::vec3 Vector; + }; + //The smallest resolution that solves the collision. + Resolution resolveShortest; + //The smallest resolution that solves the collision, that resolves upwards. + Resolution resolveUpwards; + //If player stands on the ground and collides with a ground triangle, + //we might step up onto it if the step is small enough. + bool canStairStepUp = isOnGround && FaceIsGround(triNormal.y); const glm::vec3& origin = box.Origin(); const glm::vec3& half = box.HalfSize(); const glm::vec3& min = box.MinCorner(); const glm::vec3& max = box.MaxCorner(); - float minimumTranslation = INFINITY; //For each projection in xy-, xz-, and yx-planes. for (std::pair dim : dimensionPairs) { @@ -392,21 +421,35 @@ bool AABBvsTriangle(const AABB& box, //if projections don't overlap, return false. if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector, resolutionDist, pushedFromTriangleLine)) { return false; - } else if (resolutionDist < minimumTranslation) { - outVector = glm::vec3(0.f); - outVector[dim.first] = resolutionVector.x; - outVector[dim.second] = resolutionVector.y; - minimumTranslation = resolutionDist; - //If we pushed away from triangle line (edge), or if we - //move the player along one coordinate axis (pick the dimension that isn't zero). - resolveCase = pushedFromTriangleLine ? Line : static_cast((abs(outVector[dim.first]) < 0.0001f) ? dim.second : dim.first); + } else { + //Overwrite the smallest resolution if this is smaller. + if (resolutionDist < resolveShortest.DistanceSq) { + resolveShortest.Vector = glm::vec3(0.f); + resolveShortest.Vector[dim.first] = resolutionVector.x; + resolveShortest.Vector[dim.second] = resolutionVector.y; + resolveShortest.DistanceSq = resolutionDist; + //If we pushed away from triangle line (edge), or if we + //move the player along one coordinate axis (pick the dimension that isn't zero). + resolveShortest.Case = pushedFromTriangleLine ? Line : static_cast((abs(resolveShortest.Vector[dim.first]) < 0.0001f) ? dim.second : dim.first); + } + //Overwrite the smallest upward resolution if this is smaller, and resolves upwards. + constexpr int yAxis = 1; + bool resIsUpwardsIn3D = dim.first == yAxis && resolutionVector.x > 0 || dim.second == yAxis && resolutionVector.y > 0; + if (canStairStepUp && resIsUpwardsIn3D && resolutionDist < resolveUpwards.DistanceSq) { + resolveUpwards.Vector = glm::vec3(0.f); + resolveUpwards.Vector[dim.first] = resolutionVector.x; + resolveUpwards.Vector[dim.second] = resolutionVector.y; + resolveUpwards.DistanceSq = resolutionDist; + //If we pushed away from triangle line (edge), or if we + //move the player along one coordinate axis (pick the dimension that isn't zero). + resolveUpwards.Case = pushedFromTriangleLine ? Line : static_cast((abs(resolveUpwards.Vector[dim.first]) < 0.0001f) ? dim.second : dim.first); + } } } //If the triangle does intersect any of the cube diagonals, it will //intersect the cube diagonal that comes //closest to being perpendicular to the plane of the triangle. - triNormal = glm::normalize(triNormal); glm::vec3 diagonal = signNonZero(triNormal) * half; //The triangle plane contains all points P in dot(triNormal, P) == dot(triNormal, v0) //The diagonal line contains all points P in P = origin + diagonal * t. @@ -416,24 +459,62 @@ bool AABBvsTriangle(const AABB& box, return false; } glm::vec3 cornerResolution = (1+t) * diagonal; - if (glm::length(cornerResolution) < minimumTranslation) { - outVector = cornerResolution; - resolveCase = Corner; + //Overwrite the smallest resolution if this is smaller. + float lenSq = glm::length2(cornerResolution); + if (lenSq < resolveShortest.DistanceSq) { + resolveShortest.Vector = cornerResolution; + resolveShortest.Case = Corner; + } + if (canStairStepUp && cornerResolution.y > 0 && lenSq < resolveUpwards.DistanceSq) { + resolveUpwards.Vector = cornerResolution; + resolveUpwards.Case = Corner; + resolveUpwards.DistanceSq = lenSq; } - glm::vec3 projNorm; - switch (resolveCase) { - case ResolveDimX: + //Force the resolution upwards if it is smaller than the threshold verticalStepHeight. + //Else take the shortest resolution. + bool takeUp = resolveUpwards.Vector.y > 0 && resolveUpwards.Vector.y < verticalStepHeight; + Resolution& bestResolve = takeUp ? resolveUpwards : resolveShortest; + outResolution = bestResolve.Vector; + + //TODO: Debug stuff. + std::string dbg; + switch (bestResolve.Case) { case ResolveDimY: + case ResolveDimX: + case ResolveDimZ: + dbg = "Axis"; + break; + case Line: + dbg = "Line"; + break; + case Corner: + dbg = "Corner"; + break; + default: + break; + } + std::string outs = (takeUp ? "Resolve upwards " : "Resolve normal ") + dbg; + //TODO: End debug stuff. + + glm::vec3 projNorm; + switch (bestResolve.Case) { + case ResolveDimY: + boxVelocity.y = 0.f; + if (outResolution.y > 0) + isOnGround = true; + case ResolveDimX: case ResolveDimZ: { //If we get here, the resolution is along one coordinate axis. - //set velocity to 0 in that dimension. - boxVelocity[resolveCase] = 0.f; + //set velocity to 0 in y if it is along y-axis. + outs += isOnGround ? " ground" : " air"; + ImGui::Text(outs.c_str()); + LOG_INFO(outs.c_str()); return true; } case Line: - projNorm = glm::normalize(outVector); + projNorm = glm::normalize(outResolution); break; case Corner: projNorm = triNormal; @@ -442,26 +523,64 @@ bool AABBvsTriangle(const AABB& box, break; } - //If the collision was not on steep wall or similarly (e.g. walking on the ground), do special treatment. - //Magic value that makes condition correspond to: - //if the angle between horizon and the collision surface is less than 45 degrees. - if (projNorm.y > SlopeConstant(45.0f)) { + isOnGround = false; + //If the collision was not on steep wall or similarly (e.g. walking on the ground), force resolution in y only. + if (FaceIsGround(projNorm.y)) { //Ensure that the player always is moved upwards, instead of sliding down. //Also zero the vertical velocity. - float len = glm::length(outVector); - float ang = glm::half_pi() - glm::acos(outVector.y / len); + float len = glm::length(outResolution); + float ang = glm::half_pi() - glm::acos(outResolution.y / len); if (len > 0.0000001f && ang > 0.0000001f) { - outVector.x = 0; - outVector.y = len / glm::sin(ang); - outVector.z = 0; - boxVelocity.y = 0.f; + outResolution.x = 0; + outResolution.y = len / glm::sin(ang); + outResolution.z = 0; } - } else if (projNorm.y > 0) { - //Enter here if the triangle is a steep slope, and it is not facing downwards. //Project the velocity onto the normal of the hit line/face. //w = v - *n, |n|==1. - boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; + glm::vec3 projVel = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; + if (abs(originalBoxVelocity.x) < 0.001f && abs(originalBoxVelocity.z) < 0.001f) { + boxVelocity.y = 0.f; + } else { + boxVelocity.y = std::min(projVel.y, 0.f); + } + + isOnGround = true; + } else if (projNorm.y > 0) { + //Enter here if the triangle is a steep slope, and it is not facing downwards. + //Ensure that the player will be pushed in the xz-plane. + //glm::vec3 moveDir(outResolution); + //moveDir.y = 0; + //if (vectorHasLength(moveDir)) { + // moveDir = glm::normalize(moveDir); + // float len = glm::length(outResolution); + // float dotMoveOut = moveDir.x * outResolution.x + moveDir.z * outResolution.z; + // float ang = glm::half_pi() - glm::acos(dotMoveOut / len); + // if (len > 0.0000001f && ang > 0.0000001f) { + // outResolution = (len / glm::sin(ang)) * moveDir; + // } + //} + //Project the velocity onto the normal of the hit line/face. + //w = v - *n, |n|==1. + //TODO: What do we want.. +#if 0 //Walk up steep walls. + glm::vec3 projVel = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; + boxVelocity.y = std::min(projVel.y, 0.f); + isOnGround = true; +#elif 1 //"ice cream"-effect, air resistance + projected velocity. + if (!isOnGround) { + boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; + } + isOnGround = false; +#elif 0 //"ice cream"-effect, ground friction (full control) + projected velocity. + if (!isOnGround) { + boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; + } + isOnGround = true; +#endif } + outs += isOnGround ? " ground" : " air"; + ImGui::Text(outs.c_str()); + LOG_INFO(outs.c_str()); return true; } @@ -470,12 +589,16 @@ bool AABBvsTriangles(const AABB& box, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& boxVelocity, + float verticalStepHeight, + bool& isOnGround, glm::vec3& outResolutionVector) { bool hit = false; + bool everHitTheGround = false; AABB newBox = box; outResolutionVector = glm::vec3(0.f); + glm::vec3 originalBoxVelocity(boxVelocity); for (int i = 0; i < modelIndices.size(); ) { std::array triVertices = { Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), @@ -483,13 +606,20 @@ bool AABBvsTriangles(const AABB& box, Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) }; glm::vec3 outVec; - if (AABBvsTriangle(newBox, triVertices, boxVelocity, outVec)) { + bool collideWithGround = isOnGround; + if (AABBvsTriangle(newBox, triVertices, originalBoxVelocity, verticalStepHeight, collideWithGround, boxVelocity, outVec)) { hit = true; outResolutionVector += outVec; newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size()); + if (collideWithGround) { + everHitTheGround = isOnGround = true; + } } } + if (!everHitTheGround) { + isOnGround = false; + } return hit; } diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 846d38a7..e5c194d6 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -37,15 +37,33 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity); - glm::vec3 newVelocity = (glm::vec3)cPhysics["Velocity"]; - if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, newVelocity, resolutionVector)) { - (glm::vec3&)cTransform["Position"] += resolutionVector; - cPhysics["Velocity"] = newVelocity; - } + glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"]; + bool isOnGround = (bool)cPhysics["IsOnGround"]; + //glm::vec3 gravity = glm::vec3(0, 9.82f * dt, 0); + //TODO: glm::abs(inOutVelocity - gravity) doesn't work, because of velocity projection on ground normal. + //if (!isOnGround || glm::any(glm::greaterThan(glm::abs(inOutVelocity - gravity), glm::vec3(0.0001f)))) { + float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"]; + if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { + glm::vec3 pos = (glm::vec3)cTransform["Position"] + resolutionVector; + //Hack: Force the position to be at discrete values after collision, removes jittering. + //constexpr float discreteValue = 1.0e2f; + //pos = glm::vec3(glm::ivec3(discreteValue * pos)) / discreteValue; + //pos = glm::round(discreteValue * pos) / discreteValue; + (glm::vec3&)cTransform["Position"] = pos; + cPhysics["Velocity"] = inOutVelocity; + (bool)cPhysics["IsOnGround"] = isOnGround; + } else { + (bool)cPhysics["IsOnGround"] = false; + } + //} else { + // (glm::vec3&)cTransform["Position"] -= gravity; + // cPhysics["Velocity"] = glm::vec3(0.f); + //} } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { //Enter here if boxB has no Model. (glm::vec3&)cTransform["Position"] += resolutionVector; - if (resolutionVector.y > 0) { + (bool)cPhysics["IsOnGround"] = resolutionVector.y > 0; + if ((bool)cPhysics["IsOnGround"]){ ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; } } diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 6eab02c5..92ddf549 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -50,11 +50,13 @@ void PlayerMovementSystem::Update(double dt) wishSpeed = playerMovementSpeed; } glm::vec3& velocity = cPhysics["Velocity"]; - ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z); + bool isOnGround = (bool)cPhysics["IsOnGround"]; + ImGui::Text(isOnGround ? "On ground" : "In air"); + ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity)); glm::vec3 groundVelocity(0.f, 0.f, 0.f); - groundVelocity.x = glm::dot(velocity, glm::vec3(1.f, 0.f, 0.f)); - groundVelocity.z = glm::dot(velocity, glm::vec3(0.f, 0.f, 1.f)); - ImGui::Text("groundVelocity: (%f, %f, %f) |%f|", groundVelocity.x, groundVelocity.y, groundVelocity.z, glm::length(wishDirection)); + groundVelocity.x = velocity.x; + groundVelocity.z = velocity.z; + ImGui::Text("groundVelocity: (%f, %f, %f) |%f|", groundVelocity.x, groundVelocity.y, groundVelocity.z, glm::length(groundVelocity)); ImGui::Text("wishDirection: (%f, %f, %f) |%f|", wishDirection.x, wishDirection.y, wishDirection.z, glm::length(wishDirection)); float currentSpeedProj = glm::dot(groundVelocity, wishDirection); float addSpeed = wishSpeed - currentSpeedProj; @@ -67,7 +69,7 @@ void PlayerMovementSystem::Update(double dt) ImGui::InputFloat("accel", &accel); static float airAccel = 0.5f; ImGui::InputFloat("airAccel", &airAccel); - float actualAccel = (velocity.y != 0) ? airAccel : accel; + float actualAccel = isOnGround ? accel : airAccel; static float surfaceFriction = 5.f; ImGui::InputFloat("surfaceFriction", &surfaceFriction); float accelerationSpeed = actualAccel * (float)dt * wishSpeed * surfaceFriction; @@ -76,7 +78,8 @@ void PlayerMovementSystem::Update(double dt) ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity)); } - if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { + if (controller->Jumping() && !controller->Crouching() && isOnGround) { + (bool)cPhysics["IsOnGround"] = false; velocity.y += 4.f; } @@ -128,6 +131,7 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp ComponentWrapper& cPhysics = entity["Physics"]; glm::vec3& velocity = cPhysics["Velocity"]; + bool isOnGround = (bool)cPhysics["IsOnGround"]; // Ground friction float speed = glm::length(velocity); @@ -135,7 +139,7 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp ImGui::InputFloat("groundFriction", &groundFriction); static float airFriction = 0.f; ImGui::InputFloat("airFriction", &airFriction); - float friction = (velocity.y != 0) ? airFriction : groundFriction; + float friction = isOnGround ? groundFriction : airFriction; if (speed > 0) { float drop = speed * friction * (float)dt; float multiplier = glm::max(speed - drop, 0.f) / speed; From d1a309be10532ce58823f77578dd02d589263cbe Mon Sep 17 00:00:00 2001 From: Teejoon Date: Fri, 5 Feb 2016 13:51:47 +0100 Subject: [PATCH 072/131] Now supports reading of 3 different types of materials --- include/Engine/Rendering/RawModelCustom.h | 47 +++-- src/Engine/Rendering/RawModelCustom.cpp | 205 ++++++++++++++-------- 2 files changed, 171 insertions(+), 81 deletions(-) diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index 66477322..10bfd276 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -46,8 +46,14 @@ public: glm::vec4 BoneIndices; glm::vec4 BoneWeights; }; + + struct TextureProperties { + std::string TexturePath; + glm::vec2 UVRepeat; + std::shared_ptr<::Texture> Texture; + }; - struct MaterialGroup + struct MaterialBasic { float SpecularExponent; float ReflectionFactor; @@ -57,16 +63,32 @@ public: unsigned int StartIndex; unsigned int EndIndex; //float Transparency; - std::string TexturePath; - std::shared_ptr<::Texture> Texture; - std::string NormalMapPath; - std::shared_ptr<::Texture> NormalMap; - std::string SpecularMapPath; - std::shared_ptr<::Texture> SpecularMap; - std::string IncandescenceMapPath; - std::shared_ptr<::Texture> IncandescenceMap; }; + struct MaterialSplatMapping : public MaterialBasic + { + TextureProperties SplatMap; + std::vector ColorMaps; + std::vector NormalMaps; + std::vector SpecularMaps; + std::vector IncandescenceMaps; + }; + + struct MaterialSingleTextures : public MaterialBasic + { + TextureProperties ColorMaps; + TextureProperties NormalMaps; + TextureProperties SpecularMaps; + TextureProperties IncandescenceMaps; + }; + + enum class MaterialType { Basic = 1, SplatMapping, SingleTextures }; + + struct MaterialProperties { + MaterialType type; + MaterialBasic* material; + }; + const Vertex* Vertices() const { if (hasSkin) { return m_SkinedVertices.data(); @@ -94,8 +116,7 @@ public: bool isSkined() const { return hasSkin; }; - std::vector MaterialGroups; - + std::vector m_Materials; std::vector m_Indices; Skeleton* m_Skeleton = nullptr; @@ -115,6 +136,10 @@ private: void ReadMaterialFile(std::string filePath); void ReadMaterials(unsigned int &offset, char* fileData, unsigned int& fileByteSize); void ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize); + void ReadMaterialBasic(MaterialBasic* Material, unsigned int &offset, char* fileData, unsigned int& fileByteSize); + void ReadMaterialSingleTexture(MaterialSingleTextures* Material, unsigned int &offset, char* fileData, unsigned int& fileByteSize); + void ReadMaterialSplatMapping(MaterialSplatMapping* Material, unsigned int &offset, char* fileData, unsigned int& fileByteSize); + void ReadMaterialTextureProperties(TextureProperties& texture, unsigned int &offset, char* fileData, unsigned int& fileByteSize); void ReadAnimationFile(std::string filePath); void ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize); diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index f3291394..8bdfbbfc 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -122,7 +122,7 @@ void RawModelCustom::ReadMaterials(unsigned int& offset, char* fileData, unsigne { #ifdef BOOST_LITTLE_ENDIAN unsigned int* numMaterials = (unsigned int*)(fileData); - MaterialGroups.reserve(*numMaterials); + m_Materials.reserve(*numMaterials); offset += sizeof(unsigned int); for (int i = 0; i < *numMaterials; i++) { @@ -134,83 +134,148 @@ void RawModelCustom::ReadMaterials(unsigned int& offset, char* fileData, unsigne void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize) { - MaterialGroup newMaterial; - + MaterialProperties newMaterialProperty; #ifdef BOOST_LITTLE_ENDIAN - if (offset + sizeof(unsigned int) * 4 > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material texture names length failed"); - } + if (offset + sizeof(MaterialType) > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material Type failed"); + } + MaterialType type = *(MaterialType*)(fileData + offset); + offset += sizeof(MaterialType); - unsigned int* nameLengths = (unsigned int*)(fileData + offset); - offset += sizeof(unsigned int) * 4; + switch (type) { + case MaterialType::Basic: + newMaterialProperty.material = new MaterialBasic(); + ReadMaterialBasic(newMaterialProperty.material, offset, fileData, fileByteSize); + break; + case MaterialType::SplatMapping: + newMaterialProperty.material = new MaterialSplatMapping(); + ReadMaterialSplatMapping(static_cast(newMaterialProperty.material), offset, fileData, fileByteSize); + break; + case MaterialType::SingleTextures: + newMaterialProperty.material = new MaterialSingleTextures(); + ReadMaterialSingleTexture(static_cast(newMaterialProperty.material), offset, fileData, fileByteSize); + break; + default: + throw Resource::FailedLoadingException("Material contains an unknown MaterialType"); + }; - if (offset + sizeof(float) * 11 + sizeof(unsigned int) * 2 > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material specular, reflection, color and start and end index values failed"); - } - - newMaterial.SpecularExponent = *(float*)(fileData + offset); - offset += sizeof(float); - newMaterial.ReflectionFactor = *(float*)(fileData + offset); - offset += sizeof(float); - - memcpy(&newMaterial.DiffuseColor[0], fileData + offset, sizeof(float) * 3); - offset += sizeof(float) * 3; - memcpy(&newMaterial.SpecularColor[0], fileData + offset, sizeof(float) * 3); - offset += sizeof(float) * 3; - memcpy(&newMaterial.IncandescenceColor[0], fileData + offset, sizeof(float) * 3); - offset += sizeof(float) * 3; - - newMaterial.StartIndex = *(unsigned int*)(fileData + offset); - offset += sizeof(unsigned int); - newMaterial.EndIndex = *(unsigned int*)(fileData + offset); - offset += sizeof(unsigned int); - - if (nameLengths[0] > 0) { - if (offset + nameLengths[0] > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material texture path failed"); - } - - newMaterial.TexturePath = "Textures/"; - newMaterial.TexturePath += (fileData + offset); - newMaterial.TexturePath += ".png"; - offset += nameLengths[0]; - } - - if (nameLengths[1] > 0) { - if (offset + nameLengths[1] > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material NormalMap path failed"); - } - newMaterial.NormalMapPath = "Textures/"; - newMaterial.NormalMapPath += (fileData + offset); - newMaterial.NormalMapPath += ".png"; - offset += nameLengths[1]; - } - - if (nameLengths[2] > 0) { - if (offset + nameLengths[2] > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material SpecularMap path failed"); - } - newMaterial.SpecularMapPath = "Textures/"; - newMaterial.SpecularMapPath += (fileData + offset); - newMaterial.SpecularMapPath += ".png"; - offset += nameLengths[2]; - } - - if (nameLengths[3] > 0) { - if (offset + nameLengths[3] > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material IncandescenceMap path failed"); - } - newMaterial.IncandescenceMapPath = "Textures/"; - newMaterial.IncandescenceMapPath += (fileData + offset); - newMaterial.IncandescenceMapPath += ".png"; - offset += nameLengths[3]; - } + newMaterialProperty.type = type; #else #endif - MaterialGroups.push_back(newMaterial); + m_Materials.push_back(newMaterialProperty); +} + +void RawModelCustom::ReadMaterialBasic(RawModelCustom::MaterialBasic* newMaterial, unsigned int &offset, char* fileData, unsigned int& fileByteSize) +{ + if (offset + sizeof(unsigned int) * 4 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material texture names length failed"); + } + + unsigned int* nameLengths = (unsigned int*)(fileData + offset); + offset += sizeof(unsigned int) * 4; + + if (offset + sizeof(float) * 11 + sizeof(unsigned int) * 2 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material specular, reflection, color and start and end index values failed"); + } + + newMaterial->SpecularExponent = *(float*)(fileData + offset); + offset += sizeof(float); + newMaterial->ReflectionFactor = *(float*)(fileData + offset); + offset += sizeof(float); + + memcpy(&newMaterial->DiffuseColor[0], fileData + offset, sizeof(float) * 3); + offset += sizeof(float) * 3; + memcpy(&newMaterial->SpecularColor[0], fileData + offset, sizeof(float) * 3); + offset += sizeof(float) * 3; + memcpy(&newMaterial->IncandescenceColor[0], fileData + offset, sizeof(float) * 3); + offset += sizeof(float) * 3; + + newMaterial->StartIndex = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + newMaterial->EndIndex = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); +} + +void RawModelCustom::ReadMaterialSingleTexture(RawModelCustom::MaterialSingleTextures* newMaterial, unsigned int &offset, char* fileData, unsigned int& fileByteSize) +{ + unsigned char numberOfMaps[4]; + if (offset + sizeof(unsigned char) * 4 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material NumOfMaps failed"); + } + + if (numberOfMaps[0] > 0) + { + ReadMaterialTextureProperties(newMaterial->ColorMaps, offset, fileData, fileByteSize); + } + + if (numberOfMaps[1] > 0) + { + ReadMaterialTextureProperties(newMaterial->SpecularMaps, offset, fileData, fileByteSize); + } + + if (numberOfMaps[2] > 0) + { + ReadMaterialTextureProperties(newMaterial->NormalMaps, offset, fileData, fileByteSize); + } + + if (numberOfMaps[3] > 0) + { + ReadMaterialTextureProperties(newMaterial->IncandescenceMaps, offset, fileData, fileByteSize); + } +} + +void RawModelCustom::ReadMaterialSplatMapping(RawModelCustom::MaterialSplatMapping* newMaterial, unsigned int &offset, char* fileData, unsigned int& fileByteSize) +{ + ReadMaterialTextureProperties(newMaterial->SplatMap, offset, fileData, fileByteSize); + unsigned char numberOfMaps[4]; + if (offset + sizeof(unsigned char) * 4 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material NumOfMaps failed"); + } + + newMaterial->ColorMaps.resize(numberOfMaps[0]); + for (unsigned char i = 0; i < numberOfMaps[0]; i++) + { + ReadMaterialTextureProperties(newMaterial->ColorMaps[i], offset, fileData, fileByteSize); + } + + newMaterial->SpecularMaps.resize(numberOfMaps[1]); + for (unsigned char i = 0; i < numberOfMaps[1]; i++) + { + ReadMaterialTextureProperties(newMaterial->SpecularMaps[i], offset, fileData, fileByteSize); + } + + newMaterial->NormalMaps.resize(numberOfMaps[2]); + for (unsigned char i = 0; i < numberOfMaps[2]; i++) + { + ReadMaterialTextureProperties(newMaterial->NormalMaps[i], offset, fileData, fileByteSize); + } + + newMaterial->IncandescenceMaps.resize(numberOfMaps[3]); + for (unsigned char i = 0; i < numberOfMaps[3]; i++) + { + ReadMaterialTextureProperties(newMaterial->IncandescenceMaps[i], offset, fileData, fileByteSize); + } +} + +void RawModelCustom::ReadMaterialTextureProperties(RawModelCustom::TextureProperties& texture, unsigned int &offset, char* fileData, unsigned int& fileByteSize) { + unsigned int nameLength = *(unsigned int*)(fileData + offset); + if (nameLength > 0) { + if (offset + nameLength > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material texture path failed"); + } + texture.TexturePath = "Textures/"; + texture.TexturePath += (fileData + offset); + texture.TexturePath += ".png"; + offset += nameLength; + if (offset + sizeof(glm::vec2) > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material texture UVTiling failed"); + } + memcpy(&texture.UVRepeat[0], fileData + offset, sizeof(glm::vec2)); + offset += sizeof(glm::vec2); + } } void RawModelCustom::ReadAnimationFile(std::string filePath) From 4fe9e4f1c3586bb346684fe245a92a05adcae68a Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 5 Feb 2016 14:38:08 +0100 Subject: [PATCH 073/131] Debug cleanup and some bug fixes. --- src/Engine/Collision/Collision.cpp | 68 ++---------------------- src/Engine/Collision/CollisionSystem.cpp | 28 +++------- 2 files changed, 13 insertions(+), 83 deletions(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 7bb0d3c4..533fdc9b 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -459,7 +459,7 @@ bool AABBvsTriangle(const AABB& box, return false; } glm::vec3 cornerResolution = (1+t) * diagonal; - //Overwrite the smallest resolution if this is smaller. + //Overwrite the smallest resolution if cornerResolution is smaller. float lenSq = glm::length2(cornerResolution); if (lenSq < resolveShortest.DistanceSq) { resolveShortest.Vector = cornerResolution; @@ -477,26 +477,6 @@ bool AABBvsTriangle(const AABB& box, Resolution& bestResolve = takeUp ? resolveUpwards : resolveShortest; outResolution = bestResolve.Vector; - //TODO: Debug stuff. - std::string dbg; - switch (bestResolve.Case) { - case ResolveDimY: - case ResolveDimX: - case ResolveDimZ: - dbg = "Axis"; - break; - case Line: - dbg = "Line"; - break; - case Corner: - dbg = "Corner"; - break; - default: - break; - } - std::string outs = (takeUp ? "Resolve upwards " : "Resolve normal ") + dbg; - //TODO: End debug stuff. - glm::vec3 projNorm; switch (bestResolve.Case) { case ResolveDimY: @@ -505,14 +485,9 @@ bool AABBvsTriangle(const AABB& box, isOnGround = true; case ResolveDimX: case ResolveDimZ: - { //If we get here, the resolution is along one coordinate axis. //set velocity to 0 in y if it is along y-axis. - outs += isOnGround ? " ground" : " air"; - ImGui::Text(outs.c_str()); - LOG_INFO(outs.c_str()); return true; - } case Line: projNorm = glm::normalize(outResolution); break; @@ -523,11 +498,9 @@ bool AABBvsTriangle(const AABB& box, break; } - isOnGround = false; //If the collision was not on steep wall or similarly (e.g. walking on the ground), force resolution in y only. if (FaceIsGround(projNorm.y)) { //Ensure that the player always is moved upwards, instead of sliding down. - //Also zero the vertical velocity. float len = glm::length(outResolution); float ang = glm::half_pi() - glm::acos(outResolution.y / len); if (len > 0.0000001f && ang > 0.0000001f) { @@ -535,52 +508,21 @@ bool AABBvsTriangle(const AABB& box, outResolution.y = len / glm::sin(ang); outResolution.z = 0; } + //Also zero the vertical velocity, if it is positive, else project it onto the normal. //Project the velocity onto the normal of the hit line/face. //w = v - *n, |n|==1. - glm::vec3 projVel = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; - if (abs(originalBoxVelocity.x) < 0.001f && abs(originalBoxVelocity.z) < 0.001f) { - boxVelocity.y = 0.f; - } else { - boxVelocity.y = std::min(projVel.y, 0.f); - } - + boxVelocity.y = std::min(boxVelocity.y - glm::dot(boxVelocity, projNorm) * projNorm.y, 0.f); isOnGround = true; - } else if (projNorm.y > 0) { + } else { //Enter here if the triangle is a steep slope, and it is not facing downwards. - //Ensure that the player will be pushed in the xz-plane. - //glm::vec3 moveDir(outResolution); - //moveDir.y = 0; - //if (vectorHasLength(moveDir)) { - // moveDir = glm::normalize(moveDir); - // float len = glm::length(outResolution); - // float dotMoveOut = moveDir.x * outResolution.x + moveDir.z * outResolution.z; - // float ang = glm::half_pi() - glm::acos(dotMoveOut / len); - // if (len > 0.0000001f && ang > 0.0000001f) { - // outResolution = (len / glm::sin(ang)) * moveDir; - // } - //} //Project the velocity onto the normal of the hit line/face. //w = v - *n, |n|==1. - //TODO: What do we want.. -#if 0 //Walk up steep walls. - glm::vec3 projVel = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; - boxVelocity.y = std::min(projVel.y, 0.f); - isOnGround = true; -#elif 1 //"ice cream"-effect, air resistance + projected velocity. + //"ice cream"-effect, air resistance + projected velocity. if (!isOnGround) { boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; } isOnGround = false; -#elif 0 //"ice cream"-effect, ground friction (full control) + projected velocity. - if (!isOnGround) { - boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; - } - isOnGround = true; -#endif } - outs += isOnGround ? " ground" : " air"; - ImGui::Text(outs.c_str()); - LOG_INFO(outs.c_str()); return true; } diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index e5c194d6..b5d7a1f0 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -39,26 +39,14 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"]; bool isOnGround = (bool)cPhysics["IsOnGround"]; - //glm::vec3 gravity = glm::vec3(0, 9.82f * dt, 0); - //TODO: glm::abs(inOutVelocity - gravity) doesn't work, because of velocity projection on ground normal. - //if (!isOnGround || glm::any(glm::greaterThan(glm::abs(inOutVelocity - gravity), glm::vec3(0.0001f)))) { - float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"]; - if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { - glm::vec3 pos = (glm::vec3)cTransform["Position"] + resolutionVector; - //Hack: Force the position to be at discrete values after collision, removes jittering. - //constexpr float discreteValue = 1.0e2f; - //pos = glm::vec3(glm::ivec3(discreteValue * pos)) / discreteValue; - //pos = glm::round(discreteValue * pos) / discreteValue; - (glm::vec3&)cTransform["Position"] = pos; - cPhysics["Velocity"] = inOutVelocity; - (bool)cPhysics["IsOnGround"] = isOnGround; - } else { - (bool)cPhysics["IsOnGround"] = false; - } - //} else { - // (glm::vec3&)cTransform["Position"] -= gravity; - // cPhysics["Velocity"] = glm::vec3(0.f); - //} + float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"]; + if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { + (glm::vec3&)cTransform["Position"] += resolutionVector; + cPhysics["Velocity"] = inOutVelocity; + (bool)cPhysics["IsOnGround"] = isOnGround; + } else { + (bool)cPhysics["IsOnGround"] = false; + } } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { //Enter here if boxB has no Model. (glm::vec3&)cTransform["Position"] += resolutionVector; From 428dca003daf6daa38d81e67a3a1c29727f42094 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 5 Feb 2016 14:40:50 +0100 Subject: [PATCH 074/131] Tiny bug fix. --- src/Engine/Collision/Collision.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 533fdc9b..fe4eb5e0 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -521,7 +521,6 @@ bool AABBvsTriangle(const AABB& box, if (!isOnGround) { boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; } - isOnGround = false; } return true; } From fe6fd0bbe35005f87f32dbd3853193423229c748 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Fri, 5 Feb 2016 15:15:04 +0100 Subject: [PATCH 075/131] PickupSpawnSystem now spawns a new HealthPickup after the respawnTimer is up. Added HealthPickup.xml entity. Event PickupSpawned now gets published when a new HealthPickup spawns. Player now gains health as he picks up the HealthPickup. --- include/Engine/Core/EPickupSpawned.h | 2 +- include/Engine/Core/EPickupTaken.h | 19 -- include/Game/Systems/PickupSpawnSystem.h | 16 ++ resources/Schema/Components.xsd | 2 +- resources/Schema/Components/HealthPickup.xml | 4 + resources/Schema/Components/HealthPickup.xsd | 18 ++ resources/Schema/Components/PickupSpawn.xml | 2 - resources/Schema/Components/PickupSpawn.xsd | 11 - resources/Schema/Entities/CapturePoint.xml | 2 +- resources/Schema/Entities/HealthPickup.xml | 18 ++ .../Schema/Entities/HealthPickupTest.xml | 257 ++++++++++++++++++ src/Game/Game.cpp | 2 + src/Game/Systems/PickupSpawnSystem.cpp | 50 ++++ 13 files changed, 368 insertions(+), 35 deletions(-) delete mode 100644 include/Engine/Core/EPickupTaken.h create mode 100644 resources/Schema/Components/HealthPickup.xml create mode 100644 resources/Schema/Components/HealthPickup.xsd delete mode 100644 resources/Schema/Components/PickupSpawn.xml delete mode 100644 resources/Schema/Components/PickupSpawn.xsd create mode 100644 resources/Schema/Entities/HealthPickup.xml create mode 100644 resources/Schema/Entities/HealthPickupTest.xml diff --git a/include/Engine/Core/EPickupSpawned.h b/include/Engine/Core/EPickupSpawned.h index acb6776e..dc3bc632 100644 --- a/include/Engine/Core/EPickupSpawned.h +++ b/include/Engine/Core/EPickupSpawned.h @@ -10,7 +10,7 @@ namespace Events struct PickupSpawned : Event { EntityID PickupID; - EntityWrapper Spawner; + EntityWrapper Pickup; }; } diff --git a/include/Engine/Core/EPickupTaken.h b/include/Engine/Core/EPickupTaken.h deleted file mode 100644 index e06fd974..00000000 --- a/include/Engine/Core/EPickupTaken.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef EPickupTaken_h__ -#define EPickupTaken_h__ - -#include "Core/Event.h" -#include "Core/EntityWrapper.h" - -namespace Events -{ - -struct PickupTaken : Event -{ - EntityID PickupID; - EntityWrapper Spawner; - EntityWrapper Player; -}; - -} - -#endif \ No newline at end of file diff --git a/include/Game/Systems/PickupSpawnSystem.h b/include/Game/Systems/PickupSpawnSystem.h index 99dad0aa..8ae07265 100644 --- a/include/Game/Systems/PickupSpawnSystem.h +++ b/include/Game/Systems/PickupSpawnSystem.h @@ -9,9 +9,25 @@ #include "Rendering/ESetCamera.h" #include "Core/ConfigFile.h" #include "Core/EPickupSpawned.h" +#include "Core/EPlayerHealthPickup.h"; +#include "Engine/Collision/ETrigger.h" + +#include "Common.h" +#include class PickupSpawnSystem : public ImpureSystem { +public: + PickupSpawnSystem(World* world, EventBroker* eventBroker); + + virtual void Update(double dt) override; + +private: + EventRelay m_ETriggerTouch; + bool OnTriggerTouch(Events::TriggerTouch& e); + + std::vector> m_ETriggerTouchVector; + }; #endif diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 445d96e7..996475cf 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -29,5 +29,5 @@ - + \ No newline at end of file diff --git a/resources/Schema/Components/HealthPickup.xml b/resources/Schema/Components/HealthPickup.xml new file mode 100644 index 00000000..e9d0a23d --- /dev/null +++ b/resources/Schema/Components/HealthPickup.xml @@ -0,0 +1,4 @@ + + + 3 + \ No newline at end of file diff --git a/resources/Schema/Components/HealthPickup.xsd b/resources/Schema/Components/HealthPickup.xsd new file mode 100644 index 00000000..db9661a7 --- /dev/null +++ b/resources/Schema/Components/HealthPickup.xsd @@ -0,0 +1,18 @@ + + + + + + + + A Health Pickup + + + + + The respawn timer for a health pickup + + + + + diff --git a/resources/Schema/Components/PickupSpawn.xml b/resources/Schema/Components/PickupSpawn.xml deleted file mode 100644 index f8ce1225..00000000 --- a/resources/Schema/Components/PickupSpawn.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/resources/Schema/Components/PickupSpawn.xsd b/resources/Schema/Components/PickupSpawn.xsd deleted file mode 100644 index 7ab90407..00000000 --- a/resources/Schema/Components/PickupSpawn.xsd +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - Combined with a Spawner, defines a spawn point for a pickup - - - diff --git a/resources/Schema/Entities/CapturePoint.xml b/resources/Schema/Entities/CapturePoint.xml index 9b3c5036..9f33c4de 100644 --- a/resources/Schema/Entities/CapturePoint.xml +++ b/resources/Schema/Entities/CapturePoint.xml @@ -5,7 +5,7 @@ - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitSphere.mesh + Models/Core/UnitSphere.mesh diff --git a/resources/Schema/Entities/HealthPickup.xml b/resources/Schema/Entities/HealthPickup.xml new file mode 100644 index 00000000..f1b787f6 --- /dev/null +++ b/resources/Schema/Entities/HealthPickup.xml @@ -0,0 +1,18 @@ + + + + + + + + Models/Core/UnitSphere.mesh + + + + + + + + + + diff --git a/resources/Schema/Entities/HealthPickupTest.xml b/resources/Schema/Entities/HealthPickupTest.xml new file mode 100644 index 00000000..6a368006 --- /dev/null +++ b/resources/Schema/Entities/HealthPickupTest.xml @@ -0,0 +1,257 @@ + + + + + + + + + + + + Models\MapVersion1.mesh + + + + + + + + + 2 + + + Models/DirectionalLightWidget.mesh + false + + + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + + + + + + + + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index f5afcaeb..9e803e9e 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -10,6 +10,7 @@ #include "Systems/PlayerSpawnSystem.h" #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" +#include "Game/Systems/PickupSpawnSystem.h" #include "Game/Systems/WeaponSystem.h" #include "Game/Systems/PlayerHUD.h" #include "Game/Systems/LifetimeSystem.h" @@ -91,6 +92,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); diff --git a/src/Game/Systems/PickupSpawnSystem.cpp b/src/Game/Systems/PickupSpawnSystem.cpp index 3b758764..28f0ca86 100644 --- a/src/Game/Systems/PickupSpawnSystem.cpp +++ b/src/Game/Systems/PickupSpawnSystem.cpp @@ -1 +1,51 @@ #include "Systems/PickupSpawnSystem.h" + +PickupSpawnSystem::PickupSpawnSystem(World* m_World, EventBroker* eventBroker) + : System(m_World, eventBroker) +{ + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &PickupSpawnSystem::OnTriggerTouch); +} + +void PickupSpawnSystem::Update(double dt) +{ + for (auto &healthPickupPosition : m_ETriggerTouchVector) { + //set the double timer value (1) + std::get<1>(healthPickupPosition) -= dt; + if (std::get<1>(healthPickupPosition) < 0) { + //spawn and delete the vector item + auto entityFile = ResourceManager::Load("Schema/Entities/HealthPickup.xml"); + EntityFileParser parser(entityFile); + EntityID healthPickupID = parser.MergeEntities(m_World); + + //let the world know a pickup has spawned (graphics effects, etc) + Events::PickupSpawned ePickupSpawned; + ePickupSpawned.PickupID = healthPickupID; + ePickupSpawned.Pickup = EntityWrapper(m_World, healthPickupID); + m_EventBroker->Publish(ePickupSpawned); + + //erase the current element (healthPickupPosition) + m_ETriggerTouchVector.erase(std::remove(m_ETriggerTouchVector.begin(), m_ETriggerTouchVector.end(),healthPickupPosition), m_ETriggerTouchVector.end()); + break; + } + } +} + + +bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e) +{ + if (!e.Trigger.HasComponent("HealthPickup")) { + return false; + } + //personEntered = e.Entity, thingEntered = e.Trigger + Events::PlayerHealthPickup ePlayerHealthPickup; + ePlayerHealthPickup.HealthAmount = 30.0f; + ePlayerHealthPickup.PlayerHealedID = e.Entity.ID; + m_EventBroker->Publish(ePlayerHealthPickup); + + //copy the position to a vector -> respawntimer in ["HealthPickup"]["RespawnTimer"] + m_ETriggerTouchVector.push_back(std::make_tuple((glm::vec3)e.Trigger["Transform"]["Position"], e.Trigger["HealthPickup"]["RespawnTimer"])); + + //delete the healthpickup + m_World->DeleteEntity(e.Trigger.ID); + return true; +} From 7641ba49c751427fd419cafc59f86ab7a4b62052 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 5 Feb 2016 15:16:24 +0100 Subject: [PATCH 076/131] Weapon doesn't explode in first person. --- resources/Schema/Entities/Player.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index fe24adcc..384ffb80 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -104,13 +104,6 @@ - - true - - 3.7999999523162842 - - true - Models/AssaultWeaponRed.mesh From 254239751188f582215b47cc287508723ca0998e Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Fri, 5 Feb 2016 15:35:51 +0100 Subject: [PATCH 077/131] Miscellaneous small fixes: For Tests, CapturePoint xml file, HealthSystem, DashAbility xml file. --- include/Engine/Core/EPlayerHealthPickup.h | 12 +++--- include/Game/Systems/HealthSystem.h | 2 +- resources/Schema/Components/DashAbility.xml | 4 +- resources/Schema/Entities/CapturePoint.xml | 2 +- resources/Schema/Entities/Player.xml | 7 ---- src/Game/Systems/HealthSystem.cpp | 41 +++------------------ src/Tests/CapturePointTest.cpp | 8 ++-- src/Tests/CollisionTest.cpp | 2 +- src/Tests/HealthSystemTest.cpp | 26 ++++++------- 9 files changed, 32 insertions(+), 72 deletions(-) diff --git a/include/Engine/Core/EPlayerHealthPickup.h b/include/Engine/Core/EPlayerHealthPickup.h index f3158f92..7d44e544 100644 --- a/include/Engine/Core/EPlayerHealthPickup.h +++ b/include/Engine/Core/EPlayerHealthPickup.h @@ -2,16 +2,16 @@ #define EPlayerHealthPickup_h__ #include "EventBroker.h" -#include "../Core/Entity.h" +#include "../Core/EntityWrapper.h" namespace Events { -struct PlayerHealthPickup : Event -{ - double HealthAmount; - EntityID PlayerHealedID; -}; + struct PlayerHealthPickup : Event + { + EntityWrapper Player; + double HealthAmount; + }; } diff --git a/include/Game/Systems/HealthSystem.h b/include/Game/Systems/HealthSystem.h index 3b069349..46f24630 100644 --- a/include/Game/Systems/HealthSystem.h +++ b/include/Game/Systems/HealthSystem.h @@ -26,7 +26,7 @@ private: EventRelay m_EPlayerDamage; bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e); EventRelay m_EPlayerHealthPickup; - bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e); + bool HealthSystem::OnPlayerHealthPickup(Events::PlayerHealthPickup& e); //vector which will keep track of health changes std::vector> m_DeltaHealthVector; diff --git a/resources/Schema/Components/DashAbility.xml b/resources/Schema/Components/DashAbility.xml index 25b9e19a..a313c447 100644 --- a/resources/Schema/Components/DashAbility.xml +++ b/resources/Schema/Components/DashAbility.xml @@ -1,4 +1,4 @@ - + 2.0 - \ No newline at end of file + \ No newline at end of file diff --git a/resources/Schema/Entities/CapturePoint.xml b/resources/Schema/Entities/CapturePoint.xml index 9b3c5036..9f33c4de 100644 --- a/resources/Schema/Entities/CapturePoint.xml +++ b/resources/Schema/Entities/CapturePoint.xml @@ -5,7 +5,7 @@ - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitSphere.mesh + Models/Core/UnitSphere.mesh diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index fe24adcc..384ffb80 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -104,13 +104,6 @@ - - true - - 3.7999999523162842 - - true - Models/AssaultWeaponRed.mesh diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 9e118070..91cae148 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -11,38 +11,6 @@ HealthSystem::HealthSystem(World* m_World, EventBroker* eventBroker) void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { - //if entityID of health is 9 then the players ID is also 9 (player,health are connected to the same entity) - double maxHealth = (double)component["MaxHealth"]; - - //process the DeltaHealthVector and change the entitys health accordingly - for (size_t i = m_DeltaHealthVector.size(); i > 0; i--) - { - auto deltaHP = m_DeltaHealthVector[i - 1]; - //if we have a healthchange for the current player and health is greater than 0, then apply it - if (std::get<0>(deltaHP) == component.EntityID && (double)component["Health"] > 0.0f) { - //get the deltaHP value from the tuple and make sure you dont get more than maxHealth - double newHealth = std::min((double)component["Health"] + (double)std::get<1>(deltaHP), maxHealth); - component["Health"] = newHealth; - m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + i - 1); - //check if health is <= 0 - if ((double)component["Health"] <= 0.0f) { - component["Health"] = 0.0; - //publish death event - Events::PlayerDeath e; - e.PlayerID = component.EntityID; - m_EventBroker->Publish(e); - //clear the remaining hpDeltas for the dead player - for (size_t j = m_DeltaHealthVector.size(); j > 0; j--) - { - if (std::get<0>(m_DeltaHealthVector[j - 1]) == component.EntityID) - m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + j - 1); - } - //delete the player and break the loop - m_World->DeleteEntity(entity.ID); - break; - } - } - } } bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) @@ -58,10 +26,13 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) return true; } -bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e) +bool HealthSystem::OnPlayerHealthPickup(Events::PlayerHealthPickup& e) { - //save the changed HP to a vector. it will be taken care of in UpdateComponent - m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerHealedID, e.HealthAmount)); + ComponentWrapper cHealth = e.Player["Health"]; + double& health = cHealth["Health"]; + //NOTE: its possible to get more than MaxHealth health + health += e.HealthAmount; + return true; } diff --git a/src/Tests/CapturePointTest.cpp b/src/Tests/CapturePointTest.cpp index ffb01030..2c7bf430 100644 --- a/src/Tests/CapturePointTest.cpp +++ b/src/Tests/CapturePointTest.cpp @@ -255,14 +255,14 @@ void CapturePointTest::TestSetup8() } void CapturePointTest::DoTouchEvent(EntityID whoDidSomething, EntityID onWhatObject) { Events::TriggerTouch touchEvent; - touchEvent.Entity = whoDidSomething; - touchEvent.Trigger = onWhatObject; + touchEvent.Entity = EntityWrapper(m_World, whoDidSomething); + touchEvent.Trigger = EntityWrapper(m_World, onWhatObject); m_EventBroker->Publish(touchEvent); } void CapturePointTest::DoLeaveEvent(EntityID whoDidSomething, EntityID onWhatObject) { Events::TriggerLeave leaveEvent; - leaveEvent.Entity = whoDidSomething; - leaveEvent.Trigger = onWhatObject; + leaveEvent.Entity = EntityWrapper(m_World, whoDidSomething); + leaveEvent.Trigger = EntityWrapper(m_World, onWhatObject); m_EventBroker->Publish(leaveEvent); } void CapturePointTest::TestSuccess1() { diff --git a/src/Tests/CollisionTest.cpp b/src/Tests/CollisionTest.cpp index 67b6ce19..6cb6c88b 100644 --- a/src/Tests/CollisionTest.cpp +++ b/src/Tests/CollisionTest.cpp @@ -29,7 +29,7 @@ void RayTest(std::string fileName) { Ray ray(glm::vec3(-50, 0, 0), glm::vec3(1, 0, 0)); //using a - here, else we have to init the renderingsystem + //here, else we have to init the renderingsystem ResourceManager::RegisterType("RawModel"); auto unitBox = ResourceManager::Load(fileName); BOOST_REQUIRE(unitBox != nullptr); diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index bdd9ba4b..36608f8f 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -48,42 +48,38 @@ GameHealthSystemTest::GameHealthSystemTest() fp.MergeEntities(m_World); // Create system pipeline - m_SystemPipeline = new SystemPipeline(m_World,m_EventBroker); + m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker); m_SystemPipeline->AddSystem(0); //The Test //create entity which has transform,player,model,health in it. i.e. is a player EntityID playerID = m_World->CreateEntity(); - ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform"); - ComponentWrapper model = m_World->AttachComponent(playerID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere ComponentWrapper player = m_World->AttachComponent(playerID, "Player"); ComponentWrapper health = m_World->AttachComponent(playerID, "Health"); healthsID = playerID; - double currentHealth = (double)m_World->GetComponent(healthsID, "Health")["Health"]; + + EntityID playerID2 = m_World->CreateEntity(); + ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player"); + ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health"); //heal player with 40 Events::PlayerHealthPickup e3; e3.HealthAmount = 40.0f; - e3.PlayerHealedID = healthsID; + e3.Player = EntityWrapper(m_World, player.EntityID); m_EventBroker->Publish(e3); + //damage player with 50 Events::PlayerDamage e; - e.DamageAmount = 50.0f; - e.PlayerDamagedID = healthsID; + e.Damage = 50.0f; + e.Player = EntityWrapper(m_World, player.EntityID); m_EventBroker->Publish(e); + //heal some other player with 40 Events::PlayerHealthPickup e2; e2.HealthAmount = 40.0f; - e2.PlayerHealedID = healthsID + 1; + e2.Player = EntityWrapper(m_World, player2.EntityID); m_EventBroker->Publish(e2); - EntityID playerID2 = m_World->CreateEntity(); - ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform"); - ComponentWrapper model2 = m_World->AttachComponent(playerID2, "Model"); - model2["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere - ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player"); - ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health"); //END TEST } From 66f442f1afbe6e6a0ce76bb461d1d20fdd19368a Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Fri, 5 Feb 2016 16:13:59 +0100 Subject: [PATCH 078/131] Added HealthGain to HealthPickup component. Changed PickupSpawnSystem so it copies the values from the old to the new entity. --- include/Game/Systems/PickupSpawnSystem.h | 14 +++-------- resources/Schema/Components/HealthPickup.xml | 1 + resources/Schema/Components/HealthPickup.xsd | 3 +++ .../Schema/Entities/HealthPickupTest.xml | 14 ----------- src/Game/Systems/PickupSpawnSystem.cpp | 25 +++++++++++++------ 5 files changed, 26 insertions(+), 31 deletions(-) diff --git a/include/Game/Systems/PickupSpawnSystem.h b/include/Game/Systems/PickupSpawnSystem.h index 8ae07265..fbb2f082 100644 --- a/include/Game/Systems/PickupSpawnSystem.h +++ b/include/Game/Systems/PickupSpawnSystem.h @@ -2,16 +2,12 @@ #define PickupSpawnSystem_h__ #include "Core/System.h" -#include "Input/EInputCommand.h" -#include "Systems/SpawnerSystem.h" -#include "Events/ESpawnerSpawn.h" -#include "Core/EPlayerSpawned.h" -#include "Rendering/ESetCamera.h" -#include "Core/ConfigFile.h" +#include "Core/Transform.h" +#include "Core/ResourceManager.h" +#include "Core/EntityFileParser.h" #include "Core/EPickupSpawned.h" #include "Core/EPlayerHealthPickup.h"; #include "Engine/Collision/ETrigger.h" - #include "Common.h" #include @@ -26,8 +22,6 @@ private: EventRelay m_ETriggerTouch; bool OnTriggerTouch(Events::TriggerTouch& e); - std::vector> m_ETriggerTouchVector; - - + std::vector> m_ETriggerTouchVector; }; #endif diff --git a/resources/Schema/Components/HealthPickup.xml b/resources/Schema/Components/HealthPickup.xml index e9d0a23d..1c9ee0f4 100644 --- a/resources/Schema/Components/HealthPickup.xml +++ b/resources/Schema/Components/HealthPickup.xml @@ -1,4 +1,5 @@ 3 + 30 \ No newline at end of file diff --git a/resources/Schema/Components/HealthPickup.xsd b/resources/Schema/Components/HealthPickup.xsd index db9661a7..c5fae00f 100644 --- a/resources/Schema/Components/HealthPickup.xsd +++ b/resources/Schema/Components/HealthPickup.xsd @@ -12,6 +12,9 @@ The respawn timer for a health pickup + + How much health the player will get when he picks the healthPickup up + diff --git a/resources/Schema/Entities/HealthPickupTest.xml b/resources/Schema/Entities/HealthPickupTest.xml index 6a368006..97fd3f4d 100644 --- a/resources/Schema/Entities/HealthPickupTest.xml +++ b/resources/Schema/Entities/HealthPickupTest.xml @@ -238,20 +238,6 @@ - - - - - - Models/Core/UnitSphere.mesh - - - - - - - - diff --git a/src/Game/Systems/PickupSpawnSystem.cpp b/src/Game/Systems/PickupSpawnSystem.cpp index 28f0ca86..558aef14 100644 --- a/src/Game/Systems/PickupSpawnSystem.cpp +++ b/src/Game/Systems/PickupSpawnSystem.cpp @@ -9,9 +9,9 @@ PickupSpawnSystem::PickupSpawnSystem(World* m_World, EventBroker* eventBroker) void PickupSpawnSystem::Update(double dt) { for (auto &healthPickupPosition : m_ETriggerTouchVector) { - //set the double timer value (1) - std::get<1>(healthPickupPosition) -= dt; - if (std::get<1>(healthPickupPosition) < 0) { + //set the double timer value (value 3) + std::get<3>(healthPickupPosition) -= dt; + if (std::get<3>(healthPickupPosition) < 0) { //spawn and delete the vector item auto entityFile = ResourceManager::Load("Schema/Entities/HealthPickup.xml"); EntityFileParser parser(entityFile); @@ -23,8 +23,14 @@ void PickupSpawnSystem::Update(double dt) ePickupSpawned.Pickup = EntityWrapper(m_World, healthPickupID); m_EventBroker->Publish(ePickupSpawned); + //set values from the old entity to the new entity + auto& newHealthPickupEntity = EntityWrapper(m_World, healthPickupID); + newHealthPickupEntity["Transform"]["Position"] = std::get<0>(healthPickupPosition); + newHealthPickupEntity["HealthPickup"]["HealthGain"] = std::get<1>(healthPickupPosition); + newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = std::get<2>(healthPickupPosition); + //erase the current element (healthPickupPosition) - m_ETriggerTouchVector.erase(std::remove(m_ETriggerTouchVector.begin(), m_ETriggerTouchVector.end(),healthPickupPosition), m_ETriggerTouchVector.end()); + m_ETriggerTouchVector.erase(std::remove(m_ETriggerTouchVector.begin(), m_ETriggerTouchVector.end(), healthPickupPosition), m_ETriggerTouchVector.end()); break; } } @@ -38,12 +44,17 @@ bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e) } //personEntered = e.Entity, thingEntered = e.Trigger Events::PlayerHealthPickup ePlayerHealthPickup; - ePlayerHealthPickup.HealthAmount = 30.0f; + ePlayerHealthPickup.HealthAmount = e.Trigger["HealthPickup"]["HealthGain"]; ePlayerHealthPickup.PlayerHealedID = e.Entity.ID; m_EventBroker->Publish(ePlayerHealthPickup); - //copy the position to a vector -> respawntimer in ["HealthPickup"]["RespawnTimer"] - m_ETriggerTouchVector.push_back(std::make_tuple((glm::vec3)e.Trigger["Transform"]["Position"], e.Trigger["HealthPickup"]["RespawnTimer"])); + //copy position, healthgain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object) + //we need to copy all values since each value can be different for each healthPickup + m_ETriggerTouchVector.push_back(std::make_tuple( + (glm::vec3)e.Trigger["Transform"]["Position"], + e.Trigger["HealthPickup"]["HealthGain"], + e.Trigger["HealthPickup"]["RespawnTimer"], + e.Trigger["HealthPickup"]["RespawnTimer"])); //delete the healthpickup m_World->DeleteEntity(e.Trigger.ID); From 3e2afd7bf29773d6a8d3ff503321a1ad25d7d5d7 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 5 Feb 2016 16:37:56 +0100 Subject: [PATCH 079/131] Added dash sound --- assets | 2 +- include/Game/Events/EDashAbility.h | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 include/Game/Events/EDashAbility.h diff --git a/assets b/assets index a7387630..cfeeb1f8 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit a73876309264a0751e3a46f15020dd46d5a67f98 +Subproject commit cfeeb1f880e19356477a703da92204eede09db5d diff --git a/include/Game/Events/EDashAbility.h b/include/Game/Events/EDashAbility.h new file mode 100644 index 00000000..62a2b935 --- /dev/null +++ b/include/Game/Events/EDashAbility.h @@ -0,0 +1,13 @@ +#ifndef Events_DashAbility_h__ +#define Events_DashAbility_h__ + +#include "Core/Event.h" + +namespace Events +{ + +struct DashAbility : public Event { }; + +} + +#endif \ No newline at end of file From fbdaf92953569db374bbd96dccafaa1e036b5869 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 5 Feb 2016 16:39:23 +0100 Subject: [PATCH 080/131] Started refactoring. Put player walk logic in a designated sound system. --- .../Engine/Input/FirstPersonInputController.h | 4 + .../Sound/{SoundSystem.h => SoundManager.h} | 89 +++--- include/Game/Game.h | 5 +- include/Game/Systems/SoundSystem.h | 31 ++ .../{SoundSystem.cpp => SoundManager.cpp} | 287 +++++++----------- src/Game/Game.cpp | 8 +- src/Game/Systems/SoundSystem.cpp | 73 +++++ 7 files changed, 281 insertions(+), 216 deletions(-) rename include/Engine/Sound/{SoundSystem.h => SoundManager.h} (71%) create mode 100644 include/Game/Systems/SoundSystem.h rename src/Engine/Sound/{SoundSystem.cpp => SoundManager.cpp} (65%) create mode 100644 src/Game/Systems/SoundSystem.cpp diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index 2bbd768d..f3b0a17a 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -4,6 +4,7 @@ #include "../GLM.h" #include "../Core/InputController.h" #include "../Core/ELockMouse.h" +#include "../Game/Events/EDashAbility.h" #include "InputHandler.h" template @@ -230,6 +231,9 @@ void FirstPersonInputController::AssaultDashCheck(double dt, bool m_AssaultDashDoubleTapped = true; m_AssaultDashDoubleTapDeltaTime = 0.f; m_AssaultDashCoolDownTimer = assaultDashCoolDownMaxTimer; + + Events::DashAbility e; + m_EventBroker->Publish(e); } #endif \ No newline at end of file diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundManager.h similarity index 71% rename from include/Engine/Sound/SoundSystem.h rename to include/Engine/Sound/SoundManager.h index 51f80427..a9fb23a9 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundManager.h @@ -1,5 +1,5 @@ -#ifndef SoundSystem_h__ -#define SoundSystem_h__ +#ifndef SoundManager_h__ +#define SoundManager_h__ #include #include @@ -34,6 +34,7 @@ #include "Collision/ETrigger.h" #include "Core/EPause.h" #include "Game/Events/EDoubleJump.h" +#include "Game/Events/EDashAbility.h" typedef std::pair> QueuedBuffers; @@ -51,14 +52,30 @@ struct Source SoundType Type; }; -class SoundSystem +class SoundManager { public: - SoundSystem() { } - SoundSystem(World* world, EventBroker* eventBroker, bool editorMode); - ~SoundSystem(); + SoundManager() { } + SoundManager(World* world, EventBroker* eventBroker, bool editorMode); + ~SoundManager(); // Update emitters / listener void Update(double dt); + +protected: + // Specific logic + void playSound(Source* source); + // Need to be the same format (sample rate etc) + void playQueue(QueuedBuffers qb); + void stopSound(Source* source); + void playerJumps(); + void playerStep(double dt); + EntityID createChildEmitter(); + + // Logic + World* m_World = nullptr; + EventBroker* m_EventBroker = nullptr; + std::unordered_map m_Sources; + private: // Help functions for working with OpenaAL void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; @@ -81,75 +98,63 @@ private: void setGain(Source* source, float gain); void setSoundProperties(Source* source, ComponentWrapper* soundComponent); - // Specific logic - void playSound(Source* source); - // Need to be the same format (sample rate etc) - void playQueue(QueuedBuffers qb); - void stopSound(Source* source); - void playerDamaged(); - void playerShot(); - void playerJumps(); - void playerStep(double dt); + // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; ALCcontext* m_ALCcontext = nullptr; - // Logic - World* m_World = nullptr; - EventBroker* m_EventBroker = nullptr; - std::unordered_map m_Sources; + float m_BGMVolumeChannel = 1.0f; float m_SFXVolumeChannel = 1.0f; bool m_EditorEnabled = false; - const double m_PlayerFootstepInterval = 1.0; - double m_TimeSinceLastFootstep = 0; EntityID m_LocalPlayer = EntityID_Invalid; - bool m_LeftFoot = false; std::default_random_engine generator; // Events - EventRelay m_EPlaySoundOnEntity; + EventRelay m_EPlaySoundOnEntity; bool OnPlaySoundOnEntity(const Events::PlaySoundOnEntity &e); - EventRelay m_EPlaySoundOnPosition; + EventRelay m_EPlaySoundOnPosition; bool OnPlaySoundOnPosition(const Events::PlaySoundOnPosition &e); - EventRelay m_EPlayBackgroundMusic; + EventRelay m_EPlayBackgroundMusic; bool OnPlayBackgroundMusic(const Events::PlayBackgroundMusic &e); - EventRelay m_EPauseSound; + EventRelay m_EPauseSound; bool OnPauseSound(const Events::PauseSound &e); - EventRelay m_EStopSound; + EventRelay m_EStopSound; bool OnStopSound(const Events::StopSound &e); - EventRelay m_EContinueSound; + EventRelay m_EContinueSound; bool OnContinueSound(const Events::ContinueSound &e); - EventRelay m_ESetBGMGain; + EventRelay m_ESetBGMGain; bool OnSetBGMGain(const Events::SetBGMGain &e); - EventRelay m_ESetSFXGain; + EventRelay m_ESetSFXGain; bool OnSetSFXGain(const Events::SetSFXGain &e); - EventRelay m_EShoot; + EventRelay m_EShoot; bool OnShoot(const Events::Shoot &e); - EventRelay m_EPlayerSpawned; + EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned &e); - EventRelay m_EInputCommand; + EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand &e); - EventRelay m_ECaptured; + EventRelay m_ECaptured; bool OnCaptured(const Events::Captured &e); - EventRelay m_EPlayerDamage; + EventRelay m_EPlayerDamage; bool OnPlayerDamage(const Events::PlayerDamage &e); - EventRelay m_EPlayerDeath; + EventRelay m_EPlayerDeath; bool OnPlayerDeath(const Events::PlayerDeath &e); - EventRelay m_EPlayerHealthPickup; + EventRelay m_EPlayerHealthPickup; bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); - EventRelay m_EComponentAttached; + EventRelay m_EComponentAttached; bool OnComponentAttached(const Events::ComponentAttached &e); - EventRelay m_ETriggerTouch; + EventRelay m_ETriggerTouch; bool OnTriggerTouch(const Events::TriggerTouch &e); - EventRelay m_EPause; + EventRelay m_EPause; bool OnPause(const Events::Pause &e); - EventRelay m_EResume; + EventRelay m_EResume; bool OnResume(const Events::Resume &e); - EventRelay m_EDoubleJump; + EventRelay m_EDoubleJump; bool OnDoubleJump(const Events::DoubleJump &e); + EventRelay m_EDashAbility; + bool OnDashAbility(const Events::DashAbility &e); diff --git a/include/Game/Game.h b/include/Game/Game.h index 37267a68..b6a2c0d3 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -30,7 +30,8 @@ #include "Network/Client.h" // Sound -#include "Sound/SoundSystem.h" +//#include "Sound/SoundManager.h" +#include "Systems/SoundSystem.h" class Game { @@ -64,7 +65,7 @@ private: bool m_IsClientOrServer = false; // Sound - SoundSystem* m_SoundSystem; + SoundManager* m_SoundManager; //EventRelay m_EInputCommand; //bool debugOnInputCommand(const Events::InputCommand& e); diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h new file mode 100644 index 00000000..33dbf1fc --- /dev/null +++ b/include/Game/Systems/SoundSystem.h @@ -0,0 +1,31 @@ +#ifndef Systems_SoundSystem_h__ +#define Systems_SoundSystem_h__ + +#include "../Engine/Core/System.h" +#include "../Engine/Sound/SoundManager.h" +#include "../Engine/Core/EPlayerSpawned.h" + + +class SoundSystem : public PureSystem, ImpureSystem, SoundManager +{ +public: + SoundSystem(World* world, EventBroker* eventbroker); + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override; + virtual void Update(double dt) override; +private: + void playerStep(double dt); + EntityWrapper m_LocalPlayer = EntityWrapper(); + + World* m_World = nullptr; + EventBroker* m_EventBroker = nullptr; + + // TODO: WIP Update this + double m_TimeSinceLastFootstep = 0.0; + const double m_PlayerFootstepInterval = 1.0; + bool m_LeftFoot = false; + + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(const Events::PlayerSpawned &e); +}; + +#endif diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundManager.cpp similarity index 65% rename from src/Engine/Sound/SoundSystem.cpp rename to src/Engine/Sound/SoundManager.cpp index 3045b1f4..3cec4deb 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -1,6 +1,6 @@ -#include "Sound/SoundSystem.h" +#include "Sound/SoundManager.h" -SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode) +SoundManager::SoundManager(World* world, EventBroker* eventBroker, bool editorMode) { m_EventBroker = eventBroker; m_World = world; @@ -12,27 +12,28 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode alDistanceModel(AL_LINEAR_DISTANCE); alDopplerFactor(1); - EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnEntity, &SoundSystem::OnPlaySoundOnEntity); - EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnPosition, &SoundSystem::OnPlaySoundOnPosition); - EVENT_SUBSCRIBE_MEMBER(m_EPlayBackgroundMusic, &SoundSystem::OnPlayBackgroundMusic); - EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::OnStopSound); - EVENT_SUBSCRIBE_MEMBER(m_EPauseSound, &SoundSystem::OnPauseSound); - EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundSystem::OnContinueSound); - EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundSystem::OnSetBGMGain); - EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundSystem::OnSetSFXGain); - EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundSystem::OnShoot); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundSystem::OnInputCommand); - EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); - EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); - EVENT_SUBSCRIBE_MEMBER(m_EPause, &SoundSystem::OnPause); - EVENT_SUBSCRIBE_MEMBER(m_EResume, &SoundSystem::OnResume); - EVENT_SUBSCRIBE_MEMBER(m_EComponentAttached, &SoundSystem::OnComponentAttached); - EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnEntity, &SoundManager::OnPlaySoundOnEntity); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnPosition, &SoundManager::OnPlaySoundOnPosition); + EVENT_SUBSCRIBE_MEMBER(m_EPlayBackgroundMusic, &SoundManager::OnPlayBackgroundMusic); + EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundManager::OnStopSound); + EVENT_SUBSCRIBE_MEMBER(m_EPauseSound, &SoundManager::OnPauseSound); + EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundManager::OnContinueSound); + EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundManager::OnSetBGMGain); + EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundManager::OnSetSFXGain); + EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundManager::OnShoot); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundManager::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundManager::OnPlayerDamage); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundManager::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundManager::OnCaptured); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundManager::OnTriggerTouch); + EVENT_SUBSCRIBE_MEMBER(m_EPause, &SoundManager::OnPause); + EVENT_SUBSCRIBE_MEMBER(m_EResume, &SoundManager::OnResume); + EVENT_SUBSCRIBE_MEMBER(m_EComponentAttached, &SoundManager::OnComponentAttached); + EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundManager::OnDoubleJump); + EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundManager::OnDashAbility); } -SoundSystem::~SoundSystem() +SoundManager::~SoundManager() { stopEmitters(); // Stopps emitters deleteInactiveEmitters(); // Deletes stopped emitters @@ -47,7 +48,7 @@ SoundSystem::~SoundSystem() alcCloseDevice(m_ALCdevice); } -void SoundSystem::stopEmitters() +void SoundManager::stopEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { @@ -57,10 +58,9 @@ void SoundSystem::stopEmitters() } } -void SoundSystem::Update(double dt) +void SoundManager::Update(double dt) { - m_EventBroker->Process(); - playerStep(dt); + m_EventBroker->Process(); deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" updateEmitters(dt); updateListener(dt); @@ -70,7 +70,7 @@ void SoundSystem::Update(double dt) ImGui::SliderFloat("SFX", &m_SFXVolumeChannel, 0.0f, 1.0f, "%.3f", 1.0f); } -void SoundSystem::deleteInactiveEmitters() +void SoundManager::deleteInactiveEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end();) { @@ -99,7 +99,7 @@ void SoundSystem::deleteInactiveEmitters() } } -void SoundSystem::updateEmitters(double dt) +void SoundManager::updateEmitters(double dt) { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { @@ -132,7 +132,7 @@ void SoundSystem::updateEmitters(double dt) } } -void SoundSystem::updateListener(double dt) +void SoundManager::updateListener(double dt) { // Should only be one listener. auto listenerComponents = m_World->GetComponents("Listener"); @@ -151,7 +151,7 @@ void SoundSystem::updateListener(double dt) } } -Source* SoundSystem::createSource(std::string filePath) +Source* SoundManager::createSource(std::string filePath) { ALuint alSource; alGenSources((ALuint)1, &alSource); @@ -163,13 +163,13 @@ Source* SoundSystem::createSource(std::string filePath) return source; } -void SoundSystem::playSound(Source* source) +void SoundManager::playSound(Source* source) { alSourcei(source->ALsource, AL_BUFFER, source->SoundResource->Buffer()); alSourcePlay(source->ALsource); } -void SoundSystem::playQueue(QueuedBuffers qb) +void SoundManager::playQueue(QueuedBuffers qb) { for (int i = 0; i < qb.second.size(); i++) { alSourceQueueBuffers(qb.first, 1, &qb.second[i]); @@ -177,69 +177,37 @@ void SoundSystem::playQueue(QueuedBuffers qb) alSourcePlay(qb.first); } -void SoundSystem::stopSound(Source* source) +void SoundManager::stopSound(Source* source) { alSourceStop(source->ALsource); } -void SoundSystem::playerDamaged() -{ - -} - -void SoundSystem::playerShot() -{ } - -void SoundSystem::playerJumps() +void SoundManager::playerJumps() { glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; if (vel.y == 0) { Source* source = createSource("Audio/jump/jump1.wav"); - auto emitterID = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(emitterID, "Transform"); - m_World->AttachComponent(emitterID, "SoundEmitter"); source->Type = SoundType::SFX; - m_Sources[emitterID] = source; + m_Sources[createChildEmitter()] = source; playSound(source); } } -void SoundSystem::playerStep(double dt) +void SoundManager::playerStep(double dt) { - if (!m_World->ValidEntity(m_LocalPlayer)) { - return; - } - if (m_LocalPlayer == EntityID_Invalid) { - return; - } - - m_TimeSinceLastFootstep += dt; - glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; - float playerSpeed = glm::length(vel); - bool isAirborne = vel.y != 0; - if (playerSpeed > 1 && !isAirborne) { - // Player is walking - if (m_TimeSinceLastFootstep * std::min(playerSpeed, 2) > m_PlayerFootstepInterval) { - // Create footstep sound - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - Events::PlaySoundOnEntity e; - e.EmitterID = child; - if (m_LeftFoot) { - e.FilePath = "Audio/footstep/footstep2.wav"; - } else { - e.FilePath = "Audio/footstep/footstep3.wav"; - } - m_LeftFoot = !m_LeftFoot; - m_EventBroker->Publish(e); - m_TimeSinceLastFootstep = 0; - } - } + } -bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) +EntityID SoundManager::createChildEmitter() +{ + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + return child; +} + +bool SoundManager::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) { Source* source = createSource(e.FilePath); source->Type = SoundType::SFX; @@ -248,7 +216,7 @@ bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) return false; } -bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) +bool SoundManager::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) { Source* source = createSource(e.FilePath); auto emitterID = m_World->CreateEntity(); @@ -267,25 +235,25 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) return true; } -bool SoundSystem::OnPauseSound(const Events::PauseSound & e) +bool SoundManager::OnPauseSound(const Events::PauseSound & e) { alSourcePause(m_Sources[e.EmitterID]->ALsource); return true; } -bool SoundSystem::OnStopSound(const Events::StopSound & e) +bool SoundManager::OnStopSound(const Events::StopSound & e) { alSourceStop(m_Sources[e.EmitterID]->ALsource); return true; } -bool SoundSystem::OnContinueSound(const Events::ContinueSound & e) +bool SoundManager::OnContinueSound(const Events::ContinueSound & e) { alSourcePlay(m_Sources[e.EmitterID]->ALsource); return true; } -bool SoundSystem::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) +bool SoundManager::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) { auto listenerComponents = m_World->GetComponents("Listener"); for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { @@ -303,53 +271,40 @@ bool SoundSystem::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) return true; } -bool SoundSystem::OnSetBGMGain(const Events::SetBGMGain & e) +bool SoundManager::OnSetBGMGain(const Events::SetBGMGain & e) { m_BGMVolumeChannel = e.Gain; return true; } -bool SoundSystem::OnSetSFXGain(const Events::SetSFXGain & e) +bool SoundManager::OnSetSFXGain(const Events::SetSFXGain & e) { m_SFXVolumeChannel = e.Gain; return true; } -bool SoundSystem::OnShoot(const Events::Shoot & e) +bool SoundManager::OnShoot(const Events::Shoot & e) { Source* source = createSource("Audio/laser/laser1.wav"); - auto emitterID = m_World->CreateEntity(e.Player.ID); - m_World->AttachComponent(emitterID, "Transform"); - auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); + //auto emitterID = m_World->CreateEntity(e.Player.ID); + //m_World->AttachComponent(emitterID, "Transform"); + //auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); source->Type = SoundType::SFX; - m_Sources[emitterID] = source; + m_Sources[createChildEmitter()] = source; playSound(source); return true; } -bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned & e) +bool SoundManager::OnPlayerSpawned(const Events::PlayerSpawned & e) { if (e.PlayerID == -1) { // Local player m_World->AttachComponent(e.Player.ID, "Listener"); m_LocalPlayer = e.Player.ID; - EntityID child = m_World->CreateEntity(e.Player.ID); - m_World->AttachComponent(child, "SoundEmitter"); // Temp - m_World->AttachComponent(child, "Transform"); // Temp - Events::PlaySoundOnEntity event; - event.EmitterID = child; - event.FilePath = "Audio/announcer/go.wav"; - m_EventBroker->Publish(event); - // TEMP: starts bgm - { - Events::PlayBackgroundMusic ev; - ev.FilePath = "Audio/bgm/ambient.wav"; - m_EventBroker->Publish(ev); - } } return true; } -bool SoundSystem::OnInputCommand(const Events::InputCommand & e) +bool SoundManager::OnInputCommand(const Events::InputCommand & e) { if (e.Command == "Jump" && e.Value > 0) { if (e.PlayerID == -1) { // local player @@ -370,7 +325,7 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) return false; } -bool SoundSystem::OnCaptured(const Events::Captured & e) +bool SoundManager::OnCaptured(const Events::Captured & e) { int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"]; int team = (int)m_World->GetComponent(m_LocalPlayer, "Team")["Team"]; @@ -380,26 +335,20 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) } else { ev.FilePath = "Audio/announcer/objective_failed.wav"; // have not been tested } - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + ev.EmitterID = createChildEmitter(); m_EventBroker->Publish(ev); return false; } -bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) +bool SoundManager::OnPlayerDamage(const Events::PlayerDamage & e) { // Should check for only local players here... - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); std::uniform_int_distribution dist(1, 12); int rand = dist(generator); Source* source = createSource("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); source->Type = SoundType::SFX; - m_Sources[child] = source; + m_Sources[createChildEmitter()] = source; // Breathe std::vector buffers; @@ -413,35 +362,29 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) return false; } -bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) +bool SoundManager::OnPlayerDeath(const Events::PlayerDeath & e) { if (e.PlayerID == m_LocalPlayer) { Events::PlaySoundOnEntity ev; - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + ev.EmitterID = createChildEmitter(); ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch m_EventBroker->Publish(ev); } return false; } -bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) +bool SoundManager::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) { if (e.PlayerHealedID == m_LocalPlayer) { Events::PlaySoundOnEntity ev; - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + ev.EmitterID = createChildEmitter(); ev.FilePath = "Audio/pickup/pickup2.wav"; m_EventBroker->Publish(ev); } return false; } -bool SoundSystem::OnComponentAttached(const Events::ComponentAttached & e) +bool SoundManager::OnComponentAttached(const Events::ComponentAttached & e) { if (e.Component.Info.Name == "SoundEmitter") { auto component = m_World->GetComponent(e.Entity.ID, "SoundEmitter"); @@ -451,7 +394,7 @@ bool SoundSystem::OnComponentAttached(const Events::ComponentAttached & e) return false; } -bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) +bool SoundManager::OnTriggerTouch(const Events::TriggerTouch & e) { if (m_World->HasComponent(e.Trigger.ID, "CapturePoint")) { Events::PlayBackgroundMusic ev; @@ -461,7 +404,7 @@ bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) return false; } -bool SoundSystem::OnPause(const Events::Pause & e) +bool SoundManager::OnPause(const Events::Pause & e) { for (auto it = m_Sources.begin(); it != m_Sources.end(); it++) { alSourcePause(it->second->ALsource); @@ -469,7 +412,7 @@ bool SoundSystem::OnPause(const Events::Pause & e) return false; } -bool SoundSystem::OnResume(const Events::Resume &e) +bool SoundManager::OnResume(const Events::Resume &e) { for (auto it = m_Sources.begin(); it != m_Sources.end(); it++) { alSourcePlay(it->second->ALsource); @@ -477,19 +420,60 @@ bool SoundSystem::OnResume(const Events::Resume &e) return false; } -bool SoundSystem::OnDoubleJump(const Events::DoubleJump & e) +bool SoundManager::OnDoubleJump(const Events::DoubleJump & e) { Events::PlaySoundOnEntity ev; - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + ev.EmitterID = createChildEmitter(); ev.FilePath = "Audio/jump/jump2.wav"; m_EventBroker->Publish(ev); return false; } -void SoundSystem::setListenerOri(glm::vec3 ori) +bool SoundManager::OnDashAbility(const Events::DashAbility &e) +{ + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(); + ev.FilePath = "Audio/jump/dash1.wav"; + m_EventBroker->Publish(ev); + return false; +} + +ALenum SoundManager::getSourceState(ALuint source) +{ + ALenum state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return state; +} + +void SoundManager::setGain(Source * source, float gain) +{ + alSourcef(source->ALsource, AL_GAIN, gain); +} + +void SoundManager::setSoundProperties(Source* source, ComponentWrapper* soundComponent) +{ + float gain = (source->Type == SoundType::SFX) ? m_SFXVolumeChannel : m_BGMVolumeChannel; + alSourcef(source->ALsource, AL_GAIN, (float)(double)(*soundComponent)["Gain"] * gain); + alSourcef(source->ALsource, AL_PITCH, (float)(double)(*soundComponent)["Pitch"]); + alSourcei(source->ALsource, AL_LOOPING, (int)(bool)(*soundComponent)["Loop"]); // YOLO + alSourcef(source->ALsource, AL_MAX_DISTANCE, (float)(double)(*soundComponent)["MaxDistance"]); + alSourcef(source->ALsource, AL_ROLLOFF_FACTOR, (float)(double)(*soundComponent)["RollOffFactor"]); + alSourcef(source->ALsource, AL_REFERENCE_DISTANCE, (float)(double)(*soundComponent)["ReferenceDistance"]); +} + +void SoundManager::initOpenAL() +{ + // Initialize OpenAL + m_ALCdevice = alcOpenDevice(nullptr); + if (m_ALCdevice != nullptr) { + m_ALCcontext = alcCreateContext(m_ALCdevice, nullptr); + alcMakeContextCurrent(m_ALCcontext); + } else { + LOG_ERROR("OpenAL failed to initialize."); + } +} + +void SoundManager::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector. glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); @@ -504,39 +488,4 @@ void SoundSystem::setListenerOri(glm::vec3 ori) glm::normalize(up); ALfloat lOri[6] = { forward.x, forward.y, forward.z, up.x, up.y, up.z }; alListenerfv(AL_ORIENTATION, lOri); -} - -ALenum SoundSystem::getSourceState(ALuint source) -{ - ALenum state; - alGetSourcei(source, AL_SOURCE_STATE, &state); - return state; -} - -void SoundSystem::setGain(Source * source, float gain) -{ - alSourcef(source->ALsource, AL_GAIN, gain); -} - -void SoundSystem::setSoundProperties(Source* source, ComponentWrapper* soundComponent) -{ - float gain = (source->Type == SoundType::SFX) ? m_SFXVolumeChannel : m_BGMVolumeChannel; - alSourcef(source->ALsource, AL_GAIN, (float)(double)(*soundComponent)["Gain"] * gain); - alSourcef(source->ALsource, AL_PITCH, (float)(double)(*soundComponent)["Pitch"]); - alSourcei(source->ALsource, AL_LOOPING, (int)(bool)(*soundComponent)["Loop"]); // YOLO - alSourcef(source->ALsource, AL_MAX_DISTANCE, (float)(double)(*soundComponent)["MaxDistance"]); - alSourcef(source->ALsource, AL_ROLLOFF_FACTOR, (float)(double)(*soundComponent)["RollOffFactor"]); - alSourcef(source->ALsource, AL_REFERENCE_DISTANCE, (float)(double)(*soundComponent)["ReferenceDistance"]); -} - -void SoundSystem::initOpenAL() -{ - // Initialize OpenAL - m_ALCdevice = alcOpenDevice(nullptr); - if (m_ALCdevice != nullptr) { - m_ALCcontext = alcCreateContext(m_ALCdevice, nullptr); - alcMakeContextCurrent(m_ALCcontext); - } else { - LOG_ERROR("OpenAL failed to initialize."); - } } \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 04542f11..204f425e 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -81,6 +81,7 @@ Game::Game(int argc, char* argv[]) // All systems with orderlevel 0 will be updated first. unsigned int updateOrderLevel = 0; + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); @@ -91,6 +92,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); @@ -114,7 +116,7 @@ Game::Game(int argc, char* argv[]) } // Invoke sound system - m_SoundSystem = new SoundSystem(m_World, m_EventBroker, m_Config->Get("Debug.EditorEnabled", false)); + //m_SoundManager = new SoundManager(m_World, m_EventBroker, m_Config->Get("Debug.EditorEnabled", false)); m_LastTime = glfwGetTime(); } @@ -122,7 +124,7 @@ Game::Game(int argc, char* argv[]) Game::~Game() { delete m_SystemPipeline; - delete m_SoundSystem; + //delete m_SoundManager; delete m_OctreeFrustrumCulling; delete m_OctreeCollision; delete m_OctreeTrigger; @@ -157,7 +159,7 @@ void Game::Tick() if (m_IsClientOrServer) { m_ClientOrServer->Update(); } - m_SoundSystem->Update(dt); + //m_SoundManager->Update(dt); // Iterate through systems and update world! m_EventBroker->Process(); diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp new file mode 100644 index 00000000..d51996ac --- /dev/null +++ b/src/Game/Systems/SoundSystem.cpp @@ -0,0 +1,73 @@ +#include "Game/Systems/SoundSystem.h" + +SoundSystem::SoundSystem(World* world, EventBroker* eventbroker) + : System(world, eventbroker) + , PureSystem("SoundEmitter") + , ImpureSystem() + , SoundManager(world, eventbroker, true) +{ + m_World = world; + m_EventBroker = eventbroker; + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); +} + +void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) +{ + +} + +void SoundSystem::Update(double dt) +{ + SoundManager::Update(dt); + playerStep(dt); +} + +void SoundSystem::playerStep(double dt) +{ + if (!m_LocalPlayer.Valid()) { + return; + } + if (m_LocalPlayer.ID == EntityID_Invalid) { + return; + } + + m_TimeSinceLastFootstep += dt; + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; + float playerSpeed = glm::length(vel); + bool isAirborne = vel.y != 0; + if (playerSpeed > 1 && !isAirborne) { + // Player is walking + if (m_TimeSinceLastFootstep * std::min(playerSpeed, 2) > m_PlayerFootstepInterval) { + // Create footstep sound + Events::PlaySoundOnEntity e; + e.EmitterID = createChildEmitter(); + if (m_LeftFoot) { + e.FilePath = "Audio/footstep/footstep2.wav"; + } else { + e.FilePath = "Audio/footstep/footstep3.wav"; + } + m_LeftFoot = !m_LeftFoot; + m_EventBroker->Publish(e); + m_TimeSinceLastFootstep = 0; + } + } +} + +bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) +{ + if (e.PlayerID == -1) { // Local player + m_World->AttachComponent(e.Player.ID, "Listener"); + m_LocalPlayer = e.Player; + Events::PlaySoundOnEntity event; + event.EmitterID = createChildEmitter(); + event.FilePath = "Audio/announcer/go.wav"; + m_EventBroker->Publish(event); + // TEMP: starts bgm +// { +// Events::PlayBackgroundMusic ev; +// ev.FilePath = "Audio/bgm/ambient.wav"; +// m_EventBroker->Publish(ev); +// } + } + return true; +} From febbadbd013415648464602c10d5925c3499f36c Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 5 Feb 2016 17:21:31 +0100 Subject: [PATCH 081/131] Accidentally added the sound system twice. Lead to funny behavior. --- src/Game/Game.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 204f425e..541aa001 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -92,7 +92,6 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); @@ -115,16 +114,12 @@ Game::Game(int argc, char* argv[]) networkFunction(); } - // Invoke sound system - //m_SoundManager = new SoundManager(m_World, m_EventBroker, m_Config->Get("Debug.EditorEnabled", false)); - m_LastTime = glfwGetTime(); } Game::~Game() { delete m_SystemPipeline; - //delete m_SoundManager; delete m_OctreeFrustrumCulling; delete m_OctreeCollision; delete m_OctreeTrigger; From 454eef82257c28b1f657d6a9738df09323f8711e Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 5 Feb 2016 17:21:48 +0100 Subject: [PATCH 082/131] WIP. Improving player walk logic. --- include/Engine/Sound/SoundManager.h | 8 ++--- include/Game/Systems/LifetimeSystem.h | 4 ++- include/Game/Systems/SoundSystem.h | 5 +-- src/Engine/Sound/SoundManager.cpp | 31 ++++++++-------- src/Game/Systems/SoundSystem.cpp | 51 ++++++++++++--------------- 5 files changed, 47 insertions(+), 52 deletions(-) diff --git a/include/Engine/Sound/SoundManager.h b/include/Engine/Sound/SoundManager.h index a9fb23a9..ef291380 100644 --- a/include/Engine/Sound/SoundManager.h +++ b/include/Engine/Sound/SoundManager.h @@ -69,12 +69,11 @@ protected: void stopSound(Source* source); void playerJumps(); void playerStep(double dt); - EntityID createChildEmitter(); + EntityID createChildEmitter(EntityWrapper localPlayer); // Logic World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; - std::unordered_map m_Sources; private: // Help functions for working with OpenaAL @@ -98,7 +97,8 @@ private: void setGain(Source* source, float gain); void setSoundProperties(Source* source, ComponentWrapper* soundComponent); - + std::unordered_map m_Sources; + // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; @@ -109,7 +109,7 @@ private: float m_BGMVolumeChannel = 1.0f; float m_SFXVolumeChannel = 1.0f; bool m_EditorEnabled = false; - EntityID m_LocalPlayer = EntityID_Invalid; + EntityWrapper m_LocalPlayer = EntityWrapper(); std::default_random_engine generator; // Events diff --git a/include/Game/Systems/LifetimeSystem.h b/include/Game/Systems/LifetimeSystem.h index da88cfa2..99cafd89 100644 --- a/include/Game/Systems/LifetimeSystem.h +++ b/include/Game/Systems/LifetimeSystem.h @@ -9,7 +9,9 @@ public: LifetimeSystem(World* world, EventBroker* eventBroker) : System(world, eventBroker) , PureSystem("Lifetime") - { } + { + LOG_INFO("ASDASDASSA"); + } virtual void Update(double dt) override; virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cLifetime, double dt) override; diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index 33dbf1fc..ec87e98a 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -20,8 +20,9 @@ private: EventBroker* m_EventBroker = nullptr; // TODO: WIP Update this - double m_TimeSinceLastFootstep = 0.0; - const double m_PlayerFootstepInterval = 1.0; + double m_DistanceMoved = 0.0; + const float m_PlayerStepLength = 1.0; + glm::vec3 m_LastPosition = glm::vec3(); bool m_LeftFoot = false; EventRelay m_EPlayerSpawned; diff --git a/src/Engine/Sound/SoundManager.cpp b/src/Engine/Sound/SoundManager.cpp index 3cec4deb..b7aaaff6 100644 --- a/src/Engine/Sound/SoundManager.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -184,14 +184,13 @@ void SoundManager::stopSound(Source* source) void SoundManager::playerJumps() { - glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; if (vel.y == 0) { Source* source = createSource("Audio/jump/jump1.wav"); source->Type = SoundType::SFX; - m_Sources[createChildEmitter()] = source; + m_Sources[createChildEmitter(m_LocalPlayer)] = source; playSound(source); } - } void SoundManager::playerStep(double dt) @@ -199,9 +198,9 @@ void SoundManager::playerStep(double dt) } -EntityID SoundManager::createChildEmitter() +EntityID SoundManager::createChildEmitter(EntityWrapper localPlayer) { - EntityID child = m_World->CreateEntity(m_LocalPlayer); + EntityID child = m_World->CreateEntity(localPlayer.ID); m_World->AttachComponent(child, "Transform"); m_World->AttachComponent(child, "SoundEmitter"); return child; @@ -290,7 +289,7 @@ bool SoundManager::OnShoot(const Events::Shoot & e) //m_World->AttachComponent(emitterID, "Transform"); //auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); source->Type = SoundType::SFX; - m_Sources[createChildEmitter()] = source; + m_Sources[createChildEmitter(m_LocalPlayer)] = source; playSound(source); return true; } @@ -299,7 +298,7 @@ bool SoundManager::OnPlayerSpawned(const Events::PlayerSpawned & e) { if (e.PlayerID == -1) { // Local player m_World->AttachComponent(e.Player.ID, "Listener"); - m_LocalPlayer = e.Player.ID; + m_LocalPlayer.ID = e.Player.ID; } return true; } @@ -328,14 +327,14 @@ bool SoundManager::OnInputCommand(const Events::InputCommand & e) bool SoundManager::OnCaptured(const Events::Captured & e) { int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"]; - int team = (int)m_World->GetComponent(m_LocalPlayer, "Team")["Team"]; + int team = (int)m_World->GetComponent(m_LocalPlayer.ID, "Team")["Team"]; Events::PlaySoundOnEntity ev; if (team == homeTeam) { ev.FilePath = "Audio/announcer/objective_achieved.wav"; } else { ev.FilePath = "Audio/announcer/objective_failed.wav"; // have not been tested } - ev.EmitterID = createChildEmitter(); + ev.EmitterID = createChildEmitter(m_LocalPlayer); m_EventBroker->Publish(ev); return false; } @@ -348,7 +347,7 @@ bool SoundManager::OnPlayerDamage(const Events::PlayerDamage & e) int rand = dist(generator); Source* source = createSource("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); source->Type = SoundType::SFX; - m_Sources[createChildEmitter()] = source; + m_Sources[createChildEmitter(m_LocalPlayer)] = source; // Breathe std::vector buffers; @@ -364,9 +363,9 @@ bool SoundManager::OnPlayerDamage(const Events::PlayerDamage & e) bool SoundManager::OnPlayerDeath(const Events::PlayerDeath & e) { - if (e.PlayerID == m_LocalPlayer) { + if (e.PlayerID == m_LocalPlayer.ID) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(); + ev.EmitterID = createChildEmitter(m_LocalPlayer); ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch m_EventBroker->Publish(ev); } @@ -375,9 +374,9 @@ bool SoundManager::OnPlayerDeath(const Events::PlayerDeath & e) bool SoundManager::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) { - if (e.PlayerHealedID == m_LocalPlayer) { + if (e.PlayerHealedID == m_LocalPlayer.ID) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(); + ev.EmitterID = createChildEmitter(m_LocalPlayer); ev.FilePath = "Audio/pickup/pickup2.wav"; m_EventBroker->Publish(ev); } @@ -423,7 +422,7 @@ bool SoundManager::OnResume(const Events::Resume &e) bool SoundManager::OnDoubleJump(const Events::DoubleJump & e) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(); + ev.EmitterID = createChildEmitter(m_LocalPlayer); ev.FilePath = "Audio/jump/jump2.wav"; m_EventBroker->Publish(ev); return false; @@ -432,7 +431,7 @@ bool SoundManager::OnDoubleJump(const Events::DoubleJump & e) bool SoundManager::OnDashAbility(const Events::DashAbility &e) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(); + ev.EmitterID = createChildEmitter(m_LocalPlayer); ev.FilePath = "Audio/jump/dash1.wav"; m_EventBroker->Publish(ev); return false; diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index d51996ac..99f3242d 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -18,39 +18,32 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp void SoundSystem::Update(double dt) { - SoundManager::Update(dt); playerStep(dt); + SoundManager::Update(dt); } void SoundSystem::playerStep(double dt) { - if (!m_LocalPlayer.Valid()) { - return; - } - if (m_LocalPlayer.ID == EntityID_Invalid) { - return; - } - - m_TimeSinceLastFootstep += dt; - glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; - float playerSpeed = glm::length(vel); - bool isAirborne = vel.y != 0; - if (playerSpeed > 1 && !isAirborne) { - // Player is walking - if (m_TimeSinceLastFootstep * std::min(playerSpeed, 2) > m_PlayerFootstepInterval) { - // Create footstep sound - Events::PlaySoundOnEntity e; - e.EmitterID = createChildEmitter(); - if (m_LeftFoot) { - e.FilePath = "Audio/footstep/footstep2.wav"; - } else { - e.FilePath = "Audio/footstep/footstep3.wav"; - } - m_LeftFoot = !m_LeftFoot; - m_EventBroker->Publish(e); - m_TimeSinceLastFootstep = 0; - } - } + //if (!m_LocalPlayer.Valid()) { + // return; + //} + //glm::vec3 pos = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Transform")["Position"]; + //glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; + //glm::vec3 difference = pos - m_LastPosition; + //m_DistanceMoved += glm::length(difference); + //bool isAirborne = vel.y != 0; + //if (m_DistanceMoved > m_PlayerStepLength && !isAirborne) { + // // Player is walking + // if (m_TimeSinceLastFootstep * std::min(playerSpeed, 2) > m_PlayerFootstepInterval) { + // // Create footstep sound + // Events::PlaySoundOnEntity e; + // e.EmitterID = createChildEmitter(m_LocalPlayer); + // e.FilePath = m_LeftFoot ? "Audio/footstep/footstep2.wav" : "Audio/footstep/footstep3.wav"; + // m_LeftFoot = !m_LeftFoot; + // m_EventBroker->Publish(e); + // m_TimeSinceLastFootstep = 0; + // } + //} } bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) @@ -59,7 +52,7 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) m_World->AttachComponent(e.Player.ID, "Listener"); m_LocalPlayer = e.Player; Events::PlaySoundOnEntity event; - event.EmitterID = createChildEmitter(); + event.EmitterID = createChildEmitter(m_LocalPlayer); event.FilePath = "Audio/announcer/go.wav"; m_EventBroker->Publish(event); // TEMP: starts bgm From 59bdc614f2b28991b91cc1f2b0f871cefb28a1f4 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 5 Feb 2016 17:34:19 +0100 Subject: [PATCH 083/131] Put SpecialAbility on left shift, and Sprint on left shift in DefaultInput. --- resources/DefaultInput.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index a3f7d166..589dfb3f 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -13,7 +13,8 @@ A=Right,-1 R=Reload Space=Jump LeftControl=Crouch -LeftShift=Sprint +RightShift=Sprint +LeftShift=SpecialAbility F1=ToggleEditor C=ConnectToServer N=SwitchToServer From becb197feb237fb034f3a4a8d1c670b176f09e49 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 5 Feb 2016 17:46:27 +0100 Subject: [PATCH 084/131] Player walk is now based on distance traveled, and it is also reset when key is released. However when dashing the player step sound is still played. The distance of a step is also hard coded in the header file. Will config it up some day. --- include/Engine/Sound/SoundManager.h | 2 - include/Game/Systems/SoundSystem.h | 10 +++- src/Engine/Sound/SoundManager.cpp | 32 +------------ src/Game/Systems/SoundSystem.cpp | 72 ++++++++++++++++++++--------- 4 files changed, 60 insertions(+), 56 deletions(-) diff --git a/include/Engine/Sound/SoundManager.h b/include/Engine/Sound/SoundManager.h index ef291380..9ba4d2ad 100644 --- a/include/Engine/Sound/SoundManager.h +++ b/include/Engine/Sound/SoundManager.h @@ -133,8 +133,6 @@ private: bool OnShoot(const Events::Shoot &e); EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned &e); - EventRelay m_EInputCommand; - bool OnInputCommand(const Events::InputCommand &e); EventRelay m_ECaptured; bool OnCaptured(const Events::Captured &e); EventRelay m_EPlayerDamage; diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index ec87e98a..aaadc3fd 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -4,6 +4,7 @@ #include "../Engine/Core/System.h" #include "../Engine/Sound/SoundManager.h" #include "../Engine/Core/EPlayerSpawned.h" +#include "../Engine/Input/EInputCommand.h" class SoundSystem : public PureSystem, ImpureSystem, SoundManager @@ -19,14 +20,19 @@ private: World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; + void playerJumps(); + + // TODO: WIP Update this - double m_DistanceMoved = 0.0; - const float m_PlayerStepLength = 1.0; + float m_DistanceMoved = 0.0f; + const float m_PlayerStepLength = 2.0f; glm::vec3 m_LastPosition = glm::vec3(); bool m_LeftFoot = false; EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned &e); + EventRelay m_InputCommand; + bool OnInputCommand(const Events::InputCommand &e); }; #endif diff --git a/src/Engine/Sound/SoundManager.cpp b/src/Engine/Sound/SoundManager.cpp index b7aaaff6..7046ecc1 100644 --- a/src/Engine/Sound/SoundManager.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -23,7 +23,6 @@ SoundManager::SoundManager(World* world, EventBroker* eventBroker, bool editorMo EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundManager::OnShoot); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundManager::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundManager::OnPlayerDamage); - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundManager::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundManager::OnCaptured); EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundManager::OnTriggerTouch); EVENT_SUBSCRIBE_MEMBER(m_EPause, &SoundManager::OnPause); @@ -182,16 +181,7 @@ void SoundManager::stopSound(Source* source) alSourceStop(source->ALsource); } -void SoundManager::playerJumps() -{ - glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; - if (vel.y == 0) { - Source* source = createSource("Audio/jump/jump1.wav"); - source->Type = SoundType::SFX; - m_Sources[createChildEmitter(m_LocalPlayer)] = source; - playSound(source); - } -} + void SoundManager::playerStep(double dt) { @@ -303,26 +293,6 @@ bool SoundManager::OnPlayerSpawned(const Events::PlayerSpawned & e) return true; } -bool SoundManager::OnInputCommand(const Events::InputCommand & e) -{ - if (e.Command == "Jump" && e.Value > 0) { - if (e.PlayerID == -1) { // local player - playerJumps(); - return true; - } - } - // TEMP: testing purpose (obviously) - if (e.Command == "TakeDamage" && e.Value > 0) { - if (e.PlayerID == -1) { //Local Player - Events::PlayerDamage ePlayerDamage; - ePlayerDamage.Damage = 1; - ePlayerDamage.Player = EntityWrapper(m_World, e.Player.ID); - m_EventBroker->Publish(ePlayerDamage); - return true; - } - } - return false; -} bool SoundManager::OnCaptured(const Events::Captured & e) { diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 99f3242d..e8ae324f 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -9,11 +9,12 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventbroker) m_World = world; m_EventBroker = eventbroker; EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand); } void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) { - + } void SoundSystem::Update(double dt) @@ -24,26 +25,25 @@ void SoundSystem::Update(double dt) void SoundSystem::playerStep(double dt) { - //if (!m_LocalPlayer.Valid()) { - // return; - //} - //glm::vec3 pos = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Transform")["Position"]; - //glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; - //glm::vec3 difference = pos - m_LastPosition; - //m_DistanceMoved += glm::length(difference); - //bool isAirborne = vel.y != 0; - //if (m_DistanceMoved > m_PlayerStepLength && !isAirborne) { - // // Player is walking - // if (m_TimeSinceLastFootstep * std::min(playerSpeed, 2) > m_PlayerFootstepInterval) { - // // Create footstep sound - // Events::PlaySoundOnEntity e; - // e.EmitterID = createChildEmitter(m_LocalPlayer); - // e.FilePath = m_LeftFoot ? "Audio/footstep/footstep2.wav" : "Audio/footstep/footstep3.wav"; - // m_LeftFoot = !m_LeftFoot; - // m_EventBroker->Publish(e); - // m_TimeSinceLastFootstep = 0; - // } - //} + if (!m_LocalPlayer.Valid()) { + return; + } + glm::vec3 pos = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Transform")["Position"]; + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; + glm::vec3 difference = pos - m_LastPosition; + m_LastPosition = pos; + m_DistanceMoved += glm::length(difference); + bool isAirborne = vel.y != 0; + if (m_DistanceMoved > m_PlayerStepLength && !isAirborne) { + // Player moved a step's distance + // Create footstep sound + Events::PlaySoundOnEntity e; + e.EmitterID = createChildEmitter(m_LocalPlayer); + e.FilePath = m_LeftFoot ? "Audio/footstep/footstep2.wav" : "Audio/footstep/footstep3.wav"; + m_LeftFoot = !m_LeftFoot; + m_EventBroker->Publish(e); + m_DistanceMoved = 0.f; + } } bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) @@ -64,3 +64,33 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) } return true; } + +bool SoundSystem::OnInputCommand(const Events::InputCommand & e) +{ + if (e.Command == "Jump" && e.Value > 0) { + if (e.PlayerID == -1) { // local player + playerJumps(); + return true; + } + } + if (e.Command == "Forward" || e.Command == "Right") { + if (e.Value == 0) { + // Key released + // Reset the distance moved + m_DistanceMoved = 0.f; + } + } + + return false; +} + +void SoundSystem::playerJumps() +{ + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; + if (vel.y == 0) { + Events::PlaySoundOnEntity e; + e.EmitterID = createChildEmitter(m_LocalPlayer); + e.FilePath = "Audio/jump/jump1.wav"; + m_EventBroker->Publish(e); + } +} From 09fb3a6571c99193ecc932ab727256c89af7b49c Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 5 Feb 2016 18:04:36 +0100 Subject: [PATCH 085/131] Added some comments. --- include/Game/Systems/SoundSystem.h | 11 ++++++++--- src/Game/Systems/SoundSystem.cpp | 19 +++++++++++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index aaadc3fd..77ebcfa1 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -14,19 +14,24 @@ public: virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override; virtual void Update(double dt) override; private: + // The logic for making the sound play when player is moving void playerStep(double dt); EntityWrapper m_LocalPlayer = EntityWrapper(); World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; + // Logic for playing a sound when a player jumps void playerJumps(); - - // TODO: WIP Update this + // Walking logic + // Keeps track of how far the player has walked within this "key press session". float m_DistanceMoved = 0.0f; - const float m_PlayerStepLength = 2.0f; + // How far a step is (How often the step sound will be played). + const float m_PlayerStepLength = 1.75f; + // To get a difference when calculating the walking state. glm::vec3 m_LastPosition = glm::vec3(); + // Determine what sound file to play. bool m_LeftFoot = false; EventRelay m_EPlayerSpawned; diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index e8ae324f..06e028f2 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -20,6 +20,7 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp void SoundSystem::Update(double dt) { playerStep(dt); + // Update listener and emitters. SoundManager::Update(dt); } @@ -28,11 +29,13 @@ void SoundSystem::playerStep(double dt) if (!m_LocalPlayer.Valid()) { return; } + // Position of the local player, used see how far a player has moved. glm::vec3 pos = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Transform")["Position"]; + // Velocity of the local player, used to see if a player is airborne. glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; - glm::vec3 difference = pos - m_LastPosition; + m_DistanceMoved += glm::length(pos - m_LastPosition); + // Set the last position for next iteration m_LastPosition = pos; - m_DistanceMoved += glm::length(difference); bool isAirborne = vel.y != 0; if (m_DistanceMoved > m_PlayerStepLength && !isAirborne) { // Player moved a step's distance @@ -56,11 +59,11 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) event.FilePath = "Audio/announcer/go.wav"; m_EventBroker->Publish(event); // TEMP: starts bgm -// { -// Events::PlayBackgroundMusic ev; -// ev.FilePath = "Audio/bgm/ambient.wav"; -// m_EventBroker->Publish(ev); -// } + { + Events::PlayBackgroundMusic ev; + ev.FilePath = "Audio/bgm/ambient.wav"; + m_EventBroker->Publish(ev); + } } return true; } @@ -76,7 +79,7 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) if (e.Command == "Forward" || e.Command == "Right") { if (e.Value == 0) { // Key released - // Reset the distance moved + // Reset the distance moved (player walk logic) m_DistanceMoved = 0.f; } } From 4103c878ec69399e256ab13c302ef5bb3390dabf Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Fri, 5 Feb 2016 18:05:46 +0100 Subject: [PATCH 086/131] Refactoring: Changed HealthPickupSystem to use a struct instead. Removed the Id in EPickupSpawned --- include/Engine/Core/EPickupSpawned.h | 1 - include/Game/Systems/PickupSpawnSystem.h | 10 +++- resources/Schema/Entities/HealthPickup.xml | 2 +- .../Schema/Entities/HealthPickupTest.xml | 51 +++++++++++++++++++ src/Game/Systems/PickupSpawnSystem.cpp | 24 ++++----- 5 files changed, 71 insertions(+), 17 deletions(-) diff --git a/include/Engine/Core/EPickupSpawned.h b/include/Engine/Core/EPickupSpawned.h index dc3bc632..9f85913a 100644 --- a/include/Engine/Core/EPickupSpawned.h +++ b/include/Engine/Core/EPickupSpawned.h @@ -9,7 +9,6 @@ namespace Events struct PickupSpawned : Event { - EntityID PickupID; EntityWrapper Pickup; }; diff --git a/include/Game/Systems/PickupSpawnSystem.h b/include/Game/Systems/PickupSpawnSystem.h index fbb2f082..24cee2b9 100644 --- a/include/Game/Systems/PickupSpawnSystem.h +++ b/include/Game/Systems/PickupSpawnSystem.h @@ -6,7 +6,7 @@ #include "Core/ResourceManager.h" #include "Core/EntityFileParser.h" #include "Core/EPickupSpawned.h" -#include "Core/EPlayerHealthPickup.h"; +#include "Core/EPlayerHealthPickup.h" #include "Engine/Collision/ETrigger.h" #include "Common.h" #include @@ -22,6 +22,12 @@ private: EventRelay m_ETriggerTouch; bool OnTriggerTouch(Events::TriggerTouch& e); - std::vector> m_ETriggerTouchVector; + struct NewHealthPickup { + glm::vec3 Pos; + double HealthGain; + double RespawnTimer; + double DecreaseThisRespawnTimer; + }; + std::vector m_ETriggerTouchVector; }; #endif diff --git a/resources/Schema/Entities/HealthPickup.xml b/resources/Schema/Entities/HealthPickup.xml index f1b787f6..dfc6f938 100644 --- a/resources/Schema/Entities/HealthPickup.xml +++ b/resources/Schema/Entities/HealthPickup.xml @@ -8,7 +8,7 @@ Models/Core/UnitSphere.mesh - + diff --git a/resources/Schema/Entities/HealthPickupTest.xml b/resources/Schema/Entities/HealthPickupTest.xml index 97fd3f4d..2980fb51 100644 --- a/resources/Schema/Entities/HealthPickupTest.xml +++ b/resources/Schema/Entities/HealthPickupTest.xml @@ -238,6 +238,57 @@ + + + + + 1 + 22 + + + Models/Core/UnitSphere.mesh + + + + + + + + + + + + + 1 + 22 + + + Models/Core/UnitSphere.mesh + + + + + + + + + + + + + 4 + 44 + + + Models/Core/UnitSphere.mesh + + + + + + + + diff --git a/src/Game/Systems/PickupSpawnSystem.cpp b/src/Game/Systems/PickupSpawnSystem.cpp index 558aef14..783f7a62 100644 --- a/src/Game/Systems/PickupSpawnSystem.cpp +++ b/src/Game/Systems/PickupSpawnSystem.cpp @@ -8,10 +8,12 @@ PickupSpawnSystem::PickupSpawnSystem(World* m_World, EventBroker* eventBroker) void PickupSpawnSystem::Update(double dt) { - for (auto &healthPickupPosition : m_ETriggerTouchVector) { + for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it) + { + auto& healthPickupPosition = *it; //set the double timer value (value 3) - std::get<3>(healthPickupPosition) -= dt; - if (std::get<3>(healthPickupPosition) < 0) { + healthPickupPosition.DecreaseThisRespawnTimer -= dt; + if (healthPickupPosition.DecreaseThisRespawnTimer < 0) { //spawn and delete the vector item auto entityFile = ResourceManager::Load("Schema/Entities/HealthPickup.xml"); EntityFileParser parser(entityFile); @@ -19,18 +21,17 @@ void PickupSpawnSystem::Update(double dt) //let the world know a pickup has spawned (graphics effects, etc) Events::PickupSpawned ePickupSpawned; - ePickupSpawned.PickupID = healthPickupID; ePickupSpawned.Pickup = EntityWrapper(m_World, healthPickupID); m_EventBroker->Publish(ePickupSpawned); //set values from the old entity to the new entity auto& newHealthPickupEntity = EntityWrapper(m_World, healthPickupID); - newHealthPickupEntity["Transform"]["Position"] = std::get<0>(healthPickupPosition); - newHealthPickupEntity["HealthPickup"]["HealthGain"] = std::get<1>(healthPickupPosition); - newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = std::get<2>(healthPickupPosition); + newHealthPickupEntity["Transform"]["Position"] = healthPickupPosition.Pos; + newHealthPickupEntity["HealthPickup"]["HealthGain"] = healthPickupPosition.HealthGain; + newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = healthPickupPosition.RespawnTimer; //erase the current element (healthPickupPosition) - m_ETriggerTouchVector.erase(std::remove(m_ETriggerTouchVector.begin(), m_ETriggerTouchVector.end(), healthPickupPosition), m_ETriggerTouchVector.end()); + m_ETriggerTouchVector.erase(it); break; } } @@ -50,11 +51,8 @@ bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e) //copy position, healthgain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object) //we need to copy all values since each value can be different for each healthPickup - m_ETriggerTouchVector.push_back(std::make_tuple( - (glm::vec3)e.Trigger["Transform"]["Position"], - e.Trigger["HealthPickup"]["HealthGain"], - e.Trigger["HealthPickup"]["RespawnTimer"], - e.Trigger["HealthPickup"]["RespawnTimer"])); + m_ETriggerTouchVector.push_back({ (glm::vec3)e.Trigger["Transform"]["Position"] ,e.Trigger["HealthPickup"]["HealthGain"], + e.Trigger["HealthPickup"]["RespawnTimer"],e.Trigger["HealthPickup"]["RespawnTimer"] }); //delete the healthpickup m_World->DeleteEntity(e.Trigger.ID); From 933a32aa8db98ff5391637447f7b59835579ceef Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sat, 6 Feb 2016 18:09:51 +0100 Subject: [PATCH 087/131] Animations kind of working --- include/Engine/Rendering/Skeleton.h | 2 +- resources/Schema/Entities/AnimationTests2.xml | 112 ++++++++--------- resources/Schema/Entities/RenderingWorld.xml | 17 ++- resources/Shaders/Sprite.frag.glsl | 41 +++++++ resources/Shaders/Sprite.vert.glsl | 24 ++++ src/Engine/Rendering/AnimationSystem.cpp | 2 + src/Engine/Rendering/BoneAttachmentSystem.cpp | 11 +- src/Engine/Rendering/Skeleton.cpp | 115 ++++++++++++------ 8 files changed, 224 insertions(+), 100 deletions(-) create mode 100644 resources/Shaders/Sprite.frag.glsl create mode 100644 resources/Shaders/Sprite.vert.glsl diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index f1ef22c7..90e24578 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -92,7 +92,7 @@ public: void PrintSkeleton(const Bone* parent, int depthCount); std::map Animations; - glm::mat4 GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix); + glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 parentMatrix); int GetKeyframe(const Animation& animation, double time); private: diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index a116803f..21a899f5 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -13,7 +13,6 @@ - @@ -32,39 +31,21 @@ - + - Run - - 1 + Wave + + 0.099999986588954926 - Models/Asstest.mesh + Models/finaltest.mesh - + - - - - R_Leg_Top - - - - Models/Core/UnitCube.mesh - - - - - - - - - - @@ -76,9 +57,8 @@ - + - @@ -94,9 +74,8 @@ - + - @@ -112,9 +91,8 @@ - + - @@ -130,9 +108,8 @@ - + - @@ -148,9 +125,8 @@ - + - @@ -166,9 +142,8 @@ - + - @@ -184,9 +159,8 @@ - + - @@ -202,9 +176,8 @@ - + - @@ -220,9 +193,8 @@ - + - @@ -238,9 +210,8 @@ - + - @@ -256,9 +227,8 @@ - + - @@ -274,9 +244,8 @@ - + - @@ -292,9 +261,8 @@ - + - @@ -310,9 +278,8 @@ - + - @@ -328,9 +295,44 @@ - + - + + + + + + + + + + Run + + 0.099999986588954926 + + + Models/Supertest2.mesh + + + + + + + + + + R_Leg_Top + + + + + Models/Core/UnitCube.mesh + + + + + + diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 1ac95a3b..4564b3f5 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -60,6 +60,7 @@ Models/Core/UnitHexagon.mesh + true @@ -161,7 +162,7 @@ - + @@ -346,6 +347,20 @@ + + + + Run + + 0.004999999888241291 + + + Models/SuperTest.mesh + + + + + diff --git a/resources/Shaders/Sprite.frag.glsl b/resources/Shaders/Sprite.frag.glsl new file mode 100644 index 00000000..c391322d --- /dev/null +++ b/resources/Shaders/Sprite.frag.glsl @@ -0,0 +1,41 @@ +#version 430 + +uniform vec4 Color; +uniform vec4 FillColor; +uniform float FillPercentage; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout (binding = 0) uniform sampler2D DiffuseTexture; +layout (binding = 1) uniform sampler2D GlowMapTexture; + + +in VertexData{ + vec3 Position; + vec3 Normal; + vec2 TextureCoordinate; +}Input; + + +out vec4 sceneColor; +out vec4 bloomColor; + +void main() +{ + vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); + vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate); + + vec4 color_result = Color * diffuseTexel; + + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; + if(pos <= FillPercentage) { + color_result += FillColor; + } + sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); + color_result += glowTexel*3; + + bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0); +} + + diff --git a/resources/Shaders/Sprite.vert.glsl b/resources/Shaders/Sprite.vert.glsl new file mode 100644 index 00000000..e910a26a --- /dev/null +++ b/resources/Shaders/Sprite.vert.glsl @@ -0,0 +1,24 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 4) in vec2 TextureCoords; + +out VertexData{ + vec3 Position; + vec3 Normal; + vec2 TextureCoordinate; +}Output; + +void main() +{ + gl_Position = P * M * vec4(Position, 1.0); + + Output.Position = Position; + Output.TextureCoordinate = TextureCoords; + Output.Normal = Normal; +} \ No newline at end of file diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index c78aafd9..ef035dca 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -19,6 +19,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a if(skeleton == nullptr) { return; } +/* ImGui::SliderFloat("Angle", &angle, -100.f, 100.f); { @@ -28,6 +29,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle), 0.f, 0.f))); } } +*/ const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]); diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index 1f98c28e..f172d0ab 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -2,7 +2,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& BoneAttachmentComponent, double dt) { -/* + if(!entity.HasComponent("Transform")) { return; @@ -33,13 +33,8 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp return; } - int currentKeyframeIndex = skeleton->GetKeyframe(*animation, parent["Animation"]["Time"]); - const Skeleton::Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; - const Skeleton::Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; - float alpha = ((double)parent["Animation"]["Time"] - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - - glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], currentFrame, nextFrame, alpha, glm::mat4(1)); + glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time"], glm::mat4(1)); @@ -68,5 +63,5 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp } if ((bool)entity["BoneAttachment"]["InheritScale"]) { (glm::vec3&)entity["Transform"]["Scale"] = scale * (glm::vec3)entity["BoneAttachment"]["ScaleOffset"]; - }*/ + } } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 5ae6a264..d857fa5d 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -61,7 +61,7 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl //auto animationFrame = Animations[""].Keyframes[frame]; std::map frameBones; - AccumulateBoneTransforms(noRootMotion, animation, time, frameBones, RootBone, glm::mat4(1)); + AccumulateBoneTransforms(true, animation, time, frameBones, RootBone, glm::mat4(1)); //AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); std::vector finalMatrices; @@ -71,21 +71,18 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl return finalMatrices; } - - - void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { - glm::mat4 boneMatrix;// = glm::mat4(1); + glm::mat4 boneMatrix; Animation::Keyframe currentFrame; Animation::Keyframe nextFrame; - if(animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { // find the bone keyframes that surrounds the current frame + if(animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); - + if(boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone - for (int index = boneKeyFrames.size()-1; index >= 0; index--) { + for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame if (time >= boneKeyFrames.at(index).Time) { currentFrame = boneKeyFrames.at(index); nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); @@ -93,10 +90,18 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim } } - float progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu + float progress; + + if(nextFrame.Index == 0) { + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); + } else { + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu + + } + + if(progress > 1.0f || progress < 0.0f) { - LOG_INFO("Progress %f", progress); - progress = 0.f; + progress = glm::clamp(progress, 0.0f, 1.0f); } Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; @@ -111,53 +116,93 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim positionInterp.z = 0; } - boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); - boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } else { // 1 keyframes for the current bone currentFrame = boneKeyFrames.at(0); - boneMatrix = parentMatrix * bone->ModificationMatrix *(glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); - boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + boneMatrix = parentMatrix * (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); + + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } } else { // 0 keyframes for the current bone - boneMatrix = parentMatrix * bone->ModificationMatrix; - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - + // LOG_INFO("%s Has no keyframe", bone->Name.c_str()); + if (bone->Parent) { + boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix; + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } else { + boneMatrix = glm::inverse(bone->OffsetMatrix); + boneMatrices[bone->ID] = parentMatrix; + } + } for (auto &child : bone->Children) { - std::string name = child->Name; AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, child, boneMatrix); } } -glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix) +glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 parentMatrix) { - /* glm::mat4 boneMatrix; + 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); + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; - 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; + if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { + std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); + if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone + for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame + if (time >= boneKeyFrames.at(index).Time) { + currentFrame = boneKeyFrames.at(index); + nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); + break; + } + } + + float progress; + + if (nextFrame.Index == 0) { + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); + } else { + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu + + } + + if (progress > 1.0f || progress < 0.0f) { + LOG_INFO("Progress %f", progress); + progress = glm::clamp(progress, 0.0f, 1.0f); + } + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; + + 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; + + boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + + } else { // 1 keyframes for the current bone + currentFrame = boneKeyFrames.at(0); + boneMatrix = parentMatrix * (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); - boneMatrix = (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)) * bone->ModificationMatrix * parentMatrix; - } else { - if (bone->Parent) { - boneMatrix = parentMatrix; } + } else { // 0 keyframes for the current bone + if (bone->Parent) { + boneMatrix = glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix * parentMatrix; + } else { + boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix); + } + } - if(bone->Parent) { - return GetBoneTransform(bone->Parent, currentFrame, nextFrame, progress, boneMatrix); + if (bone->Parent) { + return GetBoneTransform(bone->Parent, animation, time, boneMatrix); } else { return boneMatrix; - }*/ - return parentMatrix; + } } int Skeleton::GetBoneID(std::string name) From 92ab22e77947f36ebf6a7e8f5c8bb088cd6b5e62 Mon Sep 17 00:00:00 2001 From: Teejoon Date: Sun, 7 Feb 2016 13:39:13 +0100 Subject: [PATCH 088/131] Splatmapping now working. Rendering pipleline now support 3 different types of Material: Basic: a material with a single color on every property (diffuse, specular, ect). SingleTextures: a material with a single texture in all or any property. Have a single color on the rest. SplatMapping: has a SplatMap and 0 to 5 different textures to every property. Properties with o texture uses a single color insted. All materials with a texture has a UVRepeat, telling how many time to till in U and in V. modelJobs now uses ShadeID, ModelID and TextureID for the Hash insted of only Texture MayaExported exports 3 differnt types of material, the same as the piplen now supports. --- include/Engine/Rendering/DrawFinalPass.h | 1 + include/Engine/Rendering/ExplosionEffectJob.h | 2 +- include/Engine/Rendering/Model.h | 2 +- include/Engine/Rendering/ModelJob.h | 126 ++++++--- include/Engine/Rendering/RawModelCustom.h | 16 +- include/Engine/Rendering/RenderSystem.h | 1 - .../Shaders/ForwardPlusSplatMap.frag.glsl | 245 ++++++++++++++++++ src/Engine/Rendering/DrawBloomPass.cpp | 16 +- .../Rendering/DrawColorCorrectionPass.cpp | 4 +- src/Engine/Rendering/DrawFinalPass.cpp | 208 +++++++++++---- src/Engine/Rendering/DrawScreenQuadPass.cpp | 4 +- src/Engine/Rendering/Model.cpp | 76 +++++- src/Engine/Rendering/RawModelCustom.cpp | 49 ++-- src/Engine/Rendering/RenderSystem.cpp | 5 +- src/Engine/Rendering/Skeleton.cpp | 6 +- tools/MayaExporter/MayaExporter/Material.cpp | 190 ++++++++++++-- tools/MayaExporter/MayaExporter/Material.h | 131 ++++++---- tools/MayaExporter/MayaExporter/Mesh.cpp | 172 ++++++------ tools/MayaExporter/MayaExporter/Mesh.h | 2 +- tools/MayaExporter/MayaExporter/Skeleton.cpp | 24 +- 20 files changed, 971 insertions(+), 309 deletions(-) create mode 100644 resources/Shaders/ForwardPlusSplatMap.frag.glsl diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 74f505fe..a32c562b 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -53,6 +53,7 @@ private: ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; + ShaderProgram* m_ForwardPlusSplatMapProgram; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/ExplosionEffectJob.h b/include/Engine/Rendering/ExplosionEffectJob.h index 89b1342b..8f339526 100644 --- a/include/Engine/Rendering/ExplosionEffectJob.h +++ b/include/Engine/Rendering/ExplosionEffectJob.h @@ -15,7 +15,7 @@ struct ExplosionEffectJob : ModelJob { - ExplosionEffectJob(ComponentWrapper explosionEffectComponent, ::Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, ::World* world, glm::vec4 fillColor, float fillPercentage) + ExplosionEffectJob(ComponentWrapper explosionEffectComponent, ::Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialProperties matGroup, ComponentWrapper modelComponent, ::World* world, glm::vec4 fillColor, float fillPercentage) : ModelJob(model, camera, matrix, matGroup, modelComponent, world, fillColor, fillPercentage) { ExplosionOrigin = (glm::vec3)explosionEffectComponent["ExplosionOrigin"]; diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index 34d8462f..024c97c8 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -14,7 +14,7 @@ private: public: ~Model(); - const std::vector& MaterialGroups() const { return m_RawModel->MaterialGroups; } + const std::vector& MaterialGroups() const { return m_RawModel->m_Materials; } const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; } const RawModel::Vertex* Vertices() const { return m_RawModel->Vertices(); } unsigned int NumberOfVertices() const { return m_RawModel->NumVertices(); } diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 2cb2169c..2c662f09 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -14,39 +14,98 @@ #include "../Core/World.h" #include "../Core/Transform.h" #include "Skeleton.h" +#include "ShaderProgram.h" struct ModelJob : RenderJob { - ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, World* world, glm::vec4 fillColor, float fillPercentage) + ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialProperties matProp, ComponentWrapper modelComponent, World* world, glm::vec4 fillColor, float fillPercentage) : RenderJob() { Model = model; - TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0; - if (modelComponent["DiffuseTexture"]) { - DiffuseTexture = matGroup.Texture.get(); - } else { - DiffuseTexture = nullptr; - } - if (modelComponent["NormalMap"]) { - NormalTexture = matGroup.NormalMap.get(); - } else { - NormalTexture = nullptr; - } - if (modelComponent["SpecularMap"]) { - SpecularTexture = matGroup.SpecularMap.get(); - } else { - SpecularTexture = nullptr; - } - if (modelComponent["GlowMap"]) { - IncandescenceTexture = matGroup.IncandescenceMap.get(); - } else { - IncandescenceTexture = nullptr; - } - DiffuseColor = matGroup.DiffuseColor; - SpecularColor = matGroup.SpecularColor; - IncandescenceColor = matGroup.IncandescenceColor; - StartIndex = matGroup.StartIndex; - EndIndex = matGroup.EndIndex; + ModelID = model->ResourceID; + Type = matProp.type; + ::RawModel::MaterialBasic* matGroup = matProp.material; + switch(matProp.type){ + case ::RawModel::MaterialType::Basic: + if (Model->isSkined()) { + ShaderID = ResourceManager::Load("#ForwardPlusProgram")->ResourceID; + } + else { + //JOHAN TODO: Add Non-skined shader + } + TextureID = 0; + break; + case ::RawModel::MaterialType::SingleTextures: + { + if (Model->isSkined()) { + ShaderID = ResourceManager::Load("#ForwardPlusProgram")->ResourceID; + } + else { + //JOHAN TODO: Add Non-skined shader + } + ::RawModel::MaterialSingleTextures* singleTextures = static_cast<::RawModel::MaterialSingleTextures*>(matProp.material); + TextureID = (singleTextures->ColorMap.Texture) ? singleTextures->ColorMap.Texture->ResourceID : 0; + if (modelComponent["DiffuseTexture"]) { + DiffuseTexture.push_back(singleTextures->ColorMap.Texture.get()); + } + + if (modelComponent["NormalMap"]) { + NormalTexture.push_back(singleTextures->NormalMap.Texture.get()); + } + + if (modelComponent["SpecularMap"]) { + SpecularTexture.push_back(singleTextures->SpecularMap.Texture.get()); + } + + if (modelComponent["GlowMap"]) { + IncandescenceTexture.push_back(singleTextures->IncandescenceMap.Texture.get()); + } + } + break; + case ::RawModel::MaterialType::SplatMapping: + { + if (Model->isSkined()) { + ShaderID = ResourceManager::Load("#ForwardPlusSplatMapProgram")->ResourceID; + } + else { + //JOHAN TODO: Add Non-skinned shader + } + ::RawModel::MaterialSplatMapping* SplatTextures = static_cast<::RawModel::MaterialSplatMapping*>(matProp.material); + + SplatMap = SplatTextures->SplatMap.Texture.get(); + + TextureID = (SplatTextures->ColorMaps[0].Texture) ? SplatTextures->ColorMaps[0].Texture->ResourceID : 0; + if (modelComponent["DiffuseTexture"]) { + for (auto texture : SplatTextures->ColorMaps) { + DiffuseTexture.push_back(texture.Texture.get()); + } + } + + if (modelComponent["NormalMap"]) { + for (auto texture : SplatTextures->NormalMaps) { + NormalTexture.push_back(texture.Texture.get()); + } + } + + if (modelComponent["SpecularMap"]) { + for (auto texture : SplatTextures->SpecularMaps) { + SpecularTexture.push_back(texture.Texture.get()); + } + } + + if (modelComponent["GlowMap"]) { + for (auto texture : SplatTextures->IncandescenceMaps) { + IncandescenceTexture.push_back(texture.Texture.get()); + } + } + } + break; + } + DiffuseColor = matGroup->DiffuseColor; + SpecularColor = matGroup->SpecularColor; + IncandescenceColor = matGroup->IncandescenceColor; + StartIndex = matGroup->StartIndex; + EndIndex = matGroup->EndIndex; Matrix = matrix; Color = modelComponent["Color"]; Entity = modelComponent.EntityID; @@ -68,13 +127,16 @@ struct ModelJob : RenderJob unsigned int TextureID; unsigned int ShaderID; + unsigned int ModelID; + ::RawModel::MaterialType Type; EntityID Entity; glm::mat4 Matrix; - const Texture* DiffuseTexture; - const Texture* NormalTexture; - const Texture* SpecularTexture; - const Texture* IncandescenceTexture; + const Texture* SplatMap; + std::vector DiffuseTexture; + std::vector NormalTexture; + std::vector SpecularTexture; + std::vector IncandescenceTexture; float Shininess = 0.f; glm::vec4 Color; const ::Model* Model = nullptr; @@ -95,7 +157,7 @@ struct ModelJob : RenderJob void CalculateHash() override { - Hash = TextureID; + Hash = TextureID + ModelID << 10 + ShaderID << 20; } }; diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index d0e35646..476bf52e 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -76,10 +76,10 @@ public: struct MaterialSingleTextures : public MaterialBasic { - TextureProperties ColorMaps; - TextureProperties NormalMaps; - TextureProperties SpecularMaps; - TextureProperties IncandescenceMaps; + TextureProperties ColorMap; + TextureProperties NormalMap; + TextureProperties SpecularMap; + TextureProperties IncandescenceMap; }; enum class MaterialType { Basic = 1, SplatMapping, SingleTextures }; @@ -136,10 +136,10 @@ private: void ReadMaterialFile(std::string filePath); void ReadMaterials(std::size_t& offset, char* fileData, const unsigned int& fileByteSize); void ReadMaterialSingle(std::size_t& offset, char* fileData, const unsigned int& fileByteSize); - void ReadMaterialBasic(MaterialBasic* Material, unsigned int &offset, char* fileData, unsigned int& fileByteSize); - void ReadMaterialSingleTexture(MaterialSingleTextures* Material, unsigned int &offset, char* fileData, unsigned int& fileByteSize); - void ReadMaterialSplatMapping(MaterialSplatMapping* Material, unsigned int &offset, char* fileData, unsigned int& fileByteSize); - void ReadMaterialTextureProperties(TextureProperties& texture, unsigned int &offset, char* fileData, unsigned int& fileByteSize); + void ReadMaterialBasic(MaterialBasic* Material, std::size_t& offset, char* fileData, const unsigned int& fileByteSize); + void ReadMaterialSingleTexture(MaterialSingleTextures* Material, std::size_t& offset, char* fileData, const unsigned int& fileByteSize); + void ReadMaterialSplatMapping(MaterialSplatMapping* Material, std::size_t& offset, char* fileData, const unsigned int& fileByteSize); + void ReadMaterialTextureProperties(TextureProperties& texture, std::size_t& offset, char* fileData, const unsigned int& fileByteSize); void ReadAnimationFile(std::string filePath); void ReadAnimationBindPoses(std::size_t& offset, char* fileData, const unsigned int& fileByteSize); diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index d64147b9..50ccdb0c 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -47,7 +47,6 @@ private: void fillLight(std::list>& jobs); bool isChildOfACamera(EntityWrapper entity); bool isChildOfCurrentCamera(EntityWrapper entity); - }; #endif \ No newline at end of file diff --git a/resources/Shaders/ForwardPlusSplatMap.frag.glsl b/resources/Shaders/ForwardPlusSplatMap.frag.glsl new file mode 100644 index 00000000..fe26469e --- /dev/null +++ b/resources/Shaders/ForwardPlusSplatMap.frag.glsl @@ -0,0 +1,245 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform vec2 ScreenDimensions; +uniform float FillPercentage; +uniform vec4 DiffuseColor; +uniform vec4 FillColor; +uniform vec4 Color; +uniform vec4 AmbientColor; +layout (binding = 0) uniform sampler2D SplatMapTexture; +layout (binding = 1) uniform sampler2D DiffuseTexture1; +layout (binding = 2) uniform sampler2D DiffuseTexture2; +layout (binding = 3) uniform sampler2D DiffuseTexture3; +layout (binding = 4) uniform sampler2D DiffuseTexture4; +layout (binding = 5) uniform sampler2D DiffuseTexture5; +layout (binding = 6) uniform sampler2D NormalMapTexture1; +layout (binding = 7) uniform sampler2D NormalMapTexture2; +layout (binding = 8) uniform sampler2D NormalMapTexture3; +layout (binding = 9) uniform sampler2D NormalMapTexture4; +layout (binding = 10) uniform sampler2D NormalMapTexture5; +layout (binding = 11) uniform sampler2D SpecularMapTexture1; +layout (binding = 12) uniform sampler2D SpecularMapTexture2; +layout (binding = 13) uniform sampler2D SpecularMapTexture3; +layout (binding = 14) uniform sampler2D SpecularMapTexture4; +layout (binding = 15) uniform sampler2D SpecularMapTexture5; +layout (binding = 16) uniform sampler2D GlowMapTexture1; +layout (binding = 17) uniform sampler2D GlowMapTexture2; +layout (binding = 18) uniform sampler2D GlowMapTexture3; +layout (binding = 19) uniform sampler2D GlowMapTexture4; +layout (binding = 20) uniform sampler2D GlowMapTexture5; + +#define TILE_SIZE 16 + +struct LightSource { + vec4 Position; + vec4 Direction; + vec4 Color; + float Radius; + float Intensity; + float Falloff; + int Type; +}; + +layout (std430, binding = 1) buffer LightBuffer +{ + LightSource List[]; +} LightSources; + +struct LightGrid { + float Start; + float Amount; + vec2 Padding; +}; + +layout (std430, binding = 2) buffer LightGridBuffer +{ + LightGrid Data[]; +} LightGrids; + +layout (std430, binding = 4) buffer LightIndexBuffer +{ + float LightIndex[]; +}; + + +in VertexData{ + vec3 Position; + vec3 Normal; + vec3 Tangent; + vec3 BiTangent; + vec2 TextureCoordinate; + vec4 ExplosionColor; + float ExplosionPercentageElapsed; +}Input; + +out vec4 sceneColor; +out vec4 bloomColor; + +struct LightResult { + vec4 Diffuse; + vec4 Specular; +}; + +float CalcAttenuation(float radius, float dist, float falloff) { + return 1.0 - smoothstep(radius * 0.3, radius, dist); +} + +vec4 CalcSpecular(vec4 lightColor, vec4 viewVec, vec4 lightVec, vec4 normal) { + vec4 R = normalize( reflect(-lightVec, normal)); + float RdotV = max( dot(R, viewVec), 0.0); + return lightColor * pow(RdotV, 90.0); +} + +vec4 CalcDiffuse(vec4 lightColor, vec4 lightVec, vec4 normal) { + float power = max( dot(normal, lightVec), 0.0); + return lightColor * power; +} + +LightResult CalcPointLightSource(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff) +{ + vec4 L = lightPos - position; + float dist = length(L); + L = normalize(L); + + float attenuation = CalcAttenuation(lightRadius, dist, falloff); + + LightResult result; + result.Diffuse = CalcDiffuse(lightColor, L, normal) * attenuation * intensity; + result.Specular = CalcSpecular(lightColor, viewVec, L, normal) * attenuation * intensity; + return result; +} + +LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensity, vec4 viewVec, vec4 vertNormal) +{ + vec4 L = normalize( -vec4(direction.xyz, 0) ); + + LightResult result; + result.Diffuse = CalcDiffuse(color, L, vertNormal) * intensity; + result.Specular = CalcSpecular(color, viewVec, L, vertNormal) * intensity; + return result; +} + +vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textureCoordinate, sampler2D normalMap) +{ + mat3 TBN = mat3(tangent, bitangent, normal); + vec3 NormalMap = texture(normalMap, textureCoordinate).xyz * 2.0 - vec3(1.0); + return vec4(TBN * normalize(NormalMap), 0.0); +} + +#define TEXTURE_TILE 5.0 + +vec4 CalcBlendedTexel(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, sampler2D A, sampler2D D, vec2 tileValues){ + vec4 R_Channel = texture2D(R, Input.TextureCoordinate * tileValues); + vec4 G_Channel = texture2D(G, Input.TextureCoordinate * tileValues); + vec4 B_Channel = texture2D(B, Input.TextureCoordinate * tileValues); + vec4 A_Channel = texture2D(A, Input.TextureCoordinate * tileValues); + vec4 D_Channel = texture2D(D, Input.TextureCoordinate * tileValues); + + float total = blendValue.r + blendValue.g + blendValue.b + blendValue.a; + if(total > 1.0f){ + blendValue.r / total; + blendValue.g / total; + blendValue.b / total; + blendValue.a / total; + } + float D_percent = clamp( 1.0f - total, 0.0f, 1.0f); + + return blendValue.r * R_Channel + + blendValue.g * G_Channel + + blendValue.b * B_Channel + + blendValue.a * A_Channel + + D_percent * D_Channel; +} + +vec4 CalcBlendedNormal(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, sampler2D A, sampler2D D, vec2 tileValues){ + mat3 TBN = mat3(Input.Tangent, Input.BiTangent, Input.Normal); + vec3 R_Channel = texture(R, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); + vec3 G_Channel = texture(G, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); + vec3 B_Channel = texture(B, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); + vec3 A_Channel = texture(A, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); + vec3 D_Channel = texture(D, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); + + if(blendValue.length() > 1.0f){ + blendValue = normalize(blendValue); + } + float D_percent = 1.0f - blendValue.r - blendValue.g - blendValue.b - blendValue.a; + + vec3 Normal_result = blendValue.r * R_Channel + + blendValue.g * G_Channel + + blendValue.b * B_Channel + + blendValue.a * A_Channel + + D_percent * D_Channel; + + return vec4(TBN * normalize(Normal_result), 0.0); +} + +void main() +{ + vec4 splatTexel = texture2D(SplatMapTexture, Input.TextureCoordinate); + + vec4 diffuseTexel = CalcBlendedTexel(splatTexel, DiffuseTexture1, DiffuseTexture2, DiffuseTexture3, DiffuseTexture4, DiffuseTexture5, vec2(TEXTURE_TILE, TEXTURE_TILE)); + vec4 glowTexel = CalcBlendedTexel(splatTexel, GlowMapTexture1, GlowMapTexture2, GlowMapTexture3, GlowMapTexture4, GlowMapTexture5, vec2(TEXTURE_TILE, TEXTURE_TILE)); + vec4 specularTexel = CalcBlendedTexel(splatTexel, SpecularMapTexture1, SpecularMapTexture2, SpecularMapTexture3, SpecularMapTexture4, SpecularMapTexture5, vec2(TEXTURE_TILE, TEXTURE_TILE)); + vec4 position = V * M * vec4(Input.Position, 1.0); + //vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate, SplatMapTexture); + vec4 normal = V * CalcBlendedNormal(splatTexel, NormalMapTexture1, NormalMapTexture2, NormalMapTexture3, NormalMapTexture4, NormalMapTexture5, vec2(TEXTURE_TILE, TEXTURE_TILE)); + normal = normalize(normal); + //vec4 normal = normalize(V * vec4(Input.Normal, 0.0)); + vec4 viewVec = normalize(-position); + + vec2 tilePos; + tilePos.x = int(gl_FragCoord.x/TILE_SIZE); + tilePos.y = int(gl_FragCoord.y/TILE_SIZE); + + LightResult totalLighting; + totalLighting.Diffuse = vec4(AmbientColor.rgb, 1.0); + int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE))); + + int start = int(LightGrids.Data[currentTile].Start); + int amount = int(LightGrids.Data[currentTile].Amount); + + for(int i = start; i < start + amount; i++) { + + int l = int(LightIndex[i]); + LightSource light = LightSources.List[l]; + + LightResult light_result; + //These if statements should be removed. + if(light.Type == 1) { // point + light_result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff); + } else if (light.Type == 2) { //Directional + light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); + } + totalLighting.Diffuse += light_result.Diffuse; + totalLighting.Specular += light_result.Specular; + } + + vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); + color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); + //vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color; + + + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; + + if(pos <= FillPercentage) { + color_result += FillColor; + } + sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); + color_result += glowTexel*3; + + bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0); + + //Tiled Debug Code + /* + if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) { + sceneColor += vec4(0.5, 0, 0, 0); + } else { + sceneColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/LightSources.List.length(), 0, 0, 1); + } + */ +} + + diff --git a/src/Engine/Rendering/DrawBloomPass.cpp b/src/Engine/Rendering/DrawBloomPass.cpp index 5d8b2359..6cf3a2cc 100644 --- a/src/Engine/Rendering/DrawBloomPass.cpp +++ b/src/Engine/Rendering/DrawBloomPass.cpp @@ -77,8 +77,8 @@ void DrawBloomPass::Draw(GLuint texture) glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1 - , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); //Iterate some times to make it more gaussian. for (int i = 1; i < m_iterations; i++) { @@ -90,8 +90,8 @@ void DrawBloomPass::Draw(GLuint texture) glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1 - , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); //horizontal pass @@ -102,8 +102,8 @@ void DrawBloomPass::Draw(GLuint texture) glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1 - , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); } //final vertical gaussian after the iterations are done @@ -115,8 +115,8 @@ void DrawBloomPass::Draw(GLuint texture) glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1 - , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); GLERROR("DrawBloomPass::Draw: END"); } diff --git a/src/Engine/Rendering/DrawColorCorrectionPass.cpp b/src/Engine/Rendering/DrawColorCorrectionPass.cpp index 95de26e2..d74a0d13 100644 --- a/src/Engine/Rendering/DrawColorCorrectionPass.cpp +++ b/src/Engine/Rendering/DrawColorCorrectionPass.cpp @@ -38,6 +38,6 @@ void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLf glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1 - , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 8247797e..1ceddb4e 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -55,6 +55,15 @@ void DrawFinalPass::InitializeShaderPrograms() m_ExplosionEffectProgram->BindFragDataLocation(1, "bloomColor"); m_ExplosionEffectProgram->Link(); GLERROR("Creating explosion program"); + + m_ForwardPlusSplatMapProgram = ResourceManager::Load("#ForwardPlusSplatMapProgram"); + m_ForwardPlusSplatMapProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); + m_ForwardPlusSplatMapProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMap.frag.glsl"))); + m_ForwardPlusSplatMapProgram->Compile(); + m_ForwardPlusSplatMapProgram->BindFragDataLocation(0, "sceneColor"); + m_ForwardPlusSplatMapProgram->BindFragDataLocation(1, "bloomColor"); + m_ForwardPlusSplatMapProgram->Link(); + GLERROR("Creating SplatMap program"); } void DrawFinalPass::Draw(RenderScene& scene) @@ -114,8 +123,9 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& { GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); GLERROR("forwardHandle"); - GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle(); + GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle(); GLERROR("explosionHandle"); + GLuint forwardSplatHandle = m_ForwardPlusSplatMapProgram->GetHandle(); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); @@ -171,14 +181,32 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { //bind forward program - m_ForwardPlusProgram->Bind(); - glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + //TODO: JOHAN/TOBIAS: Bind shader based on ModelJob->ShaderID; + switch (modelJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + m_ForwardPlusProgram->Bind(); + GLERROR("Bind Forward program"); + //bind uniforms + BindModelUniforms(forwardHandle, modelJob, scene); + break; + } + case RawModel::MaterialType::SplatMapping: + { + m_ForwardPlusSplatMapProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatHandle, modelJob, scene); + break; + } + } + + //bind textures + BindModelTextures(modelJob); + GLERROR("asdasd"); - //bind uniforms - BindModelUniforms(forwardHandle, modelJob, scene); - //bind textures - BindModelTextures(modelJob); if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { @@ -230,48 +258,65 @@ void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) { - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + GLERROR("Bind 1 uniform"); + GLint Location_M = glGetUniformLocation(shaderHandle, "M"); + glUniformMatrix4fv(Location_M, 1, GL_FALSE, glm::value_ptr(job->Matrix)); + GLERROR("Bind 2 uniform"); + GLint Location_V = glGetUniformLocation(shaderHandle, "V"); + glUniformMatrix4fv(Location_V, 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + GLERROR("Bind 3 uniform"); + GLint Location_P = glGetUniformLocation(shaderHandle, "P"); + glUniformMatrix4fv(Location_P, 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + GLERROR("Bind 4 uniform"); - glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + GLint Location_ScreenDimensions = glGetUniformLocation(shaderHandle, "ScreenDimensions"); + glUniform2f(Location_ScreenDimensions, m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + GLERROR("Bind 5 uniform"); - glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(job->Color)); - glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(job->DiffuseColor)); - glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(job->FillColor)); - glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), job->FillPercentage); - glUniform4fv(glGetUniformLocation(shaderHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor)); + GLint Location_FillPercentage = glGetUniformLocation(shaderHandle, "FillPercentage"); + glUniform1f(Location_FillPercentage, job->FillPercentage); + GLERROR("Bind 6 uniform"); + GLint Location_DiffuseColor = glGetUniformLocation(shaderHandle, "DiffuseColor"); + glUniform4fv(Location_DiffuseColor, 1, glm::value_ptr(job->DiffuseColor)); + GLERROR("Bind 7 uniform"); + GLint Location_FillColor = glGetUniformLocation(shaderHandle, "FillColor"); + glUniform4fv(Location_FillColor, 1, glm::value_ptr(job->FillColor)); + GLERROR("Bind 8 uniform"); + GLint Location_Color = glGetUniformLocation(shaderHandle, "Color"); + glUniform4fv(Location_Color, 1, glm::value_ptr(job->Color)); + GLERROR("Bind 9 uniform"); + GLint Location_AmbientColor = glGetUniformLocation(shaderHandle, "AmbientColor"); + glUniform4fv(Location_AmbientColor, 1, glm::value_ptr(scene.AmbientColor)); - GLERROR("END"); + GLERROR("END"); } - void DrawFinalPass::BindExplosionTextures(std::shared_ptr& job) { glActiveTexture(GL_TEXTURE0); - if (job->DiffuseTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture->m_Texture); + if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->m_Texture); //JOHAN TODO: support multiple diffuse Textures } else { glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); } glActiveTexture(GL_TEXTURE1); - if (job->NormalTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->NormalTexture->m_Texture); + if (job->NormalTexture.size() > 0 && job->NormalTexture[0] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->m_Texture); //JOHAN TODO: support multiple diffuse Textures } else { glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); } glActiveTexture(GL_TEXTURE2); - if (job->SpecularTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->SpecularTexture->m_Texture); + if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->m_Texture); //JOHAN TODO: support multiple diffuse Textures } else { glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); } glActiveTexture(GL_TEXTURE3); - if (job->IncandescenceTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture->m_Texture); + if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->m_Texture); //JOHAN TODO: support multiple diffuse Textures } else { glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); } @@ -279,32 +324,95 @@ void DrawFinalPass::BindExplosionTextures(std::shared_ptr& j void DrawFinalPass::BindModelTextures(std::shared_ptr& job) { - glActiveTexture(GL_TEXTURE0); - if (job->DiffuseTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture->m_Texture); - } else { - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - } + switch (job->Type) { + case RawModel::MaterialType::SingleTextures: + case RawModel::MaterialType::Basic: + { + glActiveTexture(GL_TEXTURE0); + if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } - glActiveTexture(GL_TEXTURE1); - if (job->NormalTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->NormalTexture->m_Texture); - } else { - glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); - } + glActiveTexture(GL_TEXTURE1); + if (job->NormalTexture.size() > 0 && job->NormalTexture[0] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); + } - glActiveTexture(GL_TEXTURE2); - if (job->SpecularTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->SpecularTexture->m_Texture); - } else { - glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); - } + glActiveTexture(GL_TEXTURE2); + if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); + } - glActiveTexture(GL_TEXTURE3); - if (job->IncandescenceTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture->m_Texture); - } else { - glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); - } + glActiveTexture(GL_TEXTURE3); + if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, job->SplatMap->m_Texture); + + int texturePosition = GL_TEXTURE1; + //Bind 5 diffuse textures + for (unsigned int i = 0; i < 5; i++) { + glActiveTexture(texturePosition); + if (job->DiffuseTexture.size() > i && job->DiffuseTexture[i] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[i]->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } + texturePosition++; + } + //Bind 5 Normal textures + for (unsigned int i = 0; i < 5; i++) { + glActiveTexture(texturePosition); + if (job->NormalTexture.size() > i && job->NormalTexture[i] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->NormalTexture[i]->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); + } + texturePosition++; + } + //Bind 5 Specular textures + for (unsigned int i = 0; i < 5; i++) { + glActiveTexture(texturePosition); + if (job->SpecularTexture.size() > i && job->SpecularTexture[i] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[i]->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); + } + texturePosition++; + } + //Bind 5 Incandescence textures + for (unsigned int i = 0; i < 5; i++) { + glActiveTexture(texturePosition); + if (job->IncandescenceTexture.size() > i && job->IncandescenceTexture[i] != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[i]->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + } + texturePosition++; + } + break; + } + } } diff --git a/src/Engine/Rendering/DrawScreenQuadPass.cpp b/src/Engine/Rendering/DrawScreenQuadPass.cpp index b17f5e29..7a522b72 100644 --- a/src/Engine/Rendering/DrawScreenQuadPass.cpp +++ b/src/Engine/Rendering/DrawScreenQuadPass.cpp @@ -32,6 +32,6 @@ void DrawScreenQuadPass::Draw(GLuint texture) glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1 - , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); } diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index bf264b5a..7b880208 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -5,19 +5,69 @@ Model::Model(std::string fileName) //Try loading the model asyncronously, if it throws any exceptions then let it propagate back to caller. m_RawModel = ResourceManager::Load(fileName); - for (auto& group : m_RawModel->MaterialGroups) { - if (!group.TexturePath.empty()) { - group.Texture = std::shared_ptr(ResourceManager::Load(group.TexturePath)); - } - if (!group.NormalMapPath.empty()) { - group.NormalMap = std::shared_ptr(ResourceManager::Load(group.NormalMapPath)); - } - if (!group.SpecularMapPath.empty()) { - group.SpecularMap = std::shared_ptr(ResourceManager::Load(group.SpecularMapPath)); - } - if (!group.IncandescenceMapPath.empty()) { - group.IncandescenceMap = std::shared_ptr(ResourceManager::Load(group.IncandescenceMapPath)); - } + for (auto& materialProperty : m_RawModel->m_Materials) { + switch (materialProperty.type) { + case RawModel::MaterialType::SingleTextures: + { + RawModel::MaterialSingleTextures* materialSingleTexture = static_cast(materialProperty.material); + if (!materialSingleTexture->ColorMap.TexturePath.empty()) { + materialSingleTexture->ColorMap.Texture = std::shared_ptr(ResourceManager::Load(materialSingleTexture->ColorMap.TexturePath)); + } + if (!materialSingleTexture->NormalMap.TexturePath.empty()) { + materialSingleTexture->NormalMap.Texture = std::shared_ptr(ResourceManager::Load(materialSingleTexture->NormalMap.TexturePath)); + } + if (!materialSingleTexture->SpecularMap.TexturePath.empty()) { + materialSingleTexture->SpecularMap.Texture = std::shared_ptr(ResourceManager::Load(materialSingleTexture->SpecularMap.TexturePath)); + } + if (!materialSingleTexture->IncandescenceMap.TexturePath.empty()) { + materialSingleTexture->IncandescenceMap.Texture = std::shared_ptr(ResourceManager::Load(materialSingleTexture->IncandescenceMap.TexturePath)); + } + } + break; + case RawModel::MaterialType::SplatMapping: + { + RawModel::MaterialSplatMapping* materialSplatMapping = static_cast(materialProperty.material); + if (!materialSplatMapping->SplatMap.TexturePath.empty()) { + materialSplatMapping->SplatMap.Texture = std::shared_ptr(ResourceManager::Load(materialSplatMapping->SplatMap.TexturePath)); + } + for (auto& texture : materialSplatMapping->ColorMaps) + { + if (!texture.TexturePath.empty()) { + texture.Texture = std::shared_ptr(ResourceManager::Load(texture.TexturePath)); + } + else { + texture.Texture = nullptr; + } + } + for (auto& texture : materialSplatMapping->NormalMaps) + { + if (!texture.TexturePath.empty()) { + texture.Texture = std::shared_ptr(ResourceManager::Load(texture.TexturePath)); + } else { + texture.Texture = nullptr; + } + } + for (auto& texture : materialSplatMapping->SpecularMaps) + { + if (!texture.TexturePath.empty()) { + texture.Texture = std::shared_ptr(ResourceManager::Load(texture.TexturePath)); + } + else { + texture.Texture = nullptr; + } + } + for (auto& texture : materialSplatMapping->IncandescenceMaps) + { + if (!texture.TexturePath.empty()) { + texture.Texture = std::shared_ptr(ResourceManager::Load(texture.TexturePath)); + } + else { + texture.Texture = nullptr; + } + } + } + break; + } } // Generate GL buffers diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index e6d25dfd..00ae0e33 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -34,7 +34,7 @@ void RawModelCustom::ReadMeshFile(std::string filePath) ReadMeshFileHeader(offset, fileData); ReadMesh(offset, fileData, fileByteSize); } - delete fileData; + delete[] fileData; } void RawModelCustom::ReadMeshFileHeader(std::size_t& offset, char* fileData) @@ -116,7 +116,7 @@ void RawModelCustom::ReadMaterialFile(std::string filePath) if (fileByteSize > 0) { ReadMaterials(offset, fileData, fileByteSize); } - delete fileData; + delete[] fileData; } void RawModelCustom::ReadMaterials(std::size_t& offset, char* fileData, const unsigned int& fileByteSize) @@ -169,15 +169,8 @@ void RawModelCustom::ReadMaterialSingle(std::size_t& offset, char* fileData, con m_Materials.push_back(newMaterialProperty); } -void RawModelCustom::ReadMaterialBasic(RawModelCustom::MaterialBasic* newMaterial, unsigned int &offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadMaterialBasic(RawModelCustom::MaterialBasic* newMaterial, std::size_t& offset, char* fileData, const unsigned int& fileByteSize) { - if (offset + sizeof(unsigned int) * 4 > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material texture names length failed"); - } - - unsigned int* nameLengths = (unsigned int*)(fileData + offset); - offset += sizeof(unsigned int) * 4; - if (offset + sizeof(float) * 11 + sizeof(unsigned int) * 2 > fileByteSize) { throw Resource::FailedLoadingException("Reading Material specular, reflection, color and start and end index values failed"); } @@ -200,42 +193,49 @@ void RawModelCustom::ReadMaterialBasic(RawModelCustom::MaterialBasic* newMateria offset += sizeof(unsigned int); } -void RawModelCustom::ReadMaterialSingleTexture(RawModelCustom::MaterialSingleTextures* newMaterial, unsigned int &offset, char* fileData, unsigned int& fileByteSize) -{ - unsigned char numberOfMaps[4]; +void RawModelCustom::ReadMaterialSingleTexture(RawModelCustom::MaterialSingleTextures* newMaterial, std::size_t& offset, char* fileData, const unsigned int& fileByteSize) +{ + ReadMaterialBasic(newMaterial, offset, fileData, fileByteSize); if (offset + sizeof(unsigned char) * 4 > fileByteSize) { throw Resource::FailedLoadingException("Reading Material NumOfMaps failed"); } + unsigned char numberOfMaps[4]; + memcpy(numberOfMaps, fileData + offset, sizeof(unsigned char) * 4); + offset += sizeof(unsigned char) * 4; if (numberOfMaps[0] > 0) { - ReadMaterialTextureProperties(newMaterial->ColorMaps, offset, fileData, fileByteSize); + ReadMaterialTextureProperties(newMaterial->ColorMap, offset, fileData, fileByteSize); } if (numberOfMaps[1] > 0) { - ReadMaterialTextureProperties(newMaterial->SpecularMaps, offset, fileData, fileByteSize); + ReadMaterialTextureProperties(newMaterial->SpecularMap, offset, fileData, fileByteSize); } if (numberOfMaps[2] > 0) { - ReadMaterialTextureProperties(newMaterial->NormalMaps, offset, fileData, fileByteSize); + ReadMaterialTextureProperties(newMaterial->NormalMap, offset, fileData, fileByteSize); } if (numberOfMaps[3] > 0) { - ReadMaterialTextureProperties(newMaterial->IncandescenceMaps, offset, fileData, fileByteSize); + ReadMaterialTextureProperties(newMaterial->IncandescenceMap, offset, fileData, fileByteSize); } } -void RawModelCustom::ReadMaterialSplatMapping(RawModelCustom::MaterialSplatMapping* newMaterial, unsigned int &offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadMaterialSplatMapping(RawModelCustom::MaterialSplatMapping* newMaterial, std::size_t& offset, char* fileData, const unsigned int& fileByteSize) { + ReadMaterialBasic(newMaterial, offset, fileData, fileByteSize); ReadMaterialTextureProperties(newMaterial->SplatMap, offset, fileData, fileByteSize); - unsigned char numberOfMaps[4]; if (offset + sizeof(unsigned char) * 4 > fileByteSize) { throw Resource::FailedLoadingException("Reading Material NumOfMaps failed"); } + unsigned char numberOfMaps[4]; + memcpy(numberOfMaps, fileData + offset, sizeof(unsigned char) * 4); + offset += sizeof(unsigned char) * 4; + newMaterial->ColorMaps.resize(numberOfMaps[0]); for (unsigned char i = 0; i < numberOfMaps[0]; i++) { @@ -261,8 +261,10 @@ void RawModelCustom::ReadMaterialSplatMapping(RawModelCustom::MaterialSplatMappi } } -void RawModelCustom::ReadMaterialTextureProperties(RawModelCustom::TextureProperties& texture, unsigned int &offset, char* fileData, unsigned int& fileByteSize) { +void RawModelCustom::ReadMaterialTextureProperties(RawModelCustom::TextureProperties& texture, std::size_t& offset, char* fileData, const unsigned int& fileByteSize) { unsigned int nameLength = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + if (nameLength > 0) { if (offset + nameLength > fileByteSize) { throw Resource::FailedLoadingException("Reading Material texture path failed"); @@ -312,7 +314,7 @@ void RawModelCustom::ReadAnimationFile(std::string filePath) ReadAnimationBindPoses(offset, fileData, fileByteSize); ReadAnimationClips(offset, fileData, fileByteSize, numAnimations); } - delete fileData; + delete[] fileData; } void RawModelCustom::ReadAnimationBindPoses(std::size_t& offset, char* fileData, const unsigned int& fileByteSize) @@ -432,7 +434,7 @@ void RawModelCustom::ReadAnimationClipSingle(std::size_t& offset, char* fileData #endif } -void RawModelCustom::ReadAnimationKeyFrame(std::size_t& &offset, char* fileData, const unsigned int& fileByteSize, std::vector& animation) +void RawModelCustom::ReadAnimationKeyFrame(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, std::vector& animation) { Skeleton::Animation::Keyframe newKeyFrame; @@ -475,6 +477,9 @@ RawModelCustom::~RawModelCustom() if (m_Skeleton != nullptr) { delete m_Skeleton; } + for (auto material : m_Materials) { + delete material.material; + } } #endif \ No newline at end of file diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index eaecf99e..d058a443 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -113,6 +113,7 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, if (cModel["Transparent"]) { transparentJobs.push_back(explosionEffectJob); } else { + explosionEffectJob->CalculateHash(); opaqueJobs.push_back(explosionEffectJob); } } else { @@ -132,6 +133,7 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, if (cModel["Transparent"]) { transparentJobs.push_back(modelJob); } else { + modelJob->CalculateHash(); opaqueJobs.push_back(modelJob); } } @@ -196,7 +198,7 @@ void RenderSystem::fillText(std::list>& jobs, World* if (texts == nullptr) { return; } - + for (auto& textComponent : *texts) { bool visible = textComponent["Visible"]; if (!visible) { @@ -252,6 +254,7 @@ void RenderSystem::Update(double dt) } fillModels(scene.OpaqueObjects, scene.TransparentObjects); + scene.OpaqueObjects.sort(); fillPointLights(scene.PointLightJobs, m_World); fillDirectionalLights(scene.DirectionalLightJobs, m_World); fillText(scene.TextJobs, m_World); diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index c00094cd..e9c4d381 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -48,16 +48,16 @@ std::vector Skeleton::GetFrameBones(const Animation& animation, doubl while (time > animation.Duration) { time -= animation.Duration; } - + //JOHAN TODO: Ask Viktor about stuff //int currentKeyframeIndex = GetKeyframe(animation, time); //const Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex]; //const Animation::Keyframe& nextFrame = animation.Keyframes[(currentKeyframeIndex + 1) % animation.Keyframes.size()]; - double alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + //double alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); ////auto animationFrame = Animations[""].Keyframes[frame]; std::map frameBones; - AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, static_cast(alpha), frameBones, RootBone, glm::mat4(1)); + //AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, static_cast(alpha), frameBones, RootBone, glm::mat4(1)); std::vector finalMatrices; for (auto &kv : frameBones) { diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index e487d87f..a5717aa6 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -88,14 +88,30 @@ bool Material::findColorTexture(MaterialNode& material_node, MFnDependencyNode& newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); newTexture.FileNameLength = newTexture.FileName.length() + 1; - newTexture.UVTiling[0] = TextureNode.findPlug("RepeatU").asFloat(); - newTexture.UVTiling[1] = TextureNode.findPlug("RepeatV").asFloat(); + MPlug uvRepeatFile = TextureNode.findPlug("repeatUV"); + + uvRepeatFile.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kPlace2dTexture)) { + MFnDependencyNode place2DTexture(AllConnections[i].node()); + MPlug uvRepeat = place2DTexture.findPlug("repeatUV"); + + newTexture.UVTiling[0] = uvRepeat.child(0).asFloat(); + newTexture.UVTiling[1] = uvRepeat.child(1).asFloat(); + } + } material_node.ColorMaps.push_back(newTexture); + if(material_node.type == MaterialNode::MaterialType::Basic) + material_node.type = MaterialNode::MaterialType::SingleTextures; return true; + + } else if (AllConnections[i].node().hasFn(MFn::kLayeredTexture)) { + MGlobal::displayInfo(MString() + "find splat map"); + return findSplatTextures(material_node, material_node.ColorMaps, MFnDependencyNode(AllConnections[i].node())); } } - return false; } @@ -130,11 +146,25 @@ bool Material::findNormalTexture(MaterialNode& material_node, MFnDependencyNode& newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); newTexture.FileNameLength = newTexture.FileName.length() + 1; - newTexture.UVTiling[0] = TextureNode.findPlug("RepeatU").asFloat(); - newTexture.UVTiling[1] = TextureNode.findPlug("RepeatV").asFloat(); + MPlug uvRepeatFile = TextureNode.findPlug("repeatUV"); + + uvRepeatFile.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kPlace2dTexture)) { + MFnDependencyNode place2DTexture(AllConnections[i].node()); + MPlug uvRepeat = place2DTexture.findPlug("repeatUV"); + + newTexture.UVTiling[0] = uvRepeat.child(0).asFloat(); + newTexture.UVTiling[1] = uvRepeat.child(1).asFloat(); + } + } material_node.NormalMaps.push_back(newTexture); return true; + } else if (AllConnections[i].node().hasFn(MFn::kLayeredTexture)) { + MGlobal::displayInfo(MString() + "find splat map"); + return findSplatTextures(material_node, material_node.NormalMaps, MFnDependencyNode(AllConnections[i].node())); } } } @@ -168,11 +198,28 @@ bool Material::findSpecularTexture(MaterialNode& material_node, MFnDependencyNod newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); newTexture.FileNameLength = newTexture.FileName.length() + 1; - newTexture.UVTiling[0] = TextureNode.findPlug("RepeatU").asFloat(); - newTexture.UVTiling[1] = TextureNode.findPlug("RepeatV").asFloat(); + MPlug uvRepeatFile = TextureNode.findPlug("repeatUV"); + + uvRepeatFile.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kPlace2dTexture)) { + //C:\Users\kamisama\Desktop\TacticalZ\assets\test + MFnDependencyNode place2DTexture(AllConnections[i].node()); + MPlug uvRepeat = place2DTexture.findPlug("repeatUV"); + + newTexture.UVTiling[0] = uvRepeat.child(0).asFloat(); + newTexture.UVTiling[1] = uvRepeat.child(1).asFloat(); + } + } material_node.SpecularMaps.push_back(newTexture); + if (material_node.type == MaterialNode::MaterialType::Basic) + material_node.type = MaterialNode::MaterialType::SingleTextures; return true; + } else if (AllConnections[i].node().hasFn(MFn::kLayeredTexture)) { + MGlobal::displayInfo(MString() + "find splat map"); + return findSplatTextures(material_node, material_node.SpecularMaps, MFnDependencyNode(AllConnections[i].node())); } } return false; @@ -203,21 +250,133 @@ bool Material::findIncandescenceTexture(MaterialNode& material_node, MFnDependen newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); newTexture.FileNameLength = newTexture.FileName.length() + 1; - newTexture.UVTiling[0] = TextureNode.findPlug("RepeatU").asFloat(); - newTexture.UVTiling[1] = TextureNode.findPlug("RepeatV").asFloat(); + MPlug uvRepeatFile = TextureNode.findPlug("repeatUV"); + + uvRepeatFile.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kPlace2dTexture)) { + MFnDependencyNode place2DTexture(AllConnections[i].node()); + MPlug uvRepeat = place2DTexture.findPlug("repeatUV"); + + newTexture.UVTiling[0] = uvRepeat.child(0).asFloat(); + newTexture.UVTiling[1] = uvRepeat.child(1).asFloat(); + } + } material_node.IncandescenceMaps.push_back(newTexture); + if (material_node.type == MaterialNode::MaterialType::Basic) + material_node.type = MaterialNode::MaterialType::SingleTextures; return true; } else if (AllConnections[i].node().hasFn(MFn::kLayeredTexture)) { - return findSplatTextures(material_node.IncandescenceMaps, MFnDependencyNode(AllConnections[i].node())); + MGlobal::displayInfo(MString() + "find splat map"); + return findSplatTextures(material_node, material_node.IncandescenceMaps, MFnDependencyNode(AllConnections[i].node())); } } return false; } -bool Material::findSplatTextures(std::vector& textureVector, MFnDependencyNode& node) { - return false; +//C:\Users\kamisama\Desktop\TacticalZ\assets\test + +bool Material::findSplatTextures(MaterialNode& material_node, std::vector& textureVector, MFnDependencyNode& node) { + //Get all Inputs in LayeredTexture + MPlug inputs = node.findPlug("inputs"); + MGlobal::displayInfo(MString() + "inputs.numElements(): " + inputs.numElements()); + + MPlugArray AllConnections; + MStatus test; + //Try to find splat texture if using custom splatmap build up. + inputs[0].child(1).connectedTo(AllConnections, true, false); + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kMultiplyDivide)) { + MGlobal::displayInfo(MString() + "found kMultiplyDivide"); + MFnDependencyNode multiplyDivide(AllConnections[i].node()); + multiplyDivide.findPlug("input1", &test).child(0).connectedTo(AllConnections, true, false);; + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kFileTexture)) { + MFnDependencyNode TextureNode(AllConnections[i].node()); + + std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); + m_TexturePaths.push_back(FullPath); + + MString workspace; + MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"), + workspace); + FullPath = FullPath.substr(workspace.length()); + FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); + + MaterialNode::Texture newTexture; + + newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + newTexture.FileNameLength = newTexture.FileName.length() + 1; + + MPlug uvRepeatFile = TextureNode.findPlug("repeatUV"); + + uvRepeatFile.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kPlace2dTexture)) { + MFnDependencyNode place2DTexture(AllConnections[i].node()); + MPlug uvRepeat = place2DTexture.findPlug("repeatUV"); + + newTexture.UVTiling[0] = uvRepeat.child(0).asFloat(); + newTexture.UVTiling[1] = uvRepeat.child(1).asFloat(); + } + } + material_node.SplatMap = newTexture; + material_node.type = MaterialNode::MaterialType::SplatMapping; + } + } + } + } + + for (unsigned int i = 0; i < inputs.numElements(); i++) { + //Get connections to color in input[i] + inputs[i].child(0).connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kFileTexture)) { + MFnDependencyNode TextureNode(AllConnections[i].node()); + + std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); + m_TexturePaths.push_back(FullPath); + + MString workspace; + MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"), + workspace); + FullPath = FullPath.substr(workspace.length()); + FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); + + MaterialNode::Texture newTexture; + + newTexture.FileName = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + newTexture.FileNameLength = newTexture.FileName.length() + 1; + + MPlug uvRepeatFile = TextureNode.findPlug("repeatUV"); + + uvRepeatFile.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kPlace2dTexture)) { + MFnDependencyNode place2DTexture(AllConnections[i].node()); + MPlug uvRepeat = place2DTexture.findPlug("repeatUV"); + + newTexture.UVTiling[0] = uvRepeat.child(0).asFloat(); + newTexture.UVTiling[1] = uvRepeat.child(1).asFloat(); + } + } + textureVector.push_back(newTexture); + break; + } + } + if (AllConnections.length() == 0) { + MaterialNode::Texture newTexture; + newTexture.FileNameLength = 0; + textureVector.push_back(newTexture); + } + } + return true; } // Returns the absolute path for all textures. Use for copying texture files. @@ -244,8 +403,6 @@ std::vector* Material::DoIt(Mesh mesh) meshHasMaterial = true; MaterialStorage.IndexStart = totalIndices; MaterialStorage.IndexEnd = totalIndices + aMeshMaterial.second.size() - 1; - MGlobal::displayInfo("Oh noes, breaking in material"); - break; } totalIndices += aMeshMaterial.second.size(); } @@ -262,7 +419,10 @@ std::vector* Material::DoIt(Mesh mesh) MaterialStorage.ReflectionFactor = 0.0f; MaterialStorage.SpecularExponent = 0.0f; } - + MaterialStorage.NumColorMaps = MaterialStorage.ColorMaps.size(); + MaterialStorage.NumNormalMaps = MaterialStorage.NormalMaps.size(); + MaterialStorage.NumSpecularMaps = MaterialStorage.SpecularMaps.size(); + MaterialStorage.NumIncandescenceMaps = MaterialStorage.IncandescenceMaps.size(); m_AllMaterials.push_back(MaterialStorage); } matIt.next(); diff --git a/tools/MayaExporter/MayaExporter/Material.h b/tools/MayaExporter/MayaExporter/Material.h index 844b3876..d70a6399 100644 --- a/tools/MayaExporter/MayaExporter/Material.h +++ b/tools/MayaExporter/MayaExporter/Material.h @@ -17,6 +17,8 @@ //#define NormalMapSplat 1 << 2 //#define IncandescenceMapSplat 1 << 3 + + class MaterialNode : public OutputData { public: @@ -41,6 +43,10 @@ public: } }; + enum class MaterialType { Basic = 1, SplatMapping, SingleTextures }; + + MaterialType type = MaterialType::Basic; + std::string Name; float ReflectionFactor; @@ -53,11 +59,11 @@ public: unsigned int IndexStart; unsigned int IndexEnd; - char NumColormaps = 0; - char NumSpecularMap = 0; - char NumNormalMap = 0; - char NumIncandescenceMap = 0; - + unsigned char NumColorMaps = 0; + unsigned char NumSpecularMaps = 0; + unsigned char NumNormalMaps = 0; + unsigned char NumIncandescenceMaps = 0; + Texture SplatMap; std::vector ColorMaps; std::vector SpecularMaps; std::vector NormalMaps; @@ -65,6 +71,8 @@ public: virtual void WriteBinary(std::ostream& out) { + + out.write((char*)&type, sizeof(MaterialType)); out.write((char*)&SpecularExponent, sizeof(float)); out.write((char*)&ReflectionFactor, sizeof(float)); @@ -74,30 +82,52 @@ public: out.write((char*)&IndexStart, sizeof(unsigned int)); out.write((char*)&IndexEnd, sizeof(unsigned int)); + if (type != MaterialType::Basic) { + if (type == MaterialType::SplatMapping) { + SplatMap.WriteBinary(out); + } + out.write((char*)&NumColorMaps, sizeof(unsigned char)); + out.write((char*)&NumSpecularMaps, sizeof(unsigned char)); + out.write((char*)&NumNormalMaps, sizeof(unsigned char)); + out.write((char*)&NumIncandescenceMaps, sizeof(unsigned char)); + } - out.write((char*)&NumColormaps, sizeof(char)); - out.write((char*)&NumSpecularMap, sizeof(char)); - out.write((char*)&NumNormalMap, sizeof(char)); - out.write((char*)&NumIncandescenceMap, sizeof(char)); - - for(auto aTexture : ColorMaps) { - aTexture.WriteBinary(out); - } - for (auto aTexture : SpecularMaps) { - aTexture.WriteBinary(out); - } - for (auto aTexture : NormalMaps) { - aTexture.WriteBinary(out); - } - for (auto aTexture : IncandescenceMaps) { - aTexture.WriteBinary(out); + if (type != MaterialType::Basic) { + for (auto aTexture : ColorMaps) { + aTexture.WriteBinary(out); + } + for (auto aTexture : SpecularMaps) { + aTexture.WriteBinary(out); + } + for (auto aTexture : NormalMaps) { + aTexture.WriteBinary(out); + } + for (auto aTexture : IncandescenceMaps) { + aTexture.WriteBinary(out); + } } } virtual void WriteASCII(std::ostream& out) const { out << "New Material _ not in binary" << endl; - out << "number of indices: " << Name << " _ not in binary" << endl; + + out << "MaterialType(enum): "; + switch (type) { + case MaterialType::Basic: + out << "Basic"; + break; + case MaterialType::SplatMapping: + out << "SplatMapping"; + break; + case MaterialType::SingleTextures: + out << "SingleTextures"; + break; + }; + + out << endl; + + out << "Material Name: " << Name << " _ not in binary" << endl; out << "SpecularExponent: " << SpecularExponent << endl; out << "ReflectionFactor: " << ReflectionFactor << endl; @@ -107,37 +137,38 @@ public: out << "IndexStart: " << IndexStart << endl; out << "IndexEnd: " << IndexEnd << endl; - if (NumColormaps > 0) - out << "NumColormaps: " << NumColormaps << endl; + switch (type) { + case MaterialType::SplatMapping: + out << "SplatMap _ not in binary " << endl; + SplatMap.WriteASCII(out); + //Intended fall trought + case MaterialType::SingleTextures: + out << "NumColormaps (is unsigned char in Binary): " << ((unsigned int)NumColorMaps) << endl; + out << "NumSpecularMap (is unsigned char in Binary): " << ((unsigned int)NumSpecularMaps) << endl; + out << "NumNormalMap (is unsigned char in Binary): " << ((unsigned int)NumNormalMaps) << endl; + out << "NumIncandescenceMap (is unsigned char in Binary): " << ((unsigned int)NumIncandescenceMaps )<< endl; - if (NumSpecularMap > 0) - out << "NumSpecularMap: " << NumSpecularMap << endl; - - if (NumNormalMap > 0) - out << "NumNormalMap: " << NumNormalMap << endl; - - if (NumIncandescenceMap > 0) - out << "NumIncandescenceMap: " << NumIncandescenceMap << endl; + out << "ColorMaps _ not in binary " << endl; + for (auto aTexture : ColorMaps) { + aTexture.WriteASCII(out); + } - out << "ColorMaps _ not in binary " << endl; - for (auto aTexture : ColorMaps) { - aTexture.WriteASCII(out); - } + out << "SpecularMaps _ not in binary " << endl; + for (auto aTexture : SpecularMaps) { + aTexture.WriteASCII(out); + } - out << "SpecularMaps _ not in binary " << endl; - for (auto aTexture : SpecularMaps) { - aTexture.WriteASCII(out); - } + out << "NormalMaps _ not in binary " << endl; + for (auto aTexture : NormalMaps) { + aTexture.WriteASCII(out); + } - out << "NormalMaps _ not in binary " << endl; - for (auto aTexture : NormalMaps) { - aTexture.WriteASCII(out); - } - - out << "IncandescenceMaps _ not in binary " << endl; - for (auto aTexture : IncandescenceMaps) { - aTexture.WriteASCII(out); - } + out << "IncandescenceMaps _ not in binary " << endl; + for (auto aTexture : IncandescenceMaps) { + aTexture.WriteASCII(out); + } + break; + }; } }; @@ -158,7 +189,7 @@ private: bool findNormalTexture(MaterialNode& material_node, MFnDependencyNode& node); bool findSpecularTexture(MaterialNode& material_node, MFnDependencyNode& node); bool findIncandescenceTexture(MaterialNode& material_node, MFnDependencyNode& node); - bool findSplatTextures(std::vector& textureVector, MFnDependencyNode& node); + bool findSplatTextures(MaterialNode& material_node, std::vector& textureVector, MFnDependencyNode& node); void grabLambertProperties(MaterialNode& material_node, MFnDependencyNode& node); void grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node); void grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node); diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 01737683..52b1392e 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -8,91 +8,91 @@ MeshClass::MeshClass() } -std::map MeshClass::GetWeightData() -{ - MS status; - map weightMap; - - MItDependencyNodes it(MFn::kSkinClusterFilter); - - while (!it.isDone()) { - - MObject object = it.thisNode(&status); - if (status != MS::kSuccess) { - MGlobal::displayError(MString() + " it.thisNode() ERROR: " + status.errorString()); - break; - } - MFnSkinCluster skinCluster(object, &status); - if (status != MS::kSuccess) { - MGlobal::displayError(MString() + "skinCluster() ERROR: " + status.errorString()); - break; - } - MDagPathArray influences; - - unsigned int nrOfInfluences = skinCluster.influenceObjects(influences,&status); - if (status != MS::kSuccess) { - MGlobal::displayError(MString() + "skinCluster.influenceObjects() ERROR: " + status.errorString()); - break; - } - - unsigned int index; - index = skinCluster.indexForOutputConnection(0,&status); - if (status != MS::kSuccess) { - MGlobal::displayError(MString() + "skinCluster.indexForOutputConnection() ERROR: " + status.errorString()); - break; - } - MDagPath skinPath; - status = skinCluster.getPathAtIndex(index, skinPath); - if (status != MS::kSuccess) { - MGlobal::displayError(MString() + "skinCluster.getPathAtIndex() ERROR: " + status.errorString()); - break; - } - - MItGeometry geomIter(skinPath); - //for (unsigned int i = 0; i < nrOfInfluences; i++) { - // MGlobal::displayInfo(MString() + " Influence object name: " + influences[i].partialPathName().asChar()); - //} - WeightInfo weightInfo; - - while (!geomIter.isDone()) { - MObject comp = geomIter.component(&status); - if (status != MS::kSuccess) { - MGlobal::displayError(MString() + "geomIter.component() ERROR: " + status.errorString()); - break; - } - MFloatArray weights; - unsigned int influenceCount; - status = skinCluster.getWeights(skinPath, comp, weights, influenceCount); - if (status != MS::kSuccess) { - MGlobal::displayError(MString() + "skinCluster.getWeights() ERROR: " + status.errorString()); - break; - } - MFnDependencyNode test(comp); - unsigned int nrOfWeights = 0; - - for (unsigned int j = 0; j < weights.length() && nrOfWeights != 4; j++) { - if (weights[j] > 0.00001) { - weightInfo.BoneWeights[nrOfWeights] = weights[j]; - weightInfo.BoneIndices[nrOfWeights] = j; - nrOfWeights++; - } - } - - float totalWeight = 0.0f; - for (unsigned int i = 0; i < 4; i++) { - totalWeight += weightInfo.BoneWeights[i]; - } - for (unsigned int i = 0; i < 4; i++) { - weightInfo.BoneWeights[i] /= totalWeight; - } - weightMap[geomIter.index()] = weightInfo; - - geomIter.next(); - } - it.next(); - } - return weightMap; -} +//std::map MeshClass::GetWeightData() +//{ +// MS status; +// map weightMap; +// +// MItDependencyNodes it(MFn::kSkinClusterFilter); +// +// while (!it.isDone()) { +// +// MObject object = it.thisNode(&status); +// if (status != MS::kSuccess) { +// MGlobal::displayError(MString() + " it.thisNode() ERROR: " + status.errorString()); +// break; +// } +// MFnSkinCluster skinCluster(object, &status); +// if (status != MS::kSuccess) { +// MGlobal::displayError(MString() + "skinCluster() ERROR: " + status.errorString()); +// break; +// } +// MDagPathArray influences; +// +// unsigned int nrOfInfluences = skinCluster.influenceObjects(influences,&status); +// if (status != MS::kSuccess) { +// MGlobal::displayError(MString() + "skinCluster.influenceObjects() ERROR: " + status.errorString()); +// break; +// } +// +// unsigned int index; +// index = skinCluster.indexForOutputConnection(0,&status); +// if (status != MS::kSuccess) { +// MGlobal::displayError(MString() + "skinCluster.indexForOutputConnection() ERROR: " + status.errorString()); +// break; +// } +// MDagPath skinPath; +// status = skinCluster.getPathAtIndex(index, skinPath); +// if (status != MS::kSuccess) { +// MGlobal::displayError(MString() + "skinCluster.getPathAtIndex() ERROR: " + status.errorString()); +// break; +// } +// +// MItGeometry geomIter(skinPath); +// //for (unsigned int i = 0; i < nrOfInfluences; i++) { +// // MGlobal::displayInfo(MString() + " Influence object name: " + influences[i].partialPathName().asChar()); +// //} +// WeightInfo weightInfo; +// +// while (!geomIter.isDone()) { +// MObject comp = geomIter.component(&status); +// if (status != MS::kSuccess) { +// MGlobal::displayError(MString() + "geomIter.component() ERROR: " + status.errorString()); +// break; +// } +// MFloatArray weights; +// unsigned int influenceCount; +// status = skinCluster.getWeights(skinPath, comp, weights, influenceCount); +// if (status != MS::kSuccess) { +// MGlobal::displayError(MString() + "skinCluster.getWeights() ERROR: " + status.errorString()); +// break; +// } +// MFnDependencyNode test(comp); +// unsigned int nrOfWeights = 0; +// +// for (unsigned int j = 0; j < weights.length() && nrOfWeights != 4; j++) { +// if (weights[j] > 0.00001) { +// weightInfo.BoneWeights[nrOfWeights] = weights[j]; +// weightInfo.BoneIndices[nrOfWeights] = j; +// nrOfWeights++; +// } +// } +// +// float totalWeight = 0.0f; +// for (unsigned int i = 0; i < 4; i++) { +// totalWeight += weightInfo.BoneWeights[i]; +// } +// for (unsigned int i = 0; i < 4; i++) { +// weightInfo.BoneWeights[i] /= totalWeight; +// } +// weightMap[geomIter.index()] = weightInfo; +// +// geomIter.next(); +// } +// it.next(); +// } +// return weightMap; +//} Mesh MeshClass::GetMeshData(MObjectArray object) { @@ -317,7 +317,7 @@ Mesh MeshClass::GetMeshData(MObjectArray object) } for (unsigned int i = 0; i < 4; i++) { - thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight; + //thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight; } } else { thisVertex.useWeights = false; diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index 87e0ce19..eda79805 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -62,7 +62,7 @@ public: class Mesh : public OutputData { public: - bool hasSkin = false; + bool hasSkin = true; //Should be false by default... Have it true now since pipeline only support skinned vertecies unsigned int NumVertices; unsigned int NumIndices; std::vector Vertices; diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index 49a7309c..2e432476 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -230,7 +230,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MTime time = MAnimControl::currentTime(); MFnTransform thisJoint(jointIt.currentItem()); - MTransformationMatrix TransformationMatrix = thisJoint.transformationMatrix(); + MTransformationMatrix transformationMatrix = thisJoint.transformationMatrix(); double doubleMat[4][4]; @@ -256,7 +256,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MMatrix LastJointMatrix(doubleMat); //Is same as last KeyFrame - if (LastJointMatrix.isEquivalent(transformationMatrix)) { + if (LastJointMatrix.isEquivalent(transformationMatrix.asMatrix())) { //jointID++; //jointIt.next(); currentFrame++; @@ -264,7 +264,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e continue; } else if(!haxBool){ haxBool = true; - MTransformationMatrix TransformationMatrix = LastJointMatrix; + MTransformationMatrix LastJointTransformationMatrix = LastJointMatrix; MObject jointOrientObj = thisJoint.attribute("jointOrient"); MFnNumericAttribute jointOrient(jointOrientObj); double jointOrientDouble[3]; @@ -279,7 +279,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MQuaternion jo = joEuler.asQuaternion(); double tmp[4]; - TransformationMatrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); + LastJointTransformationMatrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); MQuaternion rotation(tmp); rotation = rotation * jo; @@ -294,11 +294,11 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e previousKeyFrame.Rotation[1] = tmp[1]; previousKeyFrame.Rotation[2] = tmp[2]; previousKeyFrame.Rotation[3] = tmp[3]; - TransformationMatrix.getTranslation(MSpace::kTransform).get(tmp); + LastJointTransformationMatrix.getTranslation(MSpace::kTransform).get(tmp); previousKeyFrame.Position[0] = tmp[0]; previousKeyFrame.Position[1] = tmp[1]; previousKeyFrame.Position[2] = tmp[2]; - TransformationMatrix.getScale(tmp, MSpace::kTransform); + LastJointTransformationMatrix.getScale(tmp, MSpace::kTransform); previousKeyFrame.Scale[0] = tmp[0]; previousKeyFrame.Scale[1] = tmp[1]; previousKeyFrame.Scale[2] = tmp[2]; @@ -307,7 +307,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e } } - transformationMatrix.get(doubleMat); + transformationMatrix.asMatrix().get(doubleMat); //Save transformationMatrix to joinCheckMap joinCheckMap[thisJoint.name().asChar()][0][0] = doubleMat[0][0]; @@ -327,8 +327,6 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e joinCheckMap[thisJoint.name().asChar()][3][2] = doubleMat[3][2]; joinCheckMap[thisJoint.name().asChar()][3][3] = doubleMat[3][3]; - MTransformationMatrix TransformationMatrix = thisJoint.transformation(); - if (currentFrame == startFrame) { MPlug thisJointBindPose = thisJoint.findPlug("bindPose"); MDataHandle DataHandle; @@ -348,7 +346,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e thisJointBindPoseMatrix = thisJointBindPoseMatrix * parentBindPoseMatrix.inverse(); } - if (thisJointBindPoseMatrix.isEquivalent(TransformationMatrix.asMatrix())) { + if (thisJointBindPoseMatrix.isEquivalent(transformationMatrix.asMatrix())) { //jointID++; //jointIt.next(); currentFrame++; @@ -372,7 +370,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MQuaternion jo = joEuler.asQuaternion(); double tmp[4]; - TransformationMatrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); + transformationMatrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); MQuaternion rotation(tmp); rotation = rotation * jo; @@ -386,11 +384,11 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e thisKeyFrame.Rotation[1] = tmp[1]; thisKeyFrame.Rotation[2] = tmp[2]; thisKeyFrame.Rotation[3] = tmp[3]; - TransformationMatrix.getTranslation(MSpace::kTransform).get(tmp); + transformationMatrix.getTranslation(MSpace::kTransform).get(tmp); thisKeyFrame.Position[0] = tmp[0]; thisKeyFrame.Position[1] = tmp[1]; thisKeyFrame.Position[2] = tmp[2]; - TransformationMatrix.getScale(tmp, MSpace::kTransform); + transformationMatrix.getScale(tmp, MSpace::kTransform); thisKeyFrame.Scale[0] = tmp[0]; thisKeyFrame.Scale[1] = tmp[1]; thisKeyFrame.Scale[2] = tmp[2]; From 43719f8304c924cc63e8cf8a6b6ef796fa5f819b Mon Sep 17 00:00:00 2001 From: Teejoon Date: Sun, 7 Feb 2016 15:27:26 +0100 Subject: [PATCH 089/131] Added texture tiling to shaders (exkluding ExplosinEffects) --- include/Engine/Rendering/DrawFinalPass.h | 2 +- include/Engine/Rendering/ModelJob.h | 36 +++---- .../Schema/Entities/SplatMapTesWorld.xml | 21 ++++ resources/Shaders/ForwardPlus.frag.glsl | 13 ++- .../Shaders/ForwardPlusSplatMap.frag.glsl | 70 ++++++++---- src/Engine/Rendering/DrawFinalPass.cpp | 102 +++++++++++------- 6 files changed, 162 insertions(+), 82 deletions(-) create mode 100644 resources/Schema/Entities/SplatMapTesWorld.xml diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index a32c562b..830ded3c 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -36,7 +36,7 @@ private: void BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); void BindExplosionTextures(std::shared_ptr& job); - void BindModelTextures(std::shared_ptr& job); + void BindModelTextures(GLuint shaderHandle, std::shared_ptr& job); Texture* m_WhiteTexture; Texture* m_BlackTexture; diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 2c662f09..fe8fe26f 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -46,19 +46,19 @@ struct ModelJob : RenderJob ::RawModel::MaterialSingleTextures* singleTextures = static_cast<::RawModel::MaterialSingleTextures*>(matProp.material); TextureID = (singleTextures->ColorMap.Texture) ? singleTextures->ColorMap.Texture->ResourceID : 0; if (modelComponent["DiffuseTexture"]) { - DiffuseTexture.push_back(singleTextures->ColorMap.Texture.get()); + DiffuseTexture.push_back(&singleTextures->ColorMap); } if (modelComponent["NormalMap"]) { - NormalTexture.push_back(singleTextures->NormalMap.Texture.get()); + NormalTexture.push_back(&singleTextures->NormalMap); } if (modelComponent["SpecularMap"]) { - SpecularTexture.push_back(singleTextures->SpecularMap.Texture.get()); + SpecularTexture.push_back(&singleTextures->SpecularMap); } if (modelComponent["GlowMap"]) { - IncandescenceTexture.push_back(singleTextures->IncandescenceMap.Texture.get()); + IncandescenceTexture.push_back(&singleTextures->IncandescenceMap); } } break; @@ -72,30 +72,30 @@ struct ModelJob : RenderJob } ::RawModel::MaterialSplatMapping* SplatTextures = static_cast<::RawModel::MaterialSplatMapping*>(matProp.material); - SplatMap = SplatTextures->SplatMap.Texture.get(); + SplatMap = &SplatTextures->SplatMap; TextureID = (SplatTextures->ColorMaps[0].Texture) ? SplatTextures->ColorMaps[0].Texture->ResourceID : 0; if (modelComponent["DiffuseTexture"]) { - for (auto texture : SplatTextures->ColorMaps) { - DiffuseTexture.push_back(texture.Texture.get()); + for (auto& texture : SplatTextures->ColorMaps) { + DiffuseTexture.push_back(&texture); } } if (modelComponent["NormalMap"]) { - for (auto texture : SplatTextures->NormalMaps) { - NormalTexture.push_back(texture.Texture.get()); + for (auto& texture : SplatTextures->NormalMaps) { + NormalTexture.push_back(&texture); } } if (modelComponent["SpecularMap"]) { - for (auto texture : SplatTextures->SpecularMaps) { - SpecularTexture.push_back(texture.Texture.get()); + for (auto& texture : SplatTextures->SpecularMaps) { + SpecularTexture.push_back(&texture); } } if (modelComponent["GlowMap"]) { - for (auto texture : SplatTextures->IncandescenceMaps) { - IncandescenceTexture.push_back(texture.Texture.get()); + for (auto& texture : SplatTextures->IncandescenceMaps) { + IncandescenceTexture.push_back(&texture); } } } @@ -132,11 +132,11 @@ struct ModelJob : RenderJob ::RawModel::MaterialType Type; EntityID Entity; glm::mat4 Matrix; - const Texture* SplatMap; - std::vector DiffuseTexture; - std::vector NormalTexture; - std::vector SpecularTexture; - std::vector IncandescenceTexture; + const ::RawModel::TextureProperties* SplatMap; + std::vector DiffuseTexture; + std::vector NormalTexture; + std::vector SpecularTexture; + std::vector IncandescenceTexture; float Shininess = 0.f; glm::vec4 Color; const ::Model* Model = nullptr; diff --git a/resources/Schema/Entities/SplatMapTesWorld.xml b/resources/Schema/Entities/SplatMapTesWorld.xml new file mode 100644 index 00000000..11660a63 --- /dev/null +++ b/resources/Schema/Entities/SplatMapTesWorld.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + Models/Test/SplatMapTest.mesh + + + + + + + + diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index c09e0438..471ee20b 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -9,6 +9,11 @@ uniform vec2 ScreenDimensions; uniform vec4 FillColor; uniform vec4 AmbientColor; uniform float FillPercentage; + +uniform vec2 DiffuseUVRepeat; +uniform vec2 NormalUVRepeat; +uniform vec2 SpecularUVRepeat; +uniform vec2 GlowUVRepeat; layout (binding = 0) uniform sampler2D DiffuseTexture; layout (binding = 1) uniform sampler2D NormalMapTexture; layout (binding = 2) uniform sampler2D SpecularMapTexture; @@ -114,11 +119,11 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu void main() { - vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); - vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate); - vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate); + vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate * DiffuseUVRepeat); + vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate * GlowUVRepeat); + vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate * SpecularUVRepeat); vec4 position = V * M * vec4(Input.Position, 1.0); - vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate, NormalMapTexture); + vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate * NormalUVRepeat, NormalMapTexture); normal = normalize(normal); //vec4 normal = normalize(V * vec4(Input.Normal, 0.0)); vec4 viewVec = normalize(-position); diff --git a/resources/Shaders/ForwardPlusSplatMap.frag.glsl b/resources/Shaders/ForwardPlusSplatMap.frag.glsl index fe26469e..c4908534 100644 --- a/resources/Shaders/ForwardPlusSplatMap.frag.glsl +++ b/resources/Shaders/ForwardPlusSplatMap.frag.glsl @@ -9,6 +9,28 @@ uniform vec4 DiffuseColor; uniform vec4 FillColor; uniform vec4 Color; uniform vec4 AmbientColor; + +//Get bineded at the same time as the textures +uniform vec2 DiffuseUVRepeat1; +uniform vec2 DiffuseUVRepeat2; +uniform vec2 DiffuseUVRepeat3; +uniform vec2 DiffuseUVRepeat4; +uniform vec2 DiffuseUVRepeat5; +uniform vec2 NormalUVRepeat1; +uniform vec2 NormalUVRepeat2; +uniform vec2 NormalUVRepeat3; +uniform vec2 NormalUVRepeat4; +uniform vec2 NormalUVRepeat5; +uniform vec2 SpecularUVRepeat1; +uniform vec2 SpecularUVRepeat2; +uniform vec2 SpecularUVRepeat3; +uniform vec2 SpecularUVRepeat4; +uniform vec2 SpecularUVRepeat5; +uniform vec2 GlowUVRepeat1; +uniform vec2 GlowUVRepeat2; +uniform vec2 GlowUVRepeat3; +uniform vec2 GlowUVRepeat4; +uniform vec2 GlowUVRepeat5; layout (binding = 0) uniform sampler2D SplatMapTexture; layout (binding = 1) uniform sampler2D DiffuseTexture1; layout (binding = 2) uniform sampler2D DiffuseTexture2; @@ -131,12 +153,13 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu #define TEXTURE_TILE 5.0 -vec4 CalcBlendedTexel(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, sampler2D A, sampler2D D, vec2 tileValues){ - vec4 R_Channel = texture2D(R, Input.TextureCoordinate * tileValues); - vec4 G_Channel = texture2D(G, Input.TextureCoordinate * tileValues); - vec4 B_Channel = texture2D(B, Input.TextureCoordinate * tileValues); - vec4 A_Channel = texture2D(A, Input.TextureCoordinate * tileValues); - vec4 D_Channel = texture2D(D, Input.TextureCoordinate * tileValues); +vec4 CalcBlendedTexel(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, sampler2D A, sampler2D D, + vec2 R_TileValues, vec2 G_TileValues, vec2 B_TileValues, vec2 A_TileValues, vec2 D_TileValues){ + vec4 R_Channel = texture2D(R, Input.TextureCoordinate * R_TileValues); + vec4 G_Channel = texture2D(G, Input.TextureCoordinate * G_TileValues); + vec4 B_Channel = texture2D(B, Input.TextureCoordinate * B_TileValues); + vec4 A_Channel = texture2D(A, Input.TextureCoordinate * A_TileValues); + vec4 D_Channel = texture2D(D, Input.TextureCoordinate * D_TileValues); float total = blendValue.r + blendValue.g + blendValue.b + blendValue.a; if(total > 1.0f){ @@ -154,18 +177,23 @@ vec4 CalcBlendedTexel(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, sa + D_percent * D_Channel; } -vec4 CalcBlendedNormal(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, sampler2D A, sampler2D D, vec2 tileValues){ +vec4 CalcBlendedNormal(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, sampler2D A, sampler2D D, + vec2 R_TileValues, vec2 G_TileValues, vec2 B_TileValues, vec2 A_TileValues, vec2 D_TileValues){ mat3 TBN = mat3(Input.Tangent, Input.BiTangent, Input.Normal); - vec3 R_Channel = texture(R, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); - vec3 G_Channel = texture(G, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); - vec3 B_Channel = texture(B, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); - vec3 A_Channel = texture(A, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); - vec3 D_Channel = texture(D, Input.TextureCoordinate * tileValues).xyz * 2.0 - vec3(1.0); + vec3 R_Channel = texture(R, Input.TextureCoordinate * R_TileValues).xyz * 2.0 - vec3(1.0); + vec3 G_Channel = texture(G, Input.TextureCoordinate * G_TileValues).xyz * 2.0 - vec3(1.0); + vec3 B_Channel = texture(B, Input.TextureCoordinate * B_TileValues).xyz * 2.0 - vec3(1.0); + vec3 A_Channel = texture(A, Input.TextureCoordinate * A_TileValues).xyz * 2.0 - vec3(1.0); + vec3 D_Channel = texture(D, Input.TextureCoordinate * D_TileValues).xyz * 2.0 - vec3(1.0); - if(blendValue.length() > 1.0f){ - blendValue = normalize(blendValue); + float total = blendValue.r + blendValue.g + blendValue.b + blendValue.a; + if(total > 1.0f){ + blendValue.r / total; + blendValue.g / total; + blendValue.b / total; + blendValue.a / total; } - float D_percent = 1.0f - blendValue.r - blendValue.g - blendValue.b - blendValue.a; + float D_percent = clamp( 1.0f - total, 0.0f, 1.0f); vec3 Normal_result = blendValue.r * R_Channel + blendValue.g * G_Channel @@ -180,12 +208,16 @@ void main() { vec4 splatTexel = texture2D(SplatMapTexture, Input.TextureCoordinate); - vec4 diffuseTexel = CalcBlendedTexel(splatTexel, DiffuseTexture1, DiffuseTexture2, DiffuseTexture3, DiffuseTexture4, DiffuseTexture5, vec2(TEXTURE_TILE, TEXTURE_TILE)); - vec4 glowTexel = CalcBlendedTexel(splatTexel, GlowMapTexture1, GlowMapTexture2, GlowMapTexture3, GlowMapTexture4, GlowMapTexture5, vec2(TEXTURE_TILE, TEXTURE_TILE)); - vec4 specularTexel = CalcBlendedTexel(splatTexel, SpecularMapTexture1, SpecularMapTexture2, SpecularMapTexture3, SpecularMapTexture4, SpecularMapTexture5, vec2(TEXTURE_TILE, TEXTURE_TILE)); + vec4 diffuseTexel = CalcBlendedTexel(splatTexel, DiffuseTexture1, DiffuseTexture2, DiffuseTexture3, DiffuseTexture4, DiffuseTexture5, + DiffuseUVRepeat1, DiffuseUVRepeat2, DiffuseUVRepeat3, DiffuseUVRepeat4, DiffuseUVRepeat5); + vec4 glowTexel = CalcBlendedTexel(splatTexel, GlowMapTexture1, GlowMapTexture2, GlowMapTexture3, GlowMapTexture4, GlowMapTexture5, + GlowUVRepeat1, GlowUVRepeat2, GlowUVRepeat3, GlowUVRepeat4, GlowUVRepeat5); + vec4 specularTexel = CalcBlendedTexel(splatTexel, SpecularMapTexture1, SpecularMapTexture2, SpecularMapTexture3, SpecularMapTexture4, SpecularMapTexture5, + SpecularUVRepeat1, SpecularUVRepeat2, SpecularUVRepeat3, SpecularUVRepeat4, SpecularUVRepeat5); vec4 position = V * M * vec4(Input.Position, 1.0); //vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate, SplatMapTexture); - vec4 normal = V * CalcBlendedNormal(splatTexel, NormalMapTexture1, NormalMapTexture2, NormalMapTexture3, NormalMapTexture4, NormalMapTexture5, vec2(TEXTURE_TILE, TEXTURE_TILE)); + vec4 normal = V * CalcBlendedNormal(splatTexel, NormalMapTexture1, NormalMapTexture2, NormalMapTexture3, NormalMapTexture4, NormalMapTexture5, + NormalUVRepeat1, NormalUVRepeat2, NormalUVRepeat3, NormalUVRepeat4, NormalUVRepeat5); normal = normalize(normal); //vec4 normal = normalize(V * vec4(Input.Normal, 0.0)); vec4 viewVec = normalize(-position); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 1ceddb4e..3c4406fe 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -190,6 +190,10 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& GLERROR("Bind Forward program"); //bind uniforms BindModelUniforms(forwardHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardHandle, modelJob); + GLERROR("asdasd"); + break; } case RawModel::MaterialType::SplatMapping: @@ -198,16 +202,14 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& GLERROR("Bind SplatMap program"); //bind uniforms BindModelUniforms(forwardSplatHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatHandle, modelJob); + GLERROR("asdasd"); + break; } } - //bind textures - BindModelTextures(modelJob); - GLERROR("asdasd"); - - - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { if (modelJob->Animation != nullptr) { @@ -294,120 +296,140 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job) { glActiveTexture(GL_TEXTURE0); - if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->m_Texture); //JOHAN TODO: support multiple diffuse Textures + if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->Texture->m_Texture); //JOHAN TODO: support multiple diffuse Textures } else { glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); } glActiveTexture(GL_TEXTURE1); - if (job->NormalTexture.size() > 0 && job->NormalTexture[0] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->m_Texture); //JOHAN TODO: support multiple diffuse Textures + if (job->NormalTexture.size() > 0 && job->NormalTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->Texture->m_Texture); //JOHAN TODO: support multiple diffuse Textures } else { glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); } glActiveTexture(GL_TEXTURE2); - if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->m_Texture); //JOHAN TODO: support multiple diffuse Textures + if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->Texture->m_Texture); //JOHAN TODO: support multiple diffuse Textures } else { glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); } glActiveTexture(GL_TEXTURE3); - if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->m_Texture); //JOHAN TODO: support multiple diffuse Textures + if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->Texture->m_Texture); //JOHAN TODO: support multiple diffuse Textures } else { glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); } } -void DrawFinalPass::BindModelTextures(std::shared_ptr& job) +void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptr& job) { switch (job->Type) { case RawModel::MaterialType::SingleTextures: case RawModel::MaterialType::Basic: { glActiveTexture(GL_TEXTURE0); - if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->m_Texture); + if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(job->DiffuseTexture[0]->UVRepeat)); } else { glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } glActiveTexture(GL_TEXTURE1); - if (job->NormalTexture.size() > 0 && job->NormalTexture[0] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->m_Texture); + if (job->NormalTexture.size() > 0 && job->NormalTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(job->NormalTexture[0]->UVRepeat)); } else { glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } glActiveTexture(GL_TEXTURE2); - if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->m_Texture); + if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(job->SpecularTexture[0]->UVRepeat)); } else { glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } glActiveTexture(GL_TEXTURE3); - if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->m_Texture); + if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(job->IncandescenceTexture[0]->UVRepeat)); } else { glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } break; } case RawModel::MaterialType::SplatMapping: { glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, job->SplatMap->m_Texture); + glBindTexture(GL_TEXTURE_2D, job->SplatMap->Texture->m_Texture); int texturePosition = GL_TEXTURE1; + //Bind 5 diffuse textures + std::string UniformName = "DiffuseUVRepeat"; for (unsigned int i = 0; i < 5; i++) { glActiveTexture(texturePosition); - if (job->DiffuseTexture.size() > i && job->DiffuseTexture[i] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[i]->m_Texture); - } - else { + if (job->DiffuseTexture.size() > i && job->DiffuseTexture[i]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[i]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(job->DiffuseTexture[i]->UVRepeat)); + } else { glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } texturePosition++; } + //Bind 5 Normal textures + UniformName = "NormalUVRepeat"; for (unsigned int i = 0; i < 5; i++) { glActiveTexture(texturePosition); - if (job->NormalTexture.size() > i && job->NormalTexture[i] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->NormalTexture[i]->m_Texture); - } - else { + if (job->NormalTexture.size() > i && job->NormalTexture[i]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->NormalTexture[i]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(job->NormalTexture[i]->UVRepeat)); + } else { glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } texturePosition++; } + //Bind 5 Specular textures + UniformName = "SpecularUVRepeat"; for (unsigned int i = 0; i < 5; i++) { glActiveTexture(texturePosition); - if (job->SpecularTexture.size() > i && job->SpecularTexture[i] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[i]->m_Texture); - } - else { + if (job->SpecularTexture.size() > i && job->SpecularTexture[i]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[i]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(job->SpecularTexture[i]->UVRepeat)); + } else { glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } texturePosition++; } + //Bind 5 Incandescence textures + UniformName = "GlowUVRepeat"; for (unsigned int i = 0; i < 5; i++) { glActiveTexture(texturePosition); - if (job->IncandescenceTexture.size() > i && job->IncandescenceTexture[i] != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[i]->m_Texture); - } - else { + if (job->IncandescenceTexture.size() > i && job->IncandescenceTexture[i]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[i]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(job->IncandescenceTexture[i]->UVRepeat)); + } else { glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } texturePosition++; } From ce228541689d695c7a09ef96527dc572a874193e Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Mon, 8 Feb 2016 11:22:28 +0100 Subject: [PATCH 090/131] HealthPickups are now based on a percentage of player maxhealth. You can no longer pickup healthpacks if you are at max health. You can no longer gain more than maxHealth. --- include/Game/Systems/HealthSystem.h | 1 + resources/Schema/Components/HealthPickup.xsd | 2 +- src/Game/Systems/HealthSystem.cpp | 4 ++-- src/Game/Systems/PickupSpawnSystem.cpp | 10 ++++++++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/Game/Systems/HealthSystem.h b/include/Game/Systems/HealthSystem.h index 46f24630..61456d5d 100644 --- a/include/Game/Systems/HealthSystem.h +++ b/include/Game/Systems/HealthSystem.h @@ -12,6 +12,7 @@ #include #include +#include class HealthSystem : public PureSystem { diff --git a/resources/Schema/Components/HealthPickup.xsd b/resources/Schema/Components/HealthPickup.xsd index c5fae00f..bf3b327c 100644 --- a/resources/Schema/Components/HealthPickup.xsd +++ b/resources/Schema/Components/HealthPickup.xsd @@ -13,7 +13,7 @@ The respawn timer for a health pickup - How much health the player will get when he picks the healthPickup up + How much percent max-health the player will get when he picks the healthPickup up diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 91cae148..94d98222 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -18,7 +18,7 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) ComponentWrapper cHealth = e.Player["Health"]; double& health = cHealth["Health"]; health -= e.Damage; - + if (health <= 0.0) { m_World->DeleteEntity(e.Player.ID); } @@ -30,8 +30,8 @@ bool HealthSystem::OnPlayerHealthPickup(Events::PlayerHealthPickup& e) { ComponentWrapper cHealth = e.Player["Health"]; double& health = cHealth["Health"]; - //NOTE: its possible to get more than MaxHealth health health += e.HealthAmount; + health = std::min(health, (double)cHealth["MaxHealth"]); return true; } diff --git a/src/Game/Systems/PickupSpawnSystem.cpp b/src/Game/Systems/PickupSpawnSystem.cpp index 783f7a62..e9f201c1 100644 --- a/src/Game/Systems/PickupSpawnSystem.cpp +++ b/src/Game/Systems/PickupSpawnSystem.cpp @@ -43,10 +43,16 @@ bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e) if (!e.Trigger.HasComponent("HealthPickup")) { return false; } + double healthGiven = 0.01*(double)e.Trigger["HealthPickup"]["HealthGain"] * (double)e.Entity["Health"]["MaxHealth"]; + //cant pick up healthpacks if you are already at MaxHealth + if ((double)e.Entity["Health"]["Health"] >= (double)e.Entity["Health"]["MaxHealth"]) { + return false; + } + //personEntered = e.Entity, thingEntered = e.Trigger Events::PlayerHealthPickup ePlayerHealthPickup; - ePlayerHealthPickup.HealthAmount = e.Trigger["HealthPickup"]["HealthGain"]; - ePlayerHealthPickup.PlayerHealedID = e.Entity.ID; + ePlayerHealthPickup.HealthAmount = healthGiven; + ePlayerHealthPickup.Player = e.Entity; m_EventBroker->Publish(ePlayerHealthPickup); //copy position, healthgain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object) From 99cbdd3c1e668b85603ed3fa07d5f9f84ff6f7fa Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 8 Feb 2016 11:39:29 +0100 Subject: [PATCH 091/131] Player death effect fixes --- include/Game/Systems/PlayerDeathSystem.h | 3 ++ include/Game/Systems/PlayerSpawnSystem.h | 1 + .../PlayerDeathExplosionWithCamera.xml | 30 +++++++---------- src/Game/Systems/PlayerDeathSystem.cpp | 33 +++++++++++-------- src/Game/Systems/PlayerSpawnSystem.cpp | 4 ++- 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/include/Game/Systems/PlayerDeathSystem.h b/include/Game/Systems/PlayerDeathSystem.h index 7d989dbf..988dad57 100644 --- a/include/Game/Systems/PlayerDeathSystem.h +++ b/include/Game/Systems/PlayerDeathSystem.h @@ -22,5 +22,8 @@ public: private: EventRelay m_OnPlayerDeath; bool OnPlayerDeath(Events::PlayerDeath& e); + + void createDeathEffect(EntityWrapper player); + }; #endif \ No newline at end of file diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index b0ff1d79..f5aa7b82 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -3,6 +3,7 @@ #include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" #include "Core/EPlayerSpawned.h" +#include "Core/EPlayerDeath.h" #include "Rendering/ESetCamera.h" #include "Core/ConfigFile.h" diff --git a/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml b/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml index ff33476d..8a9f5e5b 100644 --- a/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml +++ b/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml @@ -4,17 +4,18 @@ Hold Pos - - 0 - 4 + 2.5 - 0 - 4 - - + true + + + true + 3 + + true Models/AssaultAnimated.mesh @@ -22,24 +23,17 @@ true - + - - 1 - - - 120 - 0.1 - 10000 - + - - + + diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index f7fe1ab5..60c31ce5 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -11,18 +11,31 @@ void PlayerDeathSystem::Update(double dt) } bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) +{ + if (!e.Player.Valid()) { + return false; + } + + createDeathEffect(e.Player); + + // Delete player + m_World->DeleteEntity(e.Player.ID); + + return true; +} + +void PlayerDeathSystem::createDeathEffect(EntityWrapper player) { //load the explosioneffect XML auto deathEffect = ResourceManager::Load("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); - EntityFileParser parser(deathEffect); EntityID deathEffectID = parser.MergeEntities(m_World); EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID); //components that we need from player - auto playerCamera = e.Player.FirstChildByName("Camera"); - auto playerEntityModel = e.Player.FirstChildByName("PlayerModel")["Model"]; - auto playerEntityAnimation = e.Player.FirstChildByName("PlayerModel")["Animation"]; + auto playerCamera = player.FirstChildByName("Camera"); + auto playerEntityModel = player.FirstChildByName("PlayerModel")["Model"]; + auto playerEntityAnimation = player.FirstChildByName("PlayerModel")["Animation"]; //copy the data from player to explisioneffectmodel playerEntityModel.Copy(deathEffectEW["Model"]); @@ -31,20 +44,14 @@ bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) deathEffectEW["Animation"]["Speed"] = 0.0; //copy the models position,orientation - deathEffectEW["Transform"]["Position"] = (glm::vec3)e.Player["Transform"]["Position"]; - deathEffectEW["Transform"]["Orientation"] = (glm::vec3)e.Player["Transform"]["Orientation"]; + deathEffectEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"]; + deathEffectEW["Transform"]["Orientation"] = (glm::vec3)player["Transform"]["Orientation"]; //effect,camera is relative to playersPosition - deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = glm::vec3(0, 0, 0); + //deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = glm::vec3(0, 0, 0); //camera (with lifetime) behind the player auto cam = deathEffectEW.FirstChildByName("Camera"); - cam["Transform"]["Position"] = glm::vec3(0, 2.5f, 1.8f); - cam["Transform"]["Orientation"] = glm::vec3(5.655f, 0, 0); Events::SetCamera eSetCamera; eSetCamera.CameraEntity = cam; m_EventBroker->Publish(eSetCamera); - - //done -> del entity - m_World->DeleteEntity(e.Player.ID); - return true; } diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 7db6e8ff..5f46cce3 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -75,7 +75,9 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) // Check if a player already exists if (m_PlayerEntities.count(e.PlayerID) != 0) { // TODO: Disallow infinite respawning here - m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); + if (m_PlayerEntities[e.PlayerID].Valid()) { + m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); + } } // Store the player for future reference From 94b59af973e0ad7551e8c5b092825d5b1c766724 Mon Sep 17 00:00:00 2001 From: Tleety Date: Mon, 8 Feb 2016 11:47:35 +0100 Subject: [PATCH 092/131] Defender shield should now be working --- .../Rendering/DrawColorCorrectionPass.h | 2 +- include/Engine/Rendering/DrawFinalPass.h | 6 + .../Shaders/DrawColorCorrection.frag.glsl | 13 ++- resources/Shaders/FillDepthBuffer.frag.glsl | 11 ++ resources/Shaders/FillDepthBuffer.vert.glsl | 21 ++++ resources/Shaders/ShieldStencil.frag.glsl | 2 +- .../Rendering/DrawColorCorrectionPass.cpp | 8 +- src/Engine/Rendering/DrawFinalPass.cpp | 105 +++++++++++++++--- src/Engine/Rendering/Renderer.cpp | 2 +- 9 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 resources/Shaders/FillDepthBuffer.frag.glsl create mode 100644 resources/Shaders/FillDepthBuffer.vert.glsl diff --git a/include/Engine/Rendering/DrawColorCorrectionPass.h b/include/Engine/Rendering/DrawColorCorrectionPass.h index fcde73d7..231e2d33 100644 --- a/include/Engine/Rendering/DrawColorCorrectionPass.h +++ b/include/Engine/Rendering/DrawColorCorrectionPass.h @@ -17,7 +17,7 @@ public: void InitializeFrameBuffers(); void InitializeShaderPrograms(); - void Draw(GLuint sceneTexture, GLuint bloomTexture, GLfloat gamma, GLfloat exposure); + void Draw(GLuint sceneTexture, GLuint bloomTexture, GLuint sceneTextureLowRes, GLuint bloomTextureLowRes, GLfloat gamma, GLfloat exposure); private: const IRenderer* m_Renderer; diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index bacc7a8c..28ac958c 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -38,6 +38,7 @@ private: void DrawModelRenderQueues(std::list>& jobs, RenderScene& scene); void DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene); void DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene); + void DrawToDepthBuffer(std::list>& jobs, RenderScene& scene); void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); void BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); @@ -57,6 +58,10 @@ private: GLuint m_BloomTextureLowRes; GLuint m_SceneTextureLowRes; GLuint m_DepthBuffer; + GLuint m_DepthBufferLowRes; + + //maqke this component based i guess? + GLuint m_ShieldPixelRate = 16; const IRenderer* m_Renderer; const LightCullingPass* m_LightCullingPass; @@ -64,6 +69,7 @@ private: ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; ShaderProgram* m_ShieldToStencilProgram; + ShaderProgram* m_FillDepthBufferProgram; }; #endif \ No newline at end of file diff --git a/resources/Shaders/DrawColorCorrection.frag.glsl b/resources/Shaders/DrawColorCorrection.frag.glsl index 91ace0c7..76db3e82 100644 --- a/resources/Shaders/DrawColorCorrection.frag.glsl +++ b/resources/Shaders/DrawColorCorrection.frag.glsl @@ -2,6 +2,8 @@ layout (binding = 0) uniform sampler2D SceneTexture; layout (binding = 1) uniform sampler2D BloomTexture; +layout (binding = 2) uniform sampler2D SceneTextureLowRes; +layout (binding = 3) uniform sampler2D BloomTextureLowRes; uniform float Exposure; uniform float Gamma; @@ -15,10 +17,19 @@ void main() { vec4 hdrColor = texture(SceneTexture, Input.TextureCoordinate); vec4 bloomColor = texture(BloomTexture, Input.TextureCoordinate); + vec4 hdrColorLowRes = texture(SceneTextureLowRes, Input.TextureCoordinate); + vec4 bloomColorLowRes = texture(BloomTextureLowRes, Input.TextureCoordinate); hdrColor += bloomColor; + hdrColorLowRes; + float hdrColorsum = hdrColorLowRes.r + hdrColorLowRes.g + hdrColorLowRes.b; //Toon mapping thingy - vec3 result = vec3(1.0) - exp(-hdrColor.rgb * Exposure); + vec3 result; + if(hdrColorsum > 0.0) { + result = vec3(1.0) - exp(-hdrColorLowRes.rgb * Exposure); + } else { + result = vec3(1.0) - exp(-hdrColor.rgb * Exposure); + } //gamme correction result = pow(result, vec3(1.0 / Gamma)); diff --git a/resources/Shaders/FillDepthBuffer.frag.glsl b/resources/Shaders/FillDepthBuffer.frag.glsl new file mode 100644 index 00000000..a125fc25 --- /dev/null +++ b/resources/Shaders/FillDepthBuffer.frag.glsl @@ -0,0 +1,11 @@ +#version 430 + +in VertexData{ + vec3 Position; +}Input; + +void main() +{ +} + + diff --git a/resources/Shaders/FillDepthBuffer.vert.glsl b/resources/Shaders/FillDepthBuffer.vert.glsl new file mode 100644 index 00000000..ff849790 --- /dev/null +++ b/resources/Shaders/FillDepthBuffer.vert.glsl @@ -0,0 +1,21 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; +layout(location = 5) in vec4 BoneIndices; +layout(location = 6) in vec4 BoneWeights; + + +out VertexData{ + vec3 Position; +}Output; + +void main() +{ + gl_Position = P * V * M * vec4(Position, 1.0); + + Output.Position = Position; +} \ No newline at end of file diff --git a/resources/Shaders/ShieldStencil.frag.glsl b/resources/Shaders/ShieldStencil.frag.glsl index bc114fc9..db88ab24 100644 --- a/resources/Shaders/ShieldStencil.frag.glsl +++ b/resources/Shaders/ShieldStencil.frag.glsl @@ -9,7 +9,7 @@ out vec4 fragmentColor; void main() { - fragmentColor = vec4(0.5, 0.5, 0.5, 0.2); + fragmentColor = vec4(0.5, 0.0, 0.0, 0.0); } diff --git a/src/Engine/Rendering/DrawColorCorrectionPass.cpp b/src/Engine/Rendering/DrawColorCorrectionPass.cpp index 45401bce..bc2c9783 100644 --- a/src/Engine/Rendering/DrawColorCorrectionPass.cpp +++ b/src/Engine/Rendering/DrawColorCorrectionPass.cpp @@ -6,8 +6,6 @@ DrawColorCorrectionPass::DrawColorCorrectionPass(IRenderer* renderer) m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); - //m_Exposure = 0.4; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting. - InitializeShaderPrograms(); } @@ -20,7 +18,7 @@ void DrawColorCorrectionPass::InitializeShaderPrograms() m_ColorCorrectionProgram->Link(); } -void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLfloat gamma, GLfloat exposure) +void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLuint sceneTextureLowRes, GLuint bloomTextureLowRes, GLfloat gamma, GLfloat exposure) { //glBindFramebuffer(GL_FRAMEBUFFER, 0); GLERROR("DrawScreenQuadPass::Draw: Pre"); @@ -35,6 +33,10 @@ void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLf glBindTexture(GL_TEXTURE_2D, sceneTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, bloomTexture); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, sceneTextureLowRes); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, bloomTextureLowRes); glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 0a5c626b..57eecd1a 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -2,8 +2,10 @@ DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass) { + //TODO: Make sure that uniforms are not sent into shader if not needed. m_Renderer = renderer; m_LightCullingPass = lightCullingPass; + m_ShieldPixelRate = 8; InitializeTextures(); InitializeShaderPrograms(); InitializeFrameBuffers(); @@ -37,13 +39,18 @@ void DrawFinalPass::InitializeFrameBuffers() m_FinalPassFrameBuffer.Generate(); GLERROR("FBO generation"); - GenerateTexture(&m_SceneTextureLowRes, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width/16, m_Renderer->GetViewportSize().Height/16), GL_RGB16F, GL_RGB, GL_FLOAT); + glGenRenderbuffers(1, &m_DepthBufferLowRes); + glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBufferLowRes); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, (int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)); + GLERROR("RenderBufferLowRes generation"); + + GenerateTexture(&m_SceneTextureLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST, glm::vec2((int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); - GenerateTexture(&m_BloomTextureLowRes, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width/16, m_Renderer->GetViewportSize().Height/16), GL_RGB16F, GL_RGB, GL_FLOAT); + GenerateTexture(&m_BloomTextureLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST, glm::vec2((int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_FLOAT, 4); //GenerateTexture(&m_StencilTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_STENCIL, GL_STENCIL_INDEX8, GL_INT); - m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_STENCIL_ATTACHMENT))); + m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBufferLowRes, GL_DEPTH_STENCIL_ATTACHMENT))); //m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_StencilTexture, GL_STENCIL_ATTACHMENT))); m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_SceneTextureLowRes, GL_COLOR_ATTACHMENT0))); m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_BloomTextureLowRes, GL_COLOR_ATTACHMENT1))); @@ -79,6 +86,12 @@ void DrawFinalPass::InitializeShaderPrograms() m_ShieldToStencilProgram->Link(); GLERROR("Creating Shield program"); + m_FillDepthBufferProgram = ResourceManager::Load("#FillDepthBufferProgram"); + m_FillDepthBufferProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/FillDepthBuffer.vert.glsl"))); + m_FillDepthBufferProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/FillDepthBuffer.frag.glsl"))); + m_FillDepthBufferProgram->Compile(); + m_FillDepthBufferProgram->Link(); + GLERROR("Creating DepthFill program"); } void DrawFinalPass::Draw(RenderScene& scene) @@ -122,36 +135,59 @@ void DrawFinalPass::Draw(RenderScene& scene) DrawFinalPassState* stateLowRes = new DrawFinalPassState(m_FinalPassFrameBufferLowRes.GetHandle()); //Draw the lowres texture that will be shown behind the shield. - if (scene.ClearDepth) { - glClear(GL_DEPTH_BUFFER_BIT); - } - //TODO: Do we need check for this or will it be per scene always? - //glClearStencil(0x00); - //glClear(GL_STENCIL_BUFFER_BIT); + state->Enable(GL_SCISSOR_TEST); + state->Enable(GL_DEPTH_TEST); + //TODO: Viewports and scissor should be in state + glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_ShieldPixelRate, m_Renderer->GetViewportSize().Height/m_ShieldPixelRate); + glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - //state->StencilMask(0x00); - //state->StencilFunc(GL_ALWAYS, 1, 0xFF); - state->Disable(GL_STENCIL_TEST); - state->Disable(GL_DEPTH_TEST); + glClearStencil(0x00); + glClear(GL_STENCIL_BUFFER_BIT); + + //TODO: This should not be here... + state->StencilFunc(GL_ALWAYS, 1, 0xFF); + state->StencilMask(0x00); + DrawToDepthBuffer(scene.Jobs.OpaqueObjects, scene); + DrawToDepthBuffer(scene.Jobs.TransparentObjects, scene); + + //Draw shields to stencil pass + state->StencilFunc(GL_ALWAYS, 1, 0xFF); + state->StencilMask(0xFF); + state->Enable(GL_DEPTH_TEST); + DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene); + GLERROR("StencilPass"); + + glClear(GL_DEPTH_BUFFER_BIT); + + state->Enable(GL_DEPTH_TEST); + state->StencilFunc(GL_LEQUAL, 1, 0xFF); + state->StencilMask(0x00); DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); GLERROR("OpaqueObjects"); DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); GLERROR("TransparentObjects"); + glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); delete stateLowRes; } void DrawFinalPass::ClearBuffer() { + m_FinalPassFrameBufferLowRes.Bind(); + glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_ShieldPixelRate, m_Renderer->GetViewportSize().Height/m_ShieldPixelRate); + glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); + m_FinalPassFrameBufferLowRes.Unbind(); + m_FinalPassFrameBuffer.Bind(); + glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_FinalPassFrameBuffer.Unbind(); - - m_FinalPassFrameBufferLowRes.Bind(); - glClearColor(0.f, 0.f, 0.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - m_FinalPassFrameBufferLowRes.Unbind(); } void DrawFinalPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const @@ -385,6 +421,39 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene) +{ + m_FillDepthBufferProgram->Bind(); + GLuint shaderHandle = m_FillDepthBufferProgram->GetHandle(); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + + for (auto &job : jobs) { + auto modelJob = std::dynamic_pointer_cast(job); + + //bind uniforms + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + + //draw + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); + if (GLERROR("models end")) { + continue; + } + } + +} + void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) { glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 15554ab1..8530b291 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -120,7 +120,7 @@ void Renderer::Draw(RenderFrame& frame) } m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture()); if (m_DebugTextureToDraw == 0) { - m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), frame.Gamma, frame.Exposure); + m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), m_DrawFinalPass->SceneTextureLowRes(), m_DrawFinalPass->BloomTextureLowRes(), frame.Gamma, frame.Exposure); } if (m_DebugTextureToDraw == 1) { m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTexture()); From 2ee21e05d48eba278eeb3e4c905044b4fa2668f7 Mon Sep 17 00:00:00 2001 From: Tleety Date: Mon, 8 Feb 2016 12:29:41 +0100 Subject: [PATCH 093/131] Fixed so that Shielded objects can be picked. Shield objects can not however, so they will not be able to be picked in editor either. --- src/Engine/Rendering/PickingPass.cpp | 92 ++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 3baf2b2a..b0733ae2 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -147,6 +147,98 @@ void PickingPass::Draw(RenderScene& scene) glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); } } + + for (auto &job : scene.Jobs.OpaqueShieldedObjects) { + auto modelJob = std::dynamic_pointer_cast(job); + + if (modelJob) { + int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; + + PickingInfo pickInfo; + pickInfo.Entity = modelJob->Entity; + pickInfo.World = modelJob->World; + pickInfo.Camera = scene.Camera; + + auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); + if (color != m_EntityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; + } else { + m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); + if (m_ColorCounter[0] > 255) { + m_ColorCounter[0] = 0; + m_ColorCounter[1] += 1; + } else { + m_ColorCounter[0] += 1; + } + } + + m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + } + } + + for (auto &job : scene.Jobs.TransparentShieldedObjects) { + auto modelJob = std::dynamic_pointer_cast(job); + + if (modelJob) { + int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; + + PickingInfo pickInfo; + pickInfo.Entity = modelJob->Entity; + pickInfo.World = modelJob->World; + pickInfo.Camera = scene.Camera; + + auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); + if (color != m_EntityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; + } else { + m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); + if (m_ColorCounter[0] > 255) { + m_ColorCounter[0] = 0; + m_ColorCounter[1] += 1; + } else { + m_ColorCounter[0] += 1; + } + } + + m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + } + } m_PickingBuffer.Unbind(); GLERROR("PickingPass Error"); From d2cfa592f0581c970b93ae2b15c3b8dcc060cf4c Mon Sep 17 00:00:00 2001 From: Teejoon Date: Mon, 8 Feb 2016 13:01:10 +0100 Subject: [PATCH 094/131] Supports skinnd and unskinned meshes ExplosionEffects now supports SplatMapping --- include/Engine/Rendering/DrawFinalPass.h | 9 +- include/Engine/Rendering/ModelJob.h | 12 +- resources/Shaders/ForwardPlus.vert.glsl | 17 +- .../Shaders/ForwardPlusSkinned.vert.glsl | 46 +++ src/Engine/Rendering/DrawFinalPass.cpp | 370 ++++++++++++++---- src/Engine/Rendering/RawModelCustom.cpp | 9 +- tools/MayaExporter/MayaExporter.opensdf | Bin 0 -> 38 bytes tools/MayaExporter/MayaExporter/Mesh.h | 4 +- 8 files changed, 355 insertions(+), 112 deletions(-) create mode 100644 resources/Shaders/ForwardPlusSkinned.vert.glsl create mode 100644 tools/MayaExporter/MayaExporter.opensdf diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 830ded3c..dd0df84a 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -35,7 +35,7 @@ private: void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); void BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); - void BindExplosionTextures(std::shared_ptr& job); + void BindExplosionTextures(GLuint shaderHandle, std::shared_ptr& job); void BindModelTextures(GLuint shaderHandle, std::shared_ptr& job); Texture* m_WhiteTexture; @@ -53,7 +53,14 @@ private: ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; + ShaderProgram* m_ExplosionEffectSplatMapProgram; ShaderProgram* m_ForwardPlusSplatMapProgram; + + + ShaderProgram* m_ForwardPlusSkinnedProgram; + ShaderProgram* m_ExplosionEffectSkinnedProgram; + ShaderProgram* m_ExplosionEffectSplatMapSkinnedProgram; + ShaderProgram* m_ForwardPlusSplatMapSkinnedProgram; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index fe8fe26f..de7db78e 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -28,20 +28,20 @@ struct ModelJob : RenderJob switch(matProp.type){ case ::RawModel::MaterialType::Basic: if (Model->isSkined()) { - ShaderID = ResourceManager::Load("#ForwardPlusProgram")->ResourceID; + ShaderID = ResourceManager::Load("#ForwardPlusSkinnedProgram")->ResourceID; } else { - //JOHAN TODO: Add Non-skined shader + ShaderID = ResourceManager::Load("#ForwardPlusProgram")->ResourceID; } TextureID = 0; break; case ::RawModel::MaterialType::SingleTextures: { if (Model->isSkined()) { - ShaderID = ResourceManager::Load("#ForwardPlusProgram")->ResourceID; + ShaderID = ResourceManager::Load("#ForwardPlusSkinnedProgram")->ResourceID; } else { - //JOHAN TODO: Add Non-skined shader + ShaderID = ResourceManager::Load("#ForwardPlusProgram")->ResourceID; } ::RawModel::MaterialSingleTextures* singleTextures = static_cast<::RawModel::MaterialSingleTextures*>(matProp.material); TextureID = (singleTextures->ColorMap.Texture) ? singleTextures->ColorMap.Texture->ResourceID : 0; @@ -65,10 +65,10 @@ struct ModelJob : RenderJob case ::RawModel::MaterialType::SplatMapping: { if (Model->isSkined()) { - ShaderID = ResourceManager::Load("#ForwardPlusSplatMapProgram")->ResourceID; + ShaderID = ResourceManager::Load("#ForwardPlusSplatMapSkinnedProgram")->ResourceID; } else { - //JOHAN TODO: Add Non-skinned shader + ShaderID = ResourceManager::Load("#ForwardPlusSplatMapProgram")->ResourceID; } ::RawModel::MaterialSplatMapping* SplatTextures = static_cast<::RawModel::MaterialSplatMapping*>(matProp.material); diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index 3b3e931c..d475d825 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -3,15 +3,12 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; -uniform mat4 Bones[100]; layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; layout(location = 2) in vec3 Tangent; layout(location = 3) in vec3 BiTangent; layout(location = 4) in vec2 TextureCoords; -layout(location = 5) in vec4 BoneIndices; -layout(location = 6) in vec4 BoneWeights; out VertexData{ vec3 Position; @@ -25,19 +22,9 @@ out VertexData{ void main() { - - - mat4 boneTransform = mat4(1); - if(BoneWeights[0] > 0.0f){ - boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] - + BoneWeights[1] * Bones[int(BoneIndices[1])] - + BoneWeights[2] * Bones[int(BoneIndices[2])] - + BoneWeights[3] * Bones[int(BoneIndices[3])]; - } - - gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + gl_Position = P*V*M * vec4(Position, 1.0); - Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; + Output.Position = Position; Output.TextureCoordinate = TextureCoords; Output.Normal = vec3(M * vec4(Normal, 0.0)); Output.Tangent = vec3(M * vec4(Tangent, 0.0)); diff --git a/resources/Shaders/ForwardPlusSkinned.vert.glsl b/resources/Shaders/ForwardPlusSkinned.vert.glsl new file mode 100644 index 00000000..3d47b0c4 --- /dev/null +++ b/resources/Shaders/ForwardPlusSkinned.vert.glsl @@ -0,0 +1,46 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform mat4 Bones[100]; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 2) in vec3 Tangent; +layout(location = 3) in vec3 BiTangent; +layout(location = 4) in vec2 TextureCoords; +layout(location = 5) in vec4 BoneIndices; +layout(location = 6) in vec4 BoneWeights; + +out VertexData{ + vec3 Position; + vec3 Normal; + vec3 Tangent; + vec3 BiTangent; + vec2 TextureCoordinate; + vec4 ExplosionColor; + float ExplosionPercentageElapsed; +}Output; + +void main() +{ + mat4 boneTransform = mat4(1); + //Remove if(). Shoudln't have to do this scine we know it's skinned and uses bones + if(BoneWeights[0] > 0.0f){ + boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + + BoneWeights[1] * Bones[int(BoneIndices[1])] + + BoneWeights[2] * Bones[int(BoneIndices[2])] + + BoneWeights[3] * Bones[int(BoneIndices[3])]; + } + + gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + + Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; + Output.TextureCoordinate = TextureCoords; + Output.Normal = vec3(M * vec4(Normal, 0.0)); + Output.Tangent = vec3(M * vec4(Tangent, 0.0)); + Output.BiTangent = vec3(M * vec4(BiTangent, 0.0)); + Output.ExplosionColor = vec4(1.0); + Output.ExplosionPercentageElapsed = 0.0; +} \ No newline at end of file diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 3c4406fe..c97ab6b5 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -63,7 +63,54 @@ void DrawFinalPass::InitializeShaderPrograms() m_ForwardPlusSplatMapProgram->BindFragDataLocation(0, "sceneColor"); m_ForwardPlusSplatMapProgram->BindFragDataLocation(1, "bloomColor"); m_ForwardPlusSplatMapProgram->Link(); - GLERROR("Creating SplatMap program"); + GLERROR("Creating Forward SplatMap program"); + + m_ExplosionEffectSplatMapProgram = ResourceManager::Load("#ExplosionEffectSplatMapProgram"); + m_ExplosionEffectSplatMapProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); + m_ExplosionEffectSplatMapProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); + m_ExplosionEffectSplatMapProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMap.frag.glsl"))); + m_ExplosionEffectSplatMapProgram->Compile(); + m_ExplosionEffectSplatMapProgram->BindFragDataLocation(0, "sceneColor"); + m_ExplosionEffectSplatMapProgram->BindFragDataLocation(1, "bloomColor"); + m_ExplosionEffectSplatMapProgram->Link(); + GLERROR("Creating explosion SplatMap program"); + + m_ForwardPlusSkinnedProgram = ResourceManager::Load("#ForwardPlusSkinnedProgram"); + m_ForwardPlusSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); + m_ForwardPlusSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlus.frag.glsl"))); + m_ForwardPlusSkinnedProgram->Compile(); + m_ForwardPlusSkinnedProgram->BindFragDataLocation(0, "sceneColor"); + m_ForwardPlusSkinnedProgram->BindFragDataLocation(1, "bloomColor"); + m_ForwardPlusSkinnedProgram->Link(); + GLERROR("Creating forward+ Skinned program"); + + m_ExplosionEffectSkinnedProgram = ResourceManager::Load("#ExplosionEffectSkinnedProgram"); + m_ExplosionEffectSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); + m_ExplosionEffectSkinnedProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); + m_ExplosionEffectSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlus.frag.glsl"))); + m_ExplosionEffectSkinnedProgram->Compile(); + m_ExplosionEffectSkinnedProgram->BindFragDataLocation(0, "sceneColor"); + m_ExplosionEffectSkinnedProgram->BindFragDataLocation(1, "bloomColor"); + m_ExplosionEffectSkinnedProgram->Link(); + GLERROR("Creating explosion Skinned program"); + + m_ExplosionEffectSplatMapSkinnedProgram = ResourceManager::Load("#ExplosionEffectSplatMapSkinnedProgram"); + m_ExplosionEffectSplatMapSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); + m_ExplosionEffectSplatMapSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMap.frag.glsl"))); + m_ExplosionEffectSplatMapSkinnedProgram->Compile(); + m_ExplosionEffectSplatMapSkinnedProgram->BindFragDataLocation(0, "sceneColor"); + m_ExplosionEffectSplatMapSkinnedProgram->BindFragDataLocation(1, "bloomColor"); + m_ExplosionEffectSplatMapSkinnedProgram->Link(); + GLERROR("Creating Forward SplatMap Skinned program"); + + m_ForwardPlusSplatMapSkinnedProgram = ResourceManager::Load("#ForwardPlusSplatMapSkinnedProgram"); + m_ForwardPlusSplatMapSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); + m_ForwardPlusSplatMapSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMap.frag.glsl"))); + m_ForwardPlusSplatMapSkinnedProgram->Compile(); + m_ForwardPlusSplatMapSkinnedProgram->BindFragDataLocation(0, "sceneColor"); + m_ForwardPlusSplatMapSkinnedProgram->BindFragDataLocation(1, "bloomColor"); + m_ForwardPlusSplatMapSkinnedProgram->Link(); + GLERROR("Creating Forward SplatMap Skinned program"); } void DrawFinalPass::Draw(RenderScene& scene) @@ -125,7 +172,18 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& GLERROR("forwardHandle"); GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle(); GLERROR("explosionHandle"); + GLuint explosionSplatMapHandle = m_ExplosionEffectSplatMapProgram->GetHandle(); + GLERROR("explosionSplatMapHandle"); GLuint forwardSplatHandle = m_ForwardPlusSplatMapProgram->GetHandle(); + GLERROR("forwardSplatHandle"); + GLuint forwardSkinnedHandle = m_ForwardPlusSkinnedProgram->GetHandle(); + GLERROR("forwardSkinnedHandle"); + GLuint explosionSkinnedHandle = m_ExplosionEffectSkinnedProgram->GetHandle(); + GLERROR("explosionSkinnedHandle"); + GLuint explosionSplatMapSkinnedHandle = m_ExplosionEffectSplatMapSkinnedProgram->GetHandle(); + GLERROR("explosionSplatMapSkinnedHandle"); + GLuint forwardSplatMapSkinnedHandle = m_ForwardPlusSplatMapSkinnedProgram->GetHandle(); + GLERROR("forwardSplatSkinnedHandle"); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); @@ -135,48 +193,68 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& { auto explosionEffectJob = std::dynamic_pointer_cast(job); if(explosionEffectJob) { - //Bind program - if(GLERROR("Prebind")) { - continue; - } - m_ExplosionEffectProgram->Bind(); - if(GLERROR("BindProgram")) { - continue; - } - + switch (explosionEffectJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + if (explosionEffectJob->Model->isSkined()) { + m_ExplosionEffectSkinnedProgram->Bind(); + GLERROR("Bind ExplosionEffectSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); + if (explosionEffectJob->Animation != nullptr) { + std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + else { + m_ExplosionEffectProgram->Bind(); + GLERROR("Bind ExplosionEffect program"); + //bind uniforms + BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionHandle, explosionEffectJob); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + if (explosionEffectJob->Model->isSkined()) { + m_ExplosionEffectSplatMapSkinnedProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMapSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSplatMapSkinnedHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); + GLERROR("asdasd"); + if (explosionEffectJob->Animation != nullptr) { + std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + else { + m_ExplosionEffectSplatMapProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMap program"); + //bind uniforms + //bind uniforms + BindExplosionUniforms(explosionSplatMapHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapHandle, explosionEffectJob); + GLERROR("asdasd"); + } + break; + } + } glDisable(GL_CULL_FACE); - //Bind uniforms - BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); - if(GLERROR("BindExplosionUniforms")) { - continue; - } - - if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (explosionEffectJob->Animation != nullptr) { - std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } - } - if(GLERROR("Animation")) { - continue; - } - - //bind textures - BindExplosionTextures(explosionEffectJob); - if(GLERROR("BindExplosionTextures")) { - continue; - } //draw glBindVertexArray(explosionEffectJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer); glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int))); glEnable(GL_CULL_FACE); - if(GLERROR("explosion effect end")) { - continue; - } - + GLERROR("explosion effect end"); } else { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { @@ -186,38 +264,54 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& case RawModel::MaterialType::Basic: case RawModel::MaterialType::SingleTextures: { - m_ForwardPlusProgram->Bind(); - GLERROR("Bind Forward program"); - //bind uniforms - BindModelUniforms(forwardHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardHandle, modelJob); - GLERROR("asdasd"); - + if (modelJob->Model->isSkined()) { + m_ForwardPlusSkinnedProgram->Bind(); + GLERROR("Bind ForwardPlusSkinnedProgram"); + //bind uniforms + BindModelUniforms(forwardSkinnedHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSkinnedHandle, modelJob); + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } else { + m_ForwardPlusProgram->Bind(); + GLERROR("Bind ForwardPlusProgram"); + //bind uniforms + BindModelUniforms(forwardHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardHandle, modelJob); + } break; } case RawModel::MaterialType::SplatMapping: { - m_ForwardPlusSplatMapProgram->Bind(); - GLERROR("Bind SplatMap program"); - //bind uniforms - BindModelUniforms(forwardSplatHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardSplatHandle, modelJob); - GLERROR("asdasd"); - + if (modelJob->Model->isSkined()) { + m_ForwardPlusSplatMapSkinnedProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatMapSkinnedHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); + GLERROR("asdasd"); + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } else { + m_ForwardPlusSplatMapProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatHandle, modelJob); + GLERROR("asdasd"); + } break; } } - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } - } - //draw glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); @@ -233,27 +327,46 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) { + GLERROR("Bind 1 uniform"); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); + GLERROR("Bind 2 uniform"); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + GLERROR("Bind 3 uniform"); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + GLERROR("Bind 4 uniform"); glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + GLERROR("Bind 5 uniform"); glUniform3fv(glGetUniformLocation(shaderHandle, "ExplosionOrigin"), 1, glm::value_ptr(job->ExplosionOrigin)); + GLERROR("Bind 6 uniform"); glUniform1f(glGetUniformLocation(shaderHandle, "TimeSinceDeath"), job->TimeSinceDeath); + GLERROR("Bind 7 uniform"); glUniform1f(glGetUniformLocation(shaderHandle, "ExplosionDuration"), job->ExplosionDuration); + GLERROR("Bind 8 uniform"); glUniform4fv(glGetUniformLocation(shaderHandle, "EndColor"), 1, glm::value_ptr(job->EndColor)); + GLERROR("Bind 9 uniform"); glUniform1i(glGetUniformLocation(shaderHandle, "Randomness"), job->Randomness); + GLERROR("Bind 10 uniform"); glUniform1fv(glGetUniformLocation(shaderHandle, "RandomNumbers"), 50, job->RandomNumbers.data()); + GLERROR("Bind 11 uniform"); glUniform1f(glGetUniformLocation(shaderHandle, "RandomnessScalar"), job->RandomnessScalar); + GLERROR("Bind 12 uniform"); glUniform2fv(glGetUniformLocation(shaderHandle, "Velocity"), 1, glm::value_ptr(job->Velocity)); + GLERROR("Bind 13 uniform"); glUniform1i(glGetUniformLocation(shaderHandle, "ColorByDistance"), job->ColorByDistance); + GLERROR("Bind 14 uniform"); glUniform1i(glGetUniformLocation(shaderHandle, "ExponentialAccelaration"), job->ExponentialAccelaration); + GLERROR("Bind 15 uniform"); glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(job->Color)); + GLERROR("Bind 16 uniform"); glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(job->DiffuseColor)); + GLERROR("Bind 17 uniform"); glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(job->FillColor)); + GLERROR("Bind 18 uniform"); glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), job->FillPercentage); + GLERROR("Bind 19 uniform"); glUniform4fv(glGetUniformLocation(shaderHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor)); GLERROR("END"); } @@ -293,35 +406,122 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job) +void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptr& job) { - glActiveTexture(GL_TEXTURE0); - if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0]->Texture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->Texture->m_Texture); //JOHAN TODO: support multiple diffuse Textures - } else { - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - } + switch (job->Type) { + case RawModel::MaterialType::SingleTextures: + case RawModel::MaterialType::Basic: + { + glActiveTexture(GL_TEXTURE0); + if (job->DiffuseTexture.size() > 0 && job->DiffuseTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(job->DiffuseTexture[0]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } - glActiveTexture(GL_TEXTURE1); - if (job->NormalTexture.size() > 0 && job->NormalTexture[0]->Texture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->Texture->m_Texture); //JOHAN TODO: support multiple diffuse Textures - } else { - glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); - } + glActiveTexture(GL_TEXTURE1); + if (job->NormalTexture.size() > 0 && job->NormalTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(job->NormalTexture[0]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } - glActiveTexture(GL_TEXTURE2); - if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0]->Texture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->Texture->m_Texture); //JOHAN TODO: support multiple diffuse Textures - } else { - glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); - } + glActiveTexture(GL_TEXTURE2); + if (job->SpecularTexture.size() > 0 && job->SpecularTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(job->SpecularTexture[0]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } - glActiveTexture(GL_TEXTURE3); - if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0]->Texture != nullptr) { - glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->Texture->m_Texture); //JOHAN TODO: support multiple diffuse Textures - } else { - glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); - } + glActiveTexture(GL_TEXTURE3); + if (job->IncandescenceTexture.size() > 0 && job->IncandescenceTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(job->IncandescenceTexture[0]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, job->SplatMap->Texture->m_Texture); + + int texturePosition = GL_TEXTURE1; + + //Bind 5 diffuse textures + std::string UniformName = "DiffuseUVRepeat"; + for (unsigned int i = 0; i < 5; i++) { + glActiveTexture(texturePosition); + if (job->DiffuseTexture.size() > i && job->DiffuseTexture[i]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[i]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(job->DiffuseTexture[i]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } + texturePosition++; + } + + //Bind 5 Normal textures + UniformName = "NormalUVRepeat"; + for (unsigned int i = 0; i < 5; i++) { + glActiveTexture(texturePosition); + if (job->NormalTexture.size() > i && job->NormalTexture[i]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->NormalTexture[i]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(job->NormalTexture[i]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } + texturePosition++; + } + + //Bind 5 Specular textures + UniformName = "SpecularUVRepeat"; + for (unsigned int i = 0; i < 5; i++) { + glActiveTexture(texturePosition); + if (job->SpecularTexture.size() > i && job->SpecularTexture[i]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[i]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(job->SpecularTexture[i]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } + texturePosition++; + } + + //Bind 5 Incandescence textures + UniformName = "GlowUVRepeat"; + for (unsigned int i = 0; i < 5; i++) { + glActiveTexture(texturePosition); + if (job->IncandescenceTexture.size() > i && job->IncandescenceTexture[i]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[i]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(job->IncandescenceTexture[i]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, std::string(UniformName + ((char)(i + '1'))).c_str()), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } + texturePosition++; + } + break; + } + } } void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptr& job) diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 00ae0e33..69175a45 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -40,8 +40,8 @@ void RawModelCustom::ReadMeshFile(std::string filePath) void RawModelCustom::ReadMeshFileHeader(std::size_t& offset, char* fileData) { #ifdef BOOST_LITTLE_ENDIAN - hasSkin = true;//*(bool*)(fileData + offset); - //offset += sizeof(bool); + hasSkin = *(bool*)(fileData + offset); + offset += sizeof(bool); if (hasSkin) { m_SkinedVertices.resize(static_cast(*(unsigned int*)(fileData + offset))); } @@ -290,7 +290,10 @@ void RawModelCustom::ReadAnimationFile(std::string filePath) if (!in.is_open()) { //throw Resource::FailedLoadingException("Open animation file failed"); return; - } + } else if (hasSkin) { + throw Resource::FailedLoadingException("Open animation file for a skinned mesh failed, unknown stuff will happen"); + return; + } unsigned int fileByteSize = static_cast(in.tellg()); in.seekg(0, std::ios_base::beg); diff --git a/tools/MayaExporter/MayaExporter.opensdf b/tools/MayaExporter/MayaExporter.opensdf new file mode 100644 index 0000000000000000000000000000000000000000..31dea47bab049adbbcfae9b67e37a5ada58ecdf3 GIT binary patch literal 38 ncmd01NMy)m$Ydx6(}@fW3?U4z3_%RO44w>r430paKad9ihMopW literal 0 HcmV?d00001 diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index eda79805..affc4320 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -62,7 +62,7 @@ public: class Mesh : public OutputData { public: - bool hasSkin = true; //Should be false by default... Have it true now since pipeline only support skinned vertecies + bool hasSkin = false; unsigned int NumVertices; unsigned int NumIndices; std::vector Vertices; @@ -70,7 +70,7 @@ public: virtual void WriteBinary(std::ostream& out) { - //out.write((char*)&hasSkin, sizeof(bool)); + out.write((char*)&hasSkin, sizeof(bool)); out.write((char*)&NumVertices, sizeof(int)); out.write((char*)&NumIndices, sizeof(int)); for (auto aVertex : Vertices) { From 6610bb974db8da0ae68db595d49a7e3bf25b5046 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 8 Feb 2016 13:32:45 +0100 Subject: [PATCH 095/131] Only apply air friction if the ground is never hit during the frame. --- src/Engine/Collision/CollisionSystem.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index b5d7a1f0..7d8905a8 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -20,6 +20,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c // Collide against octree items m_OctreeResult.clear(); m_Octree->ObjectsInSameRegion(*boundingBox, m_OctreeResult); + bool everHitTheGround = false; for (auto& boxB : m_OctreeResult) { glm::vec3 resolutionVector; if (boxA.Entity == boxB.Entity) { @@ -43,17 +44,24 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; cPhysics["Velocity"] = inOutVelocity; - (bool)cPhysics["IsOnGround"] = isOnGround; - } else { - (bool)cPhysics["IsOnGround"] = false; + if (isOnGround) { + everHitTheGround = true; + (bool)cPhysics["IsOnGround"] = true; + } } } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { //Enter here if boxB has no Model. (glm::vec3&)cTransform["Position"] += resolutionVector; - (bool)cPhysics["IsOnGround"] = resolutionVector.y > 0; - if ((bool)cPhysics["IsOnGround"]){ + if (resolutionVector.y > 0) { + everHitTheGround = true; + (bool)cPhysics["IsOnGround"] = true; ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; } } } + + //This should apply air friction and such, iff zero models were hit. + if (!everHitTheGround) { + (bool)cPhysics["IsOnGround"] = false; + } } From 12c05d5a1cc1c5d879c3e382e4c78f17e2611c0a Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 8 Feb 2016 13:59:35 +0100 Subject: [PATCH 096/131] Added an Queue event for sound emitters. --- include/Engine/Sound/EPlayQueueOnEntity.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 include/Engine/Sound/EPlayQueueOnEntity.h diff --git a/include/Engine/Sound/EPlayQueueOnEntity.h b/include/Engine/Sound/EPlayQueueOnEntity.h new file mode 100644 index 00000000..e880819a --- /dev/null +++ b/include/Engine/Sound/EPlayQueueOnEntity.h @@ -0,0 +1,18 @@ +#ifndef Events_PlayQueueOnEntity_h__ +#define Events_PlayQueueOnEntity_h__ + +#include "../Core/Event.h" +#include "../Core/EntityWrapper.h" + +namespace Events +{ + +struct PlayQueueOnEntity : public Event +{ + EntityWrapper Emitter; + std::vector FilePaths; +}; + +} + +#endif From 3a5c0a27620e3bf443cbd0dab49746aaf9b3711d Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 8 Feb 2016 14:01:32 +0100 Subject: [PATCH 097/131] SoundSystem does not longer inherit from SoundManager. SoundManager is a individual class that listens to events. The SoundManager only listens to the local player. --- include/Engine/Sound/Sound.h | 3 + include/Engine/Sound/SoundManager.h | 65 +++-------- include/Game/Game.h | 2 +- include/Game/Systems/SoundSystem.h | 40 ++++++- src/Engine/Sound/SoundManager.cpp | 165 ++++++---------------------- src/Game/Game.cpp | 5 + src/Game/Systems/SoundSystem.cpp | 119 +++++++++++++++++++- 7 files changed, 211 insertions(+), 188 deletions(-) diff --git a/include/Engine/Sound/Sound.h b/include/Engine/Sound/Sound.h index 6b2aac04..cccbdf07 100644 --- a/include/Engine/Sound/Sound.h +++ b/include/Engine/Sound/Sound.h @@ -1,6 +1,9 @@ #ifndef Sound_h__ #define Sound_h__ +#include +#include + #include "Core/ResourceManager.h" class Sound : public Resource diff --git a/include/Engine/Sound/SoundManager.h b/include/Engine/Sound/SoundManager.h index 9ba4d2ad..3923a17b 100644 --- a/include/Engine/Sound/SoundManager.h +++ b/include/Engine/Sound/SoundManager.h @@ -15,6 +15,7 @@ #include "Core/EventBroker.h" #include "Core/Transform.h" // Absolute transform #include "Sound/Sound.h" +#include "../Engine/Sound/EPlayQueueOnEntity.h" #include "Sound/EPlaySoundOnEntity.h" #include "Sound/EPlaySoundOnPosition.h" #include "Sound/EPlayBackgroundMusic.h" @@ -23,19 +24,9 @@ #include "Sound/EStopSound.h" #include "Sound/ESetBGMGain.h" #include "Sound/ESetSFXGain.h" -#include "Core/EShoot.h" -#include "Core/EPlayerSpawned.h" -#include "Input/EInputCommand.h" -#include "Core/ECaptured.h" -#include "Core/EPlayerDamage.h" -#include "Core/EPlayerDeath.h" -#include "Core/EPlayerHealthPickup.h" -#include "Core/EComponentAttached.h" -#include "Collision/ETrigger.h" #include "Core/EPause.h" -#include "Game/Events/EDoubleJump.h" -#include "Game/Events/EDashAbility.h" - +#include "Core/EComponentAttached.h" +#include "../Core/EPlayerSpawned.h" typedef std::pair> QueuedBuffers; @@ -61,20 +52,6 @@ public: // Update emitters / listener void Update(double dt); -protected: - // Specific logic - void playSound(Source* source); - // Need to be the same format (sample rate etc) - void playQueue(QueuedBuffers qb); - void stopSound(Source* source); - void playerJumps(); - void playerStep(double dt); - EntityID createChildEmitter(EntityWrapper localPlayer); - - // Logic - World* m_World = nullptr; - EventBroker* m_EventBroker = nullptr; - private: // Help functions for working with OpenaAL void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; @@ -92,25 +69,30 @@ private: void deleteInactiveEmitters(); void stopEmitters(); void updateListener(double dt); - Source* createSource(std::string filePath); ALenum getSourceState(ALuint source); void setGain(Source* source, float gain); void setSoundProperties(Source* source, ComponentWrapper* soundComponent); + // Specific logic + void playSound(Source* source); + // Need to be the same format (sample rate etc) + void playQueue(QueuedBuffers qb); + void stopSound(Source* source); + Source* createSource(std::string filePath); std::unordered_map m_Sources; + // Logic + World* m_World = nullptr; + EventBroker* m_EventBroker = nullptr; // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; ALCcontext* m_ALCcontext = nullptr; - - float m_BGMVolumeChannel = 1.0f; float m_SFXVolumeChannel = 1.0f; bool m_EditorEnabled = false; EntityWrapper m_LocalPlayer = EntityWrapper(); - std::default_random_engine generator; // Events EventRelay m_EPlaySoundOnEntity; @@ -129,31 +111,16 @@ private: bool OnSetBGMGain(const Events::SetBGMGain &e); EventRelay m_ESetSFXGain; bool OnSetSFXGain(const Events::SetSFXGain &e); - EventRelay m_EShoot; - bool OnShoot(const Events::Shoot &e); - EventRelay m_EPlayerSpawned; - bool OnPlayerSpawned(const Events::PlayerSpawned &e); - EventRelay m_ECaptured; - bool OnCaptured(const Events::Captured &e); - EventRelay m_EPlayerDamage; - bool OnPlayerDamage(const Events::PlayerDamage &e); - EventRelay m_EPlayerDeath; - bool OnPlayerDeath(const Events::PlayerDeath &e); - EventRelay m_EPlayerHealthPickup; - bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); EventRelay m_EComponentAttached; bool OnComponentAttached(const Events::ComponentAttached &e); - EventRelay m_ETriggerTouch; - bool OnTriggerTouch(const Events::TriggerTouch &e); EventRelay m_EPause; bool OnPause(const Events::Pause &e); EventRelay m_EResume; bool OnResume(const Events::Resume &e); - EventRelay m_EDoubleJump; - bool OnDoubleJump(const Events::DoubleJump &e); - EventRelay m_EDashAbility; - bool OnDashAbility(const Events::DashAbility &e); - + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(const Events::PlayerSpawned &e); + EventRelay m_EPlayQueueOnEntity; + bool OnPlayQueueOnEntity(const Events::PlayQueueOnEntity &e); }; diff --git a/include/Game/Game.h b/include/Game/Game.h index b6a2c0d3..6177a818 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -30,7 +30,7 @@ #include "Network/Client.h" // Sound -//#include "Sound/SoundManager.h" +#include "Sound/SoundManager.h" #include "Systems/SoundSystem.h" class Game diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index 77ebcfa1..b14d7486 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -1,13 +1,29 @@ #ifndef Systems_SoundSystem_h__ #define Systems_SoundSystem_h__ +#include + #include "../Engine/Core/System.h" -#include "../Engine/Sound/SoundManager.h" +#include "../Engine/Core/ResourceManager.h" +#include "../Engine/Sound/Sound.h" +#include "../Engine/Sound/EPlayQueueOnEntity.h" #include "../Engine/Core/EPlayerSpawned.h" #include "../Engine/Input/EInputCommand.h" +#include "../Engine/Core/EShoot.h" +#include "../Engine/Core/EPlayerSpawned.h" +#include "../Engine/Input/EInputCommand.h" +#include "../Engine/Core/ECaptured.h" +#include "../Engine/Core/EPlayerDamage.h" +#include "../Engine/Core/EPlayerDeath.h" +#include "../Engine/Core/EPlayerHealthPickup.h" +#include "../Engine/Collision/ETrigger.h" +#include "../Engine/Sound/EPlaySoundOnEntity.h" +#include "../Engine/Sound/EPlayBackgroundMusic.h" +#include "../Game/Events/EDoubleJump.h" +#include "../Game/Events/EDashAbility.h" -class SoundSystem : public PureSystem, ImpureSystem, SoundManager +class SoundSystem : public PureSystem, ImpureSystem { public: SoundSystem(World* world, EventBroker* eventbroker); @@ -23,6 +39,8 @@ private: // Logic for playing a sound when a player jumps void playerJumps(); + // Helper function + EntityID createChildEmitter(EntityWrapper parent); // Walking logic // Keeps track of how far the player has walked within this "key press session". @@ -34,10 +52,28 @@ private: // Determine what sound file to play. bool m_LeftFoot = false; + std::default_random_engine generator; + EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned &e); EventRelay m_InputCommand; bool OnInputCommand(const Events::InputCommand &e); + EventRelay m_EDoubleJump; + bool OnDoubleJump(const Events::DoubleJump &e); + EventRelay m_EDashAbility; + bool OnDashAbility(const Events::DashAbility &e); + EventRelay m_ETriggerTouch; + bool OnTriggerTouch(const Events::TriggerTouch &e); + EventRelay m_EShoot; + bool OnShoot(const Events::Shoot &e); + EventRelay m_ECaptured; + bool OnCaptured(const Events::Captured &e); + EventRelay m_EPlayerDamage; + bool OnPlayerDamage(const Events::PlayerDamage &e); + EventRelay m_EPlayerDeath; + bool OnPlayerDeath(const Events::PlayerDeath &e); + EventRelay m_EPlayerHealthPickup; + bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); }; #endif diff --git a/src/Engine/Sound/SoundManager.cpp b/src/Engine/Sound/SoundManager.cpp index 7046ecc1..d75e9afc 100644 --- a/src/Engine/Sound/SoundManager.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -20,16 +20,11 @@ SoundManager::SoundManager(World* world, EventBroker* eventBroker, bool editorMo EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundManager::OnContinueSound); EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundManager::OnSetBGMGain); EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundManager::OnSetSFXGain); - EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundManager::OnShoot); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundManager::OnPlayerSpawned); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundManager::OnPlayerDamage); - EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundManager::OnCaptured); - EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundManager::OnTriggerTouch); EVENT_SUBSCRIBE_MEMBER(m_EPause, &SoundManager::OnPause); EVENT_SUBSCRIBE_MEMBER(m_EResume, &SoundManager::OnResume); EVENT_SUBSCRIBE_MEMBER(m_EComponentAttached, &SoundManager::OnComponentAttached); - EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundManager::OnDoubleJump); - EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundManager::OnDashAbility); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundManager::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EPlayQueueOnEntity, &SoundManager::OnPlayQueueOnEntity); } SoundManager::~SoundManager() @@ -135,18 +130,21 @@ void SoundManager::updateListener(double dt) { // Should only be one listener. auto listenerComponents = m_World->GetComponents("Listener"); - if (listenerComponents == nullptr) { + if (listenerComponents == nullptr || !m_LocalPlayer.Valid()) { return; } for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { - EntityID listener = (*it).EntityID; - glm::vec3 previousPos; - alGetListener3f(AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get previous pos - glm::vec3 nextPos = Transform::AbsolutePosition(m_World, listener); // Get next (current) pos - glm::vec3 velocity = glm::vec3(nextPos - previousPos) / (float)dt; // Calculate velocity - setListenerPos(nextPos); - setListenerVel(velocity); - setListenerOri(glm::eulerAngles(Transform::AbsoluteOrientation(m_World, listener))); + EntityWrapper listener(m_World, (*it).EntityID); + if (listener.IsChildOf(m_LocalPlayer) || listener == m_LocalPlayer) { + glm::vec3 previousPos; + alGetListener3f(AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get previous pos + glm::vec3 nextPos = Transform::AbsolutePosition(listener); // Get next (current) pos + glm::vec3 velocity = glm::vec3(nextPos - previousPos) / (float)dt; // Calculate velocity + setListenerPos(nextPos); + setListenerVel(velocity); + setListenerOri(glm::eulerAngles(Transform::AbsoluteOrientation(listener))); + break; + } } } @@ -181,21 +179,6 @@ void SoundManager::stopSound(Source* source) alSourceStop(source->ALsource); } - - -void SoundManager::playerStep(double dt) -{ - -} - -EntityID SoundManager::createChildEmitter(EntityWrapper localPlayer) -{ - EntityID child = m_World->CreateEntity(localPlayer.ID); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - return child; -} - bool SoundManager::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) { Source* source = createSource(e.FilePath); @@ -272,87 +255,6 @@ bool SoundManager::OnSetSFXGain(const Events::SetSFXGain & e) return true; } -bool SoundManager::OnShoot(const Events::Shoot & e) -{ - Source* source = createSource("Audio/laser/laser1.wav"); - //auto emitterID = m_World->CreateEntity(e.Player.ID); - //m_World->AttachComponent(emitterID, "Transform"); - //auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); - source->Type = SoundType::SFX; - m_Sources[createChildEmitter(m_LocalPlayer)] = source; - playSound(source); - return true; -} - -bool SoundManager::OnPlayerSpawned(const Events::PlayerSpawned & e) -{ - if (e.PlayerID == -1) { // Local player - m_World->AttachComponent(e.Player.ID, "Listener"); - m_LocalPlayer.ID = e.Player.ID; - } - return true; -} - - -bool SoundManager::OnCaptured(const Events::Captured & e) -{ - int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"]; - int team = (int)m_World->GetComponent(m_LocalPlayer.ID, "Team")["Team"]; - Events::PlaySoundOnEntity ev; - if (team == homeTeam) { - ev.FilePath = "Audio/announcer/objective_achieved.wav"; - } else { - ev.FilePath = "Audio/announcer/objective_failed.wav"; // have not been tested - } - ev.EmitterID = createChildEmitter(m_LocalPlayer); - m_EventBroker->Publish(ev); - return false; -} - -bool SoundManager::OnPlayerDamage(const Events::PlayerDamage & e) -{ - // Should check for only local players here... - - std::uniform_int_distribution dist(1, 12); - int rand = dist(generator); - Source* source = createSource("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); - source->Type = SoundType::SFX; - m_Sources[createChildEmitter(m_LocalPlayer)] = source; - - // Breathe - std::vector buffers; - buffers.push_back(source->SoundResource->Buffer()); - int ammountOfbreaths = (static_cast(e.Damage) / 10) + 2; // TEMP: Idk something stupid like this shit - for (int i = 0; i < ammountOfbreaths; i++) { - buffers.push_back(ResourceManager::Load("Audio/exhausted/breath.wav")->Buffer()); - } - playQueue(QueuedBuffers(std::make_pair(source->ALsource, buffers))); - - return false; -} - -bool SoundManager::OnPlayerDeath(const Events::PlayerDeath & e) -{ - if (e.PlayerID == m_LocalPlayer.ID) { - Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); - ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch - m_EventBroker->Publish(ev); - } - return false; -} - -bool SoundManager::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) -{ - if (e.PlayerHealedID == m_LocalPlayer.ID) { - Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); - ev.FilePath = "Audio/pickup/pickup2.wav"; - m_EventBroker->Publish(ev); - } - return false; -} - bool SoundManager::OnComponentAttached(const Events::ComponentAttached & e) { if (e.Component.Info.Name == "SoundEmitter") { @@ -363,16 +265,6 @@ bool SoundManager::OnComponentAttached(const Events::ComponentAttached & e) return false; } -bool SoundManager::OnTriggerTouch(const Events::TriggerTouch & e) -{ - if (m_World->HasComponent(e.Trigger.ID, "CapturePoint")) { - Events::PlayBackgroundMusic ev; - ev.FilePath = "Audio/bgm/drumstest.wav"; - m_EventBroker->Publish(ev); - } - return false; -} - bool SoundManager::OnPause(const Events::Pause & e) { for (auto it = m_Sources.begin(); it != m_Sources.end(); it++) { @@ -389,22 +281,29 @@ bool SoundManager::OnResume(const Events::Resume &e) return false; } -bool SoundManager::OnDoubleJump(const Events::DoubleJump & e) + +bool SoundManager::OnPlayerSpawned(const Events::PlayerSpawned &e) { - Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); - ev.FilePath = "Audio/jump/jump2.wav"; - m_EventBroker->Publish(ev); + if (e.PlayerID == -1) { // Local player + m_LocalPlayer = e.Player; + return true; + } return false; } -bool SoundManager::OnDashAbility(const Events::DashAbility &e) + +bool SoundManager::OnPlayQueueOnEntity(const Events::PlayQueueOnEntity &e) { - Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); - ev.FilePath = "Audio/jump/dash1.wav"; - m_EventBroker->Publish(ev); - return false; + Source* source = createSource(*e.FilePaths.begin()); + std::vector buffers; + buffers.push_back(source->SoundResource->Buffer()); + source->Type = SoundType::BGM; + std::vector::const_iterator it; + for (it = e.FilePaths.begin() + 1; it != e.FilePaths.end(); it++) { + buffers.push_back(ResourceManager::Load(*it)->Buffer()); + } + playQueue(QueuedBuffers(source->ALsource, buffers)); + return true; } ALenum SoundManager::getSourceState(ALuint source) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 541aa001..d18aaf8d 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -71,6 +71,8 @@ Game::Game(int argc, char* argv[]) fp.MergeEntities(m_World); } + // Create the sound manager + m_SoundManager = new SoundManager(m_World, m_EventBroker, true); // Create Octrees m_OctreeCollision = new Octree(AABB(glm::vec3(-100), glm::vec3(100)), 4); @@ -123,6 +125,7 @@ Game::~Game() delete m_OctreeFrustrumCulling; delete m_OctreeCollision; delete m_OctreeTrigger; + delete m_SoundManager; delete m_World; delete m_FrameStack; delete m_InputProxy; @@ -150,6 +153,8 @@ void Game::Tick() m_InputProxy->Process(); m_EventBroker->Swap(); + m_SoundManager->Update(dt); + // Update network if (m_IsClientOrServer) { m_ClientOrServer->Update(); diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 06e028f2..3f9b75d0 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -4,12 +4,18 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventbroker) : System(world, eventbroker) , PureSystem("SoundEmitter") , ImpureSystem() - , SoundManager(world, eventbroker, true) { m_World = world; m_EventBroker = eventbroker; EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump); + EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility); + EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundSystem::OnShoot); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); } void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) @@ -20,8 +26,6 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp void SoundSystem::Update(double dt) { playerStep(dt); - // Update listener and emitters. - SoundManager::Update(dt); } void SoundSystem::playerStep(double dt) @@ -83,6 +87,12 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) m_DistanceMoved = 0.f; } } + if (e.Command == "TakeDamage" && e.Value > 0) { + Events::PlayerDamage ev; + ev.Player = m_LocalPlayer; + ev.Damage = 1.0; + m_EventBroker->Publish(ev); + } return false; } @@ -97,3 +107,106 @@ void SoundSystem::playerJumps() m_EventBroker->Publish(e); } } + +bool SoundSystem::OnShoot(const Events::Shoot & e) +{ + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.FilePath = "Audio/laser/laser1.wav"; + m_EventBroker->Publish(ev); + return true; +} + +bool SoundSystem::OnCaptured(const Events::Captured & e) +{ + int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"]; + int team = (int)m_World->GetComponent(m_LocalPlayer.ID, "Team")["Team"]; + Events::PlaySoundOnEntity ev; + if (team == homeTeam) { + ev.FilePath = "Audio/announcer/objective_achieved.wav"; + } else { + ev.FilePath = "Audio/announcer/objective_failed.wav"; // have not been tested + } + ev.EmitterID = createChildEmitter(m_LocalPlayer); + m_EventBroker->Publish(ev); + return false; +} + +// Testing purposes atm... +bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) +{ + // Should check for only local players here... + std::uniform_int_distribution dist(1, 12); + int rand = dist(generator); + std::vector paths; + paths.push_back("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); + + // Breathe + int ammountOfbreaths = (static_cast(e.Damage) / 10) + 2; // TEMP: Idk something stupid like this shit + for (int i = 0; i < ammountOfbreaths; i++) { + paths.push_back("Audio/exhausted/breath.wav"); + } + Events::PlayQueueOnEntity ev; + ev.Emitter = m_LocalPlayer; + ev.FilePaths = paths; + m_EventBroker->Publish(ev); + return false; +} + +bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) +{ + if (e.PlayerID == m_LocalPlayer.ID) { + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch + m_EventBroker->Publish(ev); + } + return false; +} + +bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) +{ + if (e.PlayerHealedID == m_LocalPlayer.ID) { + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.FilePath = "Audio/pickup/pickup2.wav"; + m_EventBroker->Publish(ev); + } + return false; +} + +bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) +{ + if (m_World->HasComponent(e.Trigger.ID, "CapturePoint")) { + Events::PlayBackgroundMusic ev; + ev.FilePath = "Audio/bgm/drumstest.wav"; + m_EventBroker->Publish(ev); + } + return false; +} + +bool SoundSystem::OnDoubleJump(const Events::DoubleJump & e) +{ + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.FilePath = "Audio/jump/jump2.wav"; + m_EventBroker->Publish(ev); + return false; +} + +bool SoundSystem::OnDashAbility(const Events::DashAbility &e) +{ + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.FilePath = "Audio/jump/dash1.wav"; + m_EventBroker->Publish(ev); + return false; +} + +EntityID SoundSystem::createChildEmitter(EntityWrapper localPlayer) +{ + EntityID child = m_World->CreateEntity(localPlayer.ID); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + return child; +} \ No newline at end of file From 11cf85cc7346f6e189e513c9204b3a79e07096b9 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 8 Feb 2016 14:17:19 +0100 Subject: [PATCH 098/131] Renamed CollidableOctreeSystem to FillOctreeSystem. --- .../{CollidableOctreeSystem.h => FillOctreeSystem.h} | 6 +++--- .../{CollidableOctreeSystem.cpp => FillOctreeSystem.cpp} | 6 +++--- src/Game/Game.cpp | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) rename include/Engine/Collision/{CollidableOctreeSystem.h => FillOctreeSystem.h} (66%) rename src/Engine/Collision/{CollidableOctreeSystem.cpp => FillOctreeSystem.cpp} (64%) diff --git a/include/Engine/Collision/CollidableOctreeSystem.h b/include/Engine/Collision/FillOctreeSystem.h similarity index 66% rename from include/Engine/Collision/CollidableOctreeSystem.h rename to include/Engine/Collision/FillOctreeSystem.h index 0aa01d2e..9fd87b94 100644 --- a/include/Engine/Collision/CollidableOctreeSystem.h +++ b/include/Engine/Collision/FillOctreeSystem.h @@ -6,12 +6,12 @@ #include "Collision.h" #include "EntityAABB.h" -class CollidableOctreeSystem : public ImpureSystem, public PureSystem +class FillOctreeSystem : public ImpureSystem, public PureSystem { public: - CollidableOctreeSystem(World* world, EventBroker* eventBroker, Octree* octree, const std::string& componentType) + FillOctreeSystem(World* world, EventBroker* eventBroker, Octree* octree, const std::string& fillComponentType) : System(world, eventBroker) - , PureSystem(componentType) + , PureSystem(fillComponentType) , m_Octree(octree) { } diff --git a/src/Engine/Collision/CollidableOctreeSystem.cpp b/src/Engine/Collision/FillOctreeSystem.cpp similarity index 64% rename from src/Engine/Collision/CollidableOctreeSystem.cpp rename to src/Engine/Collision/FillOctreeSystem.cpp index 476414dd..d69319de 100644 --- a/src/Engine/Collision/CollidableOctreeSystem.cpp +++ b/src/Engine/Collision/FillOctreeSystem.cpp @@ -1,11 +1,11 @@ -#include "Collision/CollidableOctreeSystem.h" +#include "Collision/FillOctreeSystem.h" -void CollidableOctreeSystem::Update(double dt) +void FillOctreeSystem::Update(double dt) { m_Octree->ClearDynamicObjects(); } -void CollidableOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) +void FillOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { if (entity.HasComponent("AABB")) { boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index f5afcaeb..157ea5ab 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -1,5 +1,5 @@ #include "Game.h" -#include "Collision/CollidableOctreeSystem.h" +#include "Collision/FillOctreeSystem.h" #include "Collision/EntityAABB.h" #include "Collision/TriggerSystem.h" #include "Collision/CollisionSystem.h" @@ -93,8 +93,8 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); + m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); + m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); From 8e86cc2123b72dd26f348b355a5f30217a19eaa6 Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 8 Feb 2016 14:23:53 +0100 Subject: [PATCH 099/131] Walking sound logic moved to PlayerMovementSystem and makes use of "wishDirection" to alleviate the problem where m_DistanceMoved were reset when it was not supposed to. --- include/Game/Systems/PlayerMovementSystem.h | 14 ++++++++ include/Game/Systems/SoundSystem.h | 2 -- src/Game/Systems/PlayerMovementSystem.cpp | 40 ++++++++++++++++++++- src/Game/Systems/SoundSystem.cpp | 26 -------------- 4 files changed, 53 insertions(+), 29 deletions(-) diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 395ccce5..defaa8ae 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -5,6 +5,7 @@ #include "Input/FirstPersonInputController.h" #include #include "Events/EDoubleJump.h" +#include "../Engine/Sound/EPlaySoundOnEntity.h" class PlayerMovementSystem : public ImpureSystem, PureSystem { @@ -19,6 +20,19 @@ private: // State std::unordered_map*> m_PlayerInputControllers; + EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; + // Walking logic + // Keeps track of how far the player has walked within this "key press session". + float m_DistanceMoved = 0.0f; + // How far a step is (How often the step sound will be played). + const float m_PlayerStepLength = 1.75f; + // Determine what sound file to play. + bool m_LeftFoot = false; + // To get a difference when calculating the walking state. + glm::vec3 m_LastPosition = glm::vec3(); + // The logic for making the sound play when player is moving + void playerStep(double dt); + EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(Events::PlayerSpawned& e); diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index b14d7486..4f0e7211 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -30,8 +30,6 @@ public: virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override; virtual void Update(double dt) override; private: - // The logic for making the sound play when player is moving - void playerStep(double dt); EntityWrapper m_LocalPlayer = EntityWrapper(); World* m_World = nullptr; diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 3e4d9e76..c5c50a41 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -56,6 +56,12 @@ void PlayerMovementSystem::Update(double dt) } else { wishSpeed = playerMovementSpeed; } + if (player.ID == m_LocalPlayer.ID) { + if (glm::length(wishDirection) == 0) { + // If no key is pressed, reset the distance moved since last step. + m_DistanceMoved = 0; + } + } glm::vec3& velocity = cPhysics["Velocity"]; ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z); glm::vec3 groundVelocity(0.f, 0.f, 0.f); @@ -135,6 +141,7 @@ void PlayerMovementSystem::Update(double dt) controller->Reset(); } + playerStep(dt); } void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) @@ -169,10 +176,41 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp position += velocity * (float)dt; } +void PlayerMovementSystem::playerStep(double dt) +{ + if (!m_LocalPlayer.Valid()) { + return; + } + // Position of the local player, used see how far a player has moved. + glm::vec3 pos = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Transform")["Position"]; + // Velocity of the local player, used to see if a player is airborne. + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; + m_DistanceMoved += glm::length(pos - m_LastPosition); + // Set the last position for next iteration + m_LastPosition = pos; + bool isAirborne = vel.y != 0; + if (m_DistanceMoved > m_PlayerStepLength && !isAirborne) { + // Player moved a step's distance + // Create footstep sound + Events::PlaySoundOnEntity e; + EntityID child = m_World->CreateEntity(m_LocalPlayer.ID); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + e.EmitterID = child; + e.FilePath = m_LeftFoot ? "Audio/footstep/footstep2.wav" : "Audio/footstep/footstep3.wav"; + m_LeftFoot = !m_LeftFoot; + m_EventBroker->Publish(e); + m_DistanceMoved = 0.f; + } +} + bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e) { // When a player spawns, create an input controller for them m_PlayerInputControllers[e.Player] = new FirstPersonInputController(m_EventBroker, e.PlayerID); - + if (e.PlayerID == -1) { + // Keep track of the local player + m_LocalPlayer = e.Player; + } return true; } diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 3f9b75d0..ac3ab2e9 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -25,32 +25,6 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp void SoundSystem::Update(double dt) { - playerStep(dt); -} - -void SoundSystem::playerStep(double dt) -{ - if (!m_LocalPlayer.Valid()) { - return; - } - // Position of the local player, used see how far a player has moved. - glm::vec3 pos = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Transform")["Position"]; - // Velocity of the local player, used to see if a player is airborne. - glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; - m_DistanceMoved += glm::length(pos - m_LastPosition); - // Set the last position for next iteration - m_LastPosition = pos; - bool isAirborne = vel.y != 0; - if (m_DistanceMoved > m_PlayerStepLength && !isAirborne) { - // Player moved a step's distance - // Create footstep sound - Events::PlaySoundOnEntity e; - e.EmitterID = createChildEmitter(m_LocalPlayer); - e.FilePath = m_LeftFoot ? "Audio/footstep/footstep2.wav" : "Audio/footstep/footstep3.wav"; - m_LeftFoot = !m_LeftFoot; - m_EventBroker->Publish(e); - m_DistanceMoved = 0.f; - } } bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) From 14c5410524e12a5b0e97eb8cd5d766754a91495a Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 8 Feb 2016 14:29:55 +0100 Subject: [PATCH 100/131] Merge fix --- src/Game/Systems/SoundSystem.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index ac3ab2e9..555e7ff0 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -24,8 +24,7 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp } void SoundSystem::Update(double dt) -{ -} +{ } bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) { @@ -129,23 +128,23 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) { - if (e.PlayerID == m_LocalPlayer.ID) { - Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); - ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch - m_EventBroker->Publish(ev); - } + //if (e.PlayerID == m_LocalPlayer.ID) { + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch + m_EventBroker->Publish(ev); + //} return false; } bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) { - if (e.PlayerHealedID == m_LocalPlayer.ID) { - Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); - ev.FilePath = "Audio/pickup/pickup2.wav"; - m_EventBroker->Publish(ev); - } + //if (e.PlayerHealedID == m_LocalPlayer.ID) { + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.FilePath = "Audio/pickup/pickup2.wav"; + m_EventBroker->Publish(ev); + //} return false; } From 93c6f3c0a35e0ff673e37f956b65a989770ce8af Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 8 Feb 2016 14:34:37 +0100 Subject: [PATCH 101/131] AABBs are auto attached when adding Trigger/Collideable/etc, also added AttachComponent method to ComponentWrapper. --- include/Engine/Collision/Collision.h | 2 ++ include/Engine/Core/EntityWrapper.h | 1 + resources/Schema/Entities/GameMap.xml | 3 +- src/Engine/Collision/Collision.cpp | 36 ++++++++++------------- src/Engine/Collision/FillOctreeSystem.cpp | 14 +++++---- src/Engine/Collision/TriggerSystem.cpp | 4 +++ src/Engine/Core/EntityWrapper.cpp | 9 ++++++ 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 6e4858b2..6d16e090 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -78,6 +78,8 @@ bool AABBVsAABB(const AABB& a, const AABB& b); //Also outputs the minimum translation that box [a] would need in order to resolve collision. bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation); +//Attaches an AABB which contains all vertices in the entitys Model. +bool AttachAABBComponentFromModel(EntityWrapper entity); // Calculates an absolute AABB from an entity AABB component boost::optional EntityAbsoluteAABB(EntityWrapper& entity); diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index bf34b9be..087471c0 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -25,6 +25,7 @@ struct EntityWrapper const std::string Name(); bool HasComponent(const std::string& componentType); + void AttachComponent(const char* componentName); EntityWrapper Parent(); EntityWrapper FirstChildByName(const std::string& name); EntityWrapper FirstParentWithComponent(const std::string& componentType); diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml index 4d0a2716..90807eb5 100644 --- a/resources/Schema/Entities/GameMap.xml +++ b/resources/Schema/Entities/GameMap.xml @@ -9,7 +9,8 @@ - + + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index fe4eb5e0..b150d667 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -564,33 +564,29 @@ bool AABBvsTriangles(const AABB& box, return hit; } -bool attachAABBComponentFromModel(World* world, EntityID id) +bool AttachAABBComponentFromModel(EntityWrapper entity) { - if (!world->HasComponent(id, "Model")) { + if (!entity.HasComponent("Model")) { return false; } - ComponentWrapper model = world->GetComponent(id, "Model"); - ComponentWrapper collision = world->AttachComponent(id, "AABB"); - Model* modelRes = ResourceManager::Load(model["Resource"]); - if (modelRes == nullptr) { + //Derive AABB from model + RawModel* model; + try { + model = ResourceManager::Load(entity["Model"]["Resource"]); + } catch (const std::exception&) { return false; } - glm::mat4 modelMatrix = modelRes->Matrix(); - - glm::vec3 mini = glm::vec3(INFINITY, INFINITY, INFINITY); - glm::vec3 maxi = glm::vec3(-INFINITY, -INFINITY, -INFINITY); - for (const auto& v : modelRes->Vertices()) { - const auto& wPos = modelMatrix * glm::vec4(v.Position.x, v.Position.y, v.Position.z, 1); - maxi.x = std::max(wPos.x, maxi.x); - maxi.y = std::max(wPos.y, maxi.y); - maxi.z = std::max(wPos.z, maxi.z); - mini.x = std::min(wPos.x, mini.x); - mini.y = std::min(wPos.y, mini.y); - mini.z = std::min(wPos.z, mini.z); + glm::vec3 mini(INFINITY); + glm::vec3 maxi(-INFINITY); + for (const auto& v : model->m_Vertices) { + mini = glm::min(mini, v.Position); + maxi = glm::max(maxi, v.Position); } - collision["Origin"] = 0.5f * (maxi + mini); - collision["Size"] = maxi - mini; + + entity.AttachComponent("AABB"); + entity["AABB"]["Origin"] = 0.5f * (maxi + mini); + entity["AABB"]["Size"] = maxi - mini; return true; } diff --git a/src/Engine/Collision/FillOctreeSystem.cpp b/src/Engine/Collision/FillOctreeSystem.cpp index d69319de..8c03b5c2 100644 --- a/src/Engine/Collision/FillOctreeSystem.cpp +++ b/src/Engine/Collision/FillOctreeSystem.cpp @@ -7,12 +7,14 @@ void FillOctreeSystem::Update(double dt) void FillOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { - if (entity.HasComponent("AABB")) { - boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); - if (absoluteAABB) { - m_Octree->AddDynamicObject(*absoluteAABB); + if (!entity.HasComponent("AABB")) { + //Derive AABB from model. + if (!Collision::AttachAABBComponentFromModel(entity)) { + return; } - } else if (entity.HasComponent("Model")) { - // TODO: Derive AABB from model + } + boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); + if (absoluteAABB) { + m_Octree->AddDynamicObject(*absoluteAABB); } } \ No newline at end of file diff --git a/src/Engine/Collision/TriggerSystem.cpp b/src/Engine/Collision/TriggerSystem.cpp index 410a7fa1..adc778e5 100644 --- a/src/Engine/Collision/TriggerSystem.cpp +++ b/src/Engine/Collision/TriggerSystem.cpp @@ -6,6 +6,10 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapper& cTrigger, double dt) { // The trigger *should* have a bounding box, or something, to test against so it can be triggered. + // If it doesn't, add one as big as the model for now, then size can be modified in editor if necessary. + if (!triggerEntity.HasComponent("AABB")) { + Collision::AttachAABBComponentFromModel(triggerEntity); + } boost::optional triggerBox = Collision::EntityAbsoluteAABB(triggerEntity); if (!triggerBox) { return; diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 071329a3..b0d08e66 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -16,6 +16,15 @@ bool EntityWrapper::HasComponent(const std::string& componentName) return World->HasComponent(ID, componentName); } +void EntityWrapper::AttachComponent(const char* componentName) +{ + if (!Valid()) { + LOG_WARNING("Could not attach \"%s\" component to #%i, component is not valid.", componentName, ID); + return; + } + World->AttachComponent(ID, componentName); +} + EntityWrapper EntityWrapper::Parent() { if (this->World == nullptr || this->ID == EntityID_Invalid) { From 9055d5f69798373bbfc6cac649a0bc5af89a152d Mon Sep 17 00:00:00 2001 From: Tleety Date: Mon, 8 Feb 2016 15:22:28 +0100 Subject: [PATCH 102/131] Bugfix --- src/Engine/Rendering/DrawFinalPass.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 57eecd1a..72a65e80 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -106,6 +106,9 @@ void DrawFinalPass::Draw(RenderScene& scene) glClearStencil(0x00); glClear(GL_STENCIL_BUFFER_BIT); + //Fill depth buffer + + state->StencilMask(0x00); DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); GLERROR("OpaqueObjects"); @@ -135,8 +138,8 @@ void DrawFinalPass::Draw(RenderScene& scene) DrawFinalPassState* stateLowRes = new DrawFinalPassState(m_FinalPassFrameBufferLowRes.GetHandle()); //Draw the lowres texture that will be shown behind the shield. - state->Enable(GL_SCISSOR_TEST); - state->Enable(GL_DEPTH_TEST); + stateLowRes->Enable(GL_SCISSOR_TEST); + stateLowRes->Enable(GL_DEPTH_TEST); //TODO: Viewports and scissor should be in state glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_ShieldPixelRate, m_Renderer->GetViewportSize().Height/m_ShieldPixelRate); glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); @@ -145,23 +148,23 @@ void DrawFinalPass::Draw(RenderScene& scene) glClear(GL_STENCIL_BUFFER_BIT); //TODO: This should not be here... - state->StencilFunc(GL_ALWAYS, 1, 0xFF); - state->StencilMask(0x00); + stateLowRes->StencilFunc(GL_ALWAYS, 1, 0xFF); + stateLowRes->StencilMask(0x00); DrawToDepthBuffer(scene.Jobs.OpaqueObjects, scene); DrawToDepthBuffer(scene.Jobs.TransparentObjects, scene); //Draw shields to stencil pass - state->StencilFunc(GL_ALWAYS, 1, 0xFF); - state->StencilMask(0xFF); - state->Enable(GL_DEPTH_TEST); + stateLowRes->StencilFunc(GL_ALWAYS, 1, 0xFF); + stateLowRes->StencilMask(0xFF); + stateLowRes->Enable(GL_DEPTH_TEST); DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene); GLERROR("StencilPass"); glClear(GL_DEPTH_BUFFER_BIT); - state->Enable(GL_DEPTH_TEST); - state->StencilFunc(GL_LEQUAL, 1, 0xFF); - state->StencilMask(0x00); + stateLowRes->Enable(GL_DEPTH_TEST); + stateLowRes->StencilFunc(GL_LEQUAL, 1, 0xFF); + stateLowRes->StencilMask(0x00); DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); GLERROR("OpaqueObjects"); DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); From 6f163bf3a3dfefc01924778989c14f6a74b08e54 Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 8 Feb 2016 16:13:09 +0100 Subject: [PATCH 103/131] Fixed bug where it crashed on respawn. Also bug where i subscribed to an event twice. --- src/Engine/Sound/SoundManager.cpp | 16 ++++++++++++++++ src/Game/Systems/SoundSystem.cpp | 13 ++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Engine/Sound/SoundManager.cpp b/src/Engine/Sound/SoundManager.cpp index d75e9afc..b952426c 100644 --- a/src/Engine/Sound/SoundManager.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -101,9 +101,17 @@ void SoundManager::updateEmitters(double dt) if (!m_World->ValidEntity(it->first)) { return; } + if (!m_World->HasComponent(it->first, "SoundEmitter")) + return; + glm::vec3 previousPos; alGetSource3f(it->second->ALsource, AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get next pos + if (!m_World->HasComponent(it->first, "Transform")) + return; + if (!m_World->ValidEntity(m_World->GetParent(it->first))) { + return; + } glm::vec3 nextPos = Transform::AbsolutePosition(m_World, it->first); // Calculate velocity glm::vec3 velocity = glm::vec3(nextPos - previousPos) / (float)dt; @@ -135,6 +143,10 @@ void SoundManager::updateListener(double dt) } for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { EntityWrapper listener(m_World, (*it).EntityID); + if (!listener.Valid()) + { + break; + } if (listener.IsChildOf(m_LocalPlayer) || listener == m_LocalPlayer) { glm::vec3 previousPos; alGetListener3f(AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get previous pos @@ -228,7 +240,11 @@ bool SoundManager::OnContinueSound(const Events::ContinueSound & e) bool SoundManager::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) { auto listenerComponents = m_World->GetComponents("Listener"); + LOG_INFO("SIZZE: %i", listenerComponents->size()); for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { + if((*it).EntityID != m_LocalPlayer.ID) { + break; + } auto emitterChild = m_World->CreateEntity((*it).EntityID); auto emitter = m_World->AttachComponent(emitterChild, "SoundEmitter"); (bool&)emitter["Loop"] = false; diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 555e7ff0..8315160c 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -3,7 +3,7 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventbroker) : System(world, eventbroker) , PureSystem("SoundEmitter") - , ImpureSystem() + //, ImpureSystem() { m_World = world; m_EventBroker = eventbroker; @@ -12,7 +12,6 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventbroker) EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump); EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility); EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundSystem::OnShoot); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); @@ -31,10 +30,10 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) if (e.PlayerID == -1) { // Local player m_World->AttachComponent(e.Player.ID, "Listener"); m_LocalPlayer = e.Player; - Events::PlaySoundOnEntity event; - event.EmitterID = createChildEmitter(m_LocalPlayer); - event.FilePath = "Audio/announcer/go.wav"; - m_EventBroker->Publish(event); + Events::PlaySoundOnEntity go; + go.EmitterID = createChildEmitter(m_LocalPlayer); + go.FilePath = "Audio/announcer/go.wav"; + m_EventBroker->Publish(go); // TEMP: starts bgm { Events::PlayBackgroundMusic ev; @@ -131,7 +130,7 @@ bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) //if (e.PlayerID == m_LocalPlayer.ID) { Events::PlaySoundOnEntity ev; ev.EmitterID = createChildEmitter(m_LocalPlayer); - ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch + ev.FilePath = "Audio/die/die2.wav"; m_EventBroker->Publish(ev); //} return false; From 7752832ce54a8851a2e9bd0096ccad3bbf8190f6 Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 8 Feb 2016 16:21:49 +0100 Subject: [PATCH 104/131] No longer needs this walk logic in SoundSystem --- include/Game/Systems/SoundSystem.h | 12 +----------- src/Game/Systems/SoundSystem.cpp | 11 +---------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index 4f0e7211..c69f7296 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -39,17 +39,7 @@ private: void playerJumps(); // Helper function EntityID createChildEmitter(EntityWrapper parent); - - // Walking logic - // Keeps track of how far the player has walked within this "key press session". - float m_DistanceMoved = 0.0f; - // How far a step is (How often the step sound will be played). - const float m_PlayerStepLength = 1.75f; - // To get a difference when calculating the walking state. - glm::vec3 m_LastPosition = glm::vec3(); - // Determine what sound file to play. - bool m_LeftFoot = false; - + std::default_random_engine generator; EventRelay m_EPlayerSpawned; diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 8315160c..b218e6c1 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -18,9 +18,7 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventbroker) } void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) -{ - -} +{ } void SoundSystem::Update(double dt) { } @@ -52,13 +50,6 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) return true; } } - if (e.Command == "Forward" || e.Command == "Right") { - if (e.Value == 0) { - // Key released - // Reset the distance moved (player walk logic) - m_DistanceMoved = 0.f; - } - } if (e.Command == "TakeDamage" && e.Value > 0) { Events::PlayerDamage ev; ev.Player = m_LocalPlayer; From aa5878d6dfe8453a69c0e287c11cae53cfa7abb0 Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 8 Feb 2016 16:40:13 +0100 Subject: [PATCH 105/131] Used config for soundsystem properties. --- assets | 2 +- include/Engine/Sound/SoundManager.h | 2 ++ include/Game/Systems/SoundSystem.h | 2 ++ resources/DefaultConfig.ini | 5 +++++ src/Engine/Sound/SoundManager.cpp | 4 +++- src/Game/Systems/SoundSystem.cpp | 8 +++++--- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/assets b/assets index cfeeb1f8..88b1b9f0 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit cfeeb1f880e19356477a703da92204eede09db5d +Subproject commit 88b1b9f047c2cf02c1d39da39dff472cadfb93e7 diff --git a/include/Engine/Sound/SoundManager.h b/include/Engine/Sound/SoundManager.h index 3923a17b..2c07578c 100644 --- a/include/Engine/Sound/SoundManager.h +++ b/include/Engine/Sound/SoundManager.h @@ -13,6 +13,8 @@ #include "Core/World.h" #include "Core/EventBroker.h" +#include "../Engine/Core/ResourceManager.h" +#include "../Engine/Core/ConfigFile.h" #include "Core/Transform.h" // Absolute transform #include "Sound/Sound.h" #include "../Engine/Sound/EPlayQueueOnEntity.h" diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index c69f7296..0f7f5102 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -5,6 +5,7 @@ #include "../Engine/Core/System.h" #include "../Engine/Core/ResourceManager.h" +#include "../Engine/Core/ConfigFile.h" #include "../Engine/Sound/Sound.h" #include "../Engine/Sound/EPlayQueueOnEntity.h" #include "../Engine/Core/EPlayerSpawned.h" @@ -34,6 +35,7 @@ private: World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; + std::string m_Announcer = ""; // Logic for playing a sound when a player jumps void playerJumps(); diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index 86dc735c..12ec06c8 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -29,3 +29,8 @@ TimeoutMs=15000 [Multithreading] ResourceLoading=true + +[Sound] +BGMVolume=1.0 +SFXVolume=1.0 +Announcer=female \ No newline at end of file diff --git a/src/Engine/Sound/SoundManager.cpp b/src/Engine/Sound/SoundManager.cpp index b952426c..972a38bb 100644 --- a/src/Engine/Sound/SoundManager.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -2,12 +2,14 @@ SoundManager::SoundManager(World* world, EventBroker* eventBroker, bool editorMode) { + ConfigFile* config = ResourceManager::Load("Config.ini"); m_EventBroker = eventBroker; m_World = world; m_EditorEnabled = editorMode; + m_BGMVolumeChannel = config->Get("Sound.BGMVolume", 1.f); + m_SFXVolumeChannel = config->Get("Sound.SFXVolume", 1.f); initOpenAL(); - alSpeedOfSound(340.29f); alDistanceModel(AL_LINEAR_DISTANCE); alDopplerFactor(1); diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index b218e6c1..06e7d67a 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -5,6 +5,8 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventbroker) , PureSystem("SoundEmitter") //, ImpureSystem() { + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_Announcer = ResourceManager::Load("Config.ini")->Get("Sound.Announcer", "female"); m_World = world; m_EventBroker = eventbroker; EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); @@ -30,7 +32,7 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) m_LocalPlayer = e.Player; Events::PlaySoundOnEntity go; go.EmitterID = createChildEmitter(m_LocalPlayer); - go.FilePath = "Audio/announcer/go.wav"; + go.FilePath = "Audio/announcer/" + m_Announcer + "/go.wav"; m_EventBroker->Publish(go); // TEMP: starts bgm { @@ -86,9 +88,9 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) int team = (int)m_World->GetComponent(m_LocalPlayer.ID, "Team")["Team"]; Events::PlaySoundOnEntity ev; if (team == homeTeam) { - ev.FilePath = "Audio/announcer/objective_achieved.wav"; + ev.FilePath = "Audio/announcer/" + m_Announcer + "/objective_achieved.wav"; } else { - ev.FilePath = "Audio/announcer/objective_failed.wav"; // have not been tested + ev.FilePath = "Audio/announcer/" + m_Announcer + "/objective_failed.wav"; // have not been tested } ev.EmitterID = createChildEmitter(m_LocalPlayer); m_EventBroker->Publish(ev); From 2c64ffc3d11782a0bccb0245fc1b18b91d2b00ad Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 8 Feb 2016 16:52:35 +0100 Subject: [PATCH 106/131] No longer using a variable to see if we're in editor mode. --- include/Engine/Sound/SoundManager.h | 3 +-- src/Engine/Sound/SoundManager.cpp | 26 ++++++++++---------------- src/Game/Game.cpp | 2 +- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/include/Engine/Sound/SoundManager.h b/include/Engine/Sound/SoundManager.h index 2c07578c..38ec62ff 100644 --- a/include/Engine/Sound/SoundManager.h +++ b/include/Engine/Sound/SoundManager.h @@ -49,7 +49,7 @@ class SoundManager { public: SoundManager() { } - SoundManager(World* world, EventBroker* eventBroker, bool editorMode); + SoundManager(World* world, EventBroker* eventBroker); ~SoundManager(); // Update emitters / listener void Update(double dt); @@ -93,7 +93,6 @@ private: float m_BGMVolumeChannel = 1.0f; float m_SFXVolumeChannel = 1.0f; - bool m_EditorEnabled = false; EntityWrapper m_LocalPlayer = EntityWrapper(); // Events diff --git a/src/Engine/Sound/SoundManager.cpp b/src/Engine/Sound/SoundManager.cpp index 972a38bb..8ba6a502 100644 --- a/src/Engine/Sound/SoundManager.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -1,11 +1,10 @@ #include "Sound/SoundManager.h" -SoundManager::SoundManager(World* world, EventBroker* eventBroker, bool editorMode) +SoundManager::SoundManager(World* world, EventBroker* eventBroker) { ConfigFile* config = ResourceManager::Load("Config.ini"); m_EventBroker = eventBroker; m_World = world; - m_EditorEnabled = editorMode; m_BGMVolumeChannel = config->Get("Sound.BGMVolume", 1.f); m_SFXVolumeChannel = config->Get("Sound.SFXVolume", 1.f); @@ -103,9 +102,9 @@ void SoundManager::updateEmitters(double dt) if (!m_World->ValidEntity(it->first)) { return; } - if (!m_World->HasComponent(it->first, "SoundEmitter")) + if (!m_World->HasComponent(it->first, "SoundEmitter")) return; - + glm::vec3 previousPos; alGetSource3f(it->second->ALsource, AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get next pos @@ -123,14 +122,11 @@ void SoundManager::updateEmitters(double dt) auto emitter = m_World->GetComponent(it->first, "SoundEmitter"); setSoundProperties(it->second, &emitter); - // To make an emitter play when spawned in editor mode - if (m_EditorEnabled) { - // Path changed - if (it->second->SoundResource->Path() != (std::string)emitter["FilePath"]) { - it->second->SoundResource = ResourceManager::Load((std::string)emitter["FilePath"]); - if (it->second->SoundResource->Buffer() != 0) { - playSound(it->second); - } + // Path changed + if (it->second->SoundResource->Path() != (std::string)emitter["FilePath"]) { + it->second->SoundResource = ResourceManager::Load((std::string)emitter["FilePath"]); + if (it->second->SoundResource->Buffer() != 0) { + playSound(it->second); } } } @@ -145,8 +141,7 @@ void SoundManager::updateListener(double dt) } for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { EntityWrapper listener(m_World, (*it).EntityID); - if (!listener.Valid()) - { + if (!listener.Valid()) { break; } if (listener.IsChildOf(m_LocalPlayer) || listener == m_LocalPlayer) { @@ -242,9 +237,8 @@ bool SoundManager::OnContinueSound(const Events::ContinueSound & e) bool SoundManager::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) { auto listenerComponents = m_World->GetComponents("Listener"); - LOG_INFO("SIZZE: %i", listenerComponents->size()); for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { - if((*it).EntityID != m_LocalPlayer.ID) { + if ((*it).EntityID != m_LocalPlayer.ID) { break; } auto emitterChild = m_World->CreateEntity((*it).EntityID); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 6c495272..37eb2ea6 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -74,7 +74,7 @@ Game::Game(int argc, char* argv[]) } // Create the sound manager - m_SoundManager = new SoundManager(m_World, m_EventBroker, true); + m_SoundManager = new SoundManager(m_World, m_EventBroker); // Create Octrees m_OctreeCollision = new Octree(AABB(glm::vec3(-100), glm::vec3(100)), 4); From 060e674a6f45ddd547a53ee7a53270ae5c06547a Mon Sep 17 00:00:00 2001 From: Teejoon Date: Mon, 8 Feb 2016 17:37:18 +0100 Subject: [PATCH 107/131] Picking supports skinned meshes --- assets | 2 +- include/Engine/Rendering/PickingPass.h | 1 + resources/Schema/Entities/AnimatedArmy.xml | 10 +- resources/Schema/Entities/AssetPedistal.xml | 2 +- resources/Schema/Entities/CapturePoint.xml | 2 +- resources/Schema/Entities/CaptureTest.xml | 14 +-- .../Schema/Entities/CaptureTestState1.xml | 14 +-- .../Schema/Entities/CaptureTestState2.xml | 14 +-- .../Schema/Entities/CaptureTestState3.xml | 20 ++-- .../Schema/Entities/CaptureTestState4.xml | 20 ++-- .../Schema/Entities/CaptureTestState5.xml | 16 +-- .../Schema/Entities/CollisionTestLevel.xml | 4 +- resources/Schema/Entities/EditorTestWorld.xml | 22 ++-- .../Schema/Entities/EditorWidgetRotate.xml | 6 +- .../Schema/Entities/EditorWidgetScale.xml | 8 +- .../Schema/Entities/EditorWidgetTranslate.xml | 14 +-- resources/Schema/Entities/GameMap.xml | 4 +- resources/Schema/Entities/Model.xml | 2 +- resources/Schema/Entities/MovementTest.xml | 16 +-- resources/Schema/Entities/Player.xml | 13 +-- .../Schema/Entities/QualityAssurance.xml | 64 +++++------ resources/Schema/Entities/RayBlue.xml | 2 +- resources/Schema/Entities/RayRed.xml | 2 +- resources/Schema/Entities/RenderingWorld.xml | 10 +- resources/Schema/Entities/ShootEventTest.xml | 20 ++-- .../Entities/SpawnPointClusterWithModels.xml | 8 +- .../Entities/SpawnerWithPlayerModel.xml | 2 +- resources/Schema/Entities/Test.xml | 4 +- .../Shaders/ForwardPlusSkinned.vert.glsl | 2 +- resources/Shaders/Picking.vert.glsl | 15 +-- resources/Shaders/PickingSkinned.vert.glsl | 32 ++++++ src/Engine/Rendering/PickingPass.cpp | 104 +++++++++++++----- tools/MayaExporter/MayaExporter.opensdf | Bin 38 -> 0 bytes tools/MayaExporter/MayaExporter/Mesh.cpp | 38 +++---- 34 files changed, 281 insertions(+), 226 deletions(-) create mode 100644 resources/Shaders/PickingSkinned.vert.glsl delete mode 100644 tools/MayaExporter/MayaExporter.opensdf diff --git a/assets b/assets index c4898d82..2151ad93 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c4898d8281b5584d89b1caf14dab8e5fac120321 +Subproject commit 2151ad934d2ff3f779ae7e4b38c20bbb728cd02d diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index da3ed31b..2ce2e78d 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -40,6 +40,7 @@ private: const IRenderer* m_Renderer; ShaderProgram* m_PickingProgram; + ShaderProgram* m_PickingSkinnedProgram; Camera* m_Camera; struct PickingInfo diff --git a/resources/Schema/Entities/AnimatedArmy.xml b/resources/Schema/Entities/AnimatedArmy.xml index b711a0fe..ee1e45b3 100644 --- a/resources/Schema/Entities/AnimatedArmy.xml +++ b/resources/Schema/Entities/AnimatedArmy.xml @@ -20,7 +20,7 @@ - models/dummyscene.mesh + Models/Test/DummyScene.mesh @@ -31,7 +31,7 @@ - models/animtest. + Models/Test/AnimTest.mesh @@ -42,7 +42,7 @@ - models/animTest.mesh + Models/Test/AnimTest.mesh @@ -53,7 +53,7 @@ - models/animTest.mesh + Models/Test/AnimTest.mesh @@ -64,7 +64,7 @@ - models/animTest.mesh + Models/Test/AnimTest.mesh diff --git a/resources/Schema/Entities/AssetPedistal.xml b/resources/Schema/Entities/AssetPedistal.xml index 728a3028..3c816149 100644 --- a/resources/Schema/Entities/AssetPedistal.xml +++ b/resources/Schema/Entities/AssetPedistal.xml @@ -35,7 +35,7 @@ - Models/AssaultWeaponBlue.mesh + Models/Weapons/Blue/AssaultWeaponBlue.mesh diff --git a/resources/Schema/Entities/CapturePoint.xml b/resources/Schema/Entities/CapturePoint.xml index 9b3c5036..9f33c4de 100644 --- a/resources/Schema/Entities/CapturePoint.xml +++ b/resources/Schema/Entities/CapturePoint.xml @@ -5,7 +5,7 @@ - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitSphere.mesh + Models/Core/UnitSphere.mesh diff --git a/resources/Schema/Entities/CaptureTest.xml b/resources/Schema/Entities/CaptureTest.xml index 5f657e51..3d678bd7 100644 --- a/resources/Schema/Entities/CaptureTest.xml +++ b/resources/Schema/Entities/CaptureTest.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.mesh + Models/Test/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -81,7 +81,7 @@ 2 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -102,7 +102,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -120,7 +120,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -138,7 +138,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState1.xml b/resources/Schema/Entities/CaptureTestState1.xml index ffabd5c2..64999074 100644 --- a/resources/Schema/Entities/CaptureTestState1.xml +++ b/resources/Schema/Entities/CaptureTestState1.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.mesh + Models/Test/DummyScene.mesh @@ -42,7 +42,7 @@ 6.9158446328696002 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -63,7 +63,7 @@ 1 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -83,7 +83,7 @@ 2 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -104,7 +104,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -122,7 +122,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -140,7 +140,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState2.xml b/resources/Schema/Entities/CaptureTestState2.xml index 29abdfbd..6ddb306f 100644 --- a/resources/Schema/Entities/CaptureTestState2.xml +++ b/resources/Schema/Entities/CaptureTestState2.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.mesh + Models/Test/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -79,7 +79,7 @@ 2 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -98,7 +98,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -116,7 +116,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -134,7 +134,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState3.xml b/resources/Schema/Entities/CaptureTestState3.xml index ff875dc4..3bed3624 100644 --- a/resources/Schema/Entities/CaptureTestState3.xml +++ b/resources/Schema/Entities/CaptureTestState3.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.mesh + Models/Test/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -81,7 +81,7 @@ 2 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -101,7 +101,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -122,7 +122,7 @@ 4 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -140,7 +140,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -158,7 +158,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -176,7 +176,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -194,7 +194,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState4.xml b/resources/Schema/Entities/CaptureTestState4.xml index 740d7e7b..30db23aa 100644 --- a/resources/Schema/Entities/CaptureTestState4.xml +++ b/resources/Schema/Entities/CaptureTestState4.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.mesh + Models/Test/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -79,7 +79,7 @@ 2 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -96,7 +96,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -115,7 +115,7 @@ 4 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -133,7 +133,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -151,7 +151,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -169,7 +169,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -187,7 +187,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState5.xml b/resources/Schema/Entities/CaptureTestState5.xml index f1b07a7b..8fe85068 100644 --- a/resources/Schema/Entities/CaptureTestState5.xml +++ b/resources/Schema/Entities/CaptureTestState5.xml @@ -17,7 +17,7 @@ - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -39,7 +39,7 @@ 1 - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -57,7 +57,7 @@ 2 - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -79,7 +79,7 @@ 3 - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -104,7 +104,7 @@ 4 - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -124,7 +124,7 @@ - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitCube.mesh + Models/Core/UnitCube.mesh @@ -143,7 +143,7 @@ - C:\Users\123456\Workspace\TacticalZ\assets\Models\Core\UnitCube.mesh + Models/Core/UnitCube.mesh @@ -160,7 +160,7 @@ - C:\Users\123456\Workspace\TacticalZ\assets\Models\DummyScene.mesh + Models/Test/DummyScene.mesh diff --git a/resources/Schema/Entities/CollisionTestLevel.xml b/resources/Schema/Entities/CollisionTestLevel.xml index e58ab6ce..1a811f46 100644 --- a/resources/Schema/Entities/CollisionTestLevel.xml +++ b/resources/Schema/Entities/CollisionTestLevel.xml @@ -6,7 +6,7 @@ - Models/DummyScene.mesh + Models/Test/DummyScene.mesh @@ -28,7 +28,7 @@ - Models/RotationWidgetX.mesh + Models/Widgets/Rotate/RotationWidgetX.mesh diff --git a/resources/Schema/Entities/EditorTestWorld.xml b/resources/Schema/Entities/EditorTestWorld.xml index 4727c777..46e6d54d 100755 --- a/resources/Schema/Entities/EditorTestWorld.xml +++ b/resources/Schema/Entities/EditorTestWorld.xml @@ -37,7 +37,7 @@ 0.80000001192092896 - Models/DirectionalLightWidget.mesh + Models/Widgets/Lights/DirectionalLightWidget.mesh 1 @@ -62,7 +62,7 @@ 3 - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -73,7 +73,7 @@ - Models/AssaultWeaponRed.mesh + Models/Weapons/Red/AssaultWeaponRed.mesh true @@ -86,7 +86,7 @@ - Models/DefenderGunRed.mesh + Models/Weapons/Red/DefenderGunRed.mesh true false @@ -115,7 +115,7 @@ 1 - models/AssaultAnimated.mesh + Models/Characters/Assault/AssaultAnimated.mesh @@ -131,7 +131,7 @@ 1 - models/AssaultAnimated.mesh + Models/Characters/Assault/AssaultAnimated.mesh @@ -157,7 +157,7 @@ - Models/Log.mesh + Models/Props/TreeLog.mesh @@ -176,7 +176,7 @@ - models/NormSpecIncdMapSphere.mesh + Models/Test/NormSpecIncdMapSphere.mesh @@ -260,7 +260,7 @@ - Models/NormalMapSphere.mesh + Models/Test/NormalMapSphere.mesh @@ -271,7 +271,7 @@ - Models/SpecularMapSphere.mesh + Models/Test/SpecularMapSphere.mesh @@ -313,7 +313,7 @@ - Models/IncandescenceMapSphere.mesh + Models/Test/IncandescenceMapSphere.mesh diff --git a/resources/Schema/Entities/EditorWidgetRotate.xml b/resources/Schema/Entities/EditorWidgetRotate.xml index 88452aac..1276f3e4 100644 --- a/resources/Schema/Entities/EditorWidgetRotate.xml +++ b/resources/Schema/Entities/EditorWidgetRotate.xml @@ -18,7 +18,7 @@ - Models/RotationWidgetX.mesh + Models/Widgets/Rotate/RotationWidgetX.mesh @@ -33,7 +33,7 @@ - Models/RotationWidgetY.mesh + Models/Widgets/Rotate/RotationWidgetY.mesh @@ -48,7 +48,7 @@ - Models/RotationWidgetZ.mesh + Models/Widgets/Rotate/RotationWidgetZ.mesh diff --git a/resources/Schema/Entities/EditorWidgetScale.xml b/resources/Schema/Entities/EditorWidgetScale.xml index 786b079e..65cb2b86 100644 --- a/resources/Schema/Entities/EditorWidgetScale.xml +++ b/resources/Schema/Entities/EditorWidgetScale.xml @@ -3,7 +3,7 @@ - Models/ScaleWidgetOrigin.mesh + Models/Widgets/Scale/ScalingWidgetOrigin.mesh @@ -20,7 +20,7 @@ - Models/ScaleWidgetX.mesh + Models/Widgets/Scale/ScalingWidgetX.mesh @@ -34,7 +34,7 @@ - Models/ScaleWidgetY.mesh + Models/Widgets/Scale/ScalingWidgetY.mesh @@ -48,7 +48,7 @@ - Models/ScaleWidgetZ.mesh + Models/Widgets/Scale/ScalingWidgetZ.mesh diff --git a/resources/Schema/Entities/EditorWidgetTranslate.xml b/resources/Schema/Entities/EditorWidgetTranslate.xml index c6dba4d9..e177b7e9 100644 --- a/resources/Schema/Entities/EditorWidgetTranslate.xml +++ b/resources/Schema/Entities/EditorWidgetTranslate.xml @@ -3,7 +3,7 @@ - Models/TranslationWidgetOrigin.mesh + Models/Widgets/Translate/TranslationWidgetOrigin.mesh @@ -18,7 +18,7 @@ - Models/TranslationWidgetX.mesh + Models/Widgets/Translate/TranslationWidgetX.mesh @@ -30,7 +30,7 @@ - Models/TranslationWidgetY.mesh + Models/Widgets/Translate/TranslationWidgetY.mesh @@ -42,7 +42,7 @@ - Models/TranslationWidgetZ.mesh + Models/Widgets/Translate/TranslationWidgetZ.mesh @@ -54,7 +54,7 @@ - Models/WidgetPlaneX.mesh + Models/Widgets/Translate/TranslationWidgetPlaneX.mesh @@ -66,7 +66,7 @@ - Models/WidgetPlaneY.mesh + Models/Widgets/Translate/TranslationWidgetPlaneY.mesh @@ -78,7 +78,7 @@ - Models/WidgetPlaneZ.mesh + Models/Widgets/Translate/TranslationWidgetPlaneZ.mesh diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml index 97fd3f4d..0d6052eb 100644 --- a/resources/Schema/Entities/GameMap.xml +++ b/resources/Schema/Entities/GameMap.xml @@ -9,7 +9,7 @@ - Models\MapVersion1.mesh + Models/LevelBase/MapVersion1.mesh @@ -21,7 +21,7 @@ 2 - Models/DirectionalLightWidget.mesh + Models/Widgets/Lights/DirectionalLightWidget.mesh false diff --git a/resources/Schema/Entities/Model.xml b/resources/Schema/Entities/Model.xml index 57856cbd..bee6b7e1 100644 --- a/resources/Schema/Entities/Model.xml +++ b/resources/Schema/Entities/Model.xml @@ -19,7 +19,7 @@ - models/animTest.mesh + Models/Test/AnimTest.mesh diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 1378f623..a356b7ee 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -42,7 +42,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -55,7 +55,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -70,7 +70,7 @@ - Models/DirectionalLightWidget.mesh + sModels/Widgets/Lights/DirectionalLightWidget.mesh @@ -153,7 +153,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -166,7 +166,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -228,7 +228,7 @@ - Models/Camera.mesh + Models/Widgets/Camera.mesh @@ -243,7 +243,7 @@ - Models/Camera.mesh + Models/Widgets/Camera.mesh false @@ -256,7 +256,7 @@ - Models/AssaultHeadless.mesh + Models/Characters/Assault/AssaultHeadless.mesh diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index fe24adcc..45c75c63 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,9 +6,6 @@ - - 2.0 - @@ -53,7 +50,7 @@ - Models/Camera.mesh + Models/Widgets/Camera.mesh false @@ -92,7 +89,7 @@ - Models/CrosshairQuad.mesh + Models/Weapons/CrosshairQuad.mesh @@ -112,7 +109,7 @@ true - Models/AssaultWeaponRed.mesh + Models/Weapons/Red/AssaultWeaponRed.mesh @@ -137,7 +134,7 @@ - Models/Camera.mesh + Models/Widgets/Camera.mesh false @@ -156,7 +153,7 @@ - Models/AssaultAnimated.mesh + Models/Characters/Assault/AssaultAnimated.mesh diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index e057cf38..831e7d7c 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -97,7 +97,7 @@ 0.80000001192092896 - Models/DirectionalLightWidget.mesh + Models/Widgets/Lights/DirectionalLightWidget.mesh 1 @@ -126,7 +126,7 @@ 1 - models/AssaultAnimated.mesh + Models/Characters/Assault/AssaultAnimated.mesh @@ -142,7 +142,7 @@ 1 - models/AssaultAnimated.mesh + Models/Characters/Assault/AssaultAnimated.mesh @@ -200,7 +200,7 @@ 1 - Models/AssaultAnimated.mesh + Models/Characters/Assault/AssaultAnimated.mesh @@ -224,7 +224,7 @@ - models/NormSpecIncdMapSphere.mesh + Models/Test/NormSpecIncdMapSphere.mesh @@ -308,7 +308,7 @@ - Models/NormalMapSphere.mesh + Models/Test/NormalMapSphere.mesh @@ -319,7 +319,7 @@ - Models/SpecularMapSphere.mesh + Models/Test/SpecularMapSphere.mesh @@ -361,7 +361,7 @@ - Models/IncandescenceMapSphere.mesh + Models/Test/IncandescenceMapSphere.mesh @@ -422,7 +422,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -435,7 +435,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -448,7 +448,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -461,7 +461,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -493,7 +493,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -506,7 +506,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -519,7 +519,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -532,7 +532,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -608,7 +608,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh true @@ -690,7 +690,7 @@ - Models/AssaultWeaponBlue.mesh + Models/Weapons/Blue/AssaultWeaponBlue.mesh @@ -737,7 +737,7 @@ - Models/AssaultWeaponRed.mesh + Models/Weapons/Red/AssaultWeaponRed.mesh @@ -797,7 +797,7 @@ - Models/SecondaryWeapon.mesh + Models/Weapons/SecondaryWeapon.mesh @@ -844,7 +844,7 @@ - Models/AssualtSoft.mesh + Models/Test/AssaultTPoseSoftEdge.mesh @@ -890,7 +890,7 @@ - Models/DefenderGunBlue.mesh + Models/Weapons/Blue/DefenderGunBlue.mesh @@ -937,7 +937,7 @@ - Models/DefenderGunRed.mesh + Models/Weapons/Red/DefenderGunRed.mesh @@ -984,7 +984,7 @@ - Models/Assualt.mesh + Models/Test/AssaultTPoseHardEdge.mesh @@ -1021,7 +1021,7 @@ - Models/CapturePoint.mesh + Models/Props/CapturePoint.mesh @@ -1073,7 +1073,7 @@ - Models/CapturePoint.mesh + Models/Props/CapturePoint.mesh @@ -1118,7 +1118,7 @@ - Models/CapturePoint.mesh + Models/Props/CapturePoint.mesh @@ -1161,7 +1161,7 @@ - Models/CapturePoint.mesh + Models/Props/CapturePoint.mesh @@ -1207,7 +1207,7 @@ - Models/CapturePoint.mesh + Models/Props/CapturePoint.mesh @@ -1389,7 +1389,7 @@ true - Models/AssaultWeaponBlue.mesh + Models/Weapons/Blue/AssaultWeaponBlue.mesh true @@ -1442,7 +1442,7 @@ 1.1999860997035228 - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh true @@ -1502,7 +1502,7 @@ true - Models/AssaultAnimated.mesh + Models/Characters/Assault/AssaultAnimated.mesh true diff --git a/resources/Schema/Entities/RayBlue.xml b/resources/Schema/Entities/RayBlue.xml index 4a0bb9d4..8d8e6e1e 100644 --- a/resources/Schema/Entities/RayBlue.xml +++ b/resources/Schema/Entities/RayBlue.xml @@ -6,7 +6,7 @@ 0.25 - Models/CylinderBullet.mesh + Models/Weapons/CylinderBullet.mesh true diff --git a/resources/Schema/Entities/RayRed.xml b/resources/Schema/Entities/RayRed.xml index e69df489..11a9b077 100644 --- a/resources/Schema/Entities/RayRed.xml +++ b/resources/Schema/Entities/RayRed.xml @@ -6,7 +6,7 @@ 0.25 - Models/CylinderBullet.mesh + Models/Weapons/CylinderBullet.mesh true diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 20301d5f..8fd61e00 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -20,7 +20,7 @@ - Models/Assault.obj + Models/Characters/Assault/AssaultTPose.mesh @@ -35,7 +35,7 @@ 80 - Models/Camera.mesh + Models/Widgets/Camera.mesh @@ -132,7 +132,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -308,7 +308,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -324,7 +324,7 @@ 0.10000000149011612 - Models/DirectionalLightWidget.mesh + Models/Widgets/Lights/DirectionalLightWidget.mesh diff --git a/resources/Schema/Entities/ShootEventTest.xml b/resources/Schema/Entities/ShootEventTest.xml index 9e9adf50..80dd2f35 100644 --- a/resources/Schema/Entities/ShootEventTest.xml +++ b/resources/Schema/Entities/ShootEventTest.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.mesh + Models/Test/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -79,7 +79,7 @@ 2 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -96,7 +96,7 @@ 3 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -115,7 +115,7 @@ 4 - ../assets/Models/Core/UnitSphere.mesh + Models/Core/UnitSphere.mesh @@ -133,7 +133,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -151,7 +151,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -171,7 +171,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh @@ -191,7 +191,7 @@ - ../assets/Models/Core/UnitCube.mesh + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/SpawnPointClusterWithModels.xml b/resources/Schema/Entities/SpawnPointClusterWithModels.xml index 9c42d0e4..ea8e09d4 100644 --- a/resources/Schema/Entities/SpawnPointClusterWithModels.xml +++ b/resources/Schema/Entities/SpawnPointClusterWithModels.xml @@ -19,7 +19,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -31,7 +31,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -43,7 +43,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh @@ -55,7 +55,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh diff --git a/resources/Schema/Entities/SpawnerWithPlayerModel.xml b/resources/Schema/Entities/SpawnerWithPlayerModel.xml index 1274eefa..dbd93ed4 100644 --- a/resources/Schema/Entities/SpawnerWithPlayerModel.xml +++ b/resources/Schema/Entities/SpawnerWithPlayerModel.xml @@ -4,7 +4,7 @@ - Models/Assault.mesh + Models/Characters/Assault/AssaultTPose.mesh diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 2cdf4e17..7f40e6de 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -6,7 +6,7 @@ - Models/DummyScene.mesh + Models/Test/DummyScene.mesh @@ -36,7 +36,7 @@ 0 - Models/Camera.mesh + Models/Widgets/Camera.mesh diff --git a/resources/Shaders/ForwardPlusSkinned.vert.glsl b/resources/Shaders/ForwardPlusSkinned.vert.glsl index 3d47b0c4..5368b260 100644 --- a/resources/Shaders/ForwardPlusSkinned.vert.glsl +++ b/resources/Shaders/ForwardPlusSkinned.vert.glsl @@ -26,7 +26,7 @@ out VertexData{ void main() { mat4 boneTransform = mat4(1); - //Remove if(). Shoudln't have to do this scine we know it's skinned and uses bones + if(BoneWeights[0] > 0.0f){ boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + BoneWeights[1] * Bones[int(BoneIndices[1])] diff --git a/resources/Shaders/Picking.vert.glsl b/resources/Shaders/Picking.vert.glsl index 205a8fdd..f888cd16 100644 --- a/resources/Shaders/Picking.vert.glsl +++ b/resources/Shaders/Picking.vert.glsl @@ -3,15 +3,12 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; -uniform mat4 Bones[100]; layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; layout(location = 2) in vec3 Tangent; layout(location = 3) in vec3 BiTangent; layout(location = 4) in vec2 TextureCoords; -layout(location = 5) in vec4 BoneIndices; -layout(location = 6) in vec4 BoneWeights; out VertexData{ vec3 Position; @@ -19,14 +16,6 @@ out VertexData{ void main() { - mat4 boneTransform = mat4(1); - if(BoneWeights[0] > 0.0f){ - boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] - + BoneWeights[1] * Bones[int(BoneIndices[1])] - + BoneWeights[2] * Bones[int(BoneIndices[2])] - + BoneWeights[3] * Bones[int(BoneIndices[3])]; - } - - gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); - Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; + gl_Position = P*V*M * vec4(Position, 1.0); + Output.Position = Position, 1.0; } \ No newline at end of file diff --git a/resources/Shaders/PickingSkinned.vert.glsl b/resources/Shaders/PickingSkinned.vert.glsl new file mode 100644 index 00000000..205a8fdd --- /dev/null +++ b/resources/Shaders/PickingSkinned.vert.glsl @@ -0,0 +1,32 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform mat4 Bones[100]; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 2) in vec3 Tangent; +layout(location = 3) in vec3 BiTangent; +layout(location = 4) in vec2 TextureCoords; +layout(location = 5) in vec4 BoneIndices; +layout(location = 6) in vec4 BoneWeights; + +out VertexData{ + vec3 Position; +}Output; + +void main() +{ + mat4 boneTransform = mat4(1); + if(BoneWeights[0] > 0.0f){ + boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + + BoneWeights[1] * Bones[int(BoneIndices[1])] + + BoneWeights[2] * Bones[int(BoneIndices[2])] + + BoneWeights[3] * Bones[int(BoneIndices[3])]; + } + + gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; +} \ No newline at end of file diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index abc79f2e..c445b8fd 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -41,6 +41,14 @@ void PickingPass::InitializeShaderPrograms() m_PickingProgram->Compile(); m_PickingProgram->BindFragDataLocation(0, "TextureFragment"); m_PickingProgram->Link(); + + m_PickingSkinnedProgram = ResourceManager::Load("#PickingSkinnedProgram"); + + m_PickingSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/PickingSkinned.vert.glsl"))); + m_PickingSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Picking.frag.glsl"))); + m_PickingSkinnedProgram->Compile(); + m_PickingSkinnedProgram->BindFragDataLocation(0, "TextureFragment"); + m_PickingSkinnedProgram->Link(); } void PickingPass::Draw(RenderScene& scene) @@ -49,6 +57,7 @@ void PickingPass::Draw(RenderScene& scene) //TODO: Render: Add code for more jobs than modeljobs. GLuint shaderHandle = m_PickingProgram->GetHandle(); + GLuint shaderSkinnedHandle = m_PickingSkinnedProgram->GetHandle(); m_PickingProgram->Bind(); if (scene.ClearDepth) { @@ -60,41 +69,78 @@ void PickingPass::Draw(RenderScene& scene) auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { - int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; + if (modelJob->Model->isSkined()) + { + m_PickingSkinnedProgram->Bind(); + int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; - PickingInfo pickInfo; - pickInfo.Entity = modelJob->Entity; - pickInfo.World = modelJob->World; - pickInfo.Camera = scene.Camera; + PickingInfo pickInfo; + pickInfo.Entity = modelJob->Entity; + pickInfo.World = modelJob->World; + pickInfo.Camera = scene.Camera; - auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); - if (color != m_EntityColors.end()) { - pickColor[0] = color->second[0]; - pickColor[1] = color->second[1]; - } else { - m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); - if (m_ColorCounter[0] > 255) { - m_ColorCounter[0] = 0; - m_ColorCounter[1] += 1; - } else { - m_ColorCounter[0] += 1; - } - } + auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); + if (color != m_EntityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; + } + else { + m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); + if (m_ColorCounter[0] > 255) { + m_ColorCounter[0] = 0; + m_ColorCounter[1] += 1; + } + else { + m_ColorCounter[0] += 1; + } + } - m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } - } + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + } else { + m_PickingProgram->Bind(); + int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; + + PickingInfo pickInfo; + pickInfo.Entity = modelJob->Entity; + pickInfo.World = modelJob->World; + pickInfo.Camera = scene.Camera; + + auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); + if (color != m_EntityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; + } + else { + m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); + if (m_ColorCounter[0] > 255) { + m_ColorCounter[0] = 0; + m_ColorCounter[1] += 1; + } + else { + m_ColorCounter[0] += 1; + } + } + + m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + } glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); diff --git a/tools/MayaExporter/MayaExporter.opensdf b/tools/MayaExporter/MayaExporter.opensdf deleted file mode 100644 index 31dea47bab049adbbcfae9b67e37a5ada58ecdf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38 ncmd01NMy)m$Ydx6(}@fW3?U4z3_%RO44w>r430paKad9ihMopW diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 52b1392e..ee5a6022 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -253,43 +253,33 @@ Mesh MeshClass::GetMeshData(MObjectArray object) //mesh.getPoint(vertexIndex, pos, MSpace::kPostTransform); pos = positions[vertexIndex]; pos = pos * transformMatrix; - if (abs(pos.x) > 0.0001) - thisVertex.Pos[0] = pos.x; - if (abs(pos.y) > 0.0001) - thisVertex.Pos[1] = pos.y; - if (abs(pos.z) > 0.0001) - thisVertex.Pos[2] = pos.z; + + thisVertex.Pos[0] = pos.x; + thisVertex.Pos[1] = pos.y; + thisVertex.Pos[2] = pos.z; status = faceVert.getNormal(normal, MSpace::kObject); if (status != MS::kSuccess) { MGlobal::displayError(MString() + "faceVert.getNormal() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); break; } - if (abs(normal[0]) > 0.0001) - thisVertex.Normal[0] = normal[0]; - if (abs(normal[1]) > 0.0001) - thisVertex.Normal[1] = normal[1]; - if (abs(normal[2]) > 0.0001) - thisVertex.Normal[2] = normal[2]; + + thisVertex.Normal[0] = normal[0]; + thisVertex.Normal[1] = normal[1]; + thisVertex.Normal[2] = normal[2]; MFloatVector Tangent = Tangents[faceVert.tangentId()]; //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); //tmp.get(biTangent); - if (abs(Tangent[0]) > 0.0001) - thisVertex.Tangent[0] = Tangent[0]; - if (abs(Tangent[1]) > 0.0001) - thisVertex.Tangent[1] = Tangent[1]; - if (abs(Tangent[2]) > 0.0001) - thisVertex.Tangent[2] = Tangent[2]; + thisVertex.Tangent[0] = Tangent[0]; + thisVertex.Tangent[1] = Tangent[1]; + thisVertex.Tangent[2] = Tangent[2]; MFloatVector biNormal = biNormals[faceVert.tangentId()]; //faceVert.getBinormal().get(biNormal); - if (abs(biNormal[0]) > 0.0001) - thisVertex.BiNormal[0] = biNormal[0]; - if (abs(biNormal[1]) > 0.0001) - thisVertex.BiNormal[1] = biNormal[1]; - if (abs(biNormal[2]) > 0.0001) - thisVertex.BiNormal[2] = biNormal[2]; + thisVertex.BiNormal[0] = biNormal[0]; + thisVertex.BiNormal[1] = biNormal[1]; + thisVertex.BiNormal[2] = biNormal[2]; status = faceVert.getUV(UV); if (status != MS::kSuccess) { From b748deb1e1e91c3177af65e1c778454f6afd1585 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 10:05:49 +0100 Subject: [PATCH 108/131] WIP FrustumCulling, most code added but not working now. --- include/Engine/Core/Octree.h | 117 ++++++++++++++++++++++++ include/Engine/Rendering/RenderSystem.h | 7 +- src/Engine/Rendering/RenderSystem.cpp | 53 ++++++++++- src/Game/Game.cpp | 10 +- 4 files changed, 179 insertions(+), 8 deletions(-) diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index 907d5736..d97d644b 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -2,6 +2,7 @@ #define Octree_h__ #include +#include #include "../Common.h" #include "AABB.h" @@ -40,6 +41,8 @@ public: //The type Box must be AABB, or inherit from AABB. template void ObjectsInSameRegion(const Box& box, std::vector& outObjects); + //Get the objects that are inside the frustum defined by the viewProjection matrix, the objects are put in outObjects. + void ObjectsInFrustum(const glm::mat4x4& viewProj, std::vector& outObjects); //Empty the tree of all objects, static and dynamic. void ClearObjects(); //Empty the tree of all dynamic objects. Static objects remain in the tree. @@ -68,6 +71,56 @@ struct Output float CollideDistance; }; +//Contains points P in: dot(normal, P) + d = 0 +struct Plane +{ + glm::vec3 normal; + float distance; +}; + +//A frustum defined by 6 planes. +struct Frustum +{ + enum Output + { + Inside, + Outside, + Intersects + }; + Plane planes[6]; + + Output VsAABB(const AABB& box) const + { + const glm::vec3& maxCorner = box.MaxCorner(); + const glm::vec3& minCorner = box.MinCorner(); + bool completelyInside = true; + for (const Plane& p : planes) { + bool anyWasInside = false; + bool anyWasOutside = false; + //If points are on both sides of the plane, we can stop. + for (int i = 0; i < 8 && (!anyWasInside || !anyWasOutside); ++i) { + std::bitset<3> bits(i); + glm::vec3 corner; + corner.x = bits.test(0) ? maxCorner.x : minCorner.x; + corner.y = bits.test(1) ? maxCorner.y : minCorner.y; + corner.z = bits.test(2) ? maxCorner.z : minCorner.z; + if (glm::dot(p.normal, corner) > p.distance) { + anyWasInside = true; + } else { + anyWasOutside = true; + } + } + if (!anyWasInside) { + return Outside; + } + if (anyWasOutside) { + completelyInside = false; + } + } + return completelyInside ? Inside : Intersects; + } +}; + struct ContainedObject { ContainedObject() @@ -97,6 +150,8 @@ struct Child void AddStaticObject(const AABB& box); template void ObjectsInSameRegion(const Box& box, std::vector& outObjects) const; + template + void ObjectsInFrustum(const Frustum& frustum, std::vector& outObjects, bool takeAllDontTest) const; void ClearObjects(); void ClearDynamicObjects(); bool RayCollides(const Ray& ray, Output& data) const; @@ -154,6 +209,26 @@ void Octree::ObjectsInSameRegion(const Box& box, std::vector& outObjects) m_Root->ObjectsInSameRegion(box, outObjects); } +template +void Octree::ObjectsInFrustum(const glm::mat4x4& viewProj, std::vector& outObjects) +{ + falsifyObjectChecks(); + OctSpace::Frustum frustum; + for (int i = 0; i < 6; ++i) { + int sign = 2 * (i % 2) - 1; + int index = i / 2; + OctSpace::Plane& plane = frustum.planes[i]; + plane.normal.x = viewProj[0].w + sign * viewProj[0][index]; + plane.normal.y = viewProj[1].w + sign * viewProj[1][index]; + plane.normal.z = viewProj[2].w + sign * viewProj[2][index]; + plane.distance = viewProj[3].w + sign * viewProj[3][index]; + float divByNormalLength = 1.0f / glm::length(plane.normal); + plane.normal *= divByNormalLength; + plane.distance *= divByNormalLength; + } + m_Root->ObjectsInFrustum(frustum, outObjects, false); +} + template void Octree::ClearObjects() { @@ -230,4 +305,46 @@ void OctSpace::Child::ObjectsInSameRegion(const Box& box, std::vector& outObj } } +template +void OctSpace::Child::ObjectsInFrustum(const Frustum& frustum, std::vector& outObjects, bool takeAllDontTest) const +{ + if (hasChildren()) { + for (const Child* c : m_Children) { + Frustum::Output out = Frustum::Inside; + if (!takeAllDontTest) { + out = frustum.VsAABB(c->m_Box); + if (out == Frustum::Outside) { + continue; + } + } + c->ObjectsInFrustum(frustum, outObjects, out == Frustum::Inside); + } + } else { + size_t startIndex = outObjects.size(); + int numDuplicates = 0; + outObjects.resize(outObjects.size() + m_StaticObjIndices.size() + m_DynamicObjIndices.size()); + for (size_t i = 0; i < m_StaticObjIndices.size(); ++i) { + ContainedObject& obj = m_StaticObjectsRef[m_StaticObjIndices[i]]; + if (obj.Checked || !frustum.VsAABB(obj.Box)) { + ++numDuplicates; + } else { + obj.Checked = true; + outObjects[startIndex + i - numDuplicates] = *static_cast(obj.Box.get()); + } + } + for (size_t i = 0; i < m_DynamicObjIndices.size(); ++i) { + ContainedObject& obj = m_DynamicObjectsRef[m_DynamicObjIndices[i]]; + if (obj.Checked || !frustum.VsAABB(obj.Box)) { + ++numDuplicates; + } else { + obj.Checked = true; + outObjects[startIndex + i - numDuplicates] = *static_cast(obj.Box.get()); + } + } + for (size_t i = 0; i < numDuplicates; ++i) { + outObjects.pop_back(); + } + } +} + #endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index d64147b9..d404c56a 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -16,11 +16,13 @@ #include "PointLightJob.h" #include "../Core/Transform.h" #include "../Core/EPlayerSpawned.h" +#include "../Core/Octree.h" +#include "../Collision/EntityAABB.h" class RenderSystem : public ImpureSystem { public: - RenderSystem(World* world, EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame); + RenderSystem(World* world, EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame, Octree* frustumCullOctree); ~RenderSystem(); virtual void Update(double dt) override; @@ -29,9 +31,12 @@ private: const IRenderer* m_Renderer; RenderFrame* m_RenderFrame; Camera* m_Camera; + Camera* m_LastCullCamera; + Camera** m_FrustumCamPtr; World* m_World; EntityWrapper m_CurrentCamera = EntityWrapper::Invalid; EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; + Octree* m_Octree; EventRelay m_ESetCamera; bool OnSetCamera(Events::SetCamera &event); diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index eaecf99e..d57e263a 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -1,21 +1,26 @@ #include "Rendering/RenderSystem.h" +#include "Collision/Collision.h" -RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRenderer* renderer, RenderFrame* renderFrame) +RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRenderer* renderer, RenderFrame* renderFrame, Octree* frustumCullOctree) : System(world, eventBroker) , m_Renderer(renderer) , m_RenderFrame(renderFrame) , m_World(world) + , m_Octree(frustumCullOctree) { EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned); m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); + m_LastCullCamera = new Camera(*m_Camera); + m_FrustumCamPtr = &m_Camera; } RenderSystem::~RenderSystem() { delete m_Camera; + delete m_LastCullCamera; } bool RenderSystem::OnSetCamera(Events::SetCamera& e) @@ -28,6 +33,17 @@ bool RenderSystem::OnSetCamera(Events::SetCamera& e) m_Camera->SetPosition(cTransform["Position"]); m_Camera->SetOrientation(glm::quat((const glm::vec3&)cTransform["Orientation"])); m_CurrentCamera = e.CameraEntity; + //Right now, lets set the camera to cull away stuff if it is connected to anything. + //TODO: This won't work with spectators, or death anim. + if (m_CurrentCamera.Parent().Valid()) { + //Copy the camera into the last frustum camera, without allocating new memory. + new ((void*)m_LastCullCamera) Camera(*m_Camera); + m_FrustumCamPtr = &m_Camera; + } else { + //If the camera has no parents, i.e. a free camera, + //then we cull from the last camera, so we can see if the culling works. + m_FrustumCamPtr = &m_LastCullCamera; + } return true; } @@ -42,11 +58,33 @@ bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity) void RenderSystem::fillModels(std::list>& opaqueJobs, std::list>& transparentJobs) { + + std::vector seenEntities; + //m_Octree->ObjectsInFrustum((*m_FrustumCamPtr)->ProjectionMatrix() * (*m_FrustumCamPtr)->ViewMatrix(), seenEntities); + //m_Octree->ObjectsInFrustum((*m_FrustumCamPtr)->ViewMatrix() * (*m_FrustumCamPtr)->ProjectionMatrix(), seenEntities); + + glm::mat4x4 viewProj = (*m_FrustumCamPtr)->ViewMatrix() * (*m_FrustumCamPtr)->ProjectionMatrix(); + OctSpace::Frustum frustum; + for (int i = 0; i < 6; ++i) { + int sign = 2 * (i % 2) - 1; + int index = i / 2; + OctSpace::Plane& plane = frustum.planes[i]; + plane.normal.x = viewProj[0].w + sign * viewProj[0][index]; + plane.normal.y = viewProj[1].w + sign * viewProj[1][index]; + plane.normal.z = viewProj[2].w + sign * viewProj[2][index]; + plane.distance = viewProj[3].w + sign * viewProj[3][index]; + float divByNormalLength = 1.0f / glm::length(plane.normal); + plane.normal *= divByNormalLength; + plane.distance *= divByNormalLength; + } + + //for (auto& seenEntity : seenEntities) { + // EntityWrapper entity = seenEntity.Entity; + // ComponentWrapper cModel = entity["Model"]; auto models = m_World->GetComponents("Model"); if (models == nullptr) { return; } - for (auto& cModel : *models) { bool visible = cModel["Visible"]; if (!visible) { @@ -57,7 +95,7 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, continue; } - EntityWrapper entity(m_World, cModel.EntityID); + EntityWrapper entity = EntityWrapper(m_World, cModel.EntityID); // Only render children of a camera if that camera is currently active if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { @@ -69,6 +107,15 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, continue; } + if (entity.HasComponent("AABB")) { + OctSpace::Frustum::Output o = frustum.VsAABB(*Collision::EntityAbsoluteAABB(entity)); + if (o == OctSpace::Frustum::Outside) { + continue; + } + } else { + continue; + } + Model* model; try { model = ResourceManager::Load<::Model, true>(resource); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 0c92271d..d3c2eb57 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -75,9 +75,10 @@ Game::Game(int argc, char* argv[]) // Create Octrees - m_OctreeCollision = new Octree(AABB(glm::vec3(-100), glm::vec3(100)), 4); - m_OctreeTrigger = new Octree(AABB(glm::vec3(-100), glm::vec3(100)), 4); - m_OctreeFrustrumCulling = new Octree(AABB(glm::vec3(-100), glm::vec3(100)), 4); + AABB boxContainingTheWorld(glm::vec3(-300), glm::vec3(300)); + m_OctreeCollision = new Octree(boxContainingTheWorld, 4); + m_OctreeTrigger = new Octree(boxContainingTheWorld, 4); + m_OctreeFrustrumCulling = new Octree(boxContainingTheWorld, 4); // Create system pipeline m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker); @@ -99,6 +100,7 @@ Game::Game(int argc, char* argv[]) ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); + m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling, "Model"); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); @@ -107,7 +109,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger); ++updateOrderLevel; - m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame); + m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame, m_OctreeFrustrumCulling); ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame); From b30891aecdbd9886d4f876d01b8cad91d41b6eb2 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 15:00:30 +0100 Subject: [PATCH 109/131] WIP, debugging code added, still not working. --- include/Engine/Core/Octree.h | 27 ++++----- include/Engine/Rendering/RenderSystem.h | 1 + src/Engine/Rendering/RenderSystem.cpp | 73 ++++++++++++++++--------- 3 files changed, 62 insertions(+), 39 deletions(-) diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index d97d644b..e0165cef 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -74,8 +74,8 @@ struct Output //Contains points P in: dot(normal, P) + d = 0 struct Plane { - glm::vec3 normal; - float distance; + glm::vec3 Normal; + float Distance; }; //A frustum defined by 6 planes. @@ -87,14 +87,14 @@ struct Frustum Outside, Intersects }; - Plane planes[6]; + Plane Planes[6]; Output VsAABB(const AABB& box) const { const glm::vec3& maxCorner = box.MaxCorner(); const glm::vec3& minCorner = box.MinCorner(); bool completelyInside = true; - for (const Plane& p : planes) { + for (const Plane& p : Planes) { bool anyWasInside = false; bool anyWasOutside = false; //If points are on both sides of the plane, we can stop. @@ -104,7 +104,7 @@ struct Frustum corner.x = bits.test(0) ? maxCorner.x : minCorner.x; corner.y = bits.test(1) ? maxCorner.y : minCorner.y; corner.z = bits.test(2) ? maxCorner.z : minCorner.z; - if (glm::dot(p.normal, corner) > p.distance) { + if (glm::dot(p.Normal, corner) > p.Distance) { anyWasInside = true; } else { anyWasOutside = true; @@ -214,17 +214,18 @@ void Octree::ObjectsInFrustum(const glm::mat4x4& viewProj, std::vector& ou { falsifyObjectChecks(); OctSpace::Frustum frustum; + //Order: Right, left, top, bottom, far, near. for (int i = 0; i < 6; ++i) { int sign = 2 * (i % 2) - 1; int index = i / 2; - OctSpace::Plane& plane = frustum.planes[i]; - plane.normal.x = viewProj[0].w + sign * viewProj[0][index]; - plane.normal.y = viewProj[1].w + sign * viewProj[1][index]; - plane.normal.z = viewProj[2].w + sign * viewProj[2][index]; - plane.distance = viewProj[3].w + sign * viewProj[3][index]; - float divByNormalLength = 1.0f / glm::length(plane.normal); - plane.normal *= divByNormalLength; - plane.distance *= divByNormalLength; + OctSpace::Plane& plane = frustum.Planes[i]; + plane.Normal.x = viewProj[0].w + sign * viewProj[0][index]; + plane.Normal.y = viewProj[1].w + sign * viewProj[1][index]; + plane.Normal.z = viewProj[2].w + sign * viewProj[2][index]; + plane.Distance = viewProj[3].w + sign * viewProj[3][index]; + float divByNormalLength = 1.0f / glm::length(plane.Normal); + plane.Normal *= divByNormalLength; + plane.Distance *= divByNormalLength; } m_Root->ObjectsInFrustum(frustum, outObjects, false); } diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index d404c56a..e4e6475a 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -33,6 +33,7 @@ private: Camera* m_Camera; Camera* m_LastCullCamera; Camera** m_FrustumCamPtr; + EntityWrapper frustumEntity; World* m_World; EntityWrapper m_CurrentCamera = EntityWrapper::Invalid; EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index d57e263a..9d7e7530 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -25,6 +25,19 @@ RenderSystem::~RenderSystem() bool RenderSystem::OnSetCamera(Events::SetCamera& e) { + //Right now, lets set the camera to cull away stuff if it is connected to a player. + //TODO: This won't work with spectators, or death anim. + if (e.CameraEntity.FirstParentWithComponent("Player").Valid()) { + m_FrustumCamPtr = &m_Camera; + LOG_INFO("Setting frustum to new camera."); + } else if (e.CameraEntity != m_CurrentCamera) { + //If the camera has no parents, i.e. a free camera, + //then we cull from the last camera, so we can see if the culling works. + //Copy the camera into the last frustum camera, without allocating new memory. + new ((void*)m_LastCullCamera) Camera(*m_Camera); + m_FrustumCamPtr = &m_LastCullCamera; + LOG_INFO("New camera, frustum remains at old camera."); + } ComponentWrapper cTransform = e.CameraEntity["Transform"]; ComponentWrapper cCamera = e.CameraEntity["Camera"]; m_Camera->SetFOV((double)cCamera["FOV"]); @@ -33,17 +46,6 @@ bool RenderSystem::OnSetCamera(Events::SetCamera& e) m_Camera->SetPosition(cTransform["Position"]); m_Camera->SetOrientation(glm::quat((const glm::vec3&)cTransform["Orientation"])); m_CurrentCamera = e.CameraEntity; - //Right now, lets set the camera to cull away stuff if it is connected to anything. - //TODO: This won't work with spectators, or death anim. - if (m_CurrentCamera.Parent().Valid()) { - //Copy the camera into the last frustum camera, without allocating new memory. - new ((void*)m_LastCullCamera) Camera(*m_Camera); - m_FrustumCamPtr = &m_Camera; - } else { - //If the camera has no parents, i.e. a free camera, - //then we cull from the last camera, so we can see if the culling works. - m_FrustumCamPtr = &m_LastCullCamera; - } return true; } @@ -56,26 +58,45 @@ bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity) return entity == m_CurrentCamera || entity.IsChildOf(m_CurrentCamera); } +float frustrumTODO = 0.f; + void RenderSystem::fillModels(std::list>& opaqueJobs, std::list>& transparentJobs) { + if (!frustumEntity.Valid() && m_World->GetComponentPools().size() > 0) { + frustumEntity = EntityWrapper(m_World, m_World->CreateEntity()); + m_World->AttachComponent(frustumEntity.ID, "Transform"); + m_World->AttachComponent(frustumEntity.ID, "Model"); + frustumEntity["Model"]["Resource"] = "Models/Core/UnitCube.mesh"; + } std::vector seenEntities; //m_Octree->ObjectsInFrustum((*m_FrustumCamPtr)->ProjectionMatrix() * (*m_FrustumCamPtr)->ViewMatrix(), seenEntities); - //m_Octree->ObjectsInFrustum((*m_FrustumCamPtr)->ViewMatrix() * (*m_FrustumCamPtr)->ProjectionMatrix(), seenEntities); - glm::mat4x4 viewProj = (*m_FrustumCamPtr)->ViewMatrix() * (*m_FrustumCamPtr)->ProjectionMatrix(); + glm::mat4x4 viewProj = (*m_FrustumCamPtr)->ProjectionMatrix() * (*m_FrustumCamPtr)->ViewMatrix(); OctSpace::Frustum frustum; + //Order: Right, left, top, bottom, far, near. + int sign = 1; for (int i = 0; i < 6; ++i) { - int sign = 2 * (i % 2) - 1; + sign = -sign; int index = i / 2; - OctSpace::Plane& plane = frustum.planes[i]; - plane.normal.x = viewProj[0].w + sign * viewProj[0][index]; - plane.normal.y = viewProj[1].w + sign * viewProj[1][index]; - plane.normal.z = viewProj[2].w + sign * viewProj[2][index]; - plane.distance = viewProj[3].w + sign * viewProj[3][index]; - float divByNormalLength = 1.0f / glm::length(plane.normal); - plane.normal *= divByNormalLength; - plane.distance *= divByNormalLength; + OctSpace::Plane& plane = frustum.Planes[i]; + plane.Normal.x = viewProj[0].w + sign * viewProj[0][index]; + plane.Normal.y = viewProj[1].w + sign * viewProj[1][index]; + plane.Normal.z = viewProj[2].w + sign * viewProj[2][index]; + plane.Distance = viewProj[3].w + sign * viewProj[3][index]; + float divByNormalLength = 1.0f / glm::length(plane.Normal); + plane.Normal *= divByNormalLength; + plane.Distance *= divByNormalLength; + } + if (frustumEntity.Valid()) { + int planeI = 0; + glm::vec3 pos = (*m_FrustumCamPtr)->Position() + frustrumTODO * (*m_FrustumCamPtr)->Forward(); + float dist = glm::dot(frustum.Planes[planeI].Normal, pos) + frustum.Planes[planeI].Distance; + frustumEntity["Transform"]["Position"] = pos - dist * frustum.Planes[planeI].Normal; + frustumEntity["Transform"]["Scale"] = glm::vec3(0.15f); + } + if (++frustrumTODO > 75) { + frustrumTODO = 0.f; } //for (auto& seenEntity : seenEntities) { @@ -109,11 +130,11 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, if (entity.HasComponent("AABB")) { OctSpace::Frustum::Output o = frustum.VsAABB(*Collision::EntityAbsoluteAABB(entity)); - if (o == OctSpace::Frustum::Outside) { - continue; + if (o == OctSpace::Frustum::Outside && entity != frustumEntity) { + resource = "Models/Core/UnitRaptor.mesh"; } - } else { - continue; + } else if (entity != frustumEntity){ + resource = "Models/Core/Error.mesh"; } Model* model; From 232bf66a09491053cbccc15eb1bcc0386523bd95 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 16:09:08 +0100 Subject: [PATCH 110/131] Jump height is constant for the double jump. --- src/Game/Systems/PlayerMovementSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 7b244562..52890c3a 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -95,7 +95,7 @@ void PlayerMovementSystem::Update(double dt) } else { controller->SetDoubleJumping(true); } - velocity.y += 4.f; + velocity.y = 4.f; } if (player.HasComponent("AABB")) { From 239a8e7a6a38616614f9f09aa5a44dfab95b23e7 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 17:12:23 +0100 Subject: [PATCH 111/131] Frustum culling should be working. --- include/Engine/Core/Frustum.h | 77 +++++++++++++++++++++++ include/Engine/Core/Octree.h | 81 +++---------------------- include/Engine/Rendering/RenderSystem.h | 3 - src/Engine/Rendering/RenderSystem.cpp | 78 ++---------------------- src/Game/Game.cpp | 2 +- 5 files changed, 93 insertions(+), 148 deletions(-) create mode 100644 include/Engine/Core/Frustum.h diff --git a/include/Engine/Core/Frustum.h b/include/Engine/Core/Frustum.h new file mode 100644 index 00000000..c2d83b23 --- /dev/null +++ b/include/Engine/Core/Frustum.h @@ -0,0 +1,77 @@ +#ifndef Frustum_h__ +#define Frustum_h__ + +#include "../GLM.h" +#include "AABB.h" +#include + +//A frustum defined by 6 planes. +struct Frustum +{ + //Contains points P in: dot(normal, P) + d = 0 + struct Plane + { + glm::vec3 Normal; + float Distance; + }; + + enum class Output + { + Inside, + Outside, + Intersects + }; + Plane Planes[6]; + + Frustum() = default; + Frustum(glm::mat4x4 viewProjMatrix) + { + //Order: Right, left, top, bottom, far, near. + int sign = 1; + for (int i = 0; i < 6; ++i) { + sign = -sign; + int index = i / 2; + Plane& plane = Planes[i]; + plane.Normal.x = viewProjMatrix[0].w + sign * viewProjMatrix[0][index]; + plane.Normal.y = viewProjMatrix[1].w + sign * viewProjMatrix[1][index]; + plane.Normal.z = viewProjMatrix[2].w + sign * viewProjMatrix[2][index]; + plane.Distance = viewProjMatrix[3].w + sign * viewProjMatrix[3][index]; + float divByNormalLength = 1.0f / glm::length(plane.Normal); + plane.Normal *= divByNormalLength; + plane.Distance *= divByNormalLength; + } + } + + Output VsAABB(const AABB& box) const + { + const glm::vec3& maxCorner = box.MaxCorner(); + const glm::vec3& minCorner = box.MinCorner(); + bool completelyInside = true; + for (const Plane& p : Planes) { + bool anyWasInside = false; + bool anyWasOutside = false; + //If points are on both sides of the plane, we can stop. + for (int i = 0; i < 8 && (!anyWasInside || !anyWasOutside); ++i) { + std::bitset<3> bits(i); + glm::vec3 corner; + corner.x = bits.test(0) ? maxCorner.x : minCorner.x; + corner.y = bits.test(1) ? maxCorner.y : minCorner.y; + corner.z = bits.test(2) ? maxCorner.z : minCorner.z; + if (glm::dot(p.Normal, corner) > -p.Distance) { + anyWasInside = true; + } else { + anyWasOutside = true; + } + } + if (!anyWasInside) { + return Output::Outside; + } + if (anyWasOutside) { + completelyInside = false; + } + } + return completelyInside ? Output::Inside : Output::Intersects; + } +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index e0165cef..49a8b045 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -6,6 +6,7 @@ #include "../Common.h" #include "AABB.h" +#include "Frustum.h" //Fwd declarations. class Ray; @@ -41,8 +42,8 @@ public: //The type Box must be AABB, or inherit from AABB. template void ObjectsInSameRegion(const Box& box, std::vector& outObjects); - //Get the objects that are inside the frustum defined by the viewProjection matrix, the objects are put in outObjects. - void ObjectsInFrustum(const glm::mat4x4& viewProj, std::vector& outObjects); + //Get the objects that are inside the frustum, the objects are put in outObjects. + void ObjectsInFrustum(const Frustum& frustum, std::vector& outObjects); //Empty the tree of all objects, static and dynamic. void ClearObjects(); //Empty the tree of all dynamic objects. Static objects remain in the tree. @@ -71,56 +72,6 @@ struct Output float CollideDistance; }; -//Contains points P in: dot(normal, P) + d = 0 -struct Plane -{ - glm::vec3 Normal; - float Distance; -}; - -//A frustum defined by 6 planes. -struct Frustum -{ - enum Output - { - Inside, - Outside, - Intersects - }; - Plane Planes[6]; - - Output VsAABB(const AABB& box) const - { - const glm::vec3& maxCorner = box.MaxCorner(); - const glm::vec3& minCorner = box.MinCorner(); - bool completelyInside = true; - for (const Plane& p : Planes) { - bool anyWasInside = false; - bool anyWasOutside = false; - //If points are on both sides of the plane, we can stop. - for (int i = 0; i < 8 && (!anyWasInside || !anyWasOutside); ++i) { - std::bitset<3> bits(i); - glm::vec3 corner; - corner.x = bits.test(0) ? maxCorner.x : minCorner.x; - corner.y = bits.test(1) ? maxCorner.y : minCorner.y; - corner.z = bits.test(2) ? maxCorner.z : minCorner.z; - if (glm::dot(p.Normal, corner) > p.Distance) { - anyWasInside = true; - } else { - anyWasOutside = true; - } - } - if (!anyWasInside) { - return Outside; - } - if (anyWasOutside) { - completelyInside = false; - } - } - return completelyInside ? Inside : Intersects; - } -}; - struct ContainedObject { ContainedObject() @@ -210,23 +161,9 @@ void Octree::ObjectsInSameRegion(const Box& box, std::vector& outObjects) } template -void Octree::ObjectsInFrustum(const glm::mat4x4& viewProj, std::vector& outObjects) +void Octree::ObjectsInFrustum(const Frustum& frustum, std::vector& outObjects) { falsifyObjectChecks(); - OctSpace::Frustum frustum; - //Order: Right, left, top, bottom, far, near. - for (int i = 0; i < 6; ++i) { - int sign = 2 * (i % 2) - 1; - int index = i / 2; - OctSpace::Plane& plane = frustum.Planes[i]; - plane.Normal.x = viewProj[0].w + sign * viewProj[0][index]; - plane.Normal.y = viewProj[1].w + sign * viewProj[1][index]; - plane.Normal.z = viewProj[2].w + sign * viewProj[2][index]; - plane.Distance = viewProj[3].w + sign * viewProj[3][index]; - float divByNormalLength = 1.0f / glm::length(plane.Normal); - plane.Normal *= divByNormalLength; - plane.Distance *= divByNormalLength; - } m_Root->ObjectsInFrustum(frustum, outObjects, false); } @@ -311,14 +248,14 @@ void OctSpace::Child::ObjectsInFrustum(const Frustum& frustum, std::vector& o { if (hasChildren()) { for (const Child* c : m_Children) { - Frustum::Output out = Frustum::Inside; + Frustum::Output out = Frustum::Output::Inside; if (!takeAllDontTest) { out = frustum.VsAABB(c->m_Box); - if (out == Frustum::Outside) { + if (out == Frustum::Output::Outside) { continue; } } - c->ObjectsInFrustum(frustum, outObjects, out == Frustum::Inside); + c->ObjectsInFrustum(frustum, outObjects, out == Frustum::Output::Inside); } } else { size_t startIndex = outObjects.size(); @@ -326,7 +263,7 @@ void OctSpace::Child::ObjectsInFrustum(const Frustum& frustum, std::vector& o outObjects.resize(outObjects.size() + m_StaticObjIndices.size() + m_DynamicObjIndices.size()); for (size_t i = 0; i < m_StaticObjIndices.size(); ++i) { ContainedObject& obj = m_StaticObjectsRef[m_StaticObjIndices[i]]; - if (obj.Checked || !frustum.VsAABB(obj.Box)) { + if (obj.Checked || frustum.VsAABB(*obj.Box) == Frustum::Output::Outside) { ++numDuplicates; } else { obj.Checked = true; @@ -335,7 +272,7 @@ void OctSpace::Child::ObjectsInFrustum(const Frustum& frustum, std::vector& o } for (size_t i = 0; i < m_DynamicObjIndices.size(); ++i) { ContainedObject& obj = m_DynamicObjectsRef[m_DynamicObjIndices[i]]; - if (obj.Checked || !frustum.VsAABB(obj.Box)) { + if (obj.Checked || frustum.VsAABB(*obj.Box) == Frustum::Output::Outside) { ++numDuplicates; } else { obj.Checked = true; diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index e4e6475a..44088913 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -31,9 +31,6 @@ private: const IRenderer* m_Renderer; RenderFrame* m_RenderFrame; Camera* m_Camera; - Camera* m_LastCullCamera; - Camera** m_FrustumCamPtr; - EntityWrapper frustumEntity; World* m_World; EntityWrapper m_CurrentCamera = EntityWrapper::Invalid; EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 9d7e7530..26eea7f2 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -1,5 +1,6 @@ #include "Rendering/RenderSystem.h" #include "Collision/Collision.h" +#include "Core/Frustum.h" RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRenderer* renderer, RenderFrame* renderFrame, Octree* frustumCullOctree) : System(world, eventBroker) @@ -13,31 +14,15 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned); m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); - m_LastCullCamera = new Camera(*m_Camera); - m_FrustumCamPtr = &m_Camera; } RenderSystem::~RenderSystem() { delete m_Camera; - delete m_LastCullCamera; } bool RenderSystem::OnSetCamera(Events::SetCamera& e) { - //Right now, lets set the camera to cull away stuff if it is connected to a player. - //TODO: This won't work with spectators, or death anim. - if (e.CameraEntity.FirstParentWithComponent("Player").Valid()) { - m_FrustumCamPtr = &m_Camera; - LOG_INFO("Setting frustum to new camera."); - } else if (e.CameraEntity != m_CurrentCamera) { - //If the camera has no parents, i.e. a free camera, - //then we cull from the last camera, so we can see if the culling works. - //Copy the camera into the last frustum camera, without allocating new memory. - new ((void*)m_LastCullCamera) Camera(*m_Camera); - m_FrustumCamPtr = &m_LastCullCamera; - LOG_INFO("New camera, frustum remains at old camera."); - } ComponentWrapper cTransform = e.CameraEntity["Transform"]; ComponentWrapper cCamera = e.CameraEntity["Camera"]; m_Camera->SetFOV((double)cCamera["FOV"]); @@ -58,55 +43,15 @@ bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity) return entity == m_CurrentCamera || entity.IsChildOf(m_CurrentCamera); } -float frustrumTODO = 0.f; - void RenderSystem::fillModels(std::list>& opaqueJobs, std::list>& transparentJobs) { - if (!frustumEntity.Valid() && m_World->GetComponentPools().size() > 0) { - frustumEntity = EntityWrapper(m_World, m_World->CreateEntity()); - m_World->AttachComponent(frustumEntity.ID, "Transform"); - m_World->AttachComponent(frustumEntity.ID, "Model"); - frustumEntity["Model"]["Resource"] = "Models/Core/UnitCube.mesh"; - } - + Frustum frustum(m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix()); std::vector seenEntities; - //m_Octree->ObjectsInFrustum((*m_FrustumCamPtr)->ProjectionMatrix() * (*m_FrustumCamPtr)->ViewMatrix(), seenEntities); + m_Octree->ObjectsInFrustum(frustum, seenEntities); - glm::mat4x4 viewProj = (*m_FrustumCamPtr)->ProjectionMatrix() * (*m_FrustumCamPtr)->ViewMatrix(); - OctSpace::Frustum frustum; - //Order: Right, left, top, bottom, far, near. - int sign = 1; - for (int i = 0; i < 6; ++i) { - sign = -sign; - int index = i / 2; - OctSpace::Plane& plane = frustum.Planes[i]; - plane.Normal.x = viewProj[0].w + sign * viewProj[0][index]; - plane.Normal.y = viewProj[1].w + sign * viewProj[1][index]; - plane.Normal.z = viewProj[2].w + sign * viewProj[2][index]; - plane.Distance = viewProj[3].w + sign * viewProj[3][index]; - float divByNormalLength = 1.0f / glm::length(plane.Normal); - plane.Normal *= divByNormalLength; - plane.Distance *= divByNormalLength; - } - if (frustumEntity.Valid()) { - int planeI = 0; - glm::vec3 pos = (*m_FrustumCamPtr)->Position() + frustrumTODO * (*m_FrustumCamPtr)->Forward(); - float dist = glm::dot(frustum.Planes[planeI].Normal, pos) + frustum.Planes[planeI].Distance; - frustumEntity["Transform"]["Position"] = pos - dist * frustum.Planes[planeI].Normal; - frustumEntity["Transform"]["Scale"] = glm::vec3(0.15f); - } - if (++frustrumTODO > 75) { - frustrumTODO = 0.f; - } - - //for (auto& seenEntity : seenEntities) { - // EntityWrapper entity = seenEntity.Entity; - // ComponentWrapper cModel = entity["Model"]; - auto models = m_World->GetComponents("Model"); - if (models == nullptr) { - return; - } - for (auto& cModel : *models) { + for (auto& seenEntity : seenEntities) { + EntityWrapper entity = seenEntity.Entity; + ComponentWrapper cModel = entity["Model"]; bool visible = cModel["Visible"]; if (!visible) { continue; @@ -116,8 +61,6 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, continue; } - EntityWrapper entity = EntityWrapper(m_World, cModel.EntityID); - // Only render children of a camera if that camera is currently active if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { continue; @@ -128,15 +71,6 @@ void RenderSystem::fillModels(std::list>& opaqueJobs, continue; } - if (entity.HasComponent("AABB")) { - OctSpace::Frustum::Output o = frustum.VsAABB(*Collision::EntityAbsoluteAABB(entity)); - if (o == OctSpace::Frustum::Outside && entity != frustumEntity) { - resource = "Models/Core/UnitRaptor.mesh"; - } - } else if (entity != frustumEntity){ - resource = "Models/Core/Error.mesh"; - } - Model* model; try { model = ResourceManager::Load<::Model, true>(resource); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 669e48d0..1124f2e4 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -100,7 +100,7 @@ Game::Game(int argc, char* argv[]) ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling, "Model"); + m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling, "Model"); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); From eec59a40c842c17f2386836841ce0a6a1963d0e4 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 17:19:39 +0100 Subject: [PATCH 112/131] Nitpicks. --- include/Engine/Core/Octree.h | 1 - src/Game/Game.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index 49a8b045..6bdea4d3 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -2,7 +2,6 @@ #define Octree_h__ #include -#include #include "../Common.h" #include "AABB.h" diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 1124f2e4..d32eb2ba 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -75,6 +75,7 @@ Game::Game(int argc, char* argv[]) // Create Octrees + // TODO: Perhaps the world bounds should be set in some non-arbitrary way instead of this. AABB boxContainingTheWorld(glm::vec3(-300), glm::vec3(300)); m_OctreeCollision = new Octree(boxContainingTheWorld, 4); m_OctreeTrigger = new Octree(boxContainingTheWorld, 4); From 830e0f66c9ce9a3f84e73572c5f1c167a35f83f8 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 17:21:10 +0100 Subject: [PATCH 113/131] Tiny: Changed warning message. --- src/Engine/Core/EntityWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index b0d08e66..642421bc 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -19,7 +19,7 @@ bool EntityWrapper::HasComponent(const std::string& componentName) void EntityWrapper::AttachComponent(const char* componentName) { if (!Valid()) { - LOG_WARNING("Could not attach \"%s\" component to #%i, component is not valid.", componentName, ID); + LOG_WARNING("Could not attach \"%s\" component to #%i, entity is not valid.", componentName, ID); return; } World->AttachComponent(ID, componentName); From 7140b740b5dc06d0ff122413093d9ba88af09972 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 19:20:04 +0100 Subject: [PATCH 114/131] Models/Collideables/etc. won't need a AABB component anymore, if it has a Model component. In addition, they should take rotation into account, i.e it doesn't have to be axis-aligned. --- include/Engine/Collision/Collision.h | 2 - include/Engine/Rendering/Model.h | 5 +- src/Engine/Collision/Collision.cpp | 71 ++++++++++++----------- src/Engine/Collision/FillOctreeSystem.cpp | 6 -- src/Engine/Collision/TriggerSystem.cpp | 5 -- src/Engine/Rendering/Model.cpp | 9 +++ 6 files changed, 51 insertions(+), 47 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 6d16e090..6e4858b2 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -78,8 +78,6 @@ bool AABBVsAABB(const AABB& a, const AABB& b); //Also outputs the minimum translation that box [a] would need in order to resolve collision. bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation); -//Attaches an AABB which contains all vertices in the entitys Model. -bool AttachAABBComponentFromModel(EntityWrapper entity); // Calculates an absolute AABB from an entity AABB component boost::optional EntityAbsoluteAABB(EntityWrapper& entity); diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index f751a8cc..1f5231e2 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -4,6 +4,7 @@ #include "Rendering/RawModelCustom.h" //#include "Rendering/RawModelAssimp.h" #include "../OpenGL.h" +#include "Core/AABB.h" class Model : public ThreadUnsafeResource { @@ -17,13 +18,15 @@ public: const std::vector& MaterialGroups() const { return m_RawModel->MaterialGroups; } const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; } const std::vector& Vertices() const { return m_RawModel->m_Vertices; } + const AABB& Box() const { return m_Box; } GLuint VAO; GLuint ElementBuffer; RawModel* m_RawModel; private: - + AABB m_Box; + GLuint VertexBuffer; GLuint NormalBuffer; GLuint TangentNormalsBuffer; diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index b150d667..db2319c7 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -1,4 +1,5 @@ #include +#include #include "Collision/Collision.h" #include "Engine/GLM.h" @@ -564,45 +565,49 @@ bool AABBvsTriangles(const AABB& box, return hit; } -bool AttachAABBComponentFromModel(EntityWrapper entity) -{ - if (!entity.HasComponent("Model")) { - return false; - } - //Derive AABB from model - RawModel* model; - try { - model = ResourceManager::Load(entity["Model"]["Resource"]); - } catch (const std::exception&) { - return false; - } - - glm::vec3 mini(INFINITY); - glm::vec3 maxi(-INFINITY); - for (const auto& v : model->m_Vertices) { - mini = glm::min(mini, v.Position); - maxi = glm::max(maxi, v.Position); - } - - entity.AttachComponent("AABB"); - entity["AABB"]["Origin"] = 0.5f * (maxi + mini); - entity["AABB"]["Size"] = maxi - mini; - return true; -} - boost::optional EntityAbsoluteAABB(EntityWrapper& entity) { - if (!entity.HasComponent("AABB")) { + AABB modelSpaceBox; + if (entity.HasComponent("AABB")) { + ComponentWrapper& cAABB = entity["AABB"]; + modelSpaceBox = EntityAABB::FromOriginSize((glm::vec3)cAABB["Origin"], (glm::vec3)cAABB["Size"]); + } else if (entity.HasComponent("Model")) { + Model* model; + std::string res = entity["Model"]["Resource"]; + if (res.empty()) { + return boost::none; + } + try { + model = ResourceManager::Load<::Model, true>(res); + } catch (const Resource::StillLoadingException&) { + return boost::none; + } catch (const std::exception&) { + return boost::none; + } + modelSpaceBox = model->Box(); + } else { return boost::none; } - ComponentWrapper& cAABB = entity["AABB"]; - glm::vec3 absPosition = Transform::AbsolutePosition(entity.World, entity.ID); - glm::vec3 absScale = Transform::AbsoluteScale(entity.World, entity.ID); - glm::vec3 origin = absPosition + (glm::vec3)cAABB["Origin"]; - glm::vec3 size = (glm::vec3)cAABB["Size"] * absScale; + glm::mat4 modelMat = Transform::AbsoluteTransformation(entity); + glm::vec3 mini(INFINITY); + glm::vec3 maxi(-INFINITY); + glm::vec3 maxCorner = modelSpaceBox.MaxCorner(); + glm::vec3 minCorner = modelSpaceBox.MinCorner(); + for (int i = 0; i < 8; ++i) { + std::bitset<3> bits(i); + glm::vec3 corner; + corner.x = bits.test(0) ? maxCorner.x : minCorner.x; + corner.y = bits.test(1) ? maxCorner.y : minCorner.y; + corner.z = bits.test(2) ? maxCorner.z : minCorner.z; + corner = Transform::TransformPoint(corner, modelMat); + mini = glm::min(mini, corner); + maxi = glm::max(maxi, corner); + } + + EntityAABB aabb; + aabb = AABB(mini, maxi); - EntityAABB aabb = EntityAABB::FromOriginSize(origin, size); aabb.Entity = entity; return aabb; diff --git a/src/Engine/Collision/FillOctreeSystem.cpp b/src/Engine/Collision/FillOctreeSystem.cpp index 8c03b5c2..a727eb86 100644 --- a/src/Engine/Collision/FillOctreeSystem.cpp +++ b/src/Engine/Collision/FillOctreeSystem.cpp @@ -7,12 +7,6 @@ void FillOctreeSystem::Update(double dt) void FillOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { - if (!entity.HasComponent("AABB")) { - //Derive AABB from model. - if (!Collision::AttachAABBComponentFromModel(entity)) { - return; - } - } boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); if (absoluteAABB) { m_Octree->AddDynamicObject(*absoluteAABB); diff --git a/src/Engine/Collision/TriggerSystem.cpp b/src/Engine/Collision/TriggerSystem.cpp index adc778e5..21a47721 100644 --- a/src/Engine/Collision/TriggerSystem.cpp +++ b/src/Engine/Collision/TriggerSystem.cpp @@ -5,11 +5,6 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapper& cTrigger, double dt) { - // The trigger *should* have a bounding box, or something, to test against so it can be triggered. - // If it doesn't, add one as big as the model for now, then size can be modified in editor if necessary. - if (!triggerEntity.HasComponent("AABB")) { - Collision::AttachAABBComponentFromModel(triggerEntity); - } boost::optional triggerBox = Collision::EntityAbsoluteAABB(triggerEntity); if (!triggerBox) { return; diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index cf4923a3..a61cf8e3 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -64,6 +64,15 @@ Model::Model(std::string fileName) GLERROR("GLEW: BufferFail5"); //CreateBuffers(); + + glm::vec3 mini(INFINITY); + glm::vec3 maxi(-INFINITY); + for (const auto& v : m_RawModel->m_Vertices) { + mini = glm::min(mini, v.Position); + maxi = glm::max(maxi, v.Position); + } + + m_Box = AABB(maxi, mini); } Model::~Model() From a93ccecfeb41bcdaccfffd0e6b4d9a52f6e83c6d Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 19:23:12 +0100 Subject: [PATCH 115/131] Debug test code. --- src/Engine/Collision/Collision.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index db2319c7..a20ae4d3 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -568,10 +568,10 @@ bool AABBvsTriangles(const AABB& box, boost::optional EntityAbsoluteAABB(EntityWrapper& entity) { AABB modelSpaceBox; - if (entity.HasComponent("AABB")) { + /*if (entity.HasComponent("AABB")) { ComponentWrapper& cAABB = entity["AABB"]; modelSpaceBox = EntityAABB::FromOriginSize((glm::vec3)cAABB["Origin"], (glm::vec3)cAABB["Size"]); - } else if (entity.HasComponent("Model")) { + } else */if (entity.HasComponent("Model")) { Model* model; std::string res = entity["Model"]["Resource"]; if (res.empty()) { @@ -584,6 +584,7 @@ boost::optional EntityAbsoluteAABB(EntityWrapper& entity) } catch (const std::exception&) { return boost::none; } + entity.AttachComponent("AABB"); modelSpaceBox = model->Box(); } else { return boost::none; @@ -609,7 +610,8 @@ boost::optional EntityAbsoluteAABB(EntityWrapper& entity) aabb = AABB(mini, maxi); aabb.Entity = entity; - + (glm::vec3&)entity["AABB"]["Origin"] = aabb.Origin(); + (glm::vec3&)entity["AABB"]["Size"] = aabb.Size(); return aabb; } From ecfacee5876ad73a5fc4daa1746914390b2db8ae Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 9 Feb 2016 19:33:28 +0100 Subject: [PATCH 116/131] Undo debug test code. --- src/Engine/Collision/Collision.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index a20ae4d3..c0c27190 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -568,10 +568,10 @@ bool AABBvsTriangles(const AABB& box, boost::optional EntityAbsoluteAABB(EntityWrapper& entity) { AABB modelSpaceBox; - /*if (entity.HasComponent("AABB")) { + if (entity.HasComponent("AABB")) { ComponentWrapper& cAABB = entity["AABB"]; modelSpaceBox = EntityAABB::FromOriginSize((glm::vec3)cAABB["Origin"], (glm::vec3)cAABB["Size"]); - } else */if (entity.HasComponent("Model")) { + } else if (entity.HasComponent("Model")) { Model* model; std::string res = entity["Model"]["Resource"]; if (res.empty()) { @@ -584,7 +584,6 @@ boost::optional EntityAbsoluteAABB(EntityWrapper& entity) } catch (const std::exception&) { return boost::none; } - entity.AttachComponent("AABB"); modelSpaceBox = model->Box(); } else { return boost::none; @@ -610,8 +609,6 @@ boost::optional EntityAbsoluteAABB(EntityWrapper& entity) aabb = AABB(mini, maxi); aabb.Entity = entity; - (glm::vec3&)entity["AABB"]["Origin"] = aabb.Origin(); - (glm::vec3&)entity["AABB"]["Size"] = aabb.Size(); return aabb; } From 7212217460661fe31f8fe8d34f1b4db15fada3ae Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 9 Feb 2016 22:15:43 +0100 Subject: [PATCH 117/131] Added animation blending and offset animation component --- assets | 2 +- include/Engine/Rendering/ModelJob.h | 33 +- include/Engine/Rendering/Skeleton.h | 37 +- resources/Schema/Components.xsd | 1 + resources/Schema/Components/Animation.xml | 19 +- resources/Schema/Components/Animation.xsd | 19 +- .../Schema/Components/AnimationOffset.xml | 5 + .../Schema/Components/AnimationOffset.xsd | 17 + resources/Schema/Entities/AnimationTests2.xml | 358 ++----------- resources/Schema/Entities/Skeleton.xml | 497 ++++++++++++++++++ resources/Schema/Entities/joint.xml | 22 + src/Engine/Rendering/AnimationSystem.cpp | 94 +--- src/Engine/Rendering/BoneAttachmentSystem.cpp | 6 +- src/Engine/Rendering/DrawFinalPass.cpp | 18 +- src/Engine/Rendering/PickingPass.cpp | 8 +- src/Engine/Rendering/RawModelAssimp.cpp | 2 +- src/Engine/Rendering/Skeleton.cpp | 390 ++++++++++++-- src/Game/Systems/PlayerMovementSystem.cpp | 14 +- 18 files changed, 1091 insertions(+), 451 deletions(-) create mode 100644 resources/Schema/Components/AnimationOffset.xml create mode 100644 resources/Schema/Components/AnimationOffset.xsd create mode 100644 resources/Schema/Entities/Skeleton.xml create mode 100644 resources/Schema/Entities/joint.xml diff --git a/assets b/assets index c4898d82..ab1e1129 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c4898d8281b5584d89b1caf14dab8e5fac120321 +Subproject commit ab1e11294f54a99993bb10004fac0501b6ac0b51 diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 45c89e2d..87f27850 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -60,10 +60,30 @@ struct ModelJob : RenderJob Skeleton = Model->m_RawModel->m_Skeleton; - if (world->HasComponent(Entity, "Animation") && Skeleton != nullptr) { - auto animationComponent = world->GetComponent(Entity, "Animation"); - Animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["AnimationName"]); - AnimationTime = (double)animationComponent["Time"]; + if (Skeleton != nullptr) { + if (world->HasComponent(Entity, "Animation")) { + auto animationComponent = world->GetComponent(Entity, "Animation"); + + for (int i = 1; i <= 3; i++) { + ::Skeleton::AnimationData animationData; + animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]); + if (animationData.animation == nullptr) { + continue; + } + animationData.time = (double)animationComponent["Time" + std::to_string(i)]; + animationData.weight = (double)animationComponent["Weight" + std::to_string(i)]; + + Animations.push_back(animationData); + } + } + + if (world->HasComponent(Entity, "AnimationOffset")) { + auto animationOffsetComponent = world->GetComponent(Entity, "AnimationOffset"); + AnimationOffset.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationOffsetComponent["AnimationName"]); + AnimationOffset.time = (double)animationOffsetComponent["Time"]; + } else { + AnimationOffset.animation = nullptr; + } } }; @@ -80,7 +100,10 @@ struct ModelJob : RenderJob glm::vec4 Color; const ::Model* Model = nullptr; ::Skeleton* Skeleton = nullptr; - const ::Skeleton::Animation* Animation = nullptr; + // const ::Skeleton::Animation* Animation = nullptr; + + std::vector<::Skeleton::AnimationData> Animations; + ::Skeleton::AnimationOffset AnimationOffset; float AnimationTime = 0.f; diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 90e24578..21e38d6f 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -5,6 +5,7 @@ #include "Common.h" #include "../GLM.h" #include +#include //struct Bone //{ @@ -41,7 +42,6 @@ public: std::string Name; glm::mat4 OffsetMatrix; - glm::mat4 ModificationMatrix = glm::mat4(1); int ID; Bone* Parent; @@ -66,11 +66,27 @@ public: std::string Name; double Duration; std::map> JointAnimations; - - - }; + struct AnimationData + { + const Animation* animation; + float time; + float weight; + }; + + struct JointFrameTransform { + glm::vec3 PositionInterp = glm::vec3(0); + glm::quat RotationInterp = glm::quat(); + glm::vec3 ScaleInterp = glm::vec3(0); + float Weight; + }; + + struct AnimationOffset { + const Animation* animation; + float time; + }; + Skeleton() { } ~Skeleton(); @@ -85,19 +101,26 @@ public: int GetBoneID(std::string name); const Animation* GetAnimation(std::string name); - std::vector GetFrameBones(const Animation* animation, double time, bool noRootMotion = false); + std::vector GetFrameBones(std::vector animations, bool noRootMotion = false); + std::vector GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); + void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); std::map Animations; - glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 parentMatrix); + glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix); int GetKeyframe(const Animation& animation, double time); private: - std::map m_BonesByName; + glm::mat4 GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset); + + std::map m_BonesByName; + float aim = 0.f; }; #endif diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 991d785d..bb5c3295 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -30,4 +30,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/Animation.xml b/resources/Schema/Components/Animation.xml index ab589698..ae42009d 100644 --- a/resources/Schema/Components/Animation.xml +++ b/resources/Schema/Components/Animation.xml @@ -1,7 +1,18 @@ - - - 0 - true + + 1.0 + 0 + 0 + true + + 1.0 + 0 + 0 + true + + 1.0 + 0 + 0 + true \ No newline at end of file diff --git a/resources/Schema/Components/Animation.xsd b/resources/Schema/Components/Animation.xsd index 388dfc07..fd4a4c46 100644 --- a/resources/Schema/Components/Animation.xsd +++ b/resources/Schema/Components/Animation.xsd @@ -6,10 +6,21 @@ - - - - + + + + + + + + + + + + + + + diff --git a/resources/Schema/Components/AnimationOffset.xml b/resources/Schema/Components/AnimationOffset.xml new file mode 100644 index 00000000..4aef8219 --- /dev/null +++ b/resources/Schema/Components/AnimationOffset.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/AnimationOffset.xsd b/resources/Schema/Components/AnimationOffset.xsd new file mode 100644 index 00000000..c3430cc2 --- /dev/null +++ b/resources/Schema/Components/AnimationOffset.xsd @@ -0,0 +1,17 @@ + + + + + + + + Aim animation offset for the skeleton + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 21a899f5..adb38d8d 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -8,331 +8,87 @@ - - Models/Core/UnitPlane.mesh - - - - - - - - - - - - Models/DirectionalLightWidget.mesh - - - - - - - - - - - - Wave - - 0.099999986588954926 - - - Models/finaltest.mesh - - - + - + - - R_Leg_Bottom - - + - Models/Core/UnitCube.mesh - + Models/DirectionalLightWidget.mesh - - + + - + - - R_Foot - - + + Run + 0.5 + 0.052207647453917483 + 1 + 1 + Strafe Right + 0.5 + 0.90342197388335332 + Reload Switch + 0.11766622175243757 + 1 + + + Aim + - Models/Core/UnitCube.mesh - + Models/AssaultAnims.mesh + + true - - + + + + + + + + R_Arm_Weapon_Joint + + + Models/WepTest.mesh + + + + + + + + + + + + + + 10 + + + - + - - L_Foot - - - Models/Core/UnitCube.mesh - + Models/Core/UnitPlane.mesh - - - - - - - - - - L_Leg_Bottom - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - L_Leg_Top - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - Hip - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - Spine_1 - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - Spine_2 - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - Spine_3 - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - Neck - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - R_Shoulder - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - R_Arm - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - R_Elbow - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - R_Hand - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - Chin - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - - Run - - 0.099999986588954926 - - - Models/Supertest2.mesh - - - - - - - - - - R_Leg_Top - - - - - Models/Core/UnitCube.mesh - - - - - - + diff --git a/resources/Schema/Entities/Skeleton.xml b/resources/Schema/Entities/Skeleton.xml new file mode 100644 index 00000000..b8deb2eb --- /dev/null +++ b/resources/Schema/Entities/Skeleton.xml @@ -0,0 +1,497 @@ + + + + + + + + + + + + R_Arm_Weapon_Joint + + + + Models/Core/UnitCube.mesh + + true + + + + + + + + + + + + + R_Hand + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Arm + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Shoulder + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Neck + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_3 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_2 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_1 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Hip + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + L_Leg_Top + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Leg_Bottom + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Foot + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Toe + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Shoulder + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Arm + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Hand + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Shoulder_Armor_Joint + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Chin + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Head + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Perietal + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Elbow + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Leg_Bottom + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Elbow + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Leg_Top + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Foot + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Toe + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Shoulder_Armor_Joint + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/joint.xml b/resources/Schema/Entities/joint.xml new file mode 100644 index 00000000..912693f3 --- /dev/null +++ b/resources/Schema/Entities/joint.xml @@ -0,0 +1,22 @@ + + + + + + L_Elbow + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index ef035dca..4566410f 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -19,83 +19,35 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a if(skeleton == nullptr) { return; } -/* - ImGui::SliderFloat("Angle", &angle, -100.f, 100.f); - { - int id = skeleton->GetBoneID("Spine_3"); - auto it = skeleton->Bones.find(id); - if (it != skeleton->Bones.end()) { - it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle), 0.f, 0.f))); + for (int i = 1; i <= 3; i++) { + const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]); + + if (animation == nullptr) { + return; } - } -*/ + + double animationSpeed = (double)animationComponent["Speed" + std::to_string(i)]; + + if (animationSpeed != 0.0) { + double nextTime = (double)animationComponent["Time" + std::to_string(i)] + animationSpeed * dt; - const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]); - - if (animation == nullptr) { - return; - } - - double animationSpeed = (double)animationComponent["Speed"]; - - if (animationSpeed != 0.0) { - double nextTime = (double)animationComponent["Time"] + animationSpeed * dt; - - - if (!(bool)animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) { - (double&)animationComponent["Time"] = glm::sign(nextTime) * animation->Duration; - (double&)animationComponent["Speed"] = 0.0; - Events::AnimationComplete e; - e.Entity = entity; - e.Name = (std::string)animationComponent["AnimationName"]; - m_EventBroker->Publish(e); - } else { - if (glm::abs(nextTime) > animation->Duration) { - (double&)animationComponent["Time"] = glm::abs(nextTime) - animation->Duration; + if (!(bool)animationComponent["Loop" + std::to_string(i)] && glm::abs(nextTime) > animation->Duration) { + (double&)animationComponent["Time" + std::to_string(i)] = glm::sign(nextTime) * animation->Duration; + (double&)animationComponent["Speed" + std::to_string(i)] = 0.0; + Events::AnimationComplete e; + e.Entity = entity; + e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + m_EventBroker->Publish(e); } else { - (double&)animationComponent["Time"] = nextTime; + if (glm::abs(nextTime) > animation->Duration) { + (double&)animationComponent["Time" + std::to_string(i)] = glm::abs(nextTime) - animation->Duration; + } else { + (double&)animationComponent["Time" + std::to_string(i)] = nextTime; + } } } - } - - - - - - - /* { - int id = skeleton->GetBoneID("Spine_2"); - auto it = skeleton->Bones.find(id); - if (it != skeleton->Bones.end()) { - it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/4.f), 0.f, 0.f))); - } - } - { - int id = skeleton->GetBoneID("R_Shoulder"); - auto it = skeleton->Bones.find(id); - if (it != skeleton->Bones.end()) { - it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); - } - } - { - int id = skeleton->GetBoneID("L_Shoulder"); - auto it = skeleton->Bones.find(id); - if (it != skeleton->Bones.end()) { - it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); - } - }*/ - -/* - if (entity.HasComponent("Player")) { - EntityWrapper cameraEntity = entity.FirstChildByName("Camera"); - if (cameraEntity.Valid()) { - glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; - - - } - }*/ - + } } diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index f172d0ab..c74ec9cd 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -21,7 +21,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp Skeleton* skeleton = model->m_RawModel->m_Skeleton; - const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["AnimationName"]); + const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["AnimationName1"]); if (!animation) { return; @@ -34,9 +34,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp } - glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time"], glm::mat4(1)); - - + glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); glm::vec3 scale; glm::quat rotation; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 005249ed..4da18f4a 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -127,14 +127,13 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //Bind uniforms BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); - if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { + if (explosionEffectJob->Skeleton != nullptr) { + std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - if (explosionEffectJob->Animation != nullptr) { - std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animation, explosionEffectJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } } + //bind textures BindExplosionTextures(explosionEffectJob); //draw @@ -154,8 +153,13 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindModelTextures(modelJob); - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); + if (modelJob->Skeleton != nullptr) { + std::vector frameBones; + if(modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 58723a43..aa655951 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -89,7 +89,7 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); + std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } @@ -132,11 +132,9 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } } glBindVertexArray(modelJob->Model->VAO); diff --git a/src/Engine/Rendering/RawModelAssimp.cpp b/src/Engine/Rendering/RawModelAssimp.cpp index 7bf72a22..6b970f70 100644 --- a/src/Engine/Rendering/RawModelAssimp.cpp +++ b/src/Engine/Rendering/RawModelAssimp.cpp @@ -271,7 +271,7 @@ RawModelAssimp::RawModelAssimp(std::string fileName) skelAnim.Keyframes.push_back(animationFrame); } - m_Skeleton->Animations[animationName] = skelAnim; + m_Skeleton->Animations[animationName1] = skelAnim; } } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index d857fa5d..7f2f752f 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -39,36 +39,46 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name) } } -std::vector Skeleton::GetFrameBones(const Animation* animation, double time, bool noRootMotion /*= false*/) +std::vector Skeleton::GetFrameBones(std::vector animations, bool noRootMotion /*= false*/) { - if(animation == nullptr) { + if (animations.size() <= 0) { std::vector finalMatrices; - for(auto& b : Bones) { - finalMatrices.push_back(b.second->ModificationMatrix);//b.second->OffsetMatrix); + for (auto& b : Bones) { + finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); + } + return finalMatrices; + } + + std::map frameBones; + AccumulateBoneTransforms(true, animations, frameBones, RootBone, glm::mat4(1)); + + std::vector finalMatrices; + for (auto &kv : frameBones) { + finalMatrices.push_back(kv.second); + } + return finalMatrices; +} + + +std::vector Skeleton::GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/) +{ + if (animations.size() <= 0 || animationOffset.animation == nullptr) { + std::vector finalMatrices; + for (auto& b : Bones) { + finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); } return finalMatrices; } - // HACK: Animation wrap-around + std::map frameBones; + AccumulateBoneTransforms(true, animations, animationOffset, frameBones, RootBone, glm::mat4(1)); - while (time < 0) { - time += animation->Duration; - } - while (time > animation->Duration) { - time -= animation->Duration; - } - - //auto animationFrame = Animations[""].Keyframes[frame]; - std::map frameBones; - AccumulateBoneTransforms(true, animation, time, frameBones, RootBone, glm::mat4(1)); - //AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); - - std::vector finalMatrices; - for (auto &kv : frameBones) { - finalMatrices.push_back(kv.second); - } - return finalMatrices; + std::vector finalMatrices; + for (auto &kv : frameBones) { + finalMatrices.push_back(kv.second); + } + return finalMatrices; } void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) @@ -95,12 +105,13 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim if(nextFrame.Index == 0) { progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); } else { - progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); } - if(progress > 1.0f || progress < 0.0f) { + if (progress > 1.0f || progress < 0.0f) { + LOG_INFO("Progress: %f", progress); progress = glm::clamp(progress, 0.0f, 1.0f); } Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; @@ -116,12 +127,12 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim positionInterp.z = 0; } - boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrix = parentMatrix *(glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } else { // 1 keyframes for the current bone currentFrame = boneKeyFrames.at(0); - boneMatrix = parentMatrix * (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); + boneMatrix = parentMatrix *(glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } @@ -143,7 +154,320 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim } } -glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 parentMatrix) +void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +{ + glm::mat4 boneMatrix; + + + + std::vector JointTransforms; + + for (const AnimationData animationData : animations) { + const Animation* animation = animationData.animation; + const float time = animationData.time; + + JointFrameTransform jointTransform; + jointTransform.Weight = animationData.weight;; + + if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { + std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); + + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; + + if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone + for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame + if (time >= boneKeyFrames.at(index).Time) { + currentFrame = boneKeyFrames.at(index); + nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); + break; + } + } + + float progress; + + if (nextFrame.Index == 0) { + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); + } else { + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + + } + + + if (progress > 1.0f || progress < 0.0f) { + LOG_INFO("Progress: %f", progress); + progress = glm::clamp(progress, 0.0f, 1.0f); + } + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; + + jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; + jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); + jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; + + // Flag for no root motion + if (bone == RootBone && noRootMotion) { + jointTransform.PositionInterp.x = 0; + jointTransform.PositionInterp.z = 0; + } + + JointTransforms.push_back(jointTransform); + + } else { // 1 keyframes for the current bone + currentFrame = boneKeyFrames.at(0); + jointTransform.PositionInterp = currentFrame.BoneProperties.Position; + jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation; + jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale; + JointTransforms.push_back(jointTransform); + + } + } else { // 0 keyframes for the current bone + + } + + } + + if(JointTransforms.size() <= 0) { + if (bone->Parent) { + boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix; + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } else { + boneMatrix = glm::inverse(bone->OffsetMatrix); + boneMatrices[bone->ID] = parentMatrix; + } + } else if (JointTransforms.size() == 1) { + boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } else { + + glm::vec3 finalPosInterp; + glm::quat finalRotInterp; + glm::vec3 finalScaleInterp; + float totalWeight = 0; + + for (JointFrameTransform jointTransform : JointTransforms) { + totalWeight += jointTransform.Weight; + } + + + for (JointFrameTransform jointTransform : JointTransforms) + { + if(jointTransform.Weight == 1.0f) { + finalPosInterp = jointTransform.PositionInterp; + finalRotInterp = jointTransform.RotationInterp; + finalScaleInterp = jointTransform.ScaleInterp; + break; + } else { + finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight); + finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight)); + finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight); + } + + } + + boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } + + + + for (auto &child : bone->Children) { + AccumulateBoneTransforms(noRootMotion, animations, boneMatrices, child, boneMatrix); + } +} + + +void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +{ + glm::mat4 boneMatrix; + + + + std::vector JointTransforms; + + for (const AnimationData animationData : animations) { + const Animation* animation = animationData.animation; + const float time = animationData.time; + + JointFrameTransform jointTransform; + jointTransform.Weight = animationData.weight;; + + if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { + std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); + + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; + + if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone + for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame + if (time >= boneKeyFrames.at(index).Time) { + currentFrame = boneKeyFrames.at(index); + nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); + break; + } + } + + float progress; + + if (nextFrame.Index == 0) { + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); + } else { + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + + } + + + if (progress > 1.0f || progress < 0.0f) { + LOG_INFO("Progress: %f", progress); + progress = glm::clamp(progress, 0.0f, 1.0f); + } + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; + + jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; + jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); + jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; + + // Flag for no root motion + if (bone == RootBone && noRootMotion) { + jointTransform.PositionInterp.x = 0; + jointTransform.PositionInterp.z = 0; + } + + JointTransforms.push_back(jointTransform); + + } else { // 1 keyframes for the current bone + currentFrame = boneKeyFrames.at(0); + jointTransform.PositionInterp = currentFrame.BoneProperties.Position; + jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation; + jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale; + JointTransforms.push_back(jointTransform); + + } + } else { // 0 keyframes for the current bone + + } + + } + + + glm::mat4 offset = GetOffsetTransform(bone, animationOffset); + + if (JointTransforms.size() == 0) { + if (bone->Parent) { + if (offset != glm::mat4(1)) { + boneMatrix = parentMatrix * offset;// *((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix)); + } else { + boneMatrix = parentMatrix *((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix)); + + } + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } else { + boneMatrix = offset * glm::inverse(bone->OffsetMatrix); + boneMatrices[bone->ID] = parentMatrix; + } + } else { + + glm::vec3 finalPosInterp; + glm::quat finalRotInterp; + glm::vec3 finalScaleInterp; + float totalWeight = 0; + + for (JointFrameTransform jointTransform : JointTransforms) { + totalWeight += jointTransform.Weight; + } + + + for (JointFrameTransform jointTransform : JointTransforms) { + if (jointTransform.Weight == 1.0f) { + finalPosInterp = jointTransform.PositionInterp; + finalRotInterp = jointTransform.RotationInterp; + finalScaleInterp = jointTransform.ScaleInterp; + break; + } else { + finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight); + finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight)); + finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight); + } + + } + + + + if (offset != glm::mat4(1)) { + boneMatrix = parentMatrix * ((glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) + offset); + } else { + boneMatrix = parentMatrix * (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)); + } + + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } + + for (auto &child : bone->Children) { + AccumulateBoneTransforms(noRootMotion, animations, animationOffset, boneMatrices, child, boneMatrix); + } +} + + +glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset) +{ + const Animation* animation = animationOffset.animation; + float time = animationOffset.time; + + glm::vec3 position = glm::vec3(0); + glm::quat rotation = glm::quat(); + glm::vec3 scale = glm::vec3(1); + + if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { + std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); + + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; + + if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone + for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame + if (time >= boneKeyFrames.at(index).Time) { + currentFrame = boneKeyFrames.at(index); + nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); + break; + } + } + + float progress; + + if (nextFrame.Index == 0) { + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); + } else { + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + + } + + + if (progress > 1.0f || progress < 0.0f) { + LOG_INFO("Progress: %f", progress); + progress = glm::clamp(progress, 0.0f, 1.0f); + } + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; + + position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; + rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); + scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; + + + } else { // 1 keyframes for the current bone + currentFrame = boneKeyFrames.at(0); + position = currentFrame.BoneProperties.Position; + rotation = currentFrame.BoneProperties.Rotation; + scale = currentFrame.BoneProperties.Scale; + } + } + + return (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale)); +} + + +glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix) { glm::mat4 boneMatrix; @@ -167,8 +491,7 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio if (nextFrame.Index == 0) { progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); } else { - progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu - + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); } if (progress > 1.0f || progress < 0.0f) { @@ -182,20 +505,19 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio glm::quat rotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); glm::vec3 scaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; - boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrix = (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)) * childMatrix; } else { // 1 keyframes for the current bone currentFrame = boneKeyFrames.at(0); - boneMatrix = parentMatrix * (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); + boneMatrix = (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)) * childMatrix; } } else { // 0 keyframes for the current bone if (bone->Parent) { - boneMatrix = glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix * parentMatrix; + boneMatrix = bone->Parent->OffsetMatrix * glm::inverse(bone->OffsetMatrix) * childMatrix; } else { - boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix); + boneMatrix = glm::inverse(bone->OffsetMatrix) * childMatrix; } - } if (bone->Parent) { diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 36dbcbd0..791350f6 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -97,19 +97,19 @@ void PlayerMovementSystem::Update(double dt) float movementLength = glm::length(groundVelocity); if (glm::length(controller->Movement()) > 0.f) { if (controller->Crouching()) { - cAnimation["AnimationName"] = "Crouch Walk"; - (double&)cAnimation["Speed"] = 1.f * -glm::sign(controller->Movement().z); + cAnimation["AnimationName1"] = "Crouch Walk"; + (double&)cAnimation["Speed1"] = 1.f * -glm::sign(controller->Movement().z); } else { - cAnimation["AnimationName"] = "Run"; - (double&)cAnimation["Speed"] = 2.f * -glm::sign(controller->Movement().z); + cAnimation["AnimationName1"] = "Run"; + (double&)cAnimation["Speed1"] = 2.f * -glm::sign(controller->Movement().z); } } else { if (controller->Crouching()) { - cAnimation["AnimationName"] = "Crouch"; + cAnimation["AnimationName1"] = "Crouch"; (double&)cAnimation["Speed"] = 1.f; } else { - cAnimation["AnimationName"] = "Hold Pos"; - (double&)cAnimation["Speed"] = 1.f; + cAnimation["AnimationName1"] = "Hold Pos"; + (double&)cAnimation["Speed1"] = 1.f; } } } From 3c22dcc1659f42505680faaeb7ada6102d8d075e Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 9 Feb 2016 22:34:09 +0100 Subject: [PATCH 118/131] changed assetbranch --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index ab1e1129..c2847a65 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit ab1e11294f54a99993bb10004fac0501b6ac0b51 +Subproject commit c2847a658ef603cf5c0ee993c4133bdf9c879d1c From 001e2441dddd8d08d51daa511878669c6f858246 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 9 Feb 2016 22:54:51 +0100 Subject: [PATCH 119/131] Mergefixes --- src/Engine/Rendering/DrawFinalPass.cpp | 40 +++++++++++++++----------- src/Engine/Rendering/PickingPass.cpp | 18 +++++++----- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index c97ab6b5..46a47e7e 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -204,10 +204,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene); //bind textures BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); - if (explosionEffectJob->Animation != nullptr) { - std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } } else { m_ExplosionEffectProgram->Bind(); @@ -229,10 +231,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); GLERROR("asdasd"); - if (explosionEffectJob->Animation != nullptr) { - std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } } else { m_ExplosionEffectSplatMapProgram->Bind(); @@ -271,10 +275,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindModelUniforms(forwardSkinnedHandle, modelJob, scene); //bind textures BindModelTextures(forwardSkinnedHandle, modelJob); - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } } else { m_ForwardPlusProgram->Bind(); GLERROR("Bind ForwardPlusProgram"); @@ -295,10 +301,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); GLERROR("asdasd"); - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } } else { m_ForwardPlusSplatMapProgram->Bind(); GLERROR("Bind SplatMap program"); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index c445b8fd..9d911325 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -104,10 +104,12 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } } } else { m_PickingProgram->Bind(); @@ -182,9 +184,11 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); } } From daa96baab5ff799d329051a49b6acc7670e9d249 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 9 Feb 2016 23:03:49 +0100 Subject: [PATCH 120/131] BoneAttachmentSystem fix for not having a skeleton --- src/Engine/Rendering/BoneAttachmentSystem.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index c74ec9cd..bdc45fa6 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -21,6 +21,11 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp Skeleton* skeleton = model->m_RawModel->m_Skeleton; + + if(skeleton == nullptr) { + return; + } + const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["AnimationName1"]); if (!animation) { From d65ce805a502f82b45e92e116148b794442ce6a8 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Wed, 10 Feb 2016 10:53:25 +0100 Subject: [PATCH 121/131] FrustumOctree has its own system, won't cull away explosion effects. --- .../Collision/FillFrustumOctreeSystem.h | 25 +++++++++++++++++++ include/Engine/Collision/FillOctreeSystem.h | 4 +-- .../Collision/FillFrustumOctreeSystem.cpp | 21 ++++++++++++++++ src/Game/Game.cpp | 3 ++- 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 include/Engine/Collision/FillFrustumOctreeSystem.h create mode 100644 src/Engine/Collision/FillFrustumOctreeSystem.cpp diff --git a/include/Engine/Collision/FillFrustumOctreeSystem.h b/include/Engine/Collision/FillFrustumOctreeSystem.h new file mode 100644 index 00000000..f7f1413c --- /dev/null +++ b/include/Engine/Collision/FillFrustumOctreeSystem.h @@ -0,0 +1,25 @@ +#ifndef FillFrustumOctreeSystem_h__ +#define FillFrustumOctreeSystem_h__ + +#include "../Core/System.h" +#include "../Core/Octree.h" +#include "Collision.h" +#include "EntityAABB.h" + +class FillFrustumOctreeSystem : public ImpureSystem, public PureSystem +{ +public: + FillFrustumOctreeSystem(World* world, EventBroker* eventBroker, Octree* octree) + : System(world, eventBroker) + , PureSystem("Model") + , m_Octree(octree) + { } + + virtual void Update(double dt) override; + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override; + +private: + Octree* m_Octree; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Collision/FillOctreeSystem.h b/include/Engine/Collision/FillOctreeSystem.h index 9fd87b94..3bacccac 100644 --- a/include/Engine/Collision/FillOctreeSystem.h +++ b/include/Engine/Collision/FillOctreeSystem.h @@ -1,5 +1,5 @@ -#ifndef CollidableOctreeSystem_h__ -#define CollidableOctreeSystem_h__ +#ifndef FillOctreeSystem_h__ +#define FillOctreeSystem_h__ #include "../Core/System.h" #include "../Core/Octree.h" diff --git a/src/Engine/Collision/FillFrustumOctreeSystem.cpp b/src/Engine/Collision/FillFrustumOctreeSystem.cpp new file mode 100644 index 00000000..f02a30f1 --- /dev/null +++ b/src/Engine/Collision/FillFrustumOctreeSystem.cpp @@ -0,0 +1,21 @@ +#include "Collision/FillFrustumOctreeSystem.h" + +void FillFrustumOctreeSystem::Update(double dt) +{ + m_Octree->ClearDynamicObjects(); +} + +void FillFrustumOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) +{ + if (entity.HasComponent("ExplosionEffect")) { + //TODO: Fix hack, get real box by using shader equation. + EntityAABB aabb = AABB(glm::vec3(-300), glm::vec3(300)); + aabb.Entity = entity; + m_Octree->AddDynamicObject(aabb); + } else { + boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); + if (absoluteAABB) { + m_Octree->AddDynamicObject(*absoluteAABB); + } + } +} \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index d32eb2ba..0f836c6f 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -1,5 +1,6 @@ #include "Game.h" #include "Collision/FillOctreeSystem.h" +#include "Collision/FillFrustumOctreeSystem.h" #include "Collision/EntityAABB.h" #include "Collision/TriggerSystem.h" #include "Collision/CollisionSystem.h" @@ -101,7 +102,7 @@ Game::Game(int argc, char* argv[]) ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling, "Model"); + m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); From 09bb42b3f45aeb26133be0773f517b5019fc9f7e Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 11:00:44 +0100 Subject: [PATCH 122/131] Importer animation fix --- assets | 2 +- resources/Schema/Entities/AnimationTests2.xml | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 7 +++++++ src/Engine/Rendering/PickingPass.cpp | 4 ++++ src/Engine/Rendering/RawModelCustom.cpp | 9 ++++----- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/assets b/assets index c2847a65..6ae43521 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c2847a658ef603cf5c0ee993c4133bdf9c879d1c +Subproject commit 6ae43521b000345bd52bf92c06c5353d14b726ae diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index adb38d8d..3c482c61 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -45,7 +45,7 @@ Aim - Models/AssaultAnims.mesh + Models/Characters/Assault/HelloCube.mesh true diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 46a47e7e..abc00b89 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -210,6 +210,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } else { frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_ExplosionEffectProgram->Bind(); @@ -237,6 +238,8 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } else { frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } else { m_ExplosionEffectSplatMapProgram->Bind(); @@ -281,6 +284,8 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } else { m_ForwardPlusProgram->Bind(); GLERROR("Bind ForwardPlusProgram"); @@ -307,6 +312,8 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } else { m_ForwardPlusSplatMapProgram->Bind(); GLERROR("Bind SplatMap program"); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 9d911325..41850698 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -110,6 +110,8 @@ void PickingPass::Draw(RenderScene& scene) } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } } else { m_PickingProgram->Bind(); @@ -190,6 +192,8 @@ void PickingPass::Draw(RenderScene& scene) } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } glBindVertexArray(modelJob->Model->VAO); diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 7eb58fd4..4ebf80b6 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -288,12 +288,11 @@ void RawModelCustom::ReadAnimationFile(std::string filePath) std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate); if (!in.is_open()) { - //throw Resource::FailedLoadingException("Open animation file failed"); + if (hasSkin) { + throw Resource::FailedLoadingException("Open animation file for a skinned mesh failed, unknown stuff will happen"); + } return; - } else if (hasSkin) { - throw Resource::FailedLoadingException("Open animation file for a skinned mesh failed, unknown stuff will happen"); - return; - } + } unsigned int fileByteSize = static_cast(in.tellg()); in.seekg(0, std::ios_base::beg); From 2c48c2680f06f37427a8b10b695ef43092d187b7 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 11:04:28 +0100 Subject: [PATCH 123/131] Cleanup --- include/Engine/Rendering/Skeleton.h | 2 +- resources/Schema/Entities/AnimationTests2.xml | 34 +++++-------------- src/Engine/Rendering/Skeleton.cpp | 2 ++ 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 21e38d6f..124d618b 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -104,7 +104,7 @@ public: std::vector GetFrameBones(std::vector animations, bool noRootMotion = false); std::vector GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); - void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + //void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 3c482c61..68f27045 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -17,7 +17,7 @@ - Models/DirectionalLightWidget.mesh + Models/Widgets/Lights/DirectionalLightWidget.mesh @@ -31,21 +31,21 @@ Run 0.5 - 0.052207647453917483 + 0.44037772975435119 1 1 - Strafe Right + StrafeRight 0.5 - 0.90342197388335332 - Reload Switch - 0.11766622175243757 + 0.62650761653875175 + ReloadSwitch + 0.88913372073808805 1 - Aim + AimRifle - Models/Characters/Assault/HelloCube.mesh + Models/Characters/Assault/AssaultAnimations.mesh true @@ -53,23 +53,7 @@ - - - - - R_Arm_Weapon_Joint - - - Models/WepTest.mesh - - - - - - - - - + diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 7f2f752f..f272f14d 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -80,6 +80,7 @@ std::vector Skeleton::GetFrameBones(std::vector animat } return finalMatrices; } +/* void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { @@ -153,6 +154,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, child, boneMatrix); } } +*/ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { From 94ff12cf66e800af9c3f073e9c6031d2eedb3736 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 10 Feb 2016 11:04:18 +0100 Subject: [PATCH 124/131] When using a PlaySoundOnEntity Event, you no longer have to provide the child of an entity as parameter. --- include/Engine/Sound/SoundManager.h | 2 +- include/Game/Systems/SoundSystem.h | 3 --- src/Engine/Sound/SoundManager.cpp | 7 +++++-- src/Game/Systems/PlayerMovementSystem.cpp | 5 +---- src/Game/Systems/SoundSystem.cpp | 24 ++++++++--------------- 5 files changed, 15 insertions(+), 26 deletions(-) diff --git a/include/Engine/Sound/SoundManager.h b/include/Engine/Sound/SoundManager.h index 38ec62ff..5b027c62 100644 --- a/include/Engine/Sound/SoundManager.h +++ b/include/Engine/Sound/SoundManager.h @@ -94,7 +94,7 @@ private: float m_BGMVolumeChannel = 1.0f; float m_SFXVolumeChannel = 1.0f; EntityWrapper m_LocalPlayer = EntityWrapper(); - + // Events EventRelay m_EPlaySoundOnEntity; bool OnPlaySoundOnEntity(const Events::PlaySoundOnEntity &e); diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index 0f7f5102..ed30a3c4 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -36,11 +36,8 @@ private: World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; std::string m_Announcer = ""; - // Logic for playing a sound when a player jumps void playerJumps(); - // Helper function - EntityID createChildEmitter(EntityWrapper parent); std::default_random_engine generator; diff --git a/src/Engine/Sound/SoundManager.cpp b/src/Engine/Sound/SoundManager.cpp index 8ba6a502..8e103d5c 100644 --- a/src/Engine/Sound/SoundManager.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -192,7 +192,10 @@ bool SoundManager::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) { Source* source = createSource(e.FilePath); source->Type = SoundType::SFX; - m_Sources[e.EmitterID] = source; + EntityID child = m_World->CreateEntity(e.EmitterID); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + m_Sources[child] = source; playSound(source); return false; } @@ -243,7 +246,7 @@ bool SoundManager::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) } auto emitterChild = m_World->CreateEntity((*it).EntityID); auto emitter = m_World->AttachComponent(emitterChild, "SoundEmitter"); - (bool&)emitter["Loop"] = false; + (bool&)emitter["Loop"] = true; (std::string&)emitter["FilePath"] = e.FilePath; m_World->AttachComponent(emitterChild, "Transform"); Source* source = createSource(e.FilePath); diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index fca52dfd..34d8c689 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -197,10 +197,7 @@ void PlayerMovementSystem::playerStep(double dt) // Player moved a step's distance // Create footstep sound Events::PlaySoundOnEntity e; - EntityID child = m_World->CreateEntity(m_LocalPlayer.ID); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - e.EmitterID = child; + e.EmitterID = m_LocalPlayer.ID; e.FilePath = m_LeftFoot ? "Audio/footstep/footstep2.wav" : "Audio/footstep/footstep3.wav"; m_LeftFoot = !m_LeftFoot; m_EventBroker->Publish(e); diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 06e7d67a..0f35d617 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -31,7 +31,7 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) m_World->AttachComponent(e.Player.ID, "Listener"); m_LocalPlayer = e.Player; Events::PlaySoundOnEntity go; - go.EmitterID = createChildEmitter(m_LocalPlayer); + go.EmitterID = m_LocalPlayer.ID; go.FilePath = "Audio/announcer/" + m_Announcer + "/go.wav"; m_EventBroker->Publish(go); // TEMP: starts bgm @@ -67,7 +67,7 @@ void SoundSystem::playerJumps() glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; if (vel.y == 0) { Events::PlaySoundOnEntity e; - e.EmitterID = createChildEmitter(m_LocalPlayer); + e.EmitterID = m_LocalPlayer.ID; e.FilePath = "Audio/jump/jump1.wav"; m_EventBroker->Publish(e); } @@ -76,7 +76,7 @@ void SoundSystem::playerJumps() bool SoundSystem::OnShoot(const Events::Shoot & e) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.EmitterID = m_LocalPlayer.ID; ev.FilePath = "Audio/laser/laser1.wav"; m_EventBroker->Publish(ev); return true; @@ -92,7 +92,7 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) } else { ev.FilePath = "Audio/announcer/" + m_Announcer + "/objective_failed.wav"; // have not been tested } - ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.EmitterID = m_LocalPlayer.ID; m_EventBroker->Publish(ev); return false; } @@ -122,7 +122,7 @@ bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) { //if (e.PlayerID == m_LocalPlayer.ID) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.EmitterID = m_LocalPlayer.ID; ev.FilePath = "Audio/die/die2.wav"; m_EventBroker->Publish(ev); //} @@ -133,7 +133,7 @@ bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) { //if (e.PlayerHealedID == m_LocalPlayer.ID) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.EmitterID = m_LocalPlayer.ID; ev.FilePath = "Audio/pickup/pickup2.wav"; m_EventBroker->Publish(ev); //} @@ -153,7 +153,7 @@ bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) bool SoundSystem::OnDoubleJump(const Events::DoubleJump & e) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.EmitterID = m_LocalPlayer.ID; ev.FilePath = "Audio/jump/jump2.wav"; m_EventBroker->Publish(ev); return false; @@ -162,16 +162,8 @@ bool SoundSystem::OnDoubleJump(const Events::DoubleJump & e) bool SoundSystem::OnDashAbility(const Events::DashAbility &e) { Events::PlaySoundOnEntity ev; - ev.EmitterID = createChildEmitter(m_LocalPlayer); + ev.EmitterID = m_LocalPlayer.ID; ev.FilePath = "Audio/jump/dash1.wav"; m_EventBroker->Publish(ev); return false; -} - -EntityID SoundSystem::createChildEmitter(EntityWrapper localPlayer) -{ - EntityID child = m_World->CreateEntity(localPlayer.ID); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - return child; } \ No newline at end of file From 97be22c4a57327676722fe4f8090b3a5e794353a Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 11:22:05 +0100 Subject: [PATCH 125/131] Skinned transparent model Picking fixed --- resources/Schema/Entities/AnimationTests2.xml | 7 +- src/Engine/Rendering/PickingPass.cpp | 101 ++++++++++++------ 2 files changed, 71 insertions(+), 37 deletions(-) diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 68f27045..96a439a4 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -31,14 +31,14 @@ Run 0.5 - 0.44037772975435119 + 0.23980116887997371 1 1 StrafeRight 0.5 - 0.62650761653875175 + 0.42593105566437428 ReloadSwitch - 0.88913372073808805 + 0.68855715986371058 1 @@ -47,7 +47,6 @@ Models/Characters/Assault/AssaultAnimations.mesh - true diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 41850698..9842f659 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -156,45 +156,80 @@ void PickingPass::Draw(RenderScene& scene) auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { - int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; - PickingInfo pickInfo; - pickInfo.Entity = modelJob->Entity; - pickInfo.World = modelJob->World; - pickInfo.Camera = scene.Camera; + if (modelJob->Model->isSkined()) { + m_PickingSkinnedProgram->Bind(); + int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; - auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); - if (color != m_EntityColors.end()) { - pickColor[0] = color->second[0]; - pickColor[1] = color->second[1]; + PickingInfo pickInfo; + pickInfo.Entity = modelJob->Entity; + pickInfo.World = modelJob->World; + pickInfo.Camera = scene.Camera; + + auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); + if (color != m_EntityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; + } else { + m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); + if (m_ColorCounter[0] > 255) { + m_ColorCounter[0] = 0; + m_ColorCounter[1] += 1; + } else { + m_ColorCounter[0] += 1; + } + } + + m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } } else { - m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); - if (m_ColorCounter[0] > 255) { - m_ColorCounter[0] = 0; - m_ColorCounter[1] += 1; + int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; + + PickingInfo pickInfo; + pickInfo.Entity = modelJob->Entity; + pickInfo.World = modelJob->World; + pickInfo.Camera = scene.Camera; + + auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); + if (color != m_EntityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; } else { - m_ColorCounter[0] += 1; + m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); + if (m_ColorCounter[0] > 255) { + m_ColorCounter[0] = 0; + m_ColorCounter[1] += 1; + } else { + m_ColorCounter[0] += 1; + } } + + m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); } - m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); - - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - - } glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); @@ -214,8 +249,8 @@ void PickingPass::ClearPicking() { m_PickingColorsToEntity.clear(); m_EntityColors.clear(); - m_ColorCounter[0] = 1; - m_ColorCounter[1] = 0; + m_ColorCounter[0] = 0; + m_ColorCounter[1] = 1; m_PickingBuffer.Bind(); glClearColor(0.f, 0.f, 0.f, 0.f); From 3d2f9fa79d4a9a4362b73206ea492e7bcc808023 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 10 Feb 2016 11:36:54 +0100 Subject: [PATCH 126/131] Drum sounds does not start every single time a TriggerTouch happens. Specific and temporary logic for play test. --- include/Game/Systems/SoundSystem.h | 5 ++++ src/Game/Systems/SoundSystem.cpp | 43 ++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index ed30a3c4..09582826 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -39,6 +39,11 @@ private: // Logic for playing a sound when a player jumps void playerJumps(); + // Temporary solution for play test. + bool m_DrumsIsPlaying = false; + double m_DrumTimer = 0.0; + bool drumTimer(double dt); + std::default_random_engine generator; EventRelay m_EPlayerSpawned; diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 0f35d617..df14cd86 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -23,7 +23,12 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp { } void SoundSystem::Update(double dt) -{ } +{ + // Temp for play test. + if(m_DrumsIsPlaying) { + m_DrumsIsPlaying = !drumTimer(dt); + } +} bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) { @@ -73,6 +78,17 @@ void SoundSystem::playerJumps() } } +bool SoundSystem::drumTimer(double dt) +{ + m_DrumTimer += dt; + if (m_DrumTimer > 15) { + m_DrumTimer = 0.0; + return true; + } else { + return false; + } +} + bool SoundSystem::OnShoot(const Events::Shoot & e) { Events::PlaySoundOnEntity ev; @@ -94,6 +110,8 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) } ev.EmitterID = m_LocalPlayer.ID; m_EventBroker->Publish(ev); + // Temp for play test. + m_DrumsIsPlaying = false; return false; } @@ -106,11 +124,11 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) std::vector paths; paths.push_back("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); - // Breathe - int ammountOfbreaths = (static_cast(e.Damage) / 10) + 2; // TEMP: Idk something stupid like this shit - for (int i = 0; i < ammountOfbreaths; i++) { - paths.push_back("Audio/exhausted/breath.wav"); - } +// // Breathe +// int ammountOfbreaths = (static_cast(e.Damage) / 10) + 2; // TEMP: Idk something stupid like this shit +// for (int i = 0; i < ammountOfbreaths; i++) { +// paths.push_back("Audio/exhausted/breath.wav"); +// } Events::PlayQueueOnEntity ev; ev.Emitter = m_LocalPlayer; ev.FilePaths = paths; @@ -120,32 +138,35 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) { - //if (e.PlayerID == m_LocalPlayer.ID) { Events::PlaySoundOnEntity ev; ev.EmitterID = m_LocalPlayer.ID; ev.FilePath = "Audio/die/die2.wav"; m_EventBroker->Publish(ev); - //} return false; } bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) { - //if (e.PlayerHealedID == m_LocalPlayer.ID) { Events::PlaySoundOnEntity ev; ev.EmitterID = m_LocalPlayer.ID; ev.FilePath = "Audio/pickup/pickup2.wav"; m_EventBroker->Publish(ev); - //} return false; } bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) { + // Temp for play test. + if (m_DrumsIsPlaying) { + return false; + } if (m_World->HasComponent(e.Trigger.ID, "CapturePoint")) { - Events::PlayBackgroundMusic ev; + Events::PlaySoundOnEntity ev; // should be BGM + ev.EmitterID = m_LocalPlayer.ID; ev.FilePath = "Audio/bgm/drumstest.wav"; m_EventBroker->Publish(ev); + // Temp for play test. + m_DrumsIsPlaying = true; } return false; } From afebf879a02dcf2901048c2a1c5e6e0582b8f6bf Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 13:44:47 +0100 Subject: [PATCH 127/131] Merge fixes --- include/Engine/Collision/Collision.h | 2 +- include/Engine/Rendering/DrawFinalPass.h | 2 + .../Shaders/FillDepthBufferSkinned.vert.glsl | 33 ++ .../Shaders/ForwardPlusSkinned.vert.glsl | 2 +- .../Shaders/ShieldStencilSkinned.vert.glsl | 33 ++ src/Engine/Collision/Collision.cpp | 25 +- src/Engine/Collision/CollisionSystem.cpp | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 445 ++++++++++-------- src/Engine/Rendering/PickingPass.cpp | 26 +- src/Engine/Rendering/RenderSystem.cpp | 19 +- 10 files changed, 348 insertions(+), 241 deletions(-) create mode 100644 resources/Shaders/FillDepthBufferSkinned.vert.glsl create mode 100644 resources/Shaders/ShieldStencilSkinned.vert.glsl diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 6d16e090..624fbca0 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -64,7 +64,7 @@ bool RayVsModel(const Ray& ray, float& outVCoord); bool AABBvsTriangles(const AABB& box, - const std::vector& modelVertices, + const RawModel::Vertex* modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& boxVelocity, diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 72fd756b..7d5e2a7a 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -78,6 +78,8 @@ private: ShaderProgram* m_ExplosionEffectSkinnedProgram; ShaderProgram* m_ExplosionEffectSplatMapSkinnedProgram; ShaderProgram* m_ForwardPlusSplatMapSkinnedProgram; + ShaderProgram* m_ShieldToStencilSkinnedProgram; + ShaderProgram* m_FillDepthBufferSkinnedProgram; }; #endif \ No newline at end of file diff --git a/resources/Shaders/FillDepthBufferSkinned.vert.glsl b/resources/Shaders/FillDepthBufferSkinned.vert.glsl new file mode 100644 index 00000000..ce2a142d --- /dev/null +++ b/resources/Shaders/FillDepthBufferSkinned.vert.glsl @@ -0,0 +1,33 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform mat4 Bones[100]; + + +layout(location = 0) in vec3 Position; +layout(location = 5) in vec4 BoneIndices; +layout(location = 6) in vec4 BoneWeights; + + + +out VertexData{ + vec3 Position; +}Output; + +void main() +{ + mat4 boneTransform = mat4(1); + + if(BoneWeights[0] > 0.0f){ + boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + + BoneWeights[1] * Bones[int(BoneIndices[1])] + + BoneWeights[2] * Bones[int(BoneIndices[2])] + + BoneWeights[3] * Bones[int(BoneIndices[3])]; + } + + gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + + Output.Position = vec3(0.0); +} \ No newline at end of file diff --git a/resources/Shaders/ForwardPlusSkinned.vert.glsl b/resources/Shaders/ForwardPlusSkinned.vert.glsl index 5368b260..5fd55a8c 100644 --- a/resources/Shaders/ForwardPlusSkinned.vert.glsl +++ b/resources/Shaders/ForwardPlusSkinned.vert.glsl @@ -38,7 +38,7 @@ void main() Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; Output.TextureCoordinate = TextureCoords; - Output.Normal = vec3(M * vec4(Normal, 0.0)); + Output.Normal = vec3(M * boneTransform * vec4(Normal, 0.0)); Output.Tangent = vec3(M * vec4(Tangent, 0.0)); Output.BiTangent = vec3(M * vec4(BiTangent, 0.0)); Output.ExplosionColor = vec4(1.0); diff --git a/resources/Shaders/ShieldStencilSkinned.vert.glsl b/resources/Shaders/ShieldStencilSkinned.vert.glsl new file mode 100644 index 00000000..ce2a142d --- /dev/null +++ b/resources/Shaders/ShieldStencilSkinned.vert.glsl @@ -0,0 +1,33 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform mat4 Bones[100]; + + +layout(location = 0) in vec3 Position; +layout(location = 5) in vec4 BoneIndices; +layout(location = 6) in vec4 BoneWeights; + + + +out VertexData{ + vec3 Position; +}Output; + +void main() +{ + mat4 boneTransform = mat4(1); + + if(BoneWeights[0] > 0.0f){ + boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + + BoneWeights[1] * Bones[int(BoneIndices[1])] + + BoneWeights[2] * Bones[int(BoneIndices[2])] + + BoneWeights[3] * Bones[int(BoneIndices[3])]; + } + + gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + + Output.Position = vec3(0.0); +} \ No newline at end of file diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 839a8e77..34b7e553 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -183,7 +183,7 @@ bool RayVsTriangle(const Ray& ray, } outDistance = dist; outUCoord = glm::dot(m, DxE2) * DetInv; - outVCoord = glm::dot(ray.Direction(), MxE1) * DetInv; + outVCoord = glm::dot(ray.Direction(), MxE1) * DetInv; //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem //If u and v are positive, u+v <= 1, dist is positive, and less than closest. @@ -330,7 +330,7 @@ bool rectangleVsTriangle(const glm::vec2& boxMin, float push = rightRes < -leftRes ? rightRes : leftRes; float absPushSq = abs(push); absPushSq *= absPushSq; - + if (absPushSq < resolutionDistanceSq) { resolutionDistanceSq = absPushSq; resolutionDirection = push * normal; @@ -355,8 +355,8 @@ constexpr bool FaceIsGround(float faceNormalY) //An array containing 3 int pairs { 0, 2 }, { 0, 1 }, { 1, 2 } constexpr std::array, 3> dimensionPairs({ std::pair(0, 2), std::pair(0, 1), std::pair(1, 2) }); -bool AABBvsTriangle(const AABB& box, - const std::array& triPos, +bool AABBvsTriangle(const AABB& box, + const std::array& triPos, const glm::vec3& originalBoxVelocity, float verticalStepHeight, bool& isOnGround, @@ -385,7 +385,7 @@ bool AABBvsTriangle(const AABB& box, Resolution() : DistanceSq(INFINITY) , Vector(0.f) - {} + { } BoxTriResolveCase Case; float DistanceSq; glm::vec3 Vector; @@ -525,9 +525,9 @@ bool AABBvsTriangle(const AABB& box, return true; } -bool AABBvsTriangles(const AABB& box, - const std::vector& modelVertices, - const std::vector& modelIndices, +bool AABBvsTriangles(const AABB& box, + const RawModel::Vertex* modelVertices, + const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& boxVelocity, float verticalStepHeight, @@ -579,12 +579,11 @@ bool AttachAABBComponentFromModel(EntityWrapper entity) glm::vec3 mini(INFINITY); glm::vec3 maxi(-INFINITY); - for (const auto& v : model->m_Vertices) { + for (unsigned int i = 0; i < model->NumVertices(); i++) { + const auto& v = model->Vertices()[i]; mini = glm::min(mini, v.Position); - for (unsigned int i = 0; i < modelRes->NumberOfVertices(); i++) { - const auto& v = modelRes->Vertices()[i]; + maxi = glm::max(maxi, v.Position); } - entity.AttachComponent("AABB"); entity["AABB"]["Origin"] = 0.5f * (maxi + mini); entity["AABB"]["Size"] = maxi - mini; @@ -609,4 +608,4 @@ boost::optional EntityAbsoluteAABB(EntityWrapper& entity) return aabb; } -} +} \ No newline at end of file diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 7d8905a8..afd09022 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -41,7 +41,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"]; bool isOnGround = (bool)cPhysics["IsOnGround"]; float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"]; - if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { + if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; cPhysics["Velocity"] = inOutVelocity; if (isOnGround) { diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 66f222c5..760ecce5 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -142,12 +142,26 @@ void DrawFinalPass::InitializeShaderPrograms() m_ShieldToStencilProgram->Link(); GLERROR("Creating Shield program"); + m_ShieldToStencilSkinnedProgram = ResourceManager::Load("#ShieldToStencilProgramSkinned"); + m_ShieldToStencilSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ShieldStencilSkinned.vert.glsl"))); + m_ShieldToStencilSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ShieldStencil.frag.glsl"))); + m_ShieldToStencilSkinnedProgram->Compile(); + m_ShieldToStencilSkinnedProgram->Link(); + GLERROR("Creating Shield Skinned program"); + m_FillDepthBufferProgram = ResourceManager::Load("#FillDepthBufferProgram"); m_FillDepthBufferProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/FillDepthBuffer.vert.glsl"))); m_FillDepthBufferProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/FillDepthBuffer.frag.glsl"))); m_FillDepthBufferProgram->Compile(); m_FillDepthBufferProgram->Link(); GLERROR("Creating DepthFill program"); + + m_FillDepthBufferSkinnedProgram = ResourceManager::Load("#FillDepthBufferProgramSkinned"); + m_FillDepthBufferSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/FillDepthBufferSkinned.vert.glsl"))); + m_FillDepthBufferSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/FillDepthBuffer.frag.glsl"))); + m_FillDepthBufferSkinnedProgram->Compile(); + m_FillDepthBufferSkinnedProgram->Link(); + GLERROR("Creating DepthFill program"); } void DrawFinalPass::Draw(RenderScene& scene) @@ -181,11 +195,11 @@ void DrawFinalPass::Draw(RenderScene& scene) //Draw Opaque shielded objects state->StencilFunc(GL_NOTEQUAL, 1, 0xFF); state->StencilMask(0x00); - DrawShieldedModelRenderQueue(scene.Jobs.OpaqueShieldedObjects, scene); + DrawModelRenderQueues(scene.Jobs.OpaqueShieldedObjects, scene); //might need changing GLERROR("Shielded Opaque object"); //Draw Transparen Shielded objects - DrawShieldedModelRenderQueue(scene.Jobs.TransparentShieldedObjects, scene); + DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene); //might need changing GLERROR("Shielded Transparent objects"); GLERROR("END"); @@ -298,100 +312,186 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); - for(auto &job : jobs) - { - auto explosionEffectJob = std::dynamic_pointer_cast(job); - if(explosionEffectJob) { - //Bind program - if(GLERROR("Prebind")) { - continue; - } - m_ExplosionEffectProgram->Bind(); - if(GLERROR("BindProgram")) { - continue; - } + for (auto &job : jobs) { + auto explosionEffectJob = std::dynamic_pointer_cast(job); + if (explosionEffectJob) { + switch (explosionEffectJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + if (explosionEffectJob->Model->isSkined()) { + m_ExplosionEffectSkinnedProgram->Bind(); + GLERROR("Bind ExplosionEffectSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } else { + m_ExplosionEffectProgram->Bind(); + GLERROR("Bind ExplosionEffect program"); + //bind uniforms + BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionHandle, explosionEffectJob); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + if (explosionEffectJob->Model->isSkined()) { + m_ExplosionEffectSplatMapSkinnedProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMapSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSplatMapSkinnedHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); + GLERROR("asdasd"); + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } else { + m_ExplosionEffectSplatMapProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMap program"); + //bind uniforms + //bind uniforms + BindExplosionUniforms(explosionSplatMapHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapHandle, explosionEffectJob); + GLERROR("asdasd"); + } + break; + } + } glDisable(GL_CULL_FACE); - //Bind uniforms - BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); - if(GLERROR("BindExplosionUniforms")) { - continue; - } - - if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (explosionEffectJob->Animation != nullptr) { - std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } - } - if(GLERROR("Animation")) { - continue; - } - - //bind textures - BindExplosionTextures(explosionEffectJob); - if(GLERROR("BindExplosionTextures")) { - continue; - } //draw glBindVertexArray(explosionEffectJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer); glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int))); glEnable(GL_CULL_FACE); - if(GLERROR("explosion effect end")) { - continue; - } + GLERROR("explosion effect end"); + } else { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + //bind forward program + //TODO: JOHAN/TOBIAS: Bind shader based on ModelJob->ShaderID; + switch (modelJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + if (modelJob->Model->isSkined()) { + m_ForwardPlusSkinnedProgram->Bind(); + GLERROR("Bind ForwardPlusSkinnedProgram"); + //bind uniforms + BindModelUniforms(forwardSkinnedHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSkinnedHandle, modelJob); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } else { - auto modelJob = std::dynamic_pointer_cast(job); - if (modelJob) { - //bind forward program - m_ForwardPlusProgram->Bind(); - glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - - //bind uniforms - BindModelUniforms(forwardHandle, modelJob, scene); - - //bind textures - BindModelTextures(modelJob); - - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } else { + m_ForwardPlusProgram->Bind(); + GLERROR("Bind ForwardPlusProgram"); + //bind uniforms + BindModelUniforms(forwardHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardHandle, modelJob); + } + break; } - } + case RawModel::MaterialType::SplatMapping: + { + if (modelJob->Model->isSkined()) { + m_ForwardPlusSplatMapSkinnedProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatMapSkinnedHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); + GLERROR("asdasd"); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - //draw - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); - if(GLERROR("models end")) { - continue; + } else { + m_ForwardPlusSplatMapProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatHandle, modelJob); + GLERROR("asdasd"); + } + break; + } + } + //draw + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); + if (GLERROR("models end")) { + continue; + } } } } - } - } void DrawFinalPass::DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene) { - m_ShieldToStencilProgram->Bind(); - GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle(); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); for (auto &job : jobs) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + if(modelJob->Model->isSkined()) { + m_ShieldToStencilSkinnedProgram->Bind(); + GLuint shaderHandle = m_ShieldToStencilSkinnedProgram->GetHandle(); + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } else { + m_ShieldToStencilProgram->Bind(); + GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle(); + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + + } glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); @@ -417,139 +517,70 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list(job); if (explosionEffectJob) { - switch (explosionEffectJob->Type) { - case RawModel::MaterialType::Basic: - case RawModel::MaterialType::SingleTextures: - { - if (explosionEffectJob->Model->isSkined()) { - m_ExplosionEffectSkinnedProgram->Bind(); - GLERROR("Bind ExplosionEffectSkinned program"); - //bind uniforms - BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene); - //bind textures - BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); - std::vector frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); - } else { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } - else { - m_ExplosionEffectProgram->Bind(); - GLERROR("Bind ExplosionEffect program"); - //bind uniforms - BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); - //bind textures - BindExplosionTextures(explosionHandle, explosionEffectJob); - } - break; - } - case RawModel::MaterialType::SplatMapping: - { - if (explosionEffectJob->Model->isSkined()) { - m_ExplosionEffectSplatMapSkinnedProgram->Bind(); - GLERROR("Bind ExplosionEffectSplatMapSkinned program"); - //bind uniforms - BindExplosionUniforms(explosionSplatMapSkinnedHandle, explosionEffectJob, scene); - //bind textures - BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); - GLERROR("asdasd"); - std::vector frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); - } else { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + //Bind program + if (GLERROR("Prebind")) { + continue; + } + m_ExplosionEffectProgram->Bind(); + if (GLERROR("BindProgram")) { + continue; + } - } - else { - m_ExplosionEffectSplatMapProgram->Bind(); - GLERROR("Bind ExplosionEffectSplatMap program"); - //bind uniforms - //bind uniforms - BindExplosionUniforms(explosionSplatMapHandle, explosionEffectJob, scene); - //bind textures - BindExplosionTextures(explosionSplatMapHandle, explosionEffectJob); - GLERROR("asdasd"); - } - break; - } - } glDisable(GL_CULL_FACE); + //Bind uniforms + BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); + if (GLERROR("BindExplosionUniforms")) { + continue; + } + + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + if (GLERROR("Animation")) { + continue; + } + + //bind textures + BindExplosionTextures(explosionHandle, explosionEffectJob); + if (GLERROR("BindExplosionTextures")) { + continue; + } //draw glBindVertexArray(explosionEffectJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer); glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int))); glEnable(GL_CULL_FACE); - GLERROR("explosion effect end"); + if (GLERROR("explosion effect end")) { + continue; + } + } else { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { //bind forward program - //TODO: JOHAN/TOBIAS: Bind shader based on ModelJob->ShaderID; - switch (modelJob->Type) { - case RawModel::MaterialType::Basic: - case RawModel::MaterialType::SingleTextures: - { - if (modelJob->Model->isSkined()) { - m_ForwardPlusSkinnedProgram->Bind(); - GLERROR("Bind ForwardPlusSkinnedProgram"); - //bind uniforms - BindModelUniforms(forwardSkinnedHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardSkinnedHandle, modelJob); - std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + m_ForwardPlusProgram->Bind(); + glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - } else { - m_ForwardPlusProgram->Bind(); - GLERROR("Bind ForwardPlusProgram"); - //bind uniforms - BindModelUniforms(forwardHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardHandle, modelJob); - } - break; - } - case RawModel::MaterialType::SplatMapping: - { - if (modelJob->Model->isSkined()) { - m_ForwardPlusSplatMapSkinnedProgram->Bind(); - GLERROR("Bind SplatMap program"); - //bind uniforms - BindModelUniforms(forwardSplatMapSkinnedHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); - GLERROR("asdasd"); - std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + //bind uniforms + BindModelUniforms(forwardHandle, modelJob, scene); + + //bind textures + BindModelTextures(forwardHandle ,modelJob); + + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } else { - m_ForwardPlusSplatMapProgram->Bind(); - GLERROR("Bind SplatMap program"); - //bind uniforms - BindModelUniforms(forwardSplatHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardSplatHandle, modelJob); - GLERROR("asdasd"); - } - break; - } - } //draw glBindVertexArray(modelJob->Model->VAO); @@ -566,25 +597,35 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene) { - m_FillDepthBufferProgram->Bind(); - GLuint shaderHandle = m_FillDepthBufferProgram->GetHandle(); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - + + for (auto &job : jobs) { auto modelJob = std::dynamic_pointer_cast(job); - //bind uniforms - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + if(modelJob->Model->isSkined()) { + m_FillDepthBufferSkinnedProgram->Bind(); + GLuint shaderHandle = m_FillDepthBufferSkinnedProgram->GetHandle(); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } else { + m_FillDepthBufferProgram->Bind(); + GLuint shaderHandle = m_FillDepthBufferProgram->GetHandle(); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); } + //draw glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 795d1097..80f0efb7 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -184,13 +184,14 @@ void PickingPass::Draw(RenderScene& scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); @@ -230,13 +231,14 @@ void PickingPass::Draw(RenderScene& scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); } + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 9b9b8654..67b0cff5 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -109,7 +109,7 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) fillPercentage )); if (m_World->HasComponent(cModel.EntityID, "Shield")){ - TODO Calc hash + explosionEffectJob->CalculateHash(); Jobs.ShieldObjects.push_back(explosionEffectJob); } else if (m_World->HasComponent(cModel.EntityID, "Shielded") || m_World->HasComponent(cModel.EntityID, "Player")) { @@ -119,10 +119,9 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) } if (cModel["Transparent"]) { - TODO: Calc hash Jobs.TransparentShieldedObjects.push_back(explosionEffectJob); } else { - explosionEffectJob->CalculateHash(); + explosionEffectJob->CalculateHash(); Jobs.OpaqueShieldedObjects.push_back(explosionEffectJob); } } else { @@ -131,10 +130,9 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) } if (cModel["Transparent"]) { - TODO CALC HASH Jobs.TransparentObjects.push_back(explosionEffectJob); } else { - TODO CALC HASH + explosionEffectJob->CalculateHash(); Jobs.OpaqueObjects.push_back(explosionEffectJob); } } @@ -150,7 +148,7 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) fillPercentage )); if (m_World->HasComponent(cModel.EntityID, "Shield")) { - TODO: CALC HASH + modelJob->CalculateHash(); Jobs.ShieldObjects.push_back(modelJob); } else if (m_World->HasComponent(cModel.EntityID, "Shielded") || m_World->HasComponent(cModel.EntityID, "Player")) { @@ -160,10 +158,9 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) } if (cModel["Transparent"]) { - TODO CALC HASH Jobs.TransparentShieldedObjects.push_back(modelJob); } else { - modelJob->CalculateHash(); + modelJob->CalculateHash(); Jobs.OpaqueShieldedObjects.push_back(modelJob); } } else { @@ -172,10 +169,9 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) } if (cModel["Transparent"]) { - CALC HASH Jobs.TransparentObjects.push_back(modelJob); } else { - CALC HASH + modelJob->CalculateHash(); Jobs.OpaqueObjects.push_back(modelJob); } } @@ -298,7 +294,8 @@ void RenderSystem::Update(double dt) fillModels(scene.Jobs); fillPointLights(scene.Jobs.PointLight, m_World); - scene.OpaqueObjects.sort(); + //TODO: Make sure all objects needed are also sorted. + scene.Jobs.OpaqueObjects.sort(); fillDirectionalLights(scene.Jobs.DirectionalLight, m_World); fillText(scene.Jobs.Text, m_World); m_RenderFrame->Add(scene); From c2128790af8445d55c9559b37d499357b01ad020 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 10 Feb 2016 14:07:11 +0100 Subject: [PATCH 128/131] Now using appropriate variable to see if a player is on ground. Does not check if playervel.y == 0 which will be false if a player is on a obstacle. --- src/Game/Systems/PlayerMovementSystem.cpp | 7 +++---- src/Game/Systems/SoundSystem.cpp | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 1a0f7eb1..1cd067a6 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -187,13 +187,12 @@ void PlayerMovementSystem::playerStep(double dt) } // Position of the local player, used see how far a player has moved. glm::vec3 pos = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Transform")["Position"]; - // Velocity of the local player, used to see if a player is airborne. - glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; + // Used to see if a player is airborne. + bool grounded = (bool)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["IsOnGround"]; m_DistanceMoved += glm::length(pos - m_LastPosition); // Set the last position for next iteration m_LastPosition = pos; - bool isAirborne = vel.y != 0; - if (m_DistanceMoved > m_PlayerStepLength && !isAirborne) { + if (m_DistanceMoved > m_PlayerStepLength && grounded) { // Player moved a step's distance // Create footstep sound Events::PlaySoundOnEntity e; diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index df14cd86..acb7501c 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -69,8 +69,8 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) void SoundSystem::playerJumps() { - glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; - if (vel.y == 0) { + bool grounded = (bool)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["IsOnGround"]; + if (grounded) { Events::PlaySoundOnEntity e; e.EmitterID = m_LocalPlayer.ID; e.FilePath = "Audio/jump/jump1.wav"; From 1e238b24071af7486b6620ce1c1bf18c141b9019 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 14:28:25 +0100 Subject: [PATCH 129/131] Changed asset branch --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 6ae43521..7531e441 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6ae43521b000345bd52bf92c06c5353d14b726ae +Subproject commit 7531e441fea639076d69c6cf05e3ae8ff7170cf9 From e9d36c48a641c5c166c9a1e6b218b979a1c05fc4 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 14:36:25 +0100 Subject: [PATCH 130/131] Changed isSkined to IsSkinned and removed duplicated code in PickingPass --- include/Engine/Rendering/Model.h | 2 +- include/Engine/Rendering/ModelJob.h | 6 +- include/Engine/Rendering/RawModelCustom.h | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 12 +- src/Engine/Rendering/Model.cpp | 6 +- src/Engine/Rendering/PickingPass.cpp | 156 ++++++++-------------- 6 files changed, 67 insertions(+), 117 deletions(-) diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index 30706cc5..4d21f724 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -20,7 +20,7 @@ public: const RawModel::Vertex* Vertices() const { return m_RawModel->Vertices(); } unsigned int NumberOfVertices() const { return m_RawModel->NumVertices(); } const AABB& Box() const { return m_Box; } - bool isSkined() const { return m_RawModel->isSkined(); } + bool IsSkinned() const { return m_RawModel->IsSkinned(); } GLuint VAO; GLuint ElementBuffer; RawModel* m_RawModel; diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 633e5daa..bc2b8b6e 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -27,7 +27,7 @@ struct ModelJob : RenderJob ::RawModel::MaterialBasic* matGroup = matProp.material; switch(matProp.type){ case ::RawModel::MaterialType::Basic: - if (Model->isSkined()) { + if (Model->IsSkinned()) { ShaderID = ResourceManager::Load("#ForwardPlusSkinnedProgram")->ResourceID; } else { @@ -37,7 +37,7 @@ struct ModelJob : RenderJob break; case ::RawModel::MaterialType::SingleTextures: { - if (Model->isSkined()) { + if (Model->IsSkinned()) { ShaderID = ResourceManager::Load("#ForwardPlusSkinnedProgram")->ResourceID; } else { @@ -64,7 +64,7 @@ struct ModelJob : RenderJob break; case ::RawModel::MaterialType::SplatMapping: { - if (Model->isSkined()) { + if (Model->IsSkinned()) { ShaderID = ResourceManager::Load("#ForwardPlusSplatMapSkinnedProgram")->ResourceID; } else { diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index 476bf52e..cf21fb6d 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -114,7 +114,7 @@ public: } }; - bool isSkined() const { return hasSkin; }; + bool IsSkinned() const { return hasSkin; }; std::vector m_Materials; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 760ecce5..0d08b98f 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -320,7 +320,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& case RawModel::MaterialType::Basic: case RawModel::MaterialType::SingleTextures: { - if (explosionEffectJob->Model->isSkined()) { + if (explosionEffectJob->Model->IsSkinned()) { m_ExplosionEffectSkinnedProgram->Bind(); GLERROR("Bind ExplosionEffectSkinned program"); //bind uniforms @@ -346,7 +346,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } case RawModel::MaterialType::SplatMapping: { - if (explosionEffectJob->Model->isSkined()) { + if (explosionEffectJob->Model->IsSkinned()) { m_ExplosionEffectSplatMapSkinnedProgram->Bind(); GLERROR("Bind ExplosionEffectSplatMapSkinned program"); //bind uniforms @@ -392,7 +392,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& case RawModel::MaterialType::Basic: case RawModel::MaterialType::SingleTextures: { - if (modelJob->Model->isSkined()) { + if (modelJob->Model->IsSkinned()) { m_ForwardPlusSkinnedProgram->Bind(); GLERROR("Bind ForwardPlusSkinnedProgram"); //bind uniforms @@ -419,7 +419,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } case RawModel::MaterialType::SplatMapping: { - if (modelJob->Model->isSkined()) { + if (modelJob->Model->IsSkinned()) { m_ForwardPlusSplatMapSkinnedProgram->Bind(); GLERROR("Bind SplatMap program"); //bind uniforms @@ -468,7 +468,7 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::list(job); if (modelJob) { - if(modelJob->Model->isSkined()) { + if(modelJob->Model->IsSkinned()) { m_ShieldToStencilSkinnedProgram->Bind(); GLuint shaderHandle = m_ShieldToStencilSkinnedProgram->GetHandle(); @@ -602,7 +602,7 @@ void DrawFinalPass::DrawToDepthBuffer(std::list>& job for (auto &job : jobs) { auto modelJob = std::dynamic_pointer_cast(job); - if(modelJob->Model->isSkined()) { + if(modelJob->Model->IsSkinned()) { m_FillDepthBufferSkinnedProgram->Bind(); GLuint shaderHandle = m_FillDepthBufferSkinnedProgram->GetHandle(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index 9ce99564..6457c980 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -87,7 +87,7 @@ Model::Model(std::string fileName) glBindBuffer(GL_ARRAY_BUFFER, buffer); std::vector structSizes; - if (m_RawModel->isSkined()) { + if (m_RawModel->IsSkinned()) { structSizes = { 3, 3, 3, 3, 2, 4, 4 }; } else { structSizes = { 3, 3, 3, 3, 2 }; @@ -106,7 +106,7 @@ Model::Model(std::string fileName) 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++; - if (m_RawModel->isSkined()) { + if (m_RawModel->IsSkinned()) { 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++; } @@ -118,7 +118,7 @@ Model::Model(std::string fileName) glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); - if (m_RawModel->isSkined()) { + if (m_RawModel->IsSkinned()) { glEnableVertexAttribArray(5); glEnableVertexAttribArray(6); } diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index bef0e117..fa1b3ca3 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -69,34 +69,32 @@ void PickingPass::Draw(RenderScene& scene) auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { - if (modelJob->Model->isSkined()) + int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; + + PickingInfo pickInfo; + pickInfo.Entity = modelJob->Entity; + pickInfo.World = modelJob->World; + pickInfo.Camera = scene.Camera; + + auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); + if (color != m_EntityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; + } else { + m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); + if (m_ColorCounter[0] > 255) { + m_ColorCounter[0] = 0; + m_ColorCounter[1] += 1; + } else { + m_ColorCounter[0] += 1; + } + } + + m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + + if (modelJob->Model->IsSkinned()) { m_PickingSkinnedProgram->Bind(); - int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; - - PickingInfo pickInfo; - pickInfo.Entity = modelJob->Entity; - pickInfo.World = modelJob->World; - pickInfo.Camera = scene.Camera; - - auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); - if (color != m_EntityColors.end()) { - pickColor[0] = color->second[0]; - pickColor[1] = color->second[1]; - } - else { - m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); - if (m_ColorCounter[0] > 255) { - m_ColorCounter[0] = 0; - m_ColorCounter[1] += 1; - } - else { - m_ColorCounter[0] += 1; - } - } - - m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); @@ -114,32 +112,7 @@ void PickingPass::Draw(RenderScene& scene) } } else { - m_PickingProgram->Bind(); - int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; - - PickingInfo pickInfo; - pickInfo.Entity = modelJob->Entity; - pickInfo.World = modelJob->World; - pickInfo.Camera = scene.Camera; - - auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); - if (color != m_EntityColors.end()) { - pickColor[0] = color->second[0]; - pickColor[1] = color->second[1]; - } - else { - m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); - if (m_ColorCounter[0] > 255) { - m_ColorCounter[0] = 0; - m_ColorCounter[1] += 1; - } - else { - m_ColorCounter[0] += 1; - } - } - - m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - + m_PickingProgram->Bind(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); @@ -155,31 +128,32 @@ void PickingPass::Draw(RenderScene& scene) for (auto &job : scene.Jobs.TransparentObjects) { auto modelJob = std::dynamic_pointer_cast(job); + int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; + + PickingInfo pickInfo; + pickInfo.Entity = modelJob->Entity; + pickInfo.World = modelJob->World; + pickInfo.Camera = scene.Camera; + + auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); + if (color != m_EntityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; + } else { + m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); + if (m_ColorCounter[0] > 255) { + m_ColorCounter[0] = 0; + m_ColorCounter[1] += 1; + } else { + m_ColorCounter[0] += 1; + } + } + + m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; + if (modelJob) { - if (modelJob->Model->isSkined()) { - int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; - - PickingInfo pickInfo; - pickInfo.Entity = modelJob->Entity; - pickInfo.World = modelJob->World; - pickInfo.Camera = scene.Camera; - - auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); - if (color != m_EntityColors.end()) { - pickColor[0] = color->second[0]; - pickColor[1] = color->second[1]; - } else { - m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); - if (m_ColorCounter[0] > 255) { - m_ColorCounter[0] = 0; - m_ColorCounter[1] += 1; - } else { - m_ColorCounter[0] += 1; - } - } - - m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - + if (modelJob->Model->IsSkinned()) { + m_PickingSkinnedProgram->Bind(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); @@ -193,36 +167,12 @@ void PickingPass::Draw(RenderScene& scene) } glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { - int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] }; - - PickingInfo pickInfo; - pickInfo.Entity = modelJob->Entity; - pickInfo.World = modelJob->World; - pickInfo.Camera = scene.Camera; - - auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)); - if (color != m_EntityColors.end()) { - pickColor[0] = color->second[0]; - pickColor[1] = color->second[1]; - } else { - m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); - if (m_ColorCounter[0] > 255) { - m_ColorCounter[0] = 0; - m_ColorCounter[1] += 1; - } else { - m_ColorCounter[0] += 1; - } - } - - m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - + m_PickingProgram->Bind(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); } - - glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); @@ -257,7 +207,7 @@ void PickingPass::Draw(RenderScene& scene) m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - if(modelJob->Model->isSkined()) { + if(modelJob->Model->IsSkinned()) { m_PickingSkinnedProgram->Bind(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); @@ -314,7 +264,7 @@ void PickingPass::Draw(RenderScene& scene) m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - if (modelJob->Model->isSkined()) { + if (modelJob->Model->IsSkinned()) { m_PickingSkinnedProgram->Bind(); From 61275274f7fd1b196b88f8ee3cd72dffd853baf0 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 14:39:45 +0100 Subject: [PATCH 131/131] Commited this --- src/Engine/Rendering/RenderSystem.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index ab2b6dc2..ab9a3c27 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -62,14 +62,14 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) } // Only render children of a camera if that camera is currently active -// if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { -// continue; -// } DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS + if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { + continue; + } // Hide things parented to local player if they have the HiddenFromLocalPlayer component -// if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { -// continue; -// } DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS DO NOT COMMIT THIS + if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { + continue; + } Model* model; try {