Fix Bug #1309 Disabling Actor leaves Ghost, Dynamic and Rigid Body etc enabled.

Depth sorting for Transparent polygons.  Use ZTransp in Material buttons to enable.
This will cause an object's polygons to be sorted (back to front for alpha polygons, front to back for solid polygons.)
This commit is contained in:
Kester Maddock 2004-05-26 12:01:08 +00:00
parent 05e76c22b0
commit e5cc9abceb
16 changed files with 201 additions and 71 deletions

@ -43,7 +43,8 @@ KX_BlenderPolyMaterial::KX_BlenderPolyMaterial(const STR_String &texname,
int tilexrep,
int tileyrep,
int mode,
int transparant,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,
@ -56,6 +57,7 @@ KX_BlenderPolyMaterial::KX_BlenderPolyMaterial(const STR_String &texname,
tileyrep,
mode,
transparant,
zsort,
lightlayer,
bIsTriangle,
clientobject),

@ -53,7 +53,8 @@ public:
int tilexrep,
int tileyrep,
int mode,
int transparant,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,

@ -424,13 +424,13 @@ int KX_BlenderRenderTools::applyLights(int objectlayer)
RAS_IPolyMaterial* KX_BlenderRenderTools::CreateBlenderPolyMaterial(
const STR_String &texname,
bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,int transparant,int lightlayer
bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,bool transparant,bool zsort, int lightlayer
,bool bIsTriangle,void* clientobject,void* tface)
{
return new KX_BlenderPolyMaterial(
texname,
ba,matname,tile,tilexrep,tileyrep,mode,transparant,lightlayer
ba,matname,tile,tilexrep,tileyrep,mode,transparant,zsort, lightlayer
,bIsTriangle,clientobject,(struct TFace*)tface);
}

@ -84,17 +84,18 @@ public:
virtual void PopMatrix();
virtual class RAS_IPolyMaterial* CreateBlenderPolyMaterial(const STR_String &texname,
bool ba,
const STR_String& matname,
int tile,
int tilexrep,
int tileyrep,
int mode,
int transparant,
int lightlayer,
bool bIsTriangle,
void* clientobject,
void* tface);
bool ba,
const STR_String& matname,
int tile,
int tilexrep,
int tileyrep,
int mode,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,
void* tface);
};
#endif //__KX_BLENDERRENDERTOOLS

@ -364,8 +364,11 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
bool istriangle = (mface->v4==0);
bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false;
RAS_IPolyMaterial* polymat = rendertools->CreateBlenderPolyMaterial(imastr,false,matnameptr,tile,tilexrep,tileyrep,mode,transp, lightlayer,istriangle,blenderobj,tface);
RAS_IPolyMaterial* polymat = rendertools->CreateBlenderPolyMaterial(imastr, false, matnameptr,
tile, tilexrep, tileyrep,
mode, transp, zsort, lightlayer, istriangle, blenderobj, tface);
if (ma)
{
@ -698,13 +701,20 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
CreateMaterialFromBlenderObject(blenderobject, kxscene);
KX_ObjectProperties objprop;
objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
if ((objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0))
{
objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
} else {
objprop.m_dyna = false;
objprop.m_angular_rigidbody = false;
objprop.m_ghost = false;
}
//mmm, for now, taks this for the size of the dynamicobject
// Blender uses inertia for radius of dynamic object
objprop.m_radius = blenderobject->inertia;
objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
objprop.m_dynamic_parent=NULL;
objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
@ -763,7 +773,6 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
}
objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
objprop.m_concave = (blenderobject->boundtype & 4) != 0;
switch (physics_engine)

@ -361,10 +361,10 @@ static int my_set_tpage(TFace *tface)
GPC_PolygonMaterial::GPC_PolygonMaterial(const STR_String& texname, bool ba, const STR_String& matname,
int tile, int tileXrep, int tileYrep, int mode, int transparant,
int tile, int tileXrep, int tileYrep, int mode, bool transparant, bool zsort,
int lightlayer, bool bIsTriangle, void* clientobject, void* tpage) :
RAS_IPolyMaterial(texname, ba, matname, tile, tileXrep, tileYrep, mode,
transparant, lightlayer, bIsTriangle, clientobject), m_tface((struct TFace*)tpage)
transparant, zsort, lightlayer, bIsTriangle, clientobject), m_tface((struct TFace*)tpage)
{
// clear local caching info
my_set_tpage(0);

@ -41,7 +41,7 @@ class GPC_PolygonMaterial : public RAS_IPolyMaterial
public:
GPC_PolygonMaterial(const STR_String& texname, bool ba, const STR_String& matname,
int tile, int tileXrep, int tileYrep, int mode, int transparant,
int tile, int tileXrep, int tileYrep, int mode, bool transparant, bool zsort,
int lightlayer, bool bIsTriangle, void* clientobject, void* tpage);
virtual ~GPC_PolygonMaterial(void);

@ -312,11 +312,11 @@ void GPC_RenderTools::BL_RenderText(
RAS_IPolyMaterial* GPC_RenderTools::CreateBlenderPolyMaterial(
const STR_String &texname,
bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,int transparant,int lightlayer
,bool bIsTriangle,void* clientobject,void* tface)
bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,bool transparant, bool zsort,
int lightlayer,bool bIsTriangle,void* clientobject,void* tface)
{
return new GPC_PolygonMaterial(texname, ba,matname,tile,tilexrep,tileyrep,
mode,transparant,lightlayer,bIsTriangle,clientobject,tface);
mode,transparant,zsort,lightlayer,bIsTriangle,clientobject,tface);
}

@ -144,7 +144,8 @@ public:
int tile,
int tilexrep,int tileyrep,
int mode,
int transparant,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,

@ -91,8 +91,7 @@ void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene)
return NULL;
};
SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc);
SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc,KX_GameObject::UpdateTransformFunc);
// temporarily var until there is a button in the userinterface
// (defined in KX_PythonInit.cpp)
@ -797,7 +796,7 @@ void KX_Scene::UpdateMeshTransformations()
{
KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
gameobj->GetOpenGLMatrix();
gameobj->UpdateNonDynas();
// gameobj->UpdateNonDynas();
}
}
@ -831,11 +830,12 @@ void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty)
if (gameobj)
{
int nummeshes = gameobj->GetMeshCount();
MT_Transform t(GetActiveCamera()->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
for (int m=0;m<nummeshes;m++)
{
// this adds the vertices to the display list
(gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode(),rasty);
(gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode(),rasty);
}
gameobj->MarkVisible();
}
@ -858,11 +858,13 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
if (visible)
{
int nummeshes = gameobj->GetMeshCount();
MT_Transform t( GetActiveCamera()->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
for (int m=0;m<nummeshes;m++)
{
// this adds the vertices to the display list
(gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode(),rasty);
(gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode(),rasty);
}
}
gameobj->MarkVisible(visible && gameobj->GetVisible());
@ -895,7 +897,7 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)
if (!vis)
{
MT_Vector3 scale = gameobj->GetSGNode()->GetWorldScaling();
MT_Scalar radius = scale[scale.closestAxis()] * gameobj->GetSGNode()->Radius();
MT_Scalar radius = fabs(scale[scale.closestAxis()] * gameobj->GetSGNode()->Radius());
switch (GetActiveCamera()->SphereInsideFrustum(gameobj->NodeGetWorldPosition(), radius))
{
case KX_Camera::INSIDE:
@ -907,7 +909,7 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)
case KX_Camera::INTERSECT:
// Test the object's bound box against the view frustum.
MT_Point3 box[8];
gameobj->GetSGNode()->getBBox(box);
gameobj->GetSGNode()->getBBox(box);
vis = GetActiveCamera()->BoxInsideFrustum(box) != KX_Camera::OUTSIDE;
break;
}
@ -916,11 +918,12 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)
if (vis)
{
int nummeshes = gameobj->GetMeshCount();
MT_Transform t(GetActiveCamera()->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
for (int m=0;m<nummeshes;m++)
{
// this adds the vertices to the display list
(gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode(),rasty);
(gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode(),rasty);
}
// Visibility/ non-visibility are marked
// elsewhere now.

@ -69,6 +69,9 @@ void RAS_BucketManager::RenderAlphaBuckets(
std::multiset<alphamesh, backtofront> alphameshset;
RAS_MaterialBucket::T_MeshSlotList::iterator mit;
/* Camera's near plane equation: cam_norm.dot(point) + cam_origin */
const MT_Vector3 cam_norm(cameratrans.getBasis()[2]);
const MT_Scalar cam_origin = cameratrans.getOrigin()[2];
for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit)
{
(*bit)->ClearScheduledPolygons();
@ -77,7 +80,7 @@ void RAS_BucketManager::RenderAlphaBuckets(
if ((*mit).m_bVisible)
{
MT_Point3 pos((*mit).m_OpenGLMatrix[12], (*mit).m_OpenGLMatrix[13], (*mit).m_OpenGLMatrix[14]);
alphameshset.insert(alphamesh(MT_dot(cameratrans.getBasis()[2], pos) + cameratrans.getOrigin()[2], mit, *bit));
alphameshset.insert(alphamesh(MT_dot(cam_norm, pos) + cam_origin, mit, *bit));
}
}
}

@ -42,7 +42,8 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
int tilexrep,
int tileyrep,
int mode,
int transparant,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject=NULL) :
@ -54,6 +55,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
m_tileyrep(tileyrep),
m_drawingmode (mode),
m_transparant(transparant),
m_zsort(zsort),
m_lightlayer(lightlayer),
m_bIsTriangle(bIsTriangle)
{
@ -71,6 +73,7 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
this->m_tilexrep == lhs.m_tilexrep &&
this->m_tileyrep == lhs.m_tileyrep &&
this->m_transparant == lhs.m_transparant &&
this->m_zsort == lhs.m_zsort &&
this->m_drawingmode == lhs.m_drawingmode &&
this->m_bIsTriangle == lhs.m_bIsTriangle &&
this->m_lightlayer == lhs.m_lightlayer &&
@ -117,51 +120,49 @@ bool RAS_IPolyMaterial::Less(const RAS_IPolyMaterial& rhs) const
m_tilexrep > rhs.m_tilexrep)
return false;
return (m_tilexrep < rhs.m_tilexrep ||
m_tile < rhs.m_tile);
if (m_tilexrep < rhs.m_tilexrep ||
m_tile < rhs.m_tile)
return true;
return !(m_tile > rhs.m_tile ||
m_zsort > rhs.m_zsort);
}
int RAS_IPolyMaterial::GetLightLayer()
int RAS_IPolyMaterial::GetLightLayer() const
{
return m_lightlayer;
}
bool RAS_IPolyMaterial::IsTransparant()
bool RAS_IPolyMaterial::IsTransparant() const
{
return (m_transparant != 0);
return m_transparant;
}
bool RAS_IPolyMaterial::IsZSort() const
{
return m_zsort;
}
bool RAS_IPolyMaterial::UsesTriangles()
bool RAS_IPolyMaterial::UsesTriangles() const
{
return m_bIsTriangle;
}
unsigned int RAS_IPolyMaterial::hash() const
{
return m_texturename.hash();
}
int RAS_IPolyMaterial::GetDrawingMode()
int RAS_IPolyMaterial::GetDrawingMode() const
{
return m_drawingmode;
}
const STR_String& RAS_IPolyMaterial::GetMaterialName() const
{
return m_materialname;
}
const STR_String& RAS_IPolyMaterial::GetTextureName() const
{
return m_texturename;

@ -55,7 +55,8 @@ protected:
int m_tile;
int m_tilexrep,m_tileyrep;
int m_drawingmode; // tface->mode
int m_transparant;
bool m_transparant;
bool m_zsort;
int m_lightlayer;
bool m_bIsTriangle;
@ -84,7 +85,8 @@ public:
int tilexrep,
int tileyrep,
int mode,
int transparant,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject);
@ -108,11 +110,12 @@ public:
bool Equals(const RAS_IPolyMaterial& lhs) const;
bool Less(const RAS_IPolyMaterial& rhs) const;
int GetLightLayer();
bool IsTransparant();
bool UsesTriangles();
int GetLightLayer() const;
bool IsTransparant() const;
bool IsZSort() const;
bool UsesTriangles() const;
unsigned int hash() const;
int GetDrawingMode();
int GetDrawingMode() const;
const STR_String& GetMaterialName() const;
const STR_String& GetTextureName() const;
};

@ -184,7 +184,8 @@ public:
int tilexrep,
int tileyrep,
int mode,
int transparant,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,

@ -29,14 +29,16 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include "RAS_MeshObject.h"
#include "RAS_IRasterizer.h"
#include "MT_MinMax.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "RAS_MeshObject.h"
#include "RAS_IRasterizer.h"
#include "MT_MinMax.h"
#include "MT_Point3.h"
STR_String RAS_MeshObject::s_emptyname = "";
@ -67,6 +69,7 @@ KX_ArrayOptimizer::~KX_ArrayOptimizer()
RAS_MeshObject::RAS_MeshObject(int lightlayer)
: m_bModified(true),
m_lightlayer(lightlayer),
m_zsort(false),
m_class(0)
{
}
@ -550,9 +553,65 @@ void RAS_MeshObject::UpdateMaterialList()
}
}
RAS_MeshObject::polygonSlot::polygonSlot(const MT_Vector3 &pnorm, const MT_Scalar &pval, RAS_MeshObject *mesh, RAS_Polygon* poly) :
m_poly(poly)
{
const KX_VertexIndex &base = m_poly->GetIndexBase();
RAS_TexVert *vert = mesh->GetVertex(base.m_vtxarray, base.m_indexarray[0], poly->GetMaterial()->GetPolyMaterial());
m_z = MT_dot(pnorm, vert->getLocalXYZ()) + pval;
for( unsigned int i = 1; i < m_poly->VertexCount(); i++)
{
vert = mesh->GetVertex(base.m_vtxarray, base.m_indexarray[i], poly->GetMaterial()->GetPolyMaterial());
float z = MT_dot(pnorm, vert->getLocalXYZ()) + pval;
if (z > m_z)
m_z = z;
}
}
void RAS_MeshObject::SortPolygons(const MT_Transform &transform)
{
const MT_Vector3 pnorm(transform.getBasis()[2]);
const MT_Scalar pval = transform.getOrigin()[2];
unsigned int numpolys = m_Polygons.size();
std::multiset<polygonSlot, backtofront> alphapolyset;
std::multiset<polygonSlot, fronttoback> solidpolyset;
for (unsigned int p = 0; p < numpolys; p++)
{
RAS_Polygon* poly = m_Polygons[p];
if (poly->IsVisible())
{
if (poly->GetMaterial()->GetPolyMaterial()->IsTransparant())
{
alphapolyset.insert(polygonSlot(pnorm, pval, this, poly));
} else {
solidpolyset.insert(polygonSlot(pnorm, pval, this, poly));
}
}
}
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
vector<KX_IndexArray*> *indexcache = &GetArrayOptimizer((*it)->GetPolyMaterial())->m_IndexArrayCache1;
for (vector<KX_IndexArray*>::iterator iit = indexcache->begin(); iit != indexcache->end(); ++iit)
(*iit)->clear();
}
void RAS_MeshObject::SchedulePolygons(int drawingmode,RAS_IRasterizer* rasty)
//ClearArrayData();
std::multiset<polygonSlot, fronttoback>::iterator sit = solidpolyset.begin();
for (; sit != solidpolyset.end(); ++sit)
SchedulePoly((*sit).m_poly->GetVertexIndexBase(), (*sit).m_poly->VertexCount(), (*sit).m_poly->GetMaterial()->GetPolyMaterial());
std::multiset<polygonSlot, backtofront>::iterator ait = alphapolyset.begin();
for (; ait != alphapolyset.end(); ++ait)
SchedulePoly((*ait).m_poly->GetVertexIndexBase(), (*ait).m_poly->VertexCount(), (*ait).m_poly->GetMaterial()->GetPolyMaterial());
}
void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawingmode,RAS_IRasterizer* rasty)
{
// int nummaterials = m_materials.size();
int i;
@ -564,6 +623,8 @@ void RAS_MeshObject::SchedulePolygons(int drawingmode,RAS_IRasterizer* rasty)
RAS_MaterialBucket* bucket = *it;
bucket->SchedulePolygons(drawingmode);
if (bucket->GetPolyMaterial()->IsZSort())
m_zsort = true;
}
int numpolys = m_Polygons.size();
@ -582,17 +643,24 @@ void RAS_MeshObject::SchedulePolygons(int drawingmode,RAS_IRasterizer* rasty)
}
else
{
for (i=0;i<numpolys;i++)
if (!m_zsort)
{
RAS_Polygon* poly = m_Polygons[i];
if (poly->IsVisible())
for (i=0;i<numpolys;i++)
{
SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetMaterial()->GetPolyMaterial());
RAS_Polygon* poly = m_Polygons[i];
if (poly->IsVisible())
{
SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetMaterial()->GetPolyMaterial());
}
}
}
}
m_bModified = false;
}
// }
if (m_zsort)
{
SortPolygons(transform);
}
}

@ -135,6 +135,40 @@ class RAS_MeshObject
vector<class RAS_Polygon*> m_Polygons;
STR_String m_name;
static STR_String s_emptyname;
bool m_zsort;
struct polygonSlot
{
float m_z;
RAS_Polygon *m_poly;
polygonSlot(float z, RAS_Polygon* poly) :
m_z(z),
m_poly(poly)
{}
/**
* pnorm and pval form the plane equation that the distance from is used to
* sort against.
*/
polygonSlot(const MT_Vector3 &pnorm, const MT_Scalar &pval, RAS_MeshObject* mesh, RAS_Polygon* poly);
};
struct backtofront
{
bool operator()(const polygonSlot &a, const polygonSlot &b) const
{
return a.m_z < b.m_z;
}
};
struct fronttoback
{
bool operator()(const polygonSlot &a, const polygonSlot &b) const
{
return a.m_z > b.m_z;
}
};
protected:
GEN_Map<class RAS_IPolyMaterial,KX_ArrayOptimizer*> m_matVertexArrayS;
@ -184,7 +218,10 @@ public:
void DebugColor(unsigned int abgr);
void SortPolygons(const MT_Transform &transform);
void SchedulePolygons(
const MT_Transform &transform,
int drawingmode,
class RAS_IRasterizer* rasty
);