00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "xrb_engine2_polygon.hpp"
00012
00013 #include "xrb_gl.hpp"
00014
00015 namespace Xrb
00016 {
00017
00018 Float Engine2::Polygon::Area () const
00019 {
00020 Float area = 0.0f;
00021
00022 if (m_vertex_count < 3)
00023 return area;
00024
00025 for (Uint32 i = 0; i < m_vertex_count; ++i)
00026 area += GetVertex(i) & GetVertex((i + 1) % m_vertex_count);
00027
00028 return 0.5f * area;
00029 }
00030
00031 bool Engine2::Polygon::IsCounterclockwise () const
00032 {
00033
00034 if (m_vertex_count < 3)
00035 return true;
00036
00037
00038 for (Uint32 i = 0; i < m_vertex_count; ++i)
00039 {
00040 Float normal =
00041 (GetVertex((i + 1) % m_vertex_count) - GetVertex(i)) &
00042 (GetVertex((i + 2) % m_vertex_count) - GetVertex(i));
00043 if (normal < 0.0f)
00044 return false;
00045 }
00046
00047
00048 return true;
00049 }
00050
00051 bool Engine2::Polygon::IsConvex () const
00052 {
00053
00054 if (m_vertex_count <= 3)
00055 return true;
00056
00057
00058
00059 Float normal =
00060 (GetVertex(1) - GetVertex(0)) & (GetVertex(2) - GetVertex(0));
00061 bool triangle_is_counterclockwise = normal >= 0.0f;
00062
00063 for (Uint32 i = 1; i < m_vertex_count; ++i)
00064 {
00065 normal =
00066 (GetVertex((i + 1) % m_vertex_count) - GetVertex(i)) &
00067 (GetVertex((i + 2) % m_vertex_count) - GetVertex(i));
00068
00069
00070 if (triangle_is_counterclockwise && normal < 0.0f)
00071 return false;
00072 }
00073
00074
00075 return true;
00076 }
00077
00078 void Engine2::Polygon::Draw () const
00079 {
00080 ASSERT1(GL::Integer(GL_MATRIX_MODE) == GL_MODELVIEW);
00081 ASSERT1(GL::Boolean(GL_TEXTURE_2D));
00082
00083 glBindTexture(GL_TEXTURE_2D, m_texture->Handle());
00084
00085
00086 {
00087 FloatVector2 *vertex_array = new FloatVector2[m_vertex_count];
00088 FloatVector2 *texture_coord_array = new FloatVector2[m_vertex_count];
00089
00090 for (Uint32 i = 0; i < m_vertex_count; ++i)
00091 {
00092 texture_coord_array[i] = TextureCoordinate(i);
00093 vertex_array[i] = GetVertex(i);
00094 }
00095
00096 glEnableClientState(GL_VERTEX_ARRAY);
00097 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00098
00099 glVertexPointer(2, GL_FLOAT, 0, vertex_array);
00100
00101 glClientActiveTexture(GL_TEXTURE0);
00102 glTexCoordPointer(2, GL_FLOAT, 0, texture_coord_array);
00103 glClientActiveTexture(GL_TEXTURE1);
00104 glTexCoordPointer(2, GL_FLOAT, 0, texture_coord_array);
00105
00106 glDrawArrays(GL_TRIANGLE_FAN, 0, m_vertex_count);
00107
00108 glDisableClientState(GL_VERTEX_ARRAY);
00109 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00110
00111 delete[] vertex_array;
00112 }
00113 }
00114
00115 void Engine2::Polygon::CloneProperties (
00116 Polygon const *const source_polygon,
00117 FloatVector2 *const source_vertex_array,
00118 FloatVector2 *const destination_vertex_array)
00119 {
00120 ASSERT1(m_vertex_count == 0);
00121 ASSERT1(m_vertex_array == NULL);
00122 ASSERT1(!m_texture.IsValid());
00123
00124 ASSERT1(source_polygon != NULL);
00125 ASSERT1(source_polygon->m_vertex_count >= 3);
00126
00127 ASSERT1(destination_vertex_array != NULL);
00128 ASSERT1(source_vertex_array != NULL);
00129
00130 m_vertex_count = source_polygon->m_vertex_count;
00131 m_vertex_array = new Vertex[m_vertex_count];
00132 for (Uint32 i = 0; i < m_vertex_count; ++i)
00133 {
00134 m_vertex_array[i] = source_polygon->m_vertex_array[i];
00135 m_vertex_array[i].m_model_coordinate +=
00136 destination_vertex_array - source_vertex_array;
00137 }
00138
00139 m_texture = source_polygon->m_texture;
00140 m_area = source_polygon->m_area;
00141
00142 ASSERT1(IsCounterclockwise());
00143 ASSERT1(IsConvex());
00144 ASSERT1(!IsDegenerate());
00145 ASSERT1(m_texture.IsValid());
00146 }
00147
00148 void Engine2::Polygon::Read (
00149 Serializer &serializer,
00150 FloatVector2 *compound_vertex_array)
00151 {
00152 ASSERT1(serializer.GetIODirection() == IOD_READ);
00153 ASSERT1(compound_vertex_array != NULL);
00154
00155 ASSERT1(m_vertex_count == 0);
00156 ASSERT1(m_vertex_array == NULL);
00157 ASSERT1(!m_texture.IsValid());
00158
00159 m_vertex_count = serializer.ReadUint32();
00160 ASSERT1(m_vertex_count >= 3);
00161 m_vertex_array = new Vertex[m_vertex_count];
00162 for (Uint32 i = 0; i < m_vertex_count; ++i)
00163 {
00164 m_vertex_array[i].m_model_coordinate = compound_vertex_array + serializer.ReadUint32();
00165 serializer.ReadFloatVector2(&m_vertex_array[i].m_texture_coordinate);
00166 }
00167 m_texture =
00168 Singleton::ResourceLibrary().
00169 LoadPath<GLTexture>(GLTexture::Create, serializer.ReadStdString());
00170 m_area = Area();
00171
00172 ASSERT1(IsCounterclockwise());
00173 ASSERT1(IsConvex());
00174 ASSERT1(!IsDegenerate());
00175 ASSERT1(m_texture.IsValid());
00176 }
00177
00178 void Engine2::Polygon::Write (
00179 Serializer &serializer,
00180 FloatVector2 const *const compound_vertex_array) const
00181 {
00182 ASSERT1(serializer.GetIODirection() == IOD_WRITE);
00183 ASSERT1(compound_vertex_array != NULL);
00184 ASSERT1(m_vertex_count >= 3);
00185
00186 serializer.WriteUint32(m_vertex_count);
00187 for (Uint32 i = 0; i < m_vertex_count; ++i)
00188 {
00189 serializer.WriteUint32(m_vertex_array[i].m_model_coordinate - compound_vertex_array);
00190 serializer.WriteFloatVector2(m_vertex_array[i].m_texture_coordinate);
00191 }
00192 serializer.WriteStdString(m_texture.Path());
00193 }
00194
00195 }