void Collider::_copyFrom(const ComponentBase *model) { auto m = (Collider*)model; if (m->getColliderType() == Physics::ColliderType::Mesh) { init(m->getColliderType(), m->getMesh()); } else { init(m->getColliderType(), ""); } #ifdef EDITOR_ENABLED editorUpdate(); if (editorStruct) { editorStruct->copyDatas(m); } Link *link = entity.getLinkPtr(); auto p = scaleFromMat4(link->getGlobalTransform()); //scale(p / getSize()); #else setMaterial(m->getMaterial()->getName()); setAsTrigger(m->isATrigger()); setFilterGroup(m->getFilterGroup()); setCenter(m->getCenter()); setHeight(m->getHeight()); setRadius(m->getRadius()); setSize(m->getSize()); setMesh(m->getMesh()); if (m->isConvex()) setAsConvex(); else if (m->isConcave()) setAsConcave(); #endif }
/* private */ bool BufferInputLineSimplifier::isDeletable(int i0, int i1, int i2, double distanceTol) const { const Coordinate& p0 = inputLine[i0]; const Coordinate& p1 = inputLine[i1]; const Coordinate& p2 = inputLine[i2]; if (! isConcave(p0, p1, p2)) return false; if (! isShallow(p0, p1, p2, distanceTol)) return false; // MD - don't use this heuristic - it's too restricting // if (p0.distance(p2) > distanceTol) return false; return isShallowSampled(p0, p1, i0, i2, distanceTol); }
void Collider::setAsConvex(void) { assert(collider != nullptr && "Invalid Collider"); switch (getColliderType()) { case Physics::ColliderType::Mesh: if (isConcave()) { collider->getAsMeshColliderInterface()->setAsConvex(); scale(entity->getLink().getScale()); } break; default: break; } }
void Detection::doFacialComponentsExtractionSide(FaceGeometry& faceGeometry, const std::vector<ContourInfo>& componentContourInfo, const std::vector<ContourInfo>& faceContourInfo) { // we need at least 3 elements (left & right eye, mouth) if (componentContourInfo.size()<1 || faceContourInfo.size()<1) { throw std::exception("we need at least 1 region for classification as eye (side image)"); } const ContourInfo& eye = componentContourInfo[0]; const ContourInfo& face = faceContourInfo[0]; faceGeometry.setDetectedPoint(FaceGeometry::SideEye, cv::Point2d(eye.cogX, eye.cogY)); // find bounding polygon with at least 5 vertices std::vector<cv::Point> polygonPoints; double precission = 50.0; while (polygonPoints.size() < 5) { cv::approxPolyDP(face.contour, polygonPoints, precission, true); precission = precission / 2; } // nose tip is rightmost point (of this polygon) size_t noseIdx = 0; faceGeometry.setDetectedPoint(FaceGeometry::SideNoseTip, cv::Point2d(0, 0)); for (size_t i = 0; i < polygonPoints.size(); ++i) { if (polygonPoints[i].x > faceGeometry.getDetectedPoint(FaceGeometry::SideNoseTip).x) { faceGeometry.setDetectedPoint(FaceGeometry::SideNoseTip, polygonPoints[i]); noseIdx = i; } } // find chin: which direction must be searched for in the polygon? bool incIdx = false; const size_t numPolygonPoints = polygonPoints.size(); if (polygonPoints[(noseIdx + 1) % numPolygonPoints].y > faceGeometry.getDetectedPoint(FaceGeometry::SideNoseTip).y) { incIdx = true; } // search for the following pattern: find a convex and a neighboured concave polygon part under the nose faceGeometry.setDetectedPoint(FaceGeometry::SideChin, cv::Point2d(0, 0)); for (size_t i = noseIdx, j = 0; j<numPolygonPoints; incIdx ? ++i : --i, ++j) { // don't check the nose itself if (j==0) { continue; } // get prev, curr and next point cv::Point prevprev = polygonPoints[(incIdx ? (i - 2) : (i + 2)) % numPolygonPoints]; cv::Point prev = polygonPoints[(incIdx ? (i - 1) : (i + 1)) % numPolygonPoints]; cv::Point curr = polygonPoints[i % numPolygonPoints]; cv::Point next = polygonPoints[(incIdx ? (i + 1) : (i - 1)) % numPolygonPoints]; if (isConcave(prev, curr, next) && !isConcave(prevprev, prev, curr)) { faceGeometry.setDetectedPoint(FaceGeometry::SideChin, prev); break; } } // find back side of head const cv::Point chinPoint = faceGeometry.getDetectedPoint(FaceGeometry::SideChin); cv::Point backPoint; for (int x = 0; x<m_FaceExtracted[sideImgNr].cols; ++x) { if (m_FaceExtracted[sideImgNr].at<unsigned char>(cv::Point(x, chinPoint.y))!=0) { backPoint.x = x; backPoint.y = chinPoint.y; break; } } faceGeometry.setDetectedPoint(FaceGeometry::SideBack, backPoint); // create face mask cv::Mat mask(imgSize, imgSize, CV_8U); mask.setTo(0); cv::drawContours(mask, std::vector<std::vector<cv::Point> > {face.contour}, 0, 255, -1); m_FaceMask.push_back(mask); // show debug info cv::Mat tmp = getCopyOfOriginal(sideImgNr); cv::drawContours(tmp, std::vector<std::vector<cv::Point> > {eye.contour}, 0, cv::Scalar(255, 0, 0), -1); dbgShow(tmp, "doFacialComponentsExtractionSide"); // and the polygon cv::Mat tmpChin = cv::Mat::zeros(imgSize, imgSize, CV_8UC3); cv::drawContours(tmpChin, std::vector<std::vector<cv::Point> > {face.contour}, 0, cv::Scalar(100, 100, 100), -1); cv::RNG rng(0); for (size_t i = 0; i < numPolygonPoints; ++i) { std::cout << "Point: " << polygonPoints[i] << "\n"; cv::line(tmpChin, polygonPoints[i], polygonPoints[(i + 1) % numPolygonPoints], cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 5); } dbgShow(tmpChin, "doFacialComponentsExtractionSide"); }
vector<CB_CollisionArea*> CB_CollisionArea::getConvexPolygons() { vector<CB_CollisionArea*> areaList; vector<CB_Vector2D*> optimizedVectors = optimize(); uint32_t angles = getAngles(optimizedVectors); if(angles > 0) { optimizedVectors = reverse(optimizedVectors); } if(!isConcave(optimizedVectors)) { areaList.push_back(new CB_CollisionArea(*this)); return areaList; } bool repeat = true; vector<CB_Vector2D*>::iterator it; vector<CB_Vector2D*>::iterator itConcave; itConcave = optimizedVectors.end(); uint32_t pSize = optimizedVectors.size(); uint32_t cit = -1; while(repeat) { vector<CB_Vector2D*> tList; uint32_t vSize = optimizedVectors.size(); if(pSize == vSize) { cit++; } else { pSize = vSize; cit = 0; } for(uint32_t idx = 0; idx < (vSize = optimizedVectors.size()); idx++) { it = optimizedVectors.begin(); CB_Vector2D * curVec = *(it + (vSize + idx - 1) % vSize); double curAngle = curVec->getAngle(**(it + idx)); if(curAngle > 0) { if(tList.size() > 1) { tList.push_back(*(it + idx)); areaList.push_back(new CB_CollisionArea(tList)); if(itConcave < it + idx) { idx = optimizedVectors.erase(itConcave + 1, it + idx) - optimizedVectors.begin(); } else { optimizedVectors.erase(itConcave + 1); it = optimizedVectors.erase(optimizedVectors.begin(), it + idx); idx = 0; } } tList.clear(); tList.push_back(*(it + idx)); itConcave = it + idx; } else if(itConcave < optimizedVectors.end()) { tList.push_back(*(it + idx)); if(tList.size() > 2) { vector<CB_Vector2D*> ttList = tList; ttList.push_back(*(it + (idx + 1) % vSize)); if(isConcave(ttList)) { areaList.push_back(new CB_CollisionArea(tList)); tList.clear(); tList.push_back(*itConcave); tList.push_back(*(it + idx)); if(itConcave < it + idx) { idx = optimizedVectors.erase(itConcave + 1, it + idx) - optimizedVectors.begin(); } else { optimizedVectors.erase(itConcave + 1); it = optimizedVectors.erase(optimizedVectors.begin(), it + idx); idx = 0; } } } } } repeat = isConcave(optimizedVectors) && cit < 3; } if(optimizedVectors.size() > 2) { areaList.push_back(new CB_CollisionArea(optimizedVectors)); } return areaList; }
bool CB_CollisionArea::isConcave() { return isConcave(vectors); }
void setCollisionShape(CollisionShape c, const std::string &meshName = "") { if (c == UNDEFINED) return; _meshName = meshName; _reset(); _shapeType = c; btTransform transform; glm::vec3 position = posFromMat4(_entity->getLocalTransform()); glm::vec3 scale = scaleFromMat4(_entity->getLocalTransform()); std::cout << scale.x << " " << scale.y << " " << scale.z << std::endl; glm::vec3 rot = rotFromMat4(_entity->getLocalTransform(), true); transform.setIdentity(); transform.setOrigin(convertGLMVectorToBullet(position)); transform.setRotation(btQuaternion(rot.x, rot.y, rot.z)); _motionState = new btDefaultMotionState(transform); if (c == BOX) { _collisionShape = new btBoxShape(btVector3(0.5, 0.5, 0.5));//new btBoxShape(halfScale); } else if (c == SPHERE) { _collisionShape = new btSphereShape(0.5);//new btSphereShape(scale.x); } else if (c == MESH) { // THERE IS SOME LEAKS BECAUSE THAT'S TEMPORARY SmartPointer<Resources::SharedMesh> mesh = _scene->getEngine().getInstance<Resources::ResourceManager>().getResource(meshName); auto group = new btCompoundShape(); auto &geos = mesh->getGeometry(); for (unsigned int i = 0; i < geos.size(); ++i) { const Resources::Geometry &geo = geos[i]; // DIRTY HACK TEMPORARY // NEED TO REPLACE MESH BY MESH GROUP ! btScalar *t = new btScalar[geo.vertices.size() * 3](); for (unsigned int it = 0; it < geo.vertices.size(); ++it) { t[it * 3] = geo.vertices[it].x; t[it * 3 + 1] = geo.vertices[it].y; t[it * 3 + 2] = geo.vertices[it].z; } btConvexHullShape *tmp = new btConvexHullShape(t, geo.vertices.size(), 3 * sizeof(btScalar)); btShapeHull *hull = new btShapeHull(tmp); btScalar margin = tmp->getMargin(); hull->buildHull(margin); tmp->setUserPointer(hull); btConvexHullShape *s = new btConvexHullShape(); for (int it = 0; it < hull->numVertices(); ++it) { s->addPoint(hull->getVertexPointer()[it], false); } s->recalcLocalAabb(); btTransform localTrans; localTrans.setIdentity(); _collisionShape = s; group->addChildShape(localTrans,s); delete[] t; delete hull; delete tmp; } _collisionShape = group; } else if (c == CONCAVE_STATIC_MESH) // dont work { SmartPointer<Resources::SharedMesh> mesh = _scene->getEngine().getInstance<Resources::ResourceManager>().getResource(meshName); auto trimesh = new btTriangleMesh(); auto &geos = mesh->getGeometry(); for (unsigned int j = 0; j < geos.size(); ++j) { const Resources::Geometry &geo = geos[j]; for (unsigned int i = 2; i < geo.vertices.size(); i += 3) { trimesh->addTriangle(btVector3(geo.vertices[i - 2].x, geo.vertices[i - 2].y, geo.vertices[i - 2].z) , btVector3(geo.vertices[i - 1].x, geo.vertices[i - 1].y, geo.vertices[i - 1].z) , btVector3(geo.vertices[i].x, geo.vertices[i].y, geo.vertices[i].z)); } } auto bvh = new btBvhTriangleMeshShape(trimesh, true); bvh->buildOptimizedBvh(); bool isit = bvh->isConcave(); _collisionShape = bvh; } if (_mass != 0) _collisionShape->calculateLocalInertia(_mass, _inertia); _collisionShape->setLocalScaling(convertGLMVectorToBullet(scale)); _rigidBody = new btRigidBody(_mass, _motionState, _collisionShape, _inertia); _rigidBody->setUserPointer(&_entity); _rigidBody->setAngularFactor(convertGLMVectorToBullet(_rotationConstraint)); _rigidBody->setLinearFactor(convertGLMVectorToBullet(_transformConstraint)); if (_rigidBody->isStaticObject()) { _rigidBody->setActivationState(DISABLE_SIMULATION); } _manager->getWorld()->addRigidBody(_rigidBody); }