// Triangulate a no convex polygon void glc::triangulatePolygon(QList<GLuint>* pIndexList, const QList<float>& bulkList) { int size= pIndexList->size(); if (polygonIsConvex(pIndexList, bulkList)) { QList<GLuint> indexList(*pIndexList); pIndexList->clear(); for (int i= 0; i < size - 2; ++i) { pIndexList->append(indexList.at(0)); pIndexList->append(indexList.at(i + 1)); pIndexList->append(indexList.at(i + 2)); } } else { // Get the polygon vertice QList<GLC_Point3d> originPoints; QHash<int, int> indexMap; QList<int> face; GLC_Point3d currentPoint; int delta= 0; for (int i= 0; i < size; ++i) { const int currentIndex= pIndexList->at(i); currentPoint= GLC_Point3d(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2)); if (!originPoints.contains(currentPoint)) { originPoints.append(GLC_Point3d(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2))); indexMap.insert(i - delta, currentIndex); face.append(i - delta); } else { qDebug() << "Multi points"; ++delta; } } // Values of PindexList must be reset pIndexList->clear(); // Update size size= size - delta; // Check new size if (size < 3) return; //-------------- Change frame to mach polygon plane // Compute face normal const GLC_Point3d point1(originPoints[0]); const GLC_Point3d point2(originPoints[1]); const GLC_Point3d point3(originPoints[2]); const GLC_Vector3d edge1(point2 - point1); const GLC_Vector3d edge2(point3 - point2); GLC_Vector3d polygonPlaneNormal(edge1 ^ edge2); polygonPlaneNormal.normalize(); // Create the transformation matrix GLC_Matrix4x4 transformation; GLC_Vector3d rotationAxis(polygonPlaneNormal ^ Z_AXIS); if (!rotationAxis.isNull()) { const double angle= acos(polygonPlaneNormal * Z_AXIS); transformation.setMatRot(rotationAxis, angle); } QList<GLC_Point2d> polygon; // Transform polygon vertexs for (int i=0; i < size; ++i) { originPoints[i]= transformation * originPoints[i]; // Create 2d vector polygon << originPoints[i].toVector2d(Z_AXIS); } // Create the index QList<int> index= face; const bool faceIsCounterclockwise= isCounterclockwiseOrdered(polygon); if(!faceIsCounterclockwise) { //qDebug() << "face Is Not Counterclockwise"; const int max= size / 2; for (int i= 0; i < max; ++i) { polygon.swap(i, size - 1 -i); int temp= face[i]; face[i]= face[size - 1 - i]; face[size - 1 - i]= temp; } } QList<int> tList; triangulate(polygon, index, tList); size= tList.size(); for (int i= 0; i < size; i+= 3) { // Avoid normal problem if (faceIsCounterclockwise) { pIndexList->append(indexMap.value(face[tList[i]])); pIndexList->append(indexMap.value(face[tList[i + 1]])); pIndexList->append(indexMap.value(face[tList[i + 2]])); } else { pIndexList->append(indexMap.value(face[tList[i + 2]])); pIndexList->append(indexMap.value(face[tList[i + 1]])); pIndexList->append(indexMap.value(face[tList[i]])); } } Q_ASSERT(size == pIndexList->size()); } }
void XMLParserCollisionsMap::parse(DataUnion& data) { std::vector<StructCollision*>* result = new std::vector<StructCollision*>(); //get root node tinyxml2::XMLElement* detailsMap = doc->FirstChildElement("map"); if (detailsMap == nullptr) { std::cout << "Vacio?" << std::endl; } //get the node of collisions tinyxml2::XMLElement* collisions = detailsMap->FirstChildElement("objectgroup"); //get the object/collision tinyxml2::XMLElement* object = collisions->FirstChildElement("object"); while (object) { //creo el objeto colisionable a crear StructCollision* collisionObject = new StructCollision(); collisionObject->vertices = new sf::VertexArray(); //get the position sf::Vector2f position(object->DoubleAttribute("x"), object->DoubleAttribute("y")); collisionObject->position = position; collisionObject->typeCollision = object->Attribute("type"); if(collisionObject->typeCollision.compare("ChangeLevel")==0){ collisionObject->data=new std::string(object->Attribute("level")); }else{ collisionObject->data=nullptr; } //get the points tinyxml2::XMLElement* vertices = object->FirstChildElement("polyline"); //recojo los puntos char* points = strdup(vertices->Attribute("points")); //trato la tira de puntos char* number = strtok(points, " ,"); sf::Vertex vertex; vertex.color = sf::Color::Red; bool isX = true; while (number != nullptr) { if (isX) { vertex = sf::Vertex(); vertex.position.x = atof(number); } else { vertex.position.y = atof(number); collisionObject->vertices->append(vertex); } isX = !isX; number = strtok(nullptr, " ,"); } //compruebo que el poligono esté bien formado //assert(polygonIsConvex(collisionObject)); if (!polygonIsConvex(collisionObject)) { std::cout << "No es convexo" << std::endl; } result->push_back(collisionObject); object = object->NextSiblingElement("object"); } data.collisions = result; }