#include <glib/gslist.h>
#include "preferences.h"
#include "brush_primit.h"
+#include "signal/signal.h"
-std::set<Callback> g_patchTextureChangedCallbacks;
+Signal0 g_patchTextureChangedCallbacks;
-void Patch_addTextureChangedCallback(const Callback& callback)
+void Patch_addTextureChangedCallback(const SignalHandler& handler)
{
- g_patchTextureChangedCallbacks.insert(callback);
+ g_patchTextureChangedCallbacks.connectLast(handler);
}
void Patch_textureChanged()
{
- std::for_each(g_patchTextureChangedCallbacks.begin(), g_patchTextureChangedCallbacks.end(), CallbackInvoke());
+ g_patchTextureChangedCallbacks();
}
pCurve->crd = vector3_mid(pCurve->left, pCurve->right);
}
-void BezierCurveTree_FromCurveList(BezierCurveTree *pTree, GSList *pCurveList)
+const std::size_t PATCH_MAX_SUBDIVISION_DEPTH = 16;
+
+void BezierCurveTree_FromCurveList(BezierCurveTree *pTree, GSList *pCurveList, std::size_t depth = 0)
{
GSList *pLeftList = 0;
GSList *pRightList = 0;
}
}
- if(pLeftList != 0 && pRightList != 0)
+ if(pLeftList != 0 && pRightList != 0 && depth != PATCH_MAX_SUBDIVISION_DEPTH)
{
pTree->left = new BezierCurveTree;
pTree->right = new BezierCurveTree;
- BezierCurveTree_FromCurveList(pTree->left, pLeftList);
- BezierCurveTree_FromCurveList(pTree->right, pRightList);
+ BezierCurveTree_FromCurveList(pTree->left, pLeftList, depth + 1);
+ BezierCurveTree_FromCurveList(pTree->right, pRightList, depth + 1);
+ for(GSList* l = pLeftList; l != 0; l = g_slist_next(l))
{
- GSList *l;
- for (l = pLeftList; l != 0; l = g_slist_next(l))
delete (BezierCurve*)l->data;
+ }
- for (l = pRightList; l != 0; l = g_slist_next(l))
+ for(GSList* l = pRightList; l != 0; l = g_slist_next(l))
+ {
delete (BezierCurve*)l->data;
}
return (i%2 || (i/width)%2) ? colour_inside : colour_corner;
}
-void Patch::UpdateCachedData()
+inline bool float_valid(float f)
+{
+ return f == f;
+}
+
+bool Patch::isValid() const
{
if(!m_width || !m_height)
+ {
+ return false;
+ }
+
+ for(const_iterator i = m_ctrl.begin(); i != m_ctrl.end(); ++i)
+ {
+ if(!float_valid((*i).m_vertex.x())
+ || !float_valid((*i).m_vertex.y())
+ || !float_valid((*i).m_vertex.z())
+ || !float_valid((*i).m_texcoord.x())
+ || !float_valid((*i).m_texcoord.y()))
+ {
+ globalErrorStream() << "patch has invalid control points\n";
+ return false;
+ }
+ }
+ return true;
+}
+
+void Patch::UpdateCachedData()
+{
+ m_ctrl_vertices.clear();
+ m_lattice_indices.clear();
+
+ if(!isValid())
+ {
+ m_tess.m_numStrips = 0;
+ m_tess.m_lenStrips = 0;
+ m_tess.m_nArrayHeight = 0;
+ m_tess.m_nArrayWidth = 0;
+ m_tess.m_curveTreeU.resize(0);
+ m_tess.m_curveTreeV.resize(0);
+ m_tess.m_indices.resize(0);
+ m_tess.m_vertices.resize(0);
+ m_tess.m_arrayHeight.resize(0);
+ m_tess.m_arrayWidth.resize(0);
+ m_aabb_local = AABB();
return;
+ }
+
BuildTesselationCurves(ROW);
BuildTesselationCurves(COL);
BuildVertexArray();
IndexBuffer ctrl_indices;
- m_ctrl_vertices.clear();
- m_lattice_indices.clear();
-
m_lattice_indices.reserve(((m_width * (m_height - 1)) + (m_height * (m_width - 1))) << 1);
ctrl_indices.reserve(m_ctrlTransformed.size());
{
}
}
+const std::size_t PATCH_MAX_VERTEX_ARRAY = 1048576;
+
void Patch::BuildVertexArray()
{
const std::size_t strideU = 1;