void FitQuads(Scalar squareTolerance, std::vector<Point2D>& qs, int recurse=3, bool split=true) { Scalar time1; Scalar time2; if( !split ) { // If the lines are parallel, we must split split = !IntersectLines(p0, p1, p2, p3, time1, time2);; } if( !split ) { // Compute intersection point of p0..p1 and p2..p3 // This is the control point of the quadratic curve. Point2D q = p0+time1*(p1-p0); // Measure distance between midpoint on cubic curve [p0,p1,p2,p3] and quadratic curve [p0,q,p3] Scalar dx = (4*q.x+p3.x-3*p2.x-3*p1.x+p0.x)/8; Scalar dy = (4*q.y+p3.y-3*p2.y-3*p1.y+p0.y)/8; Scalar dd = dx*dx+dy*dy; // split curve if the quadratic isn't close enough split = dd > squareTolerance; if( !split ) { // no need to split, stop recursion qs.push_back(p0); qs.push_back(q); qs.push_back(p3); } } if( split ) { if( recurse == 0 ) { qs.push_back(p0); qs.push_back(lerp(p1,p2,0.5)); qs.push_back(p3); } else { Cubic c0, c1; Split(c0, c1); c0.FitQuads(squareTolerance,qs, recurse-1, false); c1.FitQuads(squareTolerance,qs, recurse-1, false); } } }
inline Vec3D F_Get_Translation_Gizmo_Pick_Point_In_World_Space( const EdSceneViewport& viewport , const Vec2D& xyNDC, const APlaceable* pEntity , const EGizmoAxis eAxis ) { Ray3D gizmoAxisWS = GetGizmoAxisInWorldSpace( pEntity, eAxis ); Ray3D eyeRay = GetEyeRay( viewport, xyNDC ); Vec3D pointOnGizmo, pointOnEyeRay; ELineStatus eLineStatus = IntersectLines( gizmoAxisWS, eyeRay, pointOnGizmo, pointOnEyeRay ); //Assert( eLineStatus != Lines_Parallel ); if( eLineStatus != Lines_Parallel ) { return pointOnGizmo; } return gizmoAxisWS.origin + gizmoAxisWS.direction * GetTranslateGizmoAxisScale( eyeRay.origin, pEntity->GetOrigin() ); }
void nuiGLDrawContext::DrawGradient(const nuiGradient& rGradient, const nuiRect& rEnclosingRect, nuiSize x1, nuiSize y1, nuiSize x2, nuiSize y2) { nglVector2f vec(x2 - x1, y2 - y1); nglVector2f para(-vec[1], vec[0]); nglVector2f vec1(vec); nglVector2f para1(para); vec1.Normalize(); para1.Normalize(); // What Quadrant are we in?: // | // a | b // | // ---------------- // | // c | d // | float xa, xb, xc, xd; float ya, yb, yc, yd; float x, y; float xp, yp; float xx, yy; float xxp, yyp; xa = xc = rEnclosingRect.Left(); xb = xd = rEnclosingRect.Right(); ya = yb = rEnclosingRect.Top(); yc = yd = rEnclosingRect.Bottom(); if (x1 < x2) { // Go from a to d or c to b if (y1 == y2) { x = xa; y = ya; xp = xc; yp = yc; xx = xd; yy = yd; xxp= xb; yyp= yb; } else if (y1 < y2) { // a to d IntersectLines(xa,ya, para1[0], para1[1], xb, yb, vec1[0], vec1[1], x, y); IntersectLines(xa,ya, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xp, yp); IntersectLines(xd,yd, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xx, yy); IntersectLines(xd,yd, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xxp, yyp); } else { // c to d IntersectLines(xc,yc, para1[0], para1[1], xa, ya, vec1[0], vec1[1], x, y); IntersectLines(xc,yc, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xp, yp); IntersectLines(xb,yb, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xx, yy); IntersectLines(xb,yb, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xxp, yyp); } } else { if (y1 == y2) { x = xd; y = yd; xp = xb; yp = yb; xx = xa; yy = ya; xxp= xc; yyp= yc; } else if (y1 < y2) { // b to c IntersectLines(xb,yb, para1[0], para1[1], xd, yd, vec1[0], vec1[1], x, y); IntersectLines(xb,yb, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xp, yp); IntersectLines(xc,yc, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xx, yy); IntersectLines(xc,yc, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xxp, yyp); } else { // d to a IntersectLines(xd,yd, para1[0], para1[1], xc, yc, vec1[0], vec1[1], x, y); IntersectLines(xd,yd, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xp, yp); IntersectLines(xa,ya, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xx, yy); IntersectLines(xa,ya, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xxp, yyp); } } float startx,starty; float startxp,startyp; float stopx,stopy; float stopxp,stopyp; if (y1 != y2) { IntersectLines(x1, y1, para1[0], para1[1], x, y, vec1[0], vec1[1], startx, starty); IntersectLines(x1, y1, para1[0], para1[1], xp, yp, vec1[0], vec1[1], startxp, startyp); IntersectLines(x2, y2, para1[0], para1[1], x, y, vec1[0], vec1[1], stopx, stopy); IntersectLines(x2, y2, para1[0], para1[1], xp, yp, vec1[0], vec1[1], stopxp, stopyp); } else { startx = x1; starty = y; startxp = x1; startyp = yp; stopx = x2; stopy = y; stopxp = x2; stopyp = yp; } nuiGradientStopList::const_iterator it = rGradient.GetStopList().begin(); nuiGradientStopList::const_iterator end = rGradient.GetStopList().end(); float px1, py1; float px2, py2; PushClipping(); nuiRect r = rEnclosingRect; nglMatrixf m(GetMatrix()); nglVectorf v1(r.Left(), r.Top(), 0); v1 = m * v1; nglVectorf v2 = nglVectorf(r.Right(), r.Bottom(), 0); v2 = m * v2; r.Set(v1[0], v1[1], v2[0], v2[1], false); Clip(r); SetClipping(true); std::vector<nuiShape::CacheElement::Vertex> vertices; nuiColor col = it->second; vertices.push_back(nuiShape::CacheElement::Vertex(x, y, col)); vertices.push_back(nuiShape::CacheElement::Vertex(xp, yp, col)); for ( ; it != end; ++it) { float r = it->first; float rm = 1.0f - r; px1 = startx * rm + stopx * r; py1 = starty * rm + stopy * r; px2 = startxp * rm + stopxp * r; py2 = startyp * rm + stopyp * r; col = it->second; vertices.push_back(nuiShape::CacheElement::Vertex(px1, py1, col)); vertices.push_back(nuiShape::CacheElement::Vertex(px2, py2, col)); } vertices.push_back(nuiShape::CacheElement::Vertex(xxp, yyp, col)); vertices.push_back(nuiShape::CacheElement::Vertex(xx, yy, col)); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(4, GL_FLOAT, sizeof(nuiShape::CacheElement::Vertex), vertices[0].mColor); glVertexPointer(3, GL_FLOAT, sizeof(nuiShape::CacheElement::Vertex), vertices[0].mCoord); glDrawArrays(GL_QUAD_STRIP, 0, vertices.size()); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); PopClipping(); }
int HitOutline::Raycast(Point2D p, Vector2D v, Scalar maxTime, Hit* hitArr, int hitArrSize, Scalar sense) { //local data: Bart Hit localHitArr[100]; int localHitArrSize=100; int hitCount = 0; // TODO: Currently very slow, brute force! int lineVertexCount = m_Lines.size(); int quadVertexCount = m_Quads.size(); Scalar epsilon = 1e-6; Point2D p1 = p; Point2D p2 = p+v; Point2D orig(0,0); Scalar vDv = v.Dot(v); Vector2D n = v.Orthogonal(); // Line-line intersections. if( lineVertexCount > 0 ) { Point2D* lines = &m_Lines[0]; for( int i=0; i<lineVertexCount && hitCount<localHitArrSize; i += 2 ) { Point2D q1 = lines[i+0]; Point2D q2 = lines[i+1]; Vector2D ortho = (q2-q1).Orthogonal(); if( (dot(ortho, v) * sense < 0) || sense==0) { Scalar time1; Scalar time2; if( IntersectLines(p1, p2, q1, q2, time1, time2) ) { if( time1 >= 0 && time1 < maxTime && time2 >= 0 && time2 <= 1 ) { Hit hit; hit.Time = time1; hit.Point = p + time1 * v; hit.Normal = ortho.Normalized(); localHitArr[hitCount++] = hit; } } } } } // Line-quadratic intersections. if( quadVertexCount > 0 ) { Point2D* quads = &m_Quads[0]; for( int i=0; i<quadVertexCount && hitCount<localHitArrSize; i += 3 ) { Vector2D q0 = quads[i+0] - p; Vector2D q1 = quads[i+1] - p; Vector2D q2 = quads[i+2] - p; // Hit only possible if: // (1) not all points are on same side of ray, // // (2) and some points are in front of ray (currently not checked, handled by abc formula) Scalar dot_n_q0 = dot(n,q0); Scalar dot_n_q1 = dot(n,q1); Scalar dot_n_q2 = dot(n,q2); if( dot_n_q0 <= 0 && dot_n_q1 <= 0 && dot_n_q2 <= 0 ) continue; if( dot_n_q0 >= 0 && dot_n_q1 >= 0 && dot_n_q2 >= 0 ) continue; Scalar ts[2]; Scalar a = 2*dot_n_q1-dot_n_q0-dot_n_q2; Scalar b = 2*dot_n_q0-2*dot_n_q1; Scalar c = -dot_n_q0; int n = solveQuadratic(a,b,c,ts); for( int j=0; j<n && hitCount < localHitArrSize; ++j ) { Scalar t = ts[j]; if( t >= 0 && t <= 1 ) { Vector2D diff = (2*(q2-q1)+2*(q0-q1))*t+2*(q1-q0); Vector2D ortho = diff.Orthogonal(); if( (dot(ortho, v) * sense < 0) || sense==0) { Vector2D h = lerp( lerp(q0,q1,t), lerp(q1,q2,t), t); Scalar time = h.Dot(v) / vDv; //time >= -maxTime if( time >= 0 && time < maxTime ) { Hit hit; hit.Point = p+h; hit.Time = time; hit.Normal = ortho.Normalized(); localHitArr[hitCount++] = hit; } } } } } } std::sort(localHitArr, localHitArr+hitCount, sortHitOnTime); //Bart for( int i=0; i<hitCount && i < hitArrSize; ++i ) { hitArr[i]=localHitArr[i]; } return hitCount; }
void nuiDrawContext::DrawGradient(const nuiGradient& rGradient, const nuiRect& rEnclosingRect, nuiSize x1, nuiSize y1, nuiSize x2, nuiSize y2) { nuiVector2 vec(x2 - x1, y2 - y1); nuiVector2 para(-vec[1], vec[0]); nuiVector2 vec1(vec); nuiVector2 para1(para); vec1.Normalize(); para1.Normalize(); // What Quadrant are we in?: // | // a | b // | // ---------------- // | // c | d // | float xa, xb, xc, xd; float ya, yb, yc, yd; float x, y; float xp, yp; float xx, yy; float xxp, yyp; xa = xc = rEnclosingRect.Left(); xb = xd = rEnclosingRect.Right(); ya = yb = rEnclosingRect.Top(); yc = yd = rEnclosingRect.Bottom(); if (x1 < x2) { // Go from a to d or c to b if (y1 == y2) { x = xa; y = ya; xp = xc; yp = yc; xx = xd; yy = yd; xxp= xb; yyp= yb; } else if (y1 < y2) { // a to d IntersectLines(xa,ya, para1[0], para1[1], xb, yb, vec1[0], vec1[1], x, y); IntersectLines(xa,ya, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xp, yp); IntersectLines(xd,yd, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xx, yy); IntersectLines(xd,yd, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xxp, yyp); } else { // c to d IntersectLines(xc,yc, para1[0], para1[1], xa, ya, vec1[0], vec1[1], x, y); IntersectLines(xc,yc, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xp, yp); IntersectLines(xb,yb, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xx, yy); IntersectLines(xb,yb, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xxp, yyp); } } else { if (y1 == y2) { x = xd; y = yd; xp = xb; yp = yb; xx = xa; yy = ya; xxp= xc; yyp= yc; } else if (y1 < y2) { // b to c IntersectLines(xb,yb, para1[0], para1[1], xd, yd, vec1[0], vec1[1], x, y); IntersectLines(xb,yb, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xp, yp); IntersectLines(xc,yc, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xx, yy); IntersectLines(xc,yc, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xxp, yyp); } else { // d to a IntersectLines(xd,yd, para1[0], para1[1], xc, yc, vec1[0], vec1[1], x, y); IntersectLines(xd,yd, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xp, yp); IntersectLines(xa,ya, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xx, yy); IntersectLines(xa,ya, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xxp, yyp); } } float startx,starty; float startxp,startyp; float stopx,stopy; float stopxp,stopyp; if (y1 != y2) { IntersectLines(x1, y1, para1[0], para1[1], x, y, vec1[0], vec1[1], startx, starty); IntersectLines(x1, y1, para1[0], para1[1], xp, yp, vec1[0], vec1[1], startxp, startyp); IntersectLines(x2, y2, para1[0], para1[1], x, y, vec1[0], vec1[1], stopx, stopy); IntersectLines(x2, y2, para1[0], para1[1], xp, yp, vec1[0], vec1[1], stopxp, stopyp); } else { startx = x1; starty = y; startxp = x1; startyp = yp; stopx = x2; stopy = y; stopxp = x2; stopyp = yp; } nuiGradientStopList::const_iterator it = rGradient.GetStopList().begin(); nuiGradientStopList::const_iterator end = rGradient.GetStopList().end(); float px1, py1; float px2, py2; PushClipping(); Clip(rEnclosingRect); EnableClipping(true); nuiRenderArray* pArray = new nuiRenderArray(GL_TRIANGLE_STRIP); pArray->EnableArray(nuiRenderArray::eVertex); pArray->EnableArray(nuiRenderArray::eColor); // nuiRenderArray Array(GL_LINES); // pArray->SetVertexElements(3); // pArray->SetColorElements(4); nuiColor col = it->second; pArray->SetVertex(x, y); pArray->SetColor(col); pArray->PushVertex(); pArray->SetVertex(xp, yp); pArray->PushVertex(); for ( ; it != end; ++it) { float r = it->first; float rm = 1.0f - r; px1 = startx * rm + stopx * r; py1 = starty * rm + stopy * r; px2 = startxp * rm + stopxp * r; py2 = startyp * rm + stopyp * r; col = it->second; pArray->SetColor(col); pArray->SetVertex(px2, py2); pArray->PushVertex(); pArray->SetVertex(px1, py1); pArray->PushVertex(); } pArray->SetVertex(xx, yy); pArray->PushVertex(); pArray->SetVertex(xxp, yyp); pArray->PushVertex(); DrawArray(pArray); PopClipping(); }