//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

#include "giofx.h"

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

cObj::cObj(cScene* ptr, char* fileName)
{
	parent			= ptr;
	
	active			= 0;
	totObjects		= 0;
	subObj			= NULL;
	cullMode		= GL_CCW;
    drawMode        = GL_TRIANGLES;
	fogMode			= true;
	fixedMode		= 0;
	depthTest		= true;
	alphaTest		= 0;
	isLighted		= false;
	blendMode		= 0;
	additiveTexture = 0;
    
	offset.Clear();
	scale.Set(1,1,1);
	position.Set(0,0,0);
	rotation.Set(0,0,0);
	wrotation.Set(0,0,0);
	wrotoffset.Set(0,0,0);
	SetPickColor(0,0,0,255);
	
	transition.start_position.Clear();
	transition.end_position.Clear();
	transition.start_angle.Clear();
	transition.end_angle.Clear();
	transition.start_color.Clear();
	transition.end_color.Clear();
	transition.steps   = 0;
	transition.enabled = false;
	
	subObj			= NULL;

#ifdef USE_BULLET
	p_Shape			= NULL;
	p_Body			= NULL;
	p_constraint	= NULL;
	p_static		= true;
#endif	

#ifdef USE_BOX2D
	body			= NULL;
	for (int i=0;i<MAX_JOINT;i++)
	{
		revolute_joint[i]	= NULL;
		distance_joint[i]	= NULL;
		prismatic_joint[i]	= NULL;
        line_joint[i]       = NULL;
        
    #ifndef USE_BOX2D_DEPRECATED
        rope_joint          = NULL;
        gear_joint[i]       = NULL;
        weld_joint[i]       = NULL;
    #endif
	}
	p_static		= true;
#endif

#ifdef USE_3DFILES
	if (fileName)
	{
		if (strstr(fileName,"3ds"))
			TDSRead(fileName);
		else if (strstr(fileName,"gfx"))
			GFXLoad(fileName);
	}
#endif

}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

cObj::~cObj()
{

#ifdef USE_BULLET
	if (p_Body)
	{	
		plDeleteRigidBody(p_Body);
		p_Body = NULL;
	}
		
	if (p_Shape)
	{	
		//plDeleteShape(p_Shape);		
		p_Shape = NULL;
	}
#endif
#ifdef USE_BOX2D
	if (body)
		PhysicDestroy();
#endif

	for (int p=0;p<totObjects-1;p++)
	{
		if (subObj)
		{
			
			SAFE_FREE(subObj[p].map);
			SAFE_FREE(subObj[p].normal);
			SAFE_FREE(subObj[p].vertex);
			for (int q=subObj[p].totMaterials-1;q>-1;q--)
			{
				SAFE_FREE(subObj[p].mat[q].normal);
				SAFE_DELETE(parent->pTexture[subObj[p].mat[q].tex_diffuse]);
                //SAFE_DELETE(parent->pTexture[subObj[p].mat[q].tex_lightmap]);
				SAFE_FREE(subObj[p].mat[q].face);
			}
			SAFE_FREE(subObj[p].mat);		
		}	
	}
	SAFE_FREE(subObj);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::StartTransition(
	int steps, 
	cVertex start_pos,	 cVertex end_pos,
	cVertex start_angle, cVertex end_angle,
	cColor start_color,  cColor end_color)
{
	transition.start_position = start_pos;
	transition.end_position   = end_pos;
	transition.start_angle    = start_angle;
	transition.end_angle      = end_angle;
	transition.start_color    = start_color;
	transition.end_color      = end_color;
	transition.steps		  = steps;
	transition.curr_step	  = 0;
	transition.enabled		  = true;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::StepTransition()
{
	if (++transition.curr_step >= transition.steps)
	{
		transition.enabled = false;
		transition.curr_step = 0;
		
		if (transition.start_color != transition.end_color)
		{	
			SetColor(transition.end_color);
			if (transition.end_color.a <= 0.0f) //GIO
				this->active = false;
		}
		
		return;
	}

	if (transition.start_position != transition.end_position)
	{
		cVertex oldStart = transition.start_position;
		cVertex oldEnd   = transition.end_position;
		cVertex newPos = transition.start_position + ((transition.end_position - transition.start_position) / transition.steps ) * transition.curr_step;
		this->SetPosition(newPos);
		transition.start_position = oldStart;
		transition.end_position = oldEnd;
	}
	if (transition.start_angle != transition.end_angle)
	{
		cVertex newAngle = transition.start_angle + ((transition.end_angle - transition.start_angle) / transition.steps ) * transition.curr_step;
		this->SetAngle(newAngle.x,newAngle.y,newAngle.z);
	}
	if (transition.start_color != transition.end_color)
	{
		cColor oldStart = transition.start_color;
		cColor oldEnd   = transition.end_color;
		cColor newColor = transition.start_color + ((transition.end_color - transition.start_color) / transition.steps ) * transition.curr_step;
		this->SetColor(newColor);
		transition.start_color	 = oldStart;
		transition.end_color	 = oldEnd;
	}
}
void cObj::FadeRelativeAuto(int speed)
{
    if (subObj[0].mat[0].diffuse.a <= 0.0)
        FadeRelativeIn(speed);
    else if (subObj[0].mat[0].diffuse.a >= 1.0)
        FadeRelativeIn(speed);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::FadeRelativeOut(int speed)
{
    cVertex tt(0,0,0);
    StartTransition(speed,tt,tt,tt,tt,this->subObj[0].mat[0].diffuse,cColor(0,0,0,0));
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::FadeRelativeIn(int speed)
{
    cVertex tt(0,0,0);
    active = true;
    StartTransition(speed,tt,tt,tt,tt,this->subObj[0].mat[0].diffuse,cColor(1,1,1,1));
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::FadeOut(int speed)
{
    cVertex tt(0,0,0);
    StartTransition(speed,tt,tt,tt,tt,cColor(1,1,1,1),cColor(0,0,0,0));
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::FadeIn(int speed)
{
    cVertex tt(0,0,0);
    active = true;
    StartTransition(speed,tt,tt,tt,tt,cColor(0,0,0,0),cColor(1,1,1,1));
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetPickColor(GLubyte r,GLubyte g,GLubyte b,GLubyte a)
{
	
	pickColor[0] = r;
	pickColor[1] = g;
	pickColor[2] = b;
	pickColor[3] = a;
    if (r > 255)
        printf("*** WARNING pick color out of bound (%d) ***",r);
	
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetColor(float rr,float gg,float bb,float aa)
{
	for (int o=0; o<totObjects; o++)
		for (int m=0; m<subObj[o].totMaterials; m++)
			subObj[o].mat[m].diffuse.Set(rr,gg,bb,aa);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::SetColor(cColor tColor)
{
	SetColor(tColor.r,tColor.g,tColor.b,tColor.a);

}
/*
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::ApplyEnvmap(int s,int m)
{ 
	//tu1 env
	glActiveTexture(GL_TEXTURE1);
	if (subObj[s].mat[m].tex_diffuse)
	{
		//if (isEnvAdded)
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
		//else
		//	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MULT);
	}
    
	glEnable(GL_TEXTURE_2D);
    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);
    //glBindTexture(GL_TEXTURE_2D,parent->texData[subObj[s].mat[m].tex_envmap].memAddr);
	
	//tu0 text
	glActiveTexture(GL_TEXTURE0);
	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
	if (subObj[s].mat[m].tex_diffuse)
    {
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D,parent->texData[subObj[s].mat[m].tex].memAddr);
	}
    else
    {
		glDisable(GL_TEXTURE_2D);
	}
    
	glDrawElements(drawMode,subObj[s].mat[m].totFaces*3,GL_UNSIGNED_SHORT,subObj[s].mat[m].faceVis);
	
	//disable tu1
	glActiveTexture(GL_TEXTURE1);
	glDisable(GL_TEXTURE_2D);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);
	
	//enable tu0
	glActiveTexture(GL_TEXTURE0);
	glClientActiveTexture(GL_TEXTURE0); 
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glEnable(GL_TEXTURE_2D);
}
*/

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

int cObj::Render()
{
	if (!active)
		return 0;
	
#ifdef USE_VISIBILITY_TEST
    VisibilityTest();
    if (!isVisible)
        return;
#endif
    
#ifdef USE_BULLET
	if (!p_static)
		PhysicGetPos();
#endif

#ifdef USE_BOX2D
	if (!p_static && body->IsActive())
		PhysicGetPos();
#endif

	if (transition.enabled)
		StepTransition();
	
	PushPosition();
    glScalef(scale.x,scale.y,scale.z);
    
	if (!depthTest)
    {
		glDisable(GL_DEPTH_TEST);
        glDepthMask(false);
    }
    else
    {
        glEnable(GL_DEPTH_TEST);
        glDepthMask(true);
    }
    
	if (alphaTest > 0)
	{
		glEnable(GL_ALPHA_TEST);
		glAlphaFunc(GL_GEQUAL,alphaTest);
	}
	if (isLighted)
		glEnable(GL_LIGHTING);
	else
		glDisable(GL_LIGHTING);
    
	//cull
	if (cullMode==2)
	{	
		glDisable(GL_CULL_FACE);
	}
	else
	{
		glFrontFace(cullMode);
		glEnable(GL_CULL_FACE);
		glCullFace (GL_BACK);
	}
    
	int fog_enabled = false;
	if (!fogMode)
	{
		glGetIntegerv(GL_FOG, &fog_enabled);
		glDisable(GL_FOG);
	}
	

	switch(blendMode)
	{
		case 2:	glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);			break;
		case 3:	glBlendFunc(GL_DST_COLOR,GL_ONE);				break;
		case 4:	glBlendFunc(GL_SRC_ALPHA,GL_DST_COLOR);			break;
		case 5:	glBlendFunc(GL_SRC_ALPHA,GL_ONE);				break;
		case 6: glBlendFunc(GL_ONE,GL_ONE);						break;
		case 7: glBlendFunc(GL_SRC_COLOR,GL_DST_COLOR);			break;
		case 8: glBlendFunc(GL_DST_COLOR,GL_SRC_ALPHA);			break;
		case 9: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA );	break;
		case 10:glBlendFunc(GL_SRC_COLOR, GL_ZERO );			break;
        case 11:glBlendFunc(GL_DST_COLOR,GL_ZERO);              break;      //test 
        case 12:glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);    break;      //"screen"
        case 13:glBlendFunc(GL_ZERO, GL_SRC_COLOR);             break;      //"multiply"   
        case 14:glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);  break;   //???
        case 15:glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_SRC_COLOR);  break;   //???
        case 16:glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);       break;   //???
        case 17: glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA);           break;  //????
        case 18: //glBlendFunc(GL_CONSTANT_COLOR, GL_ONE);            break;  //????
        case 19: glBlendFunc(GL_ONE_MINUS_DST_COLOR,GL_ONE);        break;  //????
        case 99: glDisable(GL_BLEND);                               break;
        case 1:
		default:
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );		
			break;
            
	}

    if (additiveTexture!= 0)
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, additiveTexture);
    
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    
	for (int t=0;t<totObjects;t++)
#ifdef USE_VISIBILITY_TEST
        if (subObj[t].isVisible)
#endif
        {
            glTexCoordPointer(2,GL_FLOAT,0,subObj[t].map);
            glVertexPointer(3,GL_FLOAT,0,subObj[t].vertex);
            glNormalPointer(GL_FLOAT,0,subObj[t].normal);
            
            for (int m=0;m<subObj[t].totMaterials;m++)
            {
                glColor4f(
                          subObj[t].mat[m].diffuse.r,
                          subObj[t].mat[m].diffuse.g,
                          subObj[t].mat[m].diffuse.b,
                          subObj[t].mat[m].diffuse.a);
                
                //ApplyEnvmap
                int idx1 = subObj[t].mat[m].tex_diffuse;
                //int idx2 = subObj[t].mat[m].tex_envmap;
                
                if (parent->pTexture[idx1] && parent->pTexture[idx1]->size.h)
                {
                    glActiveTexture(GL_TEXTURE0);
                    glEnable(GL_TEXTURE_2D);
                    glBindTexture(GL_TEXTURE_2D,parent->pTexture[idx1]->memAddr);
                }
                else
                {
                    glActiveTexture(GL_TEXTURE0);
                    glDisable(GL_TEXTURE_2D);
                }
				
                /*
                //vedere ApplyEnvmap
                if (parent->pTexture[idx2] && parent->pTexture[idx2]->size.h)
                {
                    glActiveTexture(GL_TEXTURE1);
                    glEnable(GL_TEXTURE_2D);
                    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
                    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
                    glEnable(GL_TEXTURE_GEN_S);
                    glEnable(GL_TEXTURE_GEN_T);
                    glBindTexture(GL_TEXTURE_2D,parent->pTexture[idx2]->memAddr);
                }
                */
                
                glDrawElements(drawMode,subObj[t].mat[m].totFaces*3,GL_UNSIGNED_SHORT,subObj[t].mat[m].face);
                
                /*
                glActiveTexture(GL_TEXTURE1_ARB);
                glDisable(GL_TEXTURE_2D);
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                glDisable(GL_TEXTURE_GEN_S);
                glDisable(GL_TEXTURE_GEN_T);
                glActiveTexture(GL_TEXTURE0);
                */
            }
        }
    
	glDisableClientState(GL_NORMAL_ARRAY);
    glScalef(parent->scale.x,parent->scale.y,parent->scale.z);
	PopPosition();
	
	glAlphaFunc(GL_GEQUAL,0.1);
	glDisable(GL_ALPHA_TEST);
    glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );	
	glEnable(GL_DEPTH_TEST);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glDepthMask(true);
    
	if (fog_enabled)
		glEnable(GL_FOG);
	
	return 1;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

int cObj::PickRender()
{

	if (!active || pickColor[0] == 0)
		return 0;
	
	PushPosition();

	//cull
	if (cullMode==2)
	{	
		glDisable(GL_CULL_FACE);
	}
	else
	{
		glFrontFace(cullMode);
		glEnable(GL_CULL_FACE);
		glCullFace (GL_BACK);
	}
	
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glColor4ub(pickColor[0],pickColor[1],pickColor[2],pickColor[3]);
	glDisable(GL_TEXTURE_2D);
	
	for (int t=0;t<totObjects;t++)
	{
		glVertexPointer(3,GL_FLOAT,0,subObj[t].vertex);
			
		for (int m=0;m<subObj[t].totMaterials;m++)
			glDrawElements(drawMode,subObj[t].mat[m].totFaces*3,GL_UNSIGNED_SHORT,subObj[t].mat[m].face);
	}
	
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
	PopPosition();
	
	return 1;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetBlend(int mode,int additive)
{
    additiveTexture = additive;
	blendMode       = mode;
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetPosition(cVertex tPosition)
{
	
	position = tPosition;
	UpdateBoundBoxes();

/*
#ifdef USE_BULLET	
	if (p_Body)
		PhysicSetPos();
#endif

#ifdef USE_BOX2D
	if (body)
    {
        b2Vec2 position;
        position.Set(position.x,position.y);
        body->SetTransform(position, rotation.z);
    }
#endif
*/

}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetPosition(cVertex tPosition,cVertex tAngle)
{
	
	position = tPosition;
	rotation = tAngle;
	UpdateBoundBoxes();

/*
#ifdef USE_BULLET	
	if (p_Body)
		PhysicSetPos();
#endif

#ifdef USE_BOX2D
	if (body)
    {
        b2Vec2 bPosition;
        bPosition.Set(position.x,position.y);
        body->SetTransform(bPosition, tAngle.z);
    }
#endif
*/

}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetPosition(float mx,float my,float mz)
{
	position.Set(mx,my,mz);
	UpdateBoundBoxes();

/*
#ifdef USE_BULLET	
	if (p_Body)
		PhysicSetPos();
#endif

#ifdef USE_BOX2D
	if (body)
    {
        b2Vec2 position;
        position.Set(mx,my);
        body->SetTransform(position, rotation.z);
    }
#endif
*/
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetAngle(float rx,float ry,float rz)
{
	
	rotation.Set(rx,ry,rz);
	UpdateBoundBoxes();
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetAngle(cVertex rot)
{
	
	rotation = rot;
	UpdateBoundBoxes();
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetWorldAngle(float rx,float ry,float rz,float ox,float oy,float oz)
{
	//TODO non usati ora
	wrotation.Set(rx,ry,rz);
	wrotoffset.Set(ox,oy,oz);
	UpdateBoundBoxes();

}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetTempScale(float tScale)
{
	for (int t=0;t<this->totObjects;t++)		
	{	
        subObj[t].vertex[0].x -= tScale;    subObj[t].vertex[0].y += tScale;
        subObj[t].vertex[1].x += tScale;    subObj[t].vertex[1].y += tScale;
        subObj[t].vertex[2].x += tScale;    subObj[t].vertex[2].y -= tScale;
        subObj[t].vertex[3].x -= tScale;    subObj[t].vertex[3].y -= tScale;
        
    }
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
float cObj::GetExtentX()
{
    return subObj[0].vertex[1].x;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
float cObj::GetExtentY()
{
    return subObj[0].vertex[1].y;
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::ZeroVertices()
{
	for (int t=0;t<this->totObjects;t++)		
	{	
        subObj[t].vertex[0].x = 0;    subObj[t].vertex[0].y = 0;
        subObj[t].vertex[1].x = 0;    subObj[t].vertex[1].y = 0;
        subObj[t].vertex[2].x = 0;    subObj[t].vertex[2].y = 0;
        subObj[t].vertex[3].x = 0;    subObj[t].vertex[3].y = 0;
    }
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetTempScale(float tScaleX,float tScaleY)
{
	for (int t=0;t<this->totObjects;t++)		
	{	
        subObj[t].vertex[0].x -= tScaleX;    subObj[t].vertex[0].y += tScaleY;
        subObj[t].vertex[1].x += tScaleX;    subObj[t].vertex[1].y += tScaleY;
        subObj[t].vertex[2].x += tScaleX;    subObj[t].vertex[2].y -= tScaleY;
        subObj[t].vertex[3].x -= tScaleX;    subObj[t].vertex[3].y -= tScaleY;
    }
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetScale(float tScale)
{
    cVertex newScale;
	newScale.Set(tScale,tScale,tScale);
		
	for (int t=0;t<this->totObjects;t++)		
		for (int v=0;v<this->subObj[t].totVertex;v++)
			subObj[t].vertex[v] *= newScale;

	CalcNormals();
	CreateBoundBoxes();
	UpdateBoundBoxes();
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetScale(float scaleX,float scaleY,float scaleZ)
{
	cVertex newScale;
    newScale.Set(scaleX,scaleY,scaleZ);
		
	for (int t=0;t<this->totObjects;t++)		
		for (int v=0;v<this->subObj[t].totVertex;v++)
			subObj[t].vertex[v] *= newScale;

	CalcNormals();
	CreateBoundBoxes();
	UpdateBoundBoxes();
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetScalef(float scaleX,float scaleY,float scaleZ)
{
	scale.Set(scaleX,scaleY,scaleZ);
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetOffset(bool excludeZero,float scaleX,float scaleY,float scaleZ)
{
	offset.Set(scaleX,scaleY,scaleZ);
	
	for (int t=0;t<this->totObjects;t++)		
		for (int v=0;v<this->subObj[t].totVertex;v++)
		{
			if (!excludeZero || subObj[t].vertex[v].x > 0) subObj[t].vertex[v].x += offset.x;
			if (!excludeZero || subObj[t].vertex[v].y > 0) subObj[t].vertex[v].y += offset.y;
			if (!excludeZero || subObj[t].vertex[v].z > 0) subObj[t].vertex[v].z += offset.z;
		}
		
	CalcNormals();
	CreateBoundBoxes();
	UpdateBoundBoxes();
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::SetActive(bool activate)
{

	active = activate;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::SetFixed(int fixMode)
{
	fixedMode = fixMode;

}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::PushPosition()
{
	
	glPushMatrix();
	
	if (fixedMode)
	{
		if (fixedMode > 1)
        {
			glLoadIdentity();
		}
        else
			glTranslatef(-parent->position.x,-parent->position.y,-parent->position.z);
	}

	glTranslatef(position.x,position.y,position.z);
    
#ifdef USE_BULLET
	if (!p_Body)
	{
		glRotatef(rotation.x,1,0,0);
		glRotatef(rotation.y,0,1,0);
		glRotatef(rotation.z,0,0,1);
	}
	else
	{
		glRotatef(rotation.z,0,0,1);
		glRotatef(rotation.y,0,1,0);
		glRotatef(rotation.x,1,0,0);
	}
#else
	glRotatef(rotation.x,1,0,0);
	glRotatef(rotation.y,0,1,0);
	glRotatef(rotation.z,0,0,1);
#endif
	
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::PopPosition()
{

	glPopMatrix();
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cObj::CalcNormals()
{
#ifdef USE_NORMALS

	cVertex p,q;
	for (int t=0;t<totObjects;t++)
		for (int m=0;m<subObj[t].totMaterials;m++)
			for (int f=0;f<subObj[t].mat[m].totFaces;f++)
			{
				p = subObj[t].vertex[subObj[t].mat[m].face[f].v[1]] -
				    subObj[t].vertex[subObj[t].mat[m].face[f].v[0]];

				q = subObj[t].vertex[subObj[t].mat[m].face[f].v[2]] -
				    subObj[t].vertex[subObj[t].mat[m].face[f].v[0]];
   
				subObj[t].mat[m].normal[f].Cross(p,q);
				subObj[t].mat[m].normal[f].Normalize(); 

				if (cullMode == GL_CW)
					subObj[t].mat[m].normal[f] *= -1;		
			}
    
    int shared = 0;
	cVertex sum;
	for (int t=0;t<totObjects;t++)
		for (int v=0;v<subObj[t].totVertex;v++)
		{
            subObj[t].normal[v].Clear();
            sum.Clear();
			shared = 0;
            
			for (int m=0;m<subObj[t].totMaterials;m++)
				for (int f=0;f<subObj[t].mat[m].totFaces;f++)
					if (subObj[t].mat[m].face[f].v[0]==v || 
						subObj[t].mat[m].face[f].v[1]==v || 
						subObj[t].mat[m].face[f].v[2]==v)
						{
							sum += subObj[t].mat[m].normal[f];
                            shared++;
						}

            subObj[t].normal[v] = (sum / (float) shared);
			subObj[t].normal[v].Normalize();
		}
#endif

}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::SetDrawMode(bool filled)
{
	if (!filled)
		this->drawMode = GL_LINES;
	else
		this->drawMode = GL_TRIANGLES;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------



