#ifdef _MSC_VER
#include "..\..\include\oag\OAGPrimitives.h"
#endif
oag::OAGPrimitives::OAGPrimitives(void)
:m_GeometryType( GL_LINES )
,m_GeometryData(NULL)
,m_ArraySize(0)
,m_nIndices(NULL)
,m_nVectorPos(0)
{
}
oag::OAGPrimitives::~OAGPrimitives(void)
{
if( m_GeometryData )
delete[] m_GeometryData;
if( m_nIndices )
delete[] m_nIndices;
}
//Operations
void oag::OAGPrimitives::AddVertex(float x, float y, float z)
{
m_GeometryData[m_nVectorPos] = oag::OAGVector3f(x, y, z) ;
m_nVectorPos++;
switch( m_GeometryType )
{
case GL_TRIANGLES:
case GL_TRIANGLE_FAN:
case GL_TRIANGLE_STRIP:
{
SetIndiceSize( GetVertexCount() );
}
break;
}
}
void oag::OAGPrimitives::SetArraySize(int arraySize)
{
if( m_GeometryData )
delete[] m_GeometryData;
m_nVectorPos = 0;
m_ArraySize = arraySize;
m_GeometryData = NULL;
m_GeometryData = new oag::OAGVector3f[m_ArraySize];
}
void oag::OAGPrimitives::SetIndiceSize(int indiceSize)
{
if( m_nIndices )
delete[] m_nIndices;
m_nIndices = NULL;
m_nIndices = new GLubyte[m_ArraySize];
for(int i=0; i < indiceSize; i++ )
m_nIndices[i] = i;
}
//Checks if the objects is selected by mouse point
bool oag::OAGPrimitives::IntersectsWithCursorInPoint(int x, int y)
{
if(GetVertexCount() < 2)
return false;
//Defining rect sides from x, y
oag::OAGVector3f a, b, c, d;
float size = 2.f;
bool bIntersect = false;
a.SetVertex(x-size, y-size, 0);
b.SetVertex(x-size, y+size, 0);
c.SetVertex(x+size, y+size, 0);
d.SetVertex(x+size, y-size, 0);
switch( m_GeometryType )
{
case GL_LINES:
case GL_LINE_LOOP:
case GL_LINE_STRIP:
{
for( int i=0; i< GetVertexCount()-1; ++i)
{
if(!bIntersect)
{
oag::OAGVector3f vec1 = m_GeometryData[i];
oag::OAGVector3f vec2 = m_GeometryData[i+1];
if( !LineIntersection(&vec1, &vec2, &a, &b ) )
{
if( !LineIntersection(&vec1, &vec2, &b, &c) )
{
if( !LineIntersection(&vec1, &vec2, &c, &d) )
{
if( LineIntersection(&vec1, &vec2, &d, &a) )
{
bIntersect = true;break;
}
}
else { bIntersect = true; break; }
}
else { bIntersect = true; break; }
}
else { bIntersect = true; break; }
}
}
this->SetSelected(bIntersect);
}
break;
}
return IsSelected();
}
//Virtual
void oag::OAGPrimitives::OnDraw()
{
if( m_ArraySize < 1 )
return;
::glPushMatrix();
::glLoadIdentity();
::glColor4ubv( m_Color.GetColor4ubv() );
::glPolygonMode(m_PolygonFace, m_PolygonMode);
::glTranslated(m_position.m_X, m_position.m_Y, m_position.m_Z);
switch( m_GeometryType )
{
case GL_LINES:
case GL_LINE_LOOP:
case GL_LINE_STRIP:
case GL_POINTS:
case GL_QUADS:
{
::glEnableClientState(GL_VERTEX_ARRAY);
::glVertexPointer(3, GL_FLOAT, 0, m_GeometryData);
::glDrawArrays( m_GeometryType, 0, m_ArraySize );
::glDisableClientState(GL_VERTEX_ARRAY);
}
break;
case GL_TRIANGLES:
case GL_TRIANGLE_FAN:
case GL_TRIANGLE_STRIP:
{
::glEnableClientState(GL_VERTEX_ARRAY);
::glVertexPointer(3, GL_FLOAT, 0, m_GeometryData);
::glDrawElements(m_GeometryType, GetVertexCount(), GL_UNSIGNED_BYTE, m_nIndices);
::glDisableClientState(GL_VERTEX_ARRAY);
}
break;
}
::glPopMatrix();
}
void oag::OAGPrimitives::ReadNodeXML(CXmlNode* pNode)
{
oag::OAGObject::ReadNodeXML( pNode );
CXmlNode* pNodeGeometryType = NULL;
pNodeGeometryType = pNode->GetNode("Lines");
if ( pNodeGeometryType )
SetGeometryType(GL_LINES);
if ( pNodeGeometryType == NULL )
{
pNodeGeometryType = pNode->GetNode("IndexedLines");
if ( pNodeGeometryType )
{
if ( pNodeGeometryType->GetAttribute("Closed").compare("False") == 0 )
SetGeometryType(GL_LINE_STRIP);
else
SetGeometryType(GL_LINE_LOOP);
}
}
if ( pNodeGeometryType == NULL )
{
pNodeGeometryType = pNode->GetNode("Rects");
if ( pNodeGeometryType )
SetGeometryType(GL_QUADS);
}
if ( pNodeGeometryType == NULL )
{
pNodeGeometryType = pNode->GetNode("Triangles");
if ( pNodeGeometryType )
SetGeometryType(GL_TRIANGLES);
}
if ( pNodeGeometryType == NULL )
{
pNodeGeometryType = pNode->GetNode("Points");
if ( pNodeGeometryType )
SetGeometryType(GL_POINTS);
}
if ( pNodeGeometryType )
{
//Creating the coordinates
CXmlNode* pNodeCoords = pNodeGeometryType->GetNode("Coordinates");
if ( pNodeCoords )
{
CXmlNodeList* pNodePoints = pNodeCoords->GetNodeList();
if ( pNodePoints )
{
if ( pNodePoints->Count() > 0 )
{
SetArraySize( pNodePoints->Count() );
for( std::vector<int>::size_type i = 0; i < pNodePoints->Count(); ++i )
{
float x = (float)atof ( pNodePoints->GetAt(i)->GetAttribute("x").c_str() );
float y = (float)atof ( pNodePoints->GetAt(i)->GetAttribute("y").c_str() );
float z = (float)atof ( pNodePoints->GetAt(i)->GetAttribute("z").c_str() );
AddVertex(x, y, z);
}
}
delete pNodePoints;
}
}
}
}
void oag::OAGPrimitives::SaveNodeXML(CXmlNode* pNode)
{
CXmlNode* pNodePrimitive = new CXmlNode("Primitive");
pNode->AppendChild( pNodePrimitive );
pNodePrimitive->AddAttribute( "Name", m_strName );
//Creating the color node
pNodePrimitive->AppendChild( CreateNodeColor() );
if ( m_ArraySize > 0 )
{
CXmlNode* pNodeGeometry = NULL;
//Creating the node for the primitive type
switch( m_GeometryType )
{
case GL_POINTS:
{
pNodeGeometry = new CXmlNode("Points");
pNodePrimitive->AppendChild( pNodeGeometry );
}
break;
case GL_LINES:
{
pNodeGeometry = new CXmlNode("Lines");
pNodePrimitive->AppendChild( pNodeGeometry );
}
break;
case GL_LINE_LOOP:
case GL_LINE_STRIP:
{
pNodeGeometry = new CXmlNode("IndexedLines");
pNodePrimitive->AppendChild( pNodeGeometry );
bool bClosed = ( m_GeometryType == GL_LINE_STRIP ) ? false : true;
std::string strClosed = ( bClosed ) ? "True" : "False";
pNodeGeometry->AddAttribute("Closed", strClosed );
}
break;
case GL_QUADS:
{
pNodeGeometry = new CXmlNode("Rects");
pNodePrimitive->AppendChild( pNodeGeometry );
}
break;
case GL_TRIANGLES:
{
pNodeGeometry = new CXmlNode("Triangles");
pNodePrimitive->AppendChild( pNodeGeometry );
}
break;
}
CXmlNode* pNodeCoordinates = new CXmlNode("Coordinates");
pNodeGeometry->AppendChild( pNodeCoordinates );
//Creating the coordinates
for( int i=0; i < GetVertexCount(); ++i )
{
CXmlNode* pNodePoints = CreateVectorNodeAttribute( &m_GeometryData[i], "Point");
pNodeCoordinates->AppendChild( pNodePoints );
}
}
}