X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=radiant%2Fpatch.cpp;h=c7b6344f4a469adf22b2f0362acc69b3cbc5c9ac;hp=80ffe35142058f2a07717ecec9fc926e72d8f1b0;hb=06eb8cc3a4046af318da7f7b9fae1c04be8c0380;hpb=d617f066bc8f3b5a852859e7d4be3a29bca69b89 diff --git a/radiant/patch.cpp b/radiant/patch.cpp index 80ffe351..c7b6344f 100644 --- a/radiant/patch.cpp +++ b/radiant/patch.cpp @@ -118,7 +118,9 @@ void BezierInterpolate(BezierCurve *pCurve) 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; @@ -146,19 +148,20 @@ void BezierCurveTree_FromCurveList(BezierCurveTree *pTree, GSList *pCurveList) } } - 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; } @@ -208,10 +211,54 @@ inline const Colour4b& colour_for_index(std::size_t i, std::size_t width) 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(); @@ -219,9 +266,6 @@ void Patch::UpdateCachedData() 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()); { @@ -2424,6 +2468,8 @@ void Patch::accumulateVertexTangentSpace(std::size_t index, Vector3 tangentX[6], } } +const std::size_t PATCH_MAX_VERTEX_ARRAY = 1048576; + void Patch::BuildVertexArray() { const std::size_t strideU = 1;