diff --git a/assets b/assets index e4dc9529..9b2fa74a 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e4dc9529f2178d373808ddf487165fa50a641a78 +Subproject commit 9b2fa74a6d535d512c13429997385f7aa3fb50f5 diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 6bd8acec..74f505fe 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -30,9 +30,18 @@ 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); + void BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); + + void BindExplosionTextures(std::shared_ptr& job); + void BindModelTextures(std::shared_ptr& job); Texture* m_WhiteTexture; Texture* m_BlackTexture; + Texture* m_NeutralNormalTexture; + Texture* m_GreyTexture; FrameBuffer m_FinalPassFrameBuffer; GLuint m_BloomTexture; diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 6598b950..45c89e2d 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -22,10 +22,26 @@ struct ModelJob : RenderJob { Model = model; TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0; - DiffuseTexture = matGroup.Texture.get(); - NormalTexture = matGroup.NormalMap.get(); - SpecularTexture = matGroup.SpecularMap.get(); - IncandescenceTexture = matGroup.IncandescenceMap.get(); + 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; @@ -39,7 +55,6 @@ struct ModelJob : RenderJob Depth = worldpos.z; World = world; - FillColor = fillColor; FillPercentage = fillPercentage; 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/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 08a67ac7..57371146 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -19,7 +19,8 @@ struct RenderScene { ::Camera* Camera = nullptr; - std::list> ForwardJobs; + std::list> OpaqueObjects; + std::list> TransparentObjects; std::list> PointLightJobs; std::list> TextJobs; std::list> DirectionalLightJobs; @@ -28,7 +29,8 @@ struct RenderScene void Clear() { - ForwardJobs.clear(); + OpaqueObjects.clear(); + TransparentObjects.clear(); PointLightJobs.clear(); TextJobs.clear(); DirectionalLightJobs.clear(); diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index d9b0d779..d64147b9 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -40,10 +40,10 @@ private: EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(Events::PlayerSpawned& e); + void fillModels(std::list>& opaqueJobs, std::list>& transparentJobs); void fillText(std::list>& jobs, World* world); void fillPointLights(std::list>& jobs, World* world); void fillDirectionalLights(std::list>& jobs, World* world); - void fillModels(std::list>& jobs); void fillLight(std::list>& jobs); bool isChildOfACamera(EntityWrapper entity); bool isChildOfCurrentCamera(EntityWrapper entity); diff --git a/resources/Schema/Components/Model.xml b/resources/Schema/Components/Model.xml index 8f78b9ee..4b77dacb 100644 --- a/resources/Schema/Components/Model.xml +++ b/resources/Schema/Components/Model.xml @@ -2,5 +2,10 @@ + false true + true + true + true + true \ No newline at end of file diff --git a/resources/Schema/Components/Model.xsd b/resources/Schema/Components/Model.xsd index 540ab1bf..9c0cd519 100644 --- a/resources/Schema/Components/Model.xsd +++ b/resources/Schema/Components/Model.xsd @@ -15,9 +15,24 @@ Color tint + + Wether the model is transparent or not + Whether the model is visible or not + + Whether the model should use the Diffuse texture or not + + + Whether the model should use the Normalmap or not + + + Whether the model should use the Specularmap or not + + + Whether the model should use the Glowmap or not + diff --git a/resources/Schema/Entities/EditorTestWorld.xml b/resources/Schema/Entities/EditorTestWorld.xml index 5649a630..9565e2d4 100755 --- a/resources/Schema/Entities/EditorTestWorld.xml +++ b/resources/Schema/Entities/EditorTestWorld.xml @@ -6,7 +6,7 @@ - + Models/Core/UnitCube.mesh @@ -18,69 +18,51 @@ - - - - An error - - - - - - - - - - - An error - - - - - - - - - - - + - + - + + 0.80000001192092896 + Models/DirectionalLightWidget.mesh + + 1.0499999523162842 + + - + - + Models/Assault.mesh - + + - + - Models/SecondaryWeapon.fbx + Models/SecondaryWeapon.mesh @@ -91,17 +73,219 @@ - + + + + + + + + + + + + Run + + 1 + + + models/AssaultAnimated.mesh + + + + + + + + + + + Walk + + 1 + + + models/AssaultAnimated.mesh + + + + + + + + Models/Core/UnitSphere.mesh + + true + + + + + + + + + + + + + - Models/Core/UnitSphere.mesh + Models/Log.mesh - + + + + + + + + + + + + + Models/NormalMapSphere.mesh + + + + + + + + + + + Models/SpecularMapSphere.mesh + + + + + + + + + + 1 + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + 3 + 1.1399998664855957 + + + + + + + + + + + + + + + + Models/IncandescenceMapSphere.mesh + + + + + + + + + + + models/NormSpecIncdMapSphere.mesh + + + + + + + + + 1 + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + 3 + 1.1399998664855957 + + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + 5.0100002288818359 + 0.69999998807907104 + + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + 4 + 0.80000001192092896 + + + + + + + + + + + + diff --git a/resources/Schema/Entities/PointLightWithModel.xml b/resources/Schema/Entities/PointLightWithModel.xml new file mode 100644 index 00000000..17ca950c --- /dev/null +++ b/resources/Schema/Entities/PointLightWithModel.xml @@ -0,0 +1,20 @@ + + + + + + Models/Core/UnitSphere.mesh + + + + 3 + 1.1399998664855957 + + + + + + + + + diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 42500b44..de672dd1 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -9,7 +9,9 @@ uniform vec2 ScreenDimensions; uniform vec4 FillColor; uniform float FillPercentage; layout (binding = 0) uniform sampler2D DiffuseTexture; -layout (binding = 1) uniform sampler2D GlowMap; +layout (binding = 1) uniform sampler2D NormalMapTexture; +layout (binding = 2) uniform sampler2D SpecularMapTexture; +layout (binding = 3) uniform sampler2D GlowMapTexture; #define TILE_SIZE 16 @@ -49,6 +51,8 @@ layout (std430, binding = 4) buffer LightIndexBuffer in VertexData{ vec3 Position; vec3 Normal; + vec3 Tangent; + vec3 BiTangent; vec2 TextureCoordinate; vec4 ExplosionColor; }Input; @@ -102,13 +106,21 @@ LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensi 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); +} void main() { vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); - vec4 glowTexel = texture2D(GlowMap, Input.TextureCoordinate); + vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate); + vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate); vec4 position = V * M * vec4(Input.Position, 1.0); - vec4 normal = normalize(V * vec4(Input.Normal, 0.0)); + vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate, NormalMapTexture); + //vec4 normal = normalize(V * vec4(Input.Normal, 0.0)); vec4 viewVec = normalize(-position); vec2 tilePos; @@ -139,7 +151,7 @@ void main() } - vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color; + 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; @@ -147,25 +159,10 @@ void main() if(pos <= FillPercentage) { color_result += FillColor; } - //bloomColor = vec4(0.3, 0.8, 0.6, 1.0); sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); - //These if statements should be removed if they are slow. color_result += glowTexel; - - - bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0); - /* - if(color_result.x > 1 || color_result.y > 1 || color_result.z > 1) { - bloomColor = vec4(color_result.xyz, 1.0); - } else { - bloomColor = vec4(0.0, 0.0, 0.0, 1.0); - } */ - - - - //Tiled Debug Code /* diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index bd7df47e..1a7cca12 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -16,6 +16,8 @@ layout(location = 6) in vec4 BoneWeights; out VertexData{ vec3 Position; vec3 Normal; + vec3 Tangent; + vec3 BiTangent; vec2 TextureCoordinate; vec4 ExplosionColor; }Output; @@ -37,5 +39,7 @@ void main() 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(0.0); } \ No newline at end of file diff --git a/resources/Shaders/Gaussian_horiz.frag.glsl b/resources/Shaders/Gaussian_horiz.frag.glsl index a5606372..6a9572c2 100644 --- a/resources/Shaders/Gaussian_horiz.frag.glsl +++ b/resources/Shaders/Gaussian_horiz.frag.glsl @@ -1,4 +1,5 @@ #version 430 +#extension GL_EXT_gpu_shader4 : enable layout (binding = 0) uniform sampler2D Texture; diff --git a/resources/Shaders/Gaussian_vert.frag.glsl b/resources/Shaders/Gaussian_vert.frag.glsl index 34803b08..8b0e861a 100644 --- a/resources/Shaders/Gaussian_vert.frag.glsl +++ b/resources/Shaders/Gaussian_vert.frag.glsl @@ -1,4 +1,5 @@ #version 430 +#extension GL_EXT_gpu_shader4 : enable layout (binding = 0) uniform sampler2D Texture; diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp index 7caa4044..898eac9d 100644 --- a/src/Engine/Editor/EditorRenderSystem.cpp +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -49,7 +49,11 @@ void EditorRenderSystem::Update(double dt) glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World); 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); - scene.ForwardJobs.push_back(modelJob); + if(cModel["Transparent"]) { + scene.TransparentObjects.push_back(modelJob); + } else { + scene.OpaqueObjects.push_back(modelJob); + } } } } diff --git a/src/Engine/Rendering/DrawBloomPass.cpp b/src/Engine/Rendering/DrawBloomPass.cpp index efd206d3..4f48831b 100644 --- a/src/Engine/Rendering/DrawBloomPass.cpp +++ b/src/Engine/Rendering/DrawBloomPass.cpp @@ -13,7 +13,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer) void DrawBloomPass::InitializeTextures() { - m_WhiteTexture = ResourceManager::Load("Textures/Core/Blank.png"); + m_WhiteTexture = ResourceManager::Load("Textures/Core/White.png"); } void DrawBloomPass::InitializeShaderPrograms() diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 66c4d52b..48ea4144 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -11,8 +11,10 @@ DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCulling void DrawFinalPass::InitializeTextures() { - m_WhiteTexture = ResourceManager::Load("Textures/Core/Blank.png"); + m_WhiteTexture = ResourceManager::Load("Textures/Core/White.png"); m_BlackTexture = ResourceManager::Load("Textures/Core/Black.png"); + m_NeutralNormalTexture = ResourceManager::Load("Textures/Core/NeutralNormalMap.png"); + m_GreyTexture = ResourceManager::Load("Textures/Core/Grey.png"); } void DrawFinalPass::InitializeFrameBuffers() @@ -58,117 +60,15 @@ void DrawFinalPass::Draw(RenderScene& scene) GLERROR("DrawFinalPass::Draw: Pre"); DrawFinalPassState* state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle()); - GLuint shaderHandle; - - - //TODO: Render: Add code for more jobs than modeljobs. - for (auto &job : scene.ForwardJobs) { - auto explosionEffectJob = std::dynamic_pointer_cast(job); - if (explosionEffectJob) { - m_ExplosionEffectProgram->Bind(); - shaderHandle = m_ExplosionEffectProgram->GetHandle(); //--- - - GLERROR("DrawFinalPass::ExplosionEffect: 1"); - //TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(explosionEffectJob->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())); - glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(explosionEffectJob->Color)); - glUniform3fv(glGetUniformLocation(shaderHandle, "ExplosionOrigin"), 1, glm::value_ptr(explosionEffectJob->ExplosionOrigin)); - glUniform1f(glGetUniformLocation(shaderHandle, "TimeSinceDeath"), explosionEffectJob->TimeSinceDeath); - glUniform1f(glGetUniformLocation(shaderHandle, "ExplosionDuration"), explosionEffectJob->ExplosionDuration); - glUniform4fv(glGetUniformLocation(shaderHandle, "EndColor"), 1, glm::value_ptr(explosionEffectJob->EndColor)); - glUniform1i(glGetUniformLocation(shaderHandle, "Randomness"), explosionEffectJob->Randomness); - glUniform1fv(glGetUniformLocation(shaderHandle, "RandomNumbers"), 50, explosionEffectJob->RandomNumbers.data()); - glUniform1f(glGetUniformLocation(shaderHandle, "RandomnessScalar"), explosionEffectJob->RandomnessScalar); - glUniform2fv(glGetUniformLocation(shaderHandle, "Velocity"), 1, glm::value_ptr(explosionEffectJob->Velocity)); - glUniform1i(glGetUniformLocation(shaderHandle, "ColorByDistance"), explosionEffectJob->ColorByDistance); - glUniform1i(glGetUniformLocation(shaderHandle, "ExponentialAccelaration"), explosionEffectJob->ExponentialAccelaration); - glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(explosionEffectJob->DiffuseColor)); - GLERROR("DrawFinalPass::ExplosionEffect: 2"); - - if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { - 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 - if (explosionEffectJob->DiffuseTexture != nullptr) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, explosionEffectJob->DiffuseTexture->m_Texture); - } else { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - } - 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))); - GLERROR("DrawFinalPass::ExplosionEffect: END"); - //m_ExplosionEffectProgram->Unbind(); - - } else { - auto modelJob = std::dynamic_pointer_cast(job); - if (modelJob) { - m_ForwardPlusProgram->Bind(); - GLERROR("1.1"); - shaderHandle = m_ForwardPlusProgram->GetHandle(); - - if (scene.ClearDepth) { - glClear(GL_DEPTH_BUFFER_BIT); - } - - 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()); - 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())); - glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height); - - //TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); - glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor)); - - glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(modelJob->FillColor)); - glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), modelJob->FillPercentage); - - - if (modelJob->DiffuseTexture != nullptr) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); - } else { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - } - glActiveTexture(GL_TEXTURE1); - if (modelJob->IncandescenceTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, modelJob->IncandescenceTexture->m_Texture); - } else { - glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); - } - - /*if(modelJob->GlowMap != nullptr) { - glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture); - } else { - glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); - }*/ - - 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); - - 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))); - GLERROR("DrawFinalPass::Model: END"); - // m_ForwardPlusProgram->Unbind(); - - } - } - + if (scene.ClearDepth) { + glClear(GL_DEPTH_BUFFER_BIT); } + + DrawModelRenderQueues(scene.OpaqueObjects, scene); + GLERROR("DrawFinalPass::Draw: OpaqueObjects"); + DrawModelRenderQueues(scene.TransparentObjects, scene); + GLERROR("DrawFinalPass::Draw: TransparentObjects"); + GLERROR("DrawFinalPass::Draw: END"); delete state; } @@ -206,4 +106,152 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); GLERROR("MipMap Texture initialization failed"); -} \ No newline at end of file +} + +void DrawFinalPass::DrawModelRenderQueues(std::list>& job, RenderScene& scene) +{ + GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); + GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle(); + + 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 : job) + { + auto explosionEffectJob = std::dynamic_pointer_cast(job); + if(explosionEffectJob) { + //Bind program + m_ExplosionEffectProgram->Bind(); + + //Bind uniforms + BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); + + 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])); + } + } + + //bind textures + BindExplosionTextures(explosionEffectJob); + //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))); + + } else { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + //bind forward program + m_ForwardPlusProgram->Bind(); + + //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))); + GLERROR("DrawFinalPass::Model: END"); + } + } + } + +} + +void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) +{ + 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())); + glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); + glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(job->Color)); + glUniform3fv(glGetUniformLocation(shaderHandle, "ExplosionOrigin"), 1, glm::value_ptr(job->ExplosionOrigin)); + glUniform1f(glGetUniformLocation(shaderHandle, "TimeSinceDeath"), job->TimeSinceDeath); + glUniform1f(glGetUniformLocation(shaderHandle, "ExplosionDuration"), job->ExplosionDuration); + glUniform4fv(glGetUniformLocation(shaderHandle, "EndColor"), 1, glm::value_ptr(job->EndColor)); + glUniform1i(glGetUniformLocation(shaderHandle, "Randomness"), job->Randomness); + glUniform1f(glGetUniformLocation(shaderHandle, "RandomnessScalar"), job->RandomnessScalar); + glUniform2fv(glGetUniformLocation(shaderHandle, "Velocity"), 1, glm::value_ptr(job->Velocity)); + glUniform1i(glGetUniformLocation(shaderHandle, "ColorByDistance"), job->ColorByDistance); + glUniform1i(glGetUniformLocation(shaderHandle, "ExponentialAccelaration"), job->ExponentialAccelaration); + glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(job->DiffuseColor)); + glUniform1fv(glGetUniformLocation(shaderHandle, "RandomNumbers"), 50, job->RandomNumbers.data()); +} + +void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) +{ + 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())); + glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); + 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); +} + + +void DrawFinalPass::BindExplosionTextures(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); + } + glActiveTexture(GL_TEXTURE1); + if (job->IncandescenceTexture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture->m_Texture); + } else { + glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + } +} + +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); + } + + 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_TEXTURE2); + if (job->SpecularTexture != nullptr) { + glBindTexture(GL_TEXTURE_2D, job->SpecularTexture->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); + } +} + diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 4c39bfc9..d0518ee8 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.ForwardJobs) { + for (auto &job : scene.OpaqueObjects) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { @@ -98,6 +98,52 @@ 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.TransparentObjects) { + 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] += 5; + } else { + m_ColorCounter[0] += 50; + } + } + + 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"); 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/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 1998c3d7..943fa992 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -35,13 +35,12 @@ bool RenderSystem::isChildOfACamera(EntityWrapper entity) { return entity.FirstParentWithComponent("Camera").Valid(); } - bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity) { return entity == m_CurrentCamera || entity.IsChildOf(m_CurrentCamera); } -void RenderSystem::fillModels(std::list>& jobs) +void RenderSystem::fillModels(std::list>& opaqueJobs, std::list>& transparentJobs) { auto models = m_World->GetComponents("Model"); if (models == nullptr) { @@ -84,7 +83,6 @@ void RenderSystem::fillModels(std::list>& jobs) } } - float fillPercentage = 0.f; glm::vec4 fillColor = glm::vec4(0); if(m_World->HasComponent(cModel.EntityID, "Fill")) { @@ -108,7 +106,15 @@ void RenderSystem::fillModels(std::list>& jobs) fillColor, fillPercentage )); - jobs.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"]) { + transparentJobs.push_back(explosionEffectJob); + } else { + opaqueJobs.push_back(explosionEffectJob); + } } else { std::shared_ptr modelJob = std::shared_ptr(new ModelJob( model, @@ -120,7 +126,14 @@ void RenderSystem::fillModels(std::list>& jobs) fillColor, fillPercentage )); - jobs.push_back(modelJob); + if (modelJob->Color.a != 1.f || modelJob->DiffuseColor.a != 1.f) { + cModel["Transparent"] = true; + } + if (cModel["Transparent"]) { + transparentJobs.push_back(modelJob); + } else { + opaqueJobs.push_back(modelJob); + } } } } @@ -231,7 +244,7 @@ void RenderSystem::Update(double dt) RenderScene scene; scene.Camera = m_Camera; scene.Viewport = Rectangle(1280, 720); - fillModels(scene.ForwardJobs); + fillModels(scene.OpaqueObjects, scene.TransparentObjects); fillPointLights(scene.PointLightJobs, m_World); fillDirectionalLights(scene.DirectionalLightJobs, m_World); fillText(scene.TextJobs, m_World); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 08b30afa..55cd8b03 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -148,14 +148,14 @@ PickData Renderer::Pick(glm::vec2 screenCoord) void Renderer::InitializeTextures() { m_ErrorTexture = ResourceManager::Load("Textures/Core/ErrorTexture.png"); - m_WhiteTexture = ResourceManager::Load("Textures/Core/Blank.png"); + m_WhiteTexture = ResourceManager::Load("Textures/Core/White.png"); } void Renderer::SortRenderJobsByDepth(RenderScene &scene) { //Sort all forward jobs so transparency is good. - scene.ForwardJobs.sort(Renderer::DepthSort); + scene.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/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp index d8f1abd4..3497fd04 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."); } } } @@ -109,6 +120,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/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/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/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 6af8a557..01737683 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,8 +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; for (unsigned int i = 0; i < connections.length(); i++) { @@ -122,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; } } @@ -138,7 +132,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 +166,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]]); @@ -308,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 /* ??? */; @@ -326,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 c30311b8..a6ee5897 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) { @@ -68,100 +68,226 @@ 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; - MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); - while (!jointIt.isDone()) - { - m_Hierarchy.push_back(jointIt.item()); + std::map, 4>> joinCheckMap; + std::map exportJoint; - MFnDependencyNode depNode(jointIt.item()); - for (int i = 0; i < 9; i++) - { - MStatus tmp; - MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp); + //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()); - 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; - } + // MMatrix tmp(doubleMat); + // if (!tmp.isEquivalent(transformationMatrix)) { + // MGlobal::displayInfo(MString() + MayaJoint.name() + " is exported"); + // exportJoint[MayaJoint.name().asChar()] = true; + // animatedJoints.push_back(MayaJoint.object()); + // } + // } - unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField)); - MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex); + /*for (int i = 0; i < 9; i++) + { + MStatus tmp; + MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp); - if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) { - animatedJoints.push_back(jointIt.item()); - i = 9; - break; - } + 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()); + if (connected.hasFn(MFn::kAnimCurve)) { - MPlug BindPose = MayaJoint.findPlug("bindPose"); - MDataHandle DataHandle; - BindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix BindPoseMatrix = MartixFn.matrix(); + MFnAnimCurve jointAnim(connected); - 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"); - } - } - } - } + //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); - jointIt.next(); - } + unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp); - int currentFrame = startFrame; - while (currentFrame != endFrame + 1) { // ANDREAS - Animation::Keyframe thisKeyFrame; - thisKeyFrame.Index = currentFrame - startFrame; - thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; + if (tmp == MStatus::kFailure) + MGlobal::displayInfo(MString() + "Fail :c"); - MAnimControl::setCurrentTime(MTime(currentFrame, MTime::kNTSCField)); - MTime time = MAnimControl::currentTime(); + if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) { + //MGlobal::displayInfo(MString() + "Start key time : " + jointAnim.time(startKeyFrameIndex).value()); - for (auto aJoint : animatedJoints){ - MFnTransform thisJoint(aJoint); - Animation::Keyframe::JointProperty joint; - 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 (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); + 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; + } + + 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"); + } + } + } + } + + } // 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; + + 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; + + 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]; @@ -175,95 +301,96 @@ 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)).name() == "world") { - 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); - 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 @@ -310,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 6a288c8a..47ae6f4c 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" @@ -21,6 +22,7 @@ public: int Index = 0; float Time = 0; + int NumberOfJoints; std::vector JointProperties; }; @@ -28,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) @@ -37,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); @@ -55,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;