diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 5431df4d..1fd24cc6 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -48,13 +48,13 @@ bool RayVsTriangle(const Ray& ray, 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 RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix); //Return true if the ray hits any of the triangles in the model. //Also returns the position of the intersection point. Will loop through all the whole model indices. bool RayVsModel(const Ray& ray, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outHitPosition); @@ -62,7 +62,7 @@ bool RayVsModel(const Ray& ray, //Also returns the distance from the ray origin to the closest //intersection point, and the barycentric u,v-coordinates. Will loop through all the whole model indices. bool RayVsModel(const Ray& ray, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, float& outDistance, @@ -70,7 +70,7 @@ bool RayVsModel(const Ray& ray, float& outVCoord); bool AABBvsTriangles(const AABB& box, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& boxVelocity, @@ -80,7 +80,7 @@ bool AABBvsTriangles(const AABB& box, //Detects collision, but does not resolve. bool AABBvsTriangles(const AABB& box, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix); @@ -92,7 +92,7 @@ enum Output }; //Detects intersection and containment. Output AABBvsTrianglesWContainment(const AABB& box, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix); diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index 4c63b922..acdf64db 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -16,15 +16,18 @@ private: public: ~Model(); - 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(); } + const std::vector& MaterialGroups() const { return m_Materials; } + unsigned int NumberOfVertices() const { return m_Vertices.size(); } + const AABB& Box() const { return m_Box; } - bool IsSkinned() const { return m_RawModel->IsSkinned(); } + bool IsSkinned() const { return m_IsSkinned; } GLuint VAO; GLuint ElementBuffer; - RawModel* m_RawModel; + //RawModel* m_RawModel; + + Skeleton* m_Skeleton = nullptr; + std::vector m_Vertices; + std::vector m_Indices; private: AABB m_Box; @@ -34,6 +37,9 @@ private: GLuint TangentNormalsBuffer; GLuint BiTangentNormalsBuffer; GLuint TextureCoordBuffer; + + std::vector m_Materials; + bool m_IsSkinned; }; #endif diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 4821a222..86b89ad6 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -110,7 +110,7 @@ struct ModelJob : RenderJob } if (model->IsSkinned()) { - Skeleton = Model->m_RawModel->m_Skeleton; + Skeleton = Model->m_Skeleton; if (Skeleton != nullptr) { EntityWrapper entityWrapper = EntityWrapper(world, modelComponent.EntityID); diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index f9fd18ef..12e54d3f 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -13,6 +13,7 @@ #include +#include #include "../Common.h" #include "../GLM.h" #include "../Core/ResourceManager.h" @@ -20,22 +21,17 @@ #include "Skeleton.h" #include "ShaderProgram.h" -#include "boost\endian\buffers.hpp" - - - class RawModelCustom : public Resource { friend class ResourceManager; - + friend class Model; protected: RawModelCustom(std::string fileName); public: ~RawModelCustom(); - - struct Vertex - { + + struct RenderVertex { glm::vec3 Position; glm::vec3 Normal; glm::vec3 Tangent; @@ -43,7 +39,7 @@ public: glm::vec2 TextureCoords; }; - struct SkinedVertex : public Vertex { + struct SkinedVertex : public RenderVertex { glm::vec4 BoneIndices; glm::vec4 BoneWeights; }; @@ -91,7 +87,7 @@ public: unsigned int ShaderID = 0; }; - const Vertex* Vertices() const { + const RenderVertex* Vertices() const { if (hasSkin) { return m_SkinedVertices.data(); } else { @@ -99,16 +95,16 @@ public: } }; - unsigned int VertexSize() const { + unsigned int VertexSize() const { if (hasSkin) { return sizeof(SkinedVertex); } else { - return sizeof(Vertex); + return sizeof(RenderVertex); } }; - unsigned int NumVertices() const { + size_t NumVertices() const { if (hasSkin) { return m_SkinedVertices.size(); } else { @@ -116,17 +112,39 @@ public: } }; + const std::vector& Indices() const { + return m_Indices; + } + bool IsSkinned() const { return hasSkin; }; + const std::vector& CollisionVertices(); + + size_t NumCollisionVertices() const { + return m_CollisionVertices.size(); + }; + + const std::vector& CollisionIndices() const { + if (hasCollisionMesh) { + return m_CollisionIndices; + } else { + return m_Indices; + } + }; + std::vector m_Materials; - std::vector m_Indices; + Skeleton* m_Skeleton = nullptr; glm::mat4 m_Matrix; private: bool hasSkin; - std::vector m_Vertices; + bool hasCollisionMesh = false; + std::vector m_Indices; + std::vector m_CollisionIndices; + std::vector m_CollisionVertices; + std::vector m_Vertices; std::vector m_SkinedVertices; void ReadMeshFile(std::string filePath); @@ -149,7 +167,12 @@ private: void ReadAnimationClips(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int numberOfClips); void ReadAnimationClipSingle(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int clipIndex); void ReadAnimationKeyFrame(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, std::vector& animation); - + + + void ReadCollisionFile(std::string filePath); + void ReadCollisionFileData(std::size_t& offset, char* fileData, const unsigned int& fileByteSize); + + const std::vector& ConstructCollisionList(); //void CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID); }; diff --git a/include/Game/Systems/SpawnerSystem.h b/include/Game/Systems/SpawnerSystem.h index 71ae2772..96b33cb6 100644 --- a/include/Game/Systems/SpawnerSystem.h +++ b/include/Game/Systems/SpawnerSystem.h @@ -8,6 +8,7 @@ #include "Events/ESpawnerSpawn.h" #include "Core/TransformSystem.h" #include "Core/EntityFile.h" +#include "Rendering/Model.h" class SpawnerSystem : public System { diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index dc04e8cf..ae09aeaf 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -146,14 +146,14 @@ bool RayVsTriangle(const Ray& ray, } bool RayVsModel(const Ray& ray, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix) { for (int i = 0; i < modelIndices.size();) { - glm::vec3 v0 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); - glm::vec3 v1 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); - glm::vec3 v2 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + glm::vec3 v0 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix); + glm::vec3 v1 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix); + glm::vec3 v2 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix); if (RayVsTriangle(ray, v0, v1, v2)) { return true; } @@ -194,7 +194,7 @@ bool RayVsTriangle(const Ray& ray, } bool RayVsModel(const Ray& ray, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, float& outDistance, @@ -204,9 +204,9 @@ bool RayVsModel(const Ray& ray, outDistance = INFINITY; bool hit = false; for (int i = 0; i < modelIndices.size();) { - glm::vec3 v0 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); - glm::vec3 v1 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); - glm::vec3 v2 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + glm::vec3 v0 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix); + glm::vec3 v1 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix); + glm::vec3 v2 = TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix); float dist = outDistance; float u; float v; @@ -221,7 +221,7 @@ bool RayVsModel(const Ray& ray, } bool RayVsModel(const Ray& ray, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outHitPosition) @@ -548,7 +548,7 @@ BoxTriRes AABBvsTriangle(const AABB& box, } Output AABBvsTriangles(const AABB& box, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& boxVelocity, @@ -565,9 +565,9 @@ Output AABBvsTriangles(const AABB& box, glm::vec3 originalBoxVelocity(boxVelocity); for (int i = 0; i < modelIndices.size(); ) { std::array triVertices = { - TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), - TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix), - TransformSystem::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix) + TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix), + TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix), + TransformSystem::TransformPoint(modelVertices[modelIndices[i++]], modelMatrix) }; glm::vec3 outVec; bool collideWithGround = isOnGround; @@ -595,7 +595,7 @@ Output AABBvsTriangles(const AABB& box, } bool AABBvsTriangles(const AABB& box, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& boxVelocity, @@ -615,7 +615,7 @@ bool AABBvsTriangles(const AABB& box, } bool AABBvsTriangles(const AABB& box, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix) { @@ -633,7 +633,7 @@ bool AABBvsTriangles(const AABB& box, } Output AABBvsTrianglesWContainment(const AABB& box, - const RawModel::Vertex* modelVertices, + const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix) { @@ -741,7 +741,7 @@ boost::optional EntityFirstHitByRay(const Ray& ray, std::vectorVertices(), model->m_RawModel->m_Indices, TransformSystem::ModelMatrix(entityBox.Entity), outDistance, u, v)) { + if (RayVsModel(ray, model->m_Vertices, model->m_Indices, TransformSystem::ModelMatrix(entityBox.Entity), outDistance, u, v)) { outIntersectPos = ray.Origin() + outDistance * ray.Direction(); return entityBox; } diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 433af482..e53143ac 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -41,15 +41,15 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c // Don't collide against invisible models. continue; } - RawModel* model; + Model* model; std::string res = (std::string)boxB.Entity["Model"]["Resource"]; try { - model = ResourceManager::Load(res); + model = ResourceManager::Load(res); } catch (const std::exception&) { continue; } float u, v; - hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, TransformSystem::ModelMatrix(boxB.Entity), dist, u, v); + hit = Collision::RayVsModel(ray, model->m_Vertices, model->m_Indices, TransformSystem::ModelMatrix(boxB.Entity), dist, u, v); } else { hit = Collision::RayVsAABB(ray, boxB, dist); } @@ -86,9 +86,9 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c // Don't collide against invisible models. continue; } - RawModel* model; + Model* model; try { - model = ResourceManager::Load(boxB.Entity["Model"]["Resource"]); + model = ResourceManager::Load(boxB.Entity["Model"]["Resource"]); } catch (const std::exception&) { continue; } @@ -98,7 +98,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->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { + if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { //Move the position to previous position if it is not moving in the xz-plane, else resolve with the resolution vector. (Field)cTransform["Position"] += resolutionVector; boxA = *Collision::EntityAbsoluteAABB(entity); diff --git a/src/Engine/Collision/TriggerSystem.cpp b/src/Engine/Collision/TriggerSystem.cpp index c9bc18dc..ef790bc9 100644 --- a/src/Engine/Collision/TriggerSystem.cpp +++ b/src/Engine/Collision/TriggerSystem.cpp @@ -10,11 +10,11 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapp return; } - RawModel* triggerModel = nullptr; + Model* triggerModel = nullptr; glm::mat4 triggerModelMat; if (triggerEntity.HasComponent("Model")) { try { - triggerModel = ResourceManager::Load(triggerEntity["Model"]["Resource"]); + triggerModel = ResourceManager::Load(triggerEntity["Model"]["Resource"]); triggerModelMat = TransformSystem::ModelMatrix(triggerEntity); } catch (const std::exception&) { } @@ -38,7 +38,7 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapp ? Collision::Output::OutContained : Collision::AABBvsTrianglesWContainment( colliderBox, - triggerModel->Vertices(), + triggerModel->m_Vertices, triggerModel->m_Indices, triggerModelMat); diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 895cbc28..3e53612b 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -37,7 +37,7 @@ void AnimationSystem::CreateBlendTrees() continue;; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if (skeleton == nullptr) { continue; } @@ -79,7 +79,7 @@ void AnimationSystem::UpdateAnimations(double dt) continue; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if (skeleton == nullptr) { continue; } @@ -177,7 +177,7 @@ bool AnimationSystem::OnAutoAnimationBlend(Events::AutoAnimationBlend& e) return false; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if (skeleton == nullptr) { LOG_ERROR("%s, RootNode skeleton invalid %s", e.NodeName, e.RootNode.Name().c_str()); return false; @@ -300,7 +300,7 @@ bool AnimationSystem::OnEntityDeleted(Events::EntityDeleted& e) return false; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if (skeleton == nullptr) { return false; } @@ -331,7 +331,7 @@ bool AnimationSystem::OnSetBlendWeight(Events::SetBlendWeight& e) return false; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if (skeleton == nullptr) { return false; } diff --git a/src/Engine/Rendering/AutoBlendQueue.cpp b/src/Engine/Rendering/AutoBlendQueue.cpp index f4a854ec..016ae420 100644 --- a/src/Engine/Rendering/AutoBlendQueue.cpp +++ b/src/Engine/Rendering/AutoBlendQueue.cpp @@ -22,7 +22,7 @@ void AutoBlendQueue::Insert(AutoBlendJob autoBlendJob) return; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if (skeleton == nullptr) { return; } @@ -130,7 +130,7 @@ bool AutoBlendQueue::HasActiveBlendJob() return HasActiveBlendJob(); } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if (skeleton == nullptr) { m_BlendQueue.pop_front(); return HasActiveBlendJob(); @@ -173,7 +173,7 @@ std::shared_ptr AutoBlendQueue::GetBlendTree() return nullptr; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if (skeleton == nullptr) { return nullptr; } diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index 440bb65c..82fd9507 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -26,7 +26,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp return; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; + Skeleton* skeleton = model->m_Skeleton; if(skeleton == nullptr) { return; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 19046bf0..8f221e13 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -332,14 +332,6 @@ void DrawFinalPass::Draw(RenderScene& scene, BlurHUD* blurHUDPass) glClearStencil(0x00); glClear(GL_STENCIL_BUFFER_BIT); - //Fill depth buffer - state->Enable(GL_STENCIL_TEST); - state->StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - state->StencilFunc(GL_ALWAYS, 1, 0xFF); - state->StencilMask(0xFF); - state->DepthMask(GL_FALSE); - //DrawToDepthStencilBuffer(scene.Jobs.ShieldObjects, scene); - state->DepthMask(GL_TRUE); //Draw Opaque shielded objects state->Disable(GL_STENCIL_TEST); @@ -354,10 +346,10 @@ void DrawFinalPass::Draw(RenderScene& scene, BlurHUD* blurHUDPass) GLERROR("OpaqueObjects"); //state->Disable(GL_STENCIL_TEST); - //Draw Transparen Shielded objects + //Draw Transparen objects state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); DrawModelRenderQueuesWithShieldCheck(scene.Jobs.TransparentObjects, scene); //might need changing - GLERROR("Shielded Transparent objects"); + GLERROR("Transparent objects"); //Generate blur texture. delete state; @@ -379,12 +371,6 @@ void DrawFinalPass::Draw(RenderScene& scene, BlurHUD* blurHUDPass) } else { stateSprite = new DrawFinalPassState(m_FinalPassFrameBuffer->GetHandle()); } - //Draw Transparen objects - //state->BlendFunc(GL_ONE, GL_ONE); - //state->StencilFunc(GL_EQUAL, 1, 0xFF); - //DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); - GLERROR("TransparentObjects"); - //state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); stateSprite->Enable(GL_DEPTH_TEST); //stateSprite->AlphaFunc(GL_GEQUAL, 0.05f); //stateSprite->Enable(GL_ALPHA_TEST); @@ -638,7 +624,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& std::vector frameBones; if (modelJob->BlendTree != nullptr) { frameBones = modelJob->BlendTree->GetFinalPose(); - } else { + } else if (modelJob->Skeleton != nullptr) { frameBones = modelJob->Skeleton->GetTPose(); } glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index d34ce809..596e254b 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -3,9 +3,9 @@ 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); + auto rawModel = ResourceManager::Load(fileName); - for (auto& materialProperty : m_RawModel->m_Materials) { + for (auto& materialProperty : rawModel->m_Materials) { switch (materialProperty.type) { case RawModel::MaterialType::SingleTextures: { @@ -46,11 +46,11 @@ Model::Model(std::string fileName) glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, m_RawModel->NumVertices() * m_RawModel->VertexSize(), m_RawModel->Vertices(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, rawModel->NumVertices() * rawModel->VertexSize(), rawModel->Vertices(), GL_STATIC_DRAW); glGenBuffers(1, &ElementBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_RawModel->m_Indices.size() * sizeof(unsigned int), &m_RawModel->m_Indices[0], GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, rawModel->Indices().size() * sizeof(unsigned int), rawModel->Indices().data(), GL_STATIC_DRAW); glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); @@ -58,7 +58,7 @@ Model::Model(std::string fileName) glBindBuffer(GL_ARRAY_BUFFER, buffer); std::vector structSizes; - if (m_RawModel->IsSkinned()) { + if (rawModel->IsSkinned()) { structSizes = { 3, 3, 3, 3, 2, 4, 4 }; } else { structSizes = { 3, 3, 3, 3, 2 }; @@ -77,7 +77,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->IsSkinned()) { + if (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++; } @@ -89,7 +89,7 @@ Model::Model(std::string fileName) glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); - if (m_RawModel->IsSkinned()) { + if (rawModel->IsSkinned()) { glEnableVertexAttribArray(5); glEnableVertexAttribArray(6); } @@ -99,17 +99,29 @@ Model::Model(std::string fileName) glm::vec3 mini(INFINITY); glm::vec3 maxi(-INFINITY); - - for (unsigned int i = 0; i < m_RawModel->NumVertices(); i++) { - const auto& v = m_RawModel->Vertices()[i]; + for (unsigned int i = 0; i < rawModel->NumVertices(); i++) { + const auto& v = rawModel->Vertices()[i]; mini = glm::min(mini, v.Position); maxi = glm::max(maxi, v.Position); } - m_Box = AABB(mini, maxi); + + m_Skeleton = rawModel->m_Skeleton; + m_Materials = rawModel->m_Materials; + m_Indices = rawModel->CollisionIndices(); + m_IsSkinned = rawModel->IsSkinned(); + // Copy vertex positions for collisions later + m_Vertices = rawModel->CollisionVertices(); + + ResourceManager::Release("RawModel", fileName); } Model::~Model() { - + if (m_Skeleton != nullptr) { + delete m_Skeleton; + } + for (auto material : m_Materials) { + delete material.material; + } } diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index f6343101..f75372d7 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -115,7 +115,7 @@ void PickingPass::Draw(RenderScene& scene) std::vector frameBones; if (modelJob->BlendTree != nullptr) { frameBones = modelJob->BlendTree->GetFinalPose(); - } else { + } else if (modelJob->Skeleton != nullptr) { frameBones = modelJob->Skeleton->GetTPose(); } glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "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 94a824f0..2106a699 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); + ReadCollisionFile(fileName); } void RawModelCustom::ReadMeshFile(std::string filePath) @@ -71,11 +72,11 @@ void RawModelCustom::ReadVertices(std::size_t& offset, char* fileData, const uns 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) { + if (offset + m_Vertices.size() * sizeof(RenderVertex) > fileByteSize) { throw Resource::FailedLoadingException("Reading vertices failed"); } - memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(Vertex)); - offset += m_Vertices.size() * sizeof(Vertex); + memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(RenderVertex)); + offset += m_Vertices.size() * sizeof(RenderVertex); } #else #endif @@ -491,14 +492,90 @@ void RawModelCustom::ReadAnimationKeyFrame(std::size_t& offset, char* fileData, } +void RawModelCustom::ReadCollisionFile(std::string filePath) { + char* fileData; + filePath += ".colli"; + std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate); + + if (!in.is_open()) { + return; + } + unsigned int fileByteSize = static_cast(in.tellg()); + in.seekg(0, std::ios_base::beg); + + fileData = new char[fileByteSize]; + in.read(fileData, fileByteSize); + in.close(); + + std::size_t offset = 0; + if (fileByteSize > 0) { + ReadCollisionFileData(offset, fileData, fileByteSize); + } + hasCollisionMesh = true; + delete[] fileData; +} + +const std::vector& RawModelCustom::CollisionVertices() { + if (hasCollisionMesh) { + return m_CollisionVertices; + } + else if (hasSkin) { + // We don't do collisions against skinned meshes now. + m_CollisionVertices = std::vector(); + return m_CollisionVertices; + } + else { + return ConstructCollisionList(); + } +}; + +void RawModelCustom::ReadCollisionFileData(std::size_t& offset, char* fileData, const unsigned int& fileByteSize){ + m_CollisionVertices.resize(static_cast(*(unsigned int*)(fileData + offset))); + offset += sizeof(unsigned int); + m_CollisionIndices.resize(static_cast(*(unsigned int*)(fileData + offset))); + offset += sizeof(unsigned int); + + if (offset + m_CollisionVertices.size() * sizeof(glm::vec3) > fileByteSize) { + throw Resource::FailedLoadingException("Reading collision vertices failed"); + } + memcpy(&m_CollisionVertices[0], fileData + offset, m_CollisionVertices.size() * sizeof(glm::vec3)); + offset += m_CollisionVertices.size() * sizeof(glm::vec3); + + if (offset + m_CollisionIndices.size() * sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading collision indices failed"); + } + memcpy(&m_CollisionIndices[0], fileData + offset, m_CollisionIndices.size() * sizeof(unsigned int)); + offset += m_CollisionIndices.size() * sizeof(unsigned int); +} + +const std::vector& RawModelCustom::ConstructCollisionList() +{ + if (!hasCollisionMesh && m_CollisionVertices.size() == 0) { + if (hasSkin) { + m_CollisionVertices.reserve(m_SkinedVertices.size()); + for (const auto& vertex : m_SkinedVertices) { + m_CollisionVertices.push_back(vertex.Position); + } + } else { + m_CollisionVertices.reserve(m_Vertices.size()); + for (const auto& vertex : m_Vertices) { + m_CollisionVertices.push_back(vertex.Position); + } + } + } + + return m_CollisionVertices; +} + RawModelCustom::~RawModelCustom() { - if (m_Skeleton != nullptr) { - delete m_Skeleton; - } - for (auto material : m_Materials) { - delete material.material; - } + // Ownership of skeleton and materials get transferred to Model + // 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/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 9aff0266..05430708 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -261,7 +261,7 @@ void ShadowPass::Draw(RenderScene & scene) std::vector frameBones; if (modelJob->BlendTree != nullptr) { frameBones = modelJob->BlendTree->GetFinalPose(); - } else { + } else if (modelJob->Skeleton != nullptr) { frameBones = modelJob->Skeleton->GetTPose(); } glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); diff --git a/src/Game/Systems/SpawnerSystem.cpp b/src/Game/Systems/SpawnerSystem.cpp index fb770bb5..f444827b 100644 --- a/src/Game/Systems/SpawnerSystem.cpp +++ b/src/Game/Systems/SpawnerSystem.cpp @@ -112,15 +112,15 @@ bool SpawnerSystem::spawnedEntityIsColliding(EntityWrapper spawnedEntity, Entity if (!spawnedBox.Entity.HasComponent("Model")) { return true; } - RawModel* model = nullptr; + Model* model = nullptr; try { - model = ResourceManager::Load(otherEntity["Model"]["Resource"]); + model = ResourceManager::Load(otherEntity["Model"]["Resource"]); } catch (const std::exception&) { } if (model != nullptr && Collision::AABBvsTriangles( spawnedBox, - model->Vertices(), + model->m_Vertices, model->m_Indices, TransformSystem::ModelMatrix(otherEntity))) { return true; diff --git a/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp index 3497fd04..28112cd6 100644 --- a/tools/MayaExporter/MayaExporter/Export.cpp +++ b/tools/MayaExporter/MayaExporter/Export.cpp @@ -5,7 +5,7 @@ Export::Export() } -bool Export::Meshes(std::string pathName, bool selectedOnly) +bool Export::Meshes(std::string pathName, bool selectedOnly, bool isCollision) { MStatus status; if (pathName.empty()) { @@ -92,8 +92,14 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) Objects.append(node); } } - GetMeshData(Objects); - WriteMeshData(pathName); + GetMeshData(Objects, isCollision); + + if (!isCollision) { + WriteMeshData(pathName); + } else { + WriteCollisionData(pathName); + } + MGlobal::displayInfo(MString() + "Enabling IKSolvers"); status = MGlobal::executeCommand("doEnableNodeItems true all;"); if (status != MS::kSuccess) { @@ -144,9 +150,9 @@ bool Export::Animations(std::string pathName, std::vector animInf return true; } -bool Export::GetMeshData(MObjectArray object) +bool Export::GetMeshData(MObjectArray object, bool collision) { - meshes = m_MeshHandler.GetMeshData(object); + meshes = m_MeshHandler.GetMeshData(object, collision); return true; } @@ -185,6 +191,17 @@ void Export::WriteMeshData(std::string pathName) m_MeshFile.CloseFiles(); } +void Export::WriteCollisionData(std::string pathName) { + m_ColliFile.ASCIIFilePath(pathName + "_colli.txt"); + m_ColliFile.binaryFilePath(pathName + ".colli"); + + m_ColliFile.OpenFiles(); + + m_ColliFile.writeToFiles((OutputData*)&meshes); + + m_ColliFile.CloseFiles(); +} + void Export::WriteAnimData(std::string pathName) { if (allBindPoses.size() > 0) { diff --git a/tools/MayaExporter/MayaExporter/Export.h b/tools/MayaExporter/MayaExporter/Export.h index 42b40445..c22cd26e 100644 --- a/tools/MayaExporter/MayaExporter/Export.h +++ b/tools/MayaExporter/MayaExporter/Export.h @@ -22,18 +22,19 @@ public: int End; }; - bool Meshes(std::string pathName, bool selectedOnly = false); + bool Meshes(std::string pathName, bool selectedOnly = false, bool isCollision = false); bool Materials(std::string pathName); bool Animations(std::string pathName, std::vector animInfo); private: - bool GetMeshData(MObjectArray object); + bool GetMeshData(MObjectArray object, bool collision); bool GetMaterialData(); bool GetAnimationData(AnimationInfo info); void WriteMeshData(std::string pathName); void WriteAnimData(std::string pathName); void WriteMaterialData(std::string pathName); + void WriteCollisionData(std::string pathName); Material m_MaterialHandler; Skeleton m_SkeletonHandler; @@ -44,6 +45,7 @@ private: WriteToFile m_MeshFile; WriteToFile m_AnimFile; WriteToFile m_MtrlFile; + WriteToFile m_ColliFile; //Mesh Data Mesh meshes; diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 02810018..ed3761df 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -25,6 +25,7 @@ Menu::Menu(QDialog* dialog) m_ExportSelectedButton = new QCheckBox(tr("&Export Selected")); m_ExportAnimationsButton = new QCheckBox(tr("&Export Animations")); m_ExportMaterialButton = new QCheckBox(tr("&Export Material"));; + m_IsCollision = new QCheckBox(tr("&Export as collision mesh")); m_ExportAnimationsButton->setChecked(true); m_ExportMaterialButton->setChecked(true); @@ -32,6 +33,7 @@ Menu::Menu(QDialog* dialog) vbox->addWidget(m_ExportSelectedButton); vbox->addWidget(m_ExportAnimationsButton); vbox->addWidget(m_ExportMaterialButton); + vbox->addWidget(m_IsCollision); vbox->addStretch(1); optionsBox->setLayout(vbox); @@ -46,6 +48,7 @@ Menu::Menu(QDialog* dialog) connect(m_ExportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); connect(m_ExportMaterialButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); + connect(m_IsCollision, SIGNAL(clicked(bool)), this, SLOT(NULL)); // Creating several layouts, adding widgets & adding them to one layout in the end QHBoxLayout* topLayout = new QHBoxLayout; @@ -163,40 +166,42 @@ void Menu::RemoveClipClicked(bool) void Menu::ExportAll(bool) { - if (m_ExportPath->text().isEmpty()) { - MGlobal::displayError(MString() + "Please select a folder."); - return; - } + if (m_ExportPath->text().isEmpty()) { + MGlobal::displayError(MString() + "Please select a folder."); + return; + } - //Export meshes - if (!m_Export.Meshes(m_ExportPath->text().toLocal8Bit().constData(), m_ExportSelectedButton->isChecked())) { - MGlobal::displayError(MString() + "Could not export mesh"); - return; - } + //Export meshes + if (!m_Export.Meshes(m_ExportPath->text().toLocal8Bit().constData(), m_ExportSelectedButton->isChecked(), m_IsCollision->isChecked())) { + MGlobal::displayError(MString() + "Could not export mesh"); + return; + } - if (m_ExportMaterialButton->isChecked()) { - if (!m_Export.Materials(m_ExportPath->text().toLocal8Bit().constData())) { - MGlobal::displayError(MString() + "Could not export materials"); - return; - } - } + if (!m_IsCollision->isChecked()){ + if (m_ExportMaterialButton->isChecked()) { + if (!m_Export.Materials(m_ExportPath->text().toLocal8Bit().constData())) { + MGlobal::displayError(MString() + "Could not export materials"); + return; + } + } - std::vector animations; - for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) { - Export::AnimationInfo thisClip; - thisClip.Name = std::string(m_AnimationClipName[i]->text().toLocal8Bit().constData()); - thisClip.Start = m_StartFrameLines[i]->text().toInt(); - thisClip.End = m_EndFrameLines[i]->text().toInt(); + std::vector animations; + for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) { + Export::AnimationInfo thisClip; + thisClip.Name = std::string(m_AnimationClipName[i]->text().toLocal8Bit().constData()); + thisClip.Start = m_StartFrameLines[i]->text().toInt(); + thisClip.End = m_EndFrameLines[i]->text().toInt(); - animations.push_back(thisClip); - } - if (m_ExportAnimationsButton->isChecked()) { - //Export Animations - if (!m_Export.Animations(m_ExportPath->text().toLocal8Bit().constData(), animations)) { - MGlobal::displayError(MString() + "Could not export animations"); - return; - } - } + animations.push_back(thisClip); + } + if (m_ExportAnimationsButton->isChecked()) { + //Export Animations + if (!m_Export.Animations(m_ExportPath->text().toLocal8Bit().constData(), animations)) { + MGlobal::displayError(MString() + "Could not export animations"); + return; + } + } + } } void Menu::CancelClicked(bool) diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index fb95a953..89211a12 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -66,6 +66,7 @@ private: QCheckBox* m_ExportSelectedButton = nullptr; QCheckBox* m_ExportAnimationsButton = nullptr; QCheckBox* m_ExportMaterialButton = nullptr; + QCheckBox* m_IsCollision = nullptr; QLineEdit* m_ExportPath = nullptr; QFileDialog* m_FileDialog = nullptr; diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index ee5a6022..6868e792 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -94,33 +94,37 @@ MeshClass::MeshClass() // return weightMap; //} -Mesh MeshClass::GetMeshData(MObjectArray object) +Mesh MeshClass::GetMeshData(MObjectArray object, bool collision) { MS status; Mesh newMesh; + newMesh.isCollison = collision; vector& vertexList = newMesh.Vertices; map>& indexLists = newMesh.Indices; for (int ObjectID = 0; ObjectID < object.length(); ObjectID++) { if (!object[ObjectID].hasFn(MFn::kMesh)) continue; + MObject node = object[ObjectID]; MFnDependencyNode thisNode(node); MPlugArray connections; thisNode.findPlug("inMesh").connectedTo(connections, true, true); MPlug weightList, weights; MObject weightListObject; - for (unsigned int i = 0; i < connections.length(); i++) { - if (connections[i].node().apiType() == MFn::kSkinClusterFilter) { - MFnSkinCluster skinCluster(connections[i].node()); - weightList = skinCluster.findPlug("weightList", &status); - weightListObject = weightList.attribute(); - weights = skinCluster.findPlug("weights"); - newMesh.hasSkin = true; - break; - } - } + if (!collision) { + for (unsigned int i = 0; i < connections.length(); i++) { + if (connections[i].node().apiType() == MFn::kSkinClusterFilter) { + MFnSkinCluster skinCluster(connections[i].node()); + weightList = skinCluster.findPlug("weightList", &status); + weightListObject = weightList.attribute(); + weights = skinCluster.findPlug("weights"); + newMesh.hasSkin = true; + break; + } + } + } // In here, we retrieve triangulated polygons from the mesh MFnMesh mesh(object[ObjectID]); @@ -257,62 +261,62 @@ Mesh MeshClass::GetMeshData(MObjectArray object) thisVertex.Pos[0] = pos.x; thisVertex.Pos[1] = pos.y; thisVertex.Pos[2] = pos.z; + thisVertex.isCollision = collision; - 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 (!collision) { + 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; + } - thisVertex.Normal[0] = normal[0]; - thisVertex.Normal[1] = normal[1]; - 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); - thisVertex.Tangent[0] = Tangent[0]; - thisVertex.Tangent[1] = Tangent[1]; - thisVertex.Tangent[2] = Tangent[2]; + MFloatVector Tangent = Tangents[faceVert.tangentId()]; + //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); + //tmp.get(biTangent); + thisVertex.Tangent[0] = Tangent[0]; + thisVertex.Tangent[1] = Tangent[1]; + thisVertex.Tangent[2] = Tangent[2]; - MFloatVector biNormal = biNormals[faceVert.tangentId()]; - //faceVert.getBinormal().get(biNormal); - thisVertex.BiNormal[0] = biNormal[0]; - thisVertex.BiNormal[1] = biNormal[1]; - thisVertex.BiNormal[2] = biNormal[2]; + MFloatVector biNormal = biNormals[faceVert.tangentId()]; + //faceVert.getBinormal().get(biNormal); + thisVertex.BiNormal[0] = biNormal[0]; + thisVertex.BiNormal[1] = biNormal[1]; + thisVertex.BiNormal[2] = biNormal[2]; - status = faceVert.getUV(UV); - if (status != MS::kSuccess) { - MGlobal::displayError(MString() + " faceVert.getUV() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); - break; - } - thisVertex.Uv[0] = UV[0]; - thisVertex.Uv[1] = UV[1]; + status = faceVert.getUV(UV); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + " faceVert.getUV() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); + break; + } + thisVertex.Uv[0] = UV[0]; + thisVertex.Uv[1] = UV[1]; - if (newMesh.hasSkin) { - thisVertex.useWeights = true; - float totalWeight = 0.0f; - unsigned int totalBones = 0; - MIntArray jointIDs /* ??? */; - weights.selectAncestorLogicalIndex(vertexIndex, weightListObject); - weights.getExistingArrayAttributeIndices(jointIDs); - for (unsigned int i = 0; i < jointIDs.length() && i < 4; i++) { - if (weights[i].asFloat() > 0.001f) { - thisVertex.BoneIndices[totalBones] = jointIDs[i]; - thisVertex.BoneWeights[totalBones] = weights[i].asFloat(); - totalWeight = totalWeight + weights[i].asFloat(); - totalBones++; - } - } + if (newMesh.hasSkin) { + thisVertex.useWeights = true; + float totalWeight = 0.0f; + unsigned int totalBones = 0; + MIntArray jointIDs /* ??? */; + weights.selectAncestorLogicalIndex(vertexIndex, weightListObject); + weights.getExistingArrayAttributeIndices(jointIDs); + for (unsigned int i = 0; i < jointIDs.length() && i < 4; i++) { + if (weights[i].asFloat() > 0.001f) { + thisVertex.BoneIndices[totalBones] = jointIDs[i]; + thisVertex.BoneWeights[totalBones] = weights[i].asFloat(); + totalWeight = totalWeight + weights[i].asFloat(); + totalBones++; + } + } - for (unsigned int i = 0; i < 4; i++) { - //thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight; - } - } else { - thisVertex.useWeights = false; + for (unsigned int i = 0; i < 4; i++) { + //thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight; + } + } } - //float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3]; //if (totalWeight > 0.0001f) { // thisVertex.BoneWeights[0] /= totalWeight; diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index affc4320..f9376a8c 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -11,7 +11,8 @@ class VertexLayout : public OutputData { public: - bool useWeights = true; + bool isCollision = false; + bool useWeights = false; float Pos[3]{ 0 }; float Normal[3]{ 0 }; float Tangent[3]{ 0 }; @@ -23,28 +24,31 @@ public: virtual void WriteBinary(std::ostream& out) { out.write((char*)&Pos, sizeof(float) * 3); - out.write((char*)&Normal, sizeof(float) * 3); - out.write((char*)&Tangent, sizeof(float) * 3); - out.write((char*)&BiNormal, sizeof(float) * 3); - out.write((char*)&Uv, sizeof(float) * 2); - if (useWeights) { - out.write((char*)&BoneIndices, sizeof(float) * 4); - out.write((char*)&BoneWeights, sizeof(float) * 4); + if (!isCollision) { + out.write((char*)&Normal, sizeof(float) * 3); + out.write((char*)&Tangent, sizeof(float) * 3); + out.write((char*)&BiNormal, sizeof(float) * 3); + out.write((char*)&Uv, sizeof(float) * 2); + if (useWeights) { + out.write((char*)&BoneIndices, sizeof(float) * 4); + out.write((char*)&BoneWeights, sizeof(float) * 4); + } } } virtual void WriteASCII(std::ostream& out) const { out << Pos[0] << " " << Pos[1] << " " << Pos[2] << endl; - out << Normal[0] << " " << Normal[1] << " " << Normal[2] << endl; - out << Tangent[0] << " " << Tangent[1] << " " << Tangent[2] << endl; - out << BiNormal[0] << " " << BiNormal[1] << " " << BiNormal[2] << endl; - out << Uv[0] << " " << Uv[1] << endl; - if (useWeights) { - out << BoneIndices[0] << " " << BoneIndices[1] << " " << BoneIndices[2] << " " << BoneIndices[3] << endl; - out << BoneWeights[0] << " " << BoneWeights[1] << " " << BoneWeights[2] << " " << BoneWeights[3] << endl; + if (!isCollision) { + out << Normal[0] << " " << Normal[1] << " " << Normal[2] << endl; + out << Tangent[0] << " " << Tangent[1] << " " << Tangent[2] << endl; + out << BiNormal[0] << " " << BiNormal[1] << " " << BiNormal[2] << endl; + out << Uv[0] << " " << Uv[1] << 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) { @@ -62,6 +66,7 @@ public: class Mesh : public OutputData { public: + bool isCollison = false; bool hasSkin = false; unsigned int NumVertices; unsigned int NumIndices; @@ -70,7 +75,9 @@ public: virtual void WriteBinary(std::ostream& out) { - out.write((char*)&hasSkin, sizeof(bool)); + if (!isCollison) { + out.write((char*)&hasSkin, sizeof(bool)); + } out.write((char*)&NumVertices, sizeof(int)); out.write((char*)&NumIndices, sizeof(int)); for (auto aVertex : Vertices) { @@ -86,11 +93,13 @@ 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; + if (!isCollison) { + 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; @@ -115,7 +124,7 @@ class MeshClass { public: MeshClass(); - Mesh GetMeshData(MObjectArray Object); + Mesh GetMeshData(MObjectArray Object, bool collision = false); ~MeshClass(); private: struct WeightInfo {