void ConcavePolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) { PoolVector<Vector2> s = get_segments(); int len = s.size(); if (len == 0 || (len % 2) == 1) return; PoolVector<Vector2>::Read r = s.read(); for (int i = 0; i < len; i += 2) { VisualServer::get_singleton()->canvas_item_add_line(p_to_rid, r[i], r[i + 1], p_color, 2); } }
bool ConcavePolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { PoolVector<Vector2> s = get_segments(); int len = s.size(); if (len == 0 || (len % 2) == 1) return false; PoolVector<Vector2>::Read r = s.read(); for (int i = 0; i < len; i += 2) { Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, &r[i]); if (p_point.distance_to(closest) < p_tolerance) return true; } return false; }
Rect2 ConcavePolygonShape2D::get_rect() const { PoolVector<Vector2> s = get_segments(); int len = s.size(); if (len == 0) return Rect2(); Rect2 rect; PoolVector<Vector2>::Read r = s.read(); for (int i = 0; i < len; i++) { if (i == 0) rect.position = r[i]; else rect.expand_to(r[i]); } return rect; }
bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, GrPathFill fill, GrDrawTarget* target, bool antiAlias) { const SkPath* path = &origPath; if (path->isEmpty()) { return true; } GrDrawState* drawState = target->drawState(); GrDrawState::AutoDeviceCoordDraw adcd(drawState); if (!adcd.succeeded()) { return false; } const GrMatrix* vm = &adcd.getOriginalMatrix(); GrVertexLayout layout = 0; layout |= GrDrawTarget::kEdge_VertexLayoutBit; // We use the fact that SkPath::transform path does subdivision based on // perspective. Otherwise, we apply the view matrix when copying to the // segment representation. SkPath tmpPath; if (vm->hasPerspective()) { origPath.transform(*vm, &tmpPath); path = &tmpPath; vm = &GrMatrix::I(); } QuadVertex *verts; uint16_t* idxs; int vCount; int iCount; enum { kPreallocSegmentCnt = 512 / sizeof(Segment), }; SkSTArray<kPreallocSegmentCnt, Segment, true> segments; SkPoint fanPt; if (!get_segments(*path, *vm, &segments, &fanPt, &vCount, &iCount)) { return false; } GrDrawTarget::AutoReleaseGeometry arg(target, layout, vCount, iCount); if (!arg.succeeded()) { return false; } verts = reinterpret_cast<QuadVertex*>(arg.vertices()); idxs = reinterpret_cast<uint16_t*>(arg.indices()); create_vertices(segments, fanPt, verts, idxs); GrDrawState::VertexEdgeType oldEdgeType = drawState->getVertexEdgeType(); drawState->setVertexEdgeType(GrDrawState::kQuad_EdgeType); target->drawIndexed(kTriangles_GrPrimitiveType, 0, // start vertex 0, // start index vCount, iCount); drawState->setVertexEdgeType(oldEdgeType); return true; }
bool Shape::collide_segment(const glm::vec2& a, const glm::vec2& b, glm::vec2& point, geometry::segment2& segment) const { return geometry::intersect_seg_seg(a, b, get_segments(), point, segment); }
bool Shape::collide_ray(const glm::vec2& o, const glm::vec2& r, glm::vec2& point, geometry::segment2& segment) const { return geometry::intersect_ray_seg(o, r, get_segments(), point, segment); }
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { int instanceCount = fGeoData.count(); SkMatrix invert; if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { SkDebugf("Could not invert viewmatrix\n"); return; } // Setup GrGeometryProcessor SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(this->color(), invert)); batchTarget->initDraw(quadProcessor, pipeline); // TODO remove this when batch is everywhere GrPipelineInfo init; init.fColorIgnored = fBatch.fColorIgnored; init.fOverrideColor = GrColor_ILLEGAL; init.fCoverageIgnored = fBatch.fCoverageIgnored; init.fUsesLocalCoords = this->usesLocalCoords(); quadProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init); // TODO generate all segments for all paths and use one vertex buffer for (int i = 0; i < instanceCount; i++) { Geometry& args = fGeoData[i]; // We use the fact that SkPath::transform path does subdivision based on // perspective. Otherwise, we apply the view matrix when copying to the // segment representation. const SkMatrix* viewMatrix = &args.fViewMatrix; if (viewMatrix->hasPerspective()) { args.fPath.transform(*viewMatrix); viewMatrix = &SkMatrix::I(); } int vertexCount; int indexCount; enum { kPreallocSegmentCnt = 512 / sizeof(Segment), kPreallocDrawCnt = 4, }; SkSTArray<kPreallocSegmentCnt, Segment, true> segments; SkPoint fanPt; if (!get_segments(args.fPath, *viewMatrix, &segments, &fanPt, &vertexCount, &indexCount)) { continue; } const GrVertexBuffer* vertexBuffer; int firstVertex; size_t vertexStride = quadProcessor->getVertexStride(); void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex); if (!vertices) { SkDebugf("Could not allocate vertices\n"); return; } const GrIndexBuffer* indexBuffer; int firstIndex; void *indices = batchTarget->indexPool()->makeSpace(indexCount, &indexBuffer, &firstIndex); if (!indices) { SkDebugf("Could not allocate indices\n"); return; } QuadVertex* verts = reinterpret_cast<QuadVertex*>(vertices); uint16_t* idxs = reinterpret_cast<uint16_t*>(indices); SkSTArray<kPreallocDrawCnt, Draw, true> draws; create_vertices(segments, fanPt, &draws, verts, idxs); GrDrawTarget::DrawInfo info; info.setVertexBuffer(vertexBuffer); info.setIndexBuffer(indexBuffer); info.setPrimitiveType(kTriangles_GrPrimitiveType); info.setStartIndex(firstIndex); int vOffset = 0; for (int i = 0; i < draws.count(); ++i) { const Draw& draw = draws[i]; info.setStartVertex(vOffset + firstVertex); info.setVertexCount(draw.fVertexCnt); info.setIndexCount(draw.fIndexCnt); batchTarget->draw(info); vOffset += draw.fVertexCnt; } } }
bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, GrPathFill fill, const GrVec* translate, GrDrawTarget* target, GrDrawState::StageMask stageMask, bool antiAlias) { const SkPath* path = &origPath; if (path->isEmpty()) { return true; } GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit); GrDrawState* drawState = target->drawState(); GrMatrix vm = drawState->getViewMatrix(); if (NULL != translate) { vm.postTranslate(translate->fX, translate->fY); } GrMatrix ivm; if (vm.invert(&ivm)) { drawState->preConcatSamplerMatrices(stageMask, ivm); } drawState->viewMatrix()->reset(); GrVertexLayout layout = 0; for (int s = 0; s < GrDrawState::kNumStages; ++s) { if ((1 << s) & stageMask) { layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); } } layout |= GrDrawTarget::kEdge_VertexLayoutBit; // We use the fact that SkPath::transform path does subdivision based on // perspective. Otherwise, we apply the view matrix when copying to the // segment representation. SkPath tmpPath; if (vm.hasPerspective()) { origPath.transform(vm, &tmpPath); path = &tmpPath; vm.reset(); } QuadVertex *verts; uint16_t* idxs; int vCount; int iCount; enum { kPreallocSegmentCnt = 512 / sizeof(Segment), }; SkSTArray<kPreallocSegmentCnt, Segment, true> segments; SkPoint fanPt; if (!get_segments(*path, vm, &segments, &fanPt, &vCount, &iCount)) { return false; } GrDrawTarget::AutoReleaseGeometry arg(target, layout, vCount, iCount); if (!arg.succeeded()) { return false; } verts = reinterpret_cast<QuadVertex*>(arg.vertices()); idxs = reinterpret_cast<uint16_t*>(arg.indices()); create_vertices(segments, fanPt, verts, idxs); drawState->setVertexEdgeType(GrDrawState::kQuad_EdgeType); target->drawIndexed(kTriangles_PrimitiveType, 0, // start vertex 0, // start index vCount, iCount); return true; }