From da1f38f99d3b8a07ed4ddd905f8e7d7c6e25f945 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 25 May 2008 14:37:39 +0000 Subject: Apply BGE patch 11137: Render objects with negative scaling correctly (as in Blender) --- .../gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp | 16 ++++++++++++++++ .../gameengine/BlenderRoutines/KX_BlenderRenderTools.h | 2 ++ source/gameengine/GamePlayer/common/GPC_RenderTools.cpp | 16 ++++++++++++++++ source/gameengine/GamePlayer/common/GPC_RenderTools.h | 2 ++ source/gameengine/Ketsji/KX_GameObject.cpp | 3 ++- source/gameengine/Ketsji/KX_GameObject.h | 9 +++++++++ source/gameengine/Rasterizer/RAS_IRenderTools.h | 1 + source/gameengine/Rasterizer/RAS_MaterialBucket.cpp | 2 ++ 8 files changed, 50 insertions(+), 1 deletion(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index a656c5e5523..ffd66655069 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -125,6 +125,22 @@ void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty) } +void KX_BlenderRenderTools::SetClientObject(void* obj) +{ + if (m_clientobject != obj) + { + if (obj == NULL || !((KX_GameObject*)obj)->IsNegativeScaling()) + { + glFrontFace(GL_CCW); + } else + { + glFrontFace(GL_CW); + } + m_clientobject = obj; + m_modified = true; + } +} + bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data) { double* const oglmatrix = (double* const) data; diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index 662f5bd9af1..31eaa14d66b 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -105,6 +105,8 @@ public: virtual void Render2DFilters(RAS_ICanvas* canvas); + virtual void SetClientObject(void* obj); + }; #endif //__KX_BLENDERRENDERTOOLS diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index edda7657ef9..885981a2898 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -462,6 +462,22 @@ int GPC_RenderTools::applyLights(int objectlayer) } +void GPC_RenderTools::SetClientObject(void* obj) +{ + if (m_clientobject != obj) + { + if (obj == NULL || !((KX_GameObject*)obj)->IsNegativeScaling()) + { + glFrontFace(GL_CCW); + } else + { + glFrontFace(GL_CW); + } + m_clientobject = obj; + m_modified = true; + } +} + bool GPC_RenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data) { double* const oglmatrix = (double* const) data; diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h index 9b86869af73..ee0212da643 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h @@ -153,6 +153,8 @@ public: virtual void Render2DFilters(RAS_ICanvas* canvas); + virtual void SetClientObject(void* obj); + protected: /** * Copied from KX_BlenderGL.cpp in KX_blenderhook diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 5fd5d2d5492..dada47e2fa4 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -77,6 +77,7 @@ KX_GameObject::KX_GameObject( m_layer(0), m_bSuspendDynamics(false), m_bUseObjectColor(false), + m_bIsNegativeScaling(false), m_bVisible(true), m_pPhysicsController1(NULL), m_pPhysicsEnvironment(NULL), @@ -335,7 +336,7 @@ double* KX_GameObject::GetOpenGLMatrix() trans.setBasis(GetSGNode()->GetWorldOrientation()); MT_Vector3 scaling = GetSGNode()->GetWorldScaling(); - + m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false; trans.scale(scaling[0], scaling[1], scaling[2]); trans.getValue(fl); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 6e765978821..3758651f53d 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -75,6 +75,7 @@ protected: bool m_bSuspendDynamics; bool m_bUseObjectColor; + bool m_bIsNegativeScaling; MT_Vector4 m_objectColor; // Is this object set to be visible? Only useful for the @@ -598,6 +599,14 @@ public: void ); + /** + * Get the negative scaling state + */ + bool + IsNegativeScaling( + void + ) { return m_bIsNegativeScaling; } + /** * @section Logic bubbling methods. */ diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h index 16e15653c82..bcbf907741b 100644 --- a/source/gameengine/Rasterizer/RAS_IRenderTools.h +++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h @@ -146,6 +146,7 @@ public: int layer )=0; + virtual void SetClientObject( void* obj diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 02e84f8a243..96ce220ae4d 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -325,6 +325,8 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans, while (ActivateMaterial(cameratrans, rasty, rendertools, drawmode)) RenderMeshSlot(cameratrans, rasty, rendertools, *it, drawmode); } + // to reset the eventual GL_CW mode + rendertools->SetClientObject(NULL); } -- cgit v1.2.3