double DistanceTransform::rayTriangleIntersection(int nt, const Point3f& begin, const Point3f& end) { const double TOLERANCE = 1.0e-6; Vector3f norm; Point3f v0, v1, v2; p_Surf->getTriNormal(nt, norm); p_Surf->getTriVerts(nt, v0, v1, v2); double dbeg = signedDist2Plane(begin, v0, norm); double dend = signedDist2Plane(end, v0, norm); if(fabs(dbeg) < TOLERANCE) { if(pointInTriangle(begin, v0, v1, v2, norm)) return 0; } if(fabs(dend) < TOLERANCE) { if(pointInTriangle(end, v0, v1, v2, norm)) return 1; } if(dbeg * dend > 0) return MAX_FLOAT; if(fabs(dbeg) < TOLERANCE && fabs(dend) < TOLERANCE) return 0.5; // a hack that needs to fixed later double denom = DotProduct(norm, end - begin); double t = - dbeg / denom; assert (t >= 0); if(t > 1) t = 1; Point3f intersect; intersect[0] = begin[0] + t*(end[0] - begin[0]); intersect[1] = begin[1] + t*(end[1] - begin[1]); intersect[2] = begin[2] + t*(end[2] - begin[2]); if(pointInTriangle(intersect, v0, v1, v2, norm)) return t; return MAX_FLOAT; }
bool carve::triangulate::detail::vertex_info::isClipable() const { for (const vertex_info *v_test = next->next; v_test != prev; v_test = v_test->next) { if (v_test->convex) { continue; } if (v_test->p == prev->p || v_test->p == next->p) { continue; } if (v_test->p == p) { if (v_test->next->p == prev->p && v_test->prev->p == next->p) { return false; } if (v_test->next->p == prev->p || v_test->prev->p == next->p) { continue; } } if (pointInTriangle(prev, this, next, v_test)) { return false; } } return true; }
// checks if any point in _shape is inside the triangle formed by point and it's adjacent points bool SteerLib::GJK_EPA::checkTriangle(std::vector<Util::Vector> _shape, Util::Vector predecessor, Util::Vector point, Util::Vector successor) { for (int i = 0; i < _shape.size(); i++) { // checks if shapePoint at i is inside the triangle formed by point and it's adjacent points if (pointInTriangle(_shape.at(i), predecessor, point, successor)) { return true; } } return false; }
double phiFunction(QPointF *points, quint32 size, quint32 layers, QPointF point, quint32 vertexNumber, QPointF *centerPtr) { Vertex vertex = getVertex(size, vertexNumber); TriangleList triangles = getSurroundingTriangles(points, size, layers, vertex, centerPtr); for (int i = 0; i < triangles.size(); ++i) { if (pointInTriangle(point, triangles.at(i))) return phiFunction(point, triangles.at(i), getPoint(points, size, layers, vertex, centerPtr)); } return 0; }
float heightInTriangleAt(glm::vec3 p, Triangle t) const { if(!pointInTriangle(p, t)) return 0.0; const float d0 = glm::distance(glm::vec2(p), glm::vec2(t.p0)); const float d1 = glm::distance(glm::vec2(p), glm::vec2(t.p1)); const float d2 = glm::distance(glm::vec2(p), glm::vec2(t.p2)); const float total = d0 + d1 + d2; const glm::vec3 hello = glm::normalize(glm::vec3(d0, d1, d2) / total); return hello.x * t.p0.z + hello.y * t.p1.z + hello.z + t.p1.z; }
double DistanceTransform::distance2Triangle(const Point3f& pnt, int nt, Point3f& nearPnt) { double dist, temp[3]; Point3f v0, v1, v2; p_Surf->getTriVerts(nt, v0, v1, v2); Vector3f norm; p_Surf->getTriNormal(nt, norm); vector3 vnorm(norm[0], norm[1], norm[2]), vdiff; Point3f edgePnt; //1) First compute the shortest distance from the pnt to the plane of the Triangle. vdiff[0] = pnt[0] - v0[0]; vdiff[1] = pnt[1] - v0[1]; vdiff[2] = pnt[2] - v0[2]; dist = DotProduct(vdiff, vnorm); nearPnt[0] = pnt[0] - dist * norm[0]; nearPnt[1] = pnt[1] - dist * norm[1]; nearPnt[2] = pnt[2] - dist * norm[2]; //2) Then check if the projected point is within the triangle or not. // if yes, then the above is the correct shortest distance. if(pointInTriangle(nearPnt, v0, v1, v2, norm)) { return fabs(dist); } //3) now, the closest point must on the edge. // find the nearest point on each edge. dist = distance2Edge(pnt, v0, v1, nearPnt); double edgeDist = distance2Edge(pnt, v1, v2, edgePnt); if(edgeDist < dist) { dist = edgeDist; nearPnt = edgePnt; } edgeDist = distance2Edge(pnt, v2, v0, edgePnt); if(edgeDist < dist) { dist = edgeDist; nearPnt = edgePnt; } assert(dist >= 0); return dist; }
Vector2 closestPointOnTriangle(Vector2 p, Vector2 v[3]) { if (pointInTriangle(p, v)) return p; float maxDist = 10000.f; Vector2 closest; for (int i = 0; i < 3; ++i) { Vector2 temp = closestPointOnSegment(p, v[i], v[(i + 1) % 3]); float dist = (temp - p).lengthSq(); if (dist < maxDist) { maxDist = dist; closest = temp; } } return closest; }
float rayTriangleCollision( const Vec3f &rayOrign, const Vec3f &rayDir, const Vec3f &p0, const Vec3f &p1, const Vec3f &p2) { Planef trigPlane(p0, p1, p2); float div = vecDot(rayDir, trigPlane.normal); if ( div == 0.0f ) return NoIntersection; const float t = -(vecDot(rayOrign, trigPlane.normal) + trigPlane.d) / div; if ( t < 0.0f ) return NoIntersection; Vec3f interscPoint = rayOrign + rayDir * t; if ( pointInTriangle(interscPoint, rayOrign, p0, p1, p2) == true ) return t; else return NoIntersection; }
// Checks if two co-planar triangles intersect. bool CCLayerSorter::LayerIntersector::triangleTriangleTest(const FloatPoint& a1, const FloatPoint& b1, const FloatPoint& c1, const FloatPoint& a2, const FloatPoint& b2, const FloatPoint& c2) { // Check all edges of first triangle with edges of the second one. if (edgeTriangleTest(a1, b1, a2, b2, c2) || edgeTriangleTest(a1, c1, a2, b2, c2) || edgeTriangleTest(b1, c1, a2, b2, c2)) return true; // Check all points of the first triangle for inclusion in the second triangle. if ((pointInTriangle(a1, a2, b2, c2) && checkZDiff(a1)) || (pointInTriangle(b1, a2, b2, c2) && checkZDiff(b1)) || (pointInTriangle(c1, a2, b2, c2) && checkZDiff(c1))) return true; // Check all points of the second triangle for inclusion in the first triangle. if ((pointInTriangle(a2, a1, b1, c1) && checkZDiff(a2)) || (pointInTriangle(b2, a1, b1, c1) && checkZDiff(b2)) || (pointInTriangle(c2, a1, b1, c1) && checkZDiff(c2))) return true; return false; }
bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal) { btVector3 lp(p); btVector3 lnormal(normal); return pointInTriangle(vertices, lnormal, &lp); }
float sphereTriangleCollision( const BoundingSphere &sphere, const Vec3f &dir, const Vec3f &p0, const Vec3f &p1, const Vec3f &p2, Vec3f *contactPoint) { Planef trigPlane(p0, p1, p2); float d = vecDot(dir, trigPlane.normal); float minDist = NoIntersection; if ( vecDot(dir, trigPlane.normal) > 0.0 ) { return NoIntersection; } if ( d == 0.0f ) { if ( trigPlane.distance(sphere.center()) < sphere.radius() ) return NoIntersection; } else { const Vec3f orign = sphere.center() - sphere.radius()*vecNormal(trigPlane.normal); const float t = -(trigPlane.d + vecDot(orign, trigPlane.normal)) / d; if ( t >= 0.0f ) { const Vec3f planePoint = orign + dir * t; if ( pointInTriangle(planePoint, vecNormal(trigPlane.normal), p0, p1, p2) ) { *contactPoint = planePoint; return t; } } } float dist = spherePointDistance(sphere, dir, p0); if ( dist < minDist ) { minDist = dist; *contactPoint = p0; } dist = spherePointDistance(sphere, dir, p1); if ( dist < minDist ) { minDist = dist; *contactPoint = p1; } dist = spherePointDistance(sphere, dir, p2); if ( dist < minDist ) { minDist = dist; *contactPoint = p2; } Vec3f edgeContactPoint; dist = sphereEdgeDistance(sphere, dir, p1, p0, &edgeContactPoint); if ( dist < minDist ) { minDist = dist; *contactPoint = edgeContactPoint; } dist = sphereEdgeDistance(sphere, dir, p2, p1, &edgeContactPoint); if ( dist < minDist ) { minDist = dist; *contactPoint = edgeContactPoint; } dist = sphereEdgeDistance(sphere, dir, p0, p2, &edgeContactPoint); if ( dist < minDist ) { minDist = dist; *contactPoint = edgeContactPoint; } return minDist; }
bool point_in_hull(const Quadratic& quad, const _Point& pt) { return pointInTriangle((const Triangle&) quad, pt); }
static void drawDebugMaterials() { if(!ACTIVEBKG || !ACTIVEBKG->exist) { return; } PolyType skip = POLY_NODRAW | POLY_HIDE; if(GInput->isKeyPressed(Keyboard::Key_LeftShift)) { skip |= POLY_TRANS | POLY_WATER; } Vec2f point(DANAEMouse); Entity * owner = GetFirstInterAtPos(Vec2s(point)); TextureContainer * material = NULL; size_t count = 0; Vec2f pp[4]; Vec2f puv[4]; PolyType flags; float minz = std::numeric_limits<float>::max(); for(size_t k = 1; k < entities.size(); k++) { EntityHandle h = EntityHandle(k); if(!entities[h] || !entities[h]->obj) { continue; } Entity * entity = entities[h]; if((entity->ioflags & IO_CAMERA) || (entity->ioflags & IO_MARKER)) continue; if(!(entity->gameFlags & GFLAG_ISINTREATZONE)) continue; if((entity->gameFlags & GFLAG_INVISIBILITY)) continue; if((entity->gameFlags & GFLAG_MEGAHIDE)) continue; switch(entity->show) { case SHOW_FLAG_DESTROYED: continue; case SHOW_FLAG_IN_INVENTORY: continue; case SHOW_FLAG_ON_PLAYER: continue; case SHOW_FLAG_LINKED: break; case SHOW_FLAG_NOT_DRAWN: continue; case SHOW_FLAG_HIDDEN: continue; case SHOW_FLAG_MEGAHIDE: continue; case SHOW_FLAG_KILLED: continue; case SHOW_FLAG_IN_SCENE: break; case SHOW_FLAG_TELEPORTING: break; } if(!entity->bbox2D.valid()) { continue; } for(size_t j = 0; j < entity->obj->facelist.size(); j++) { const EERIE_FACE & face = entity->obj->facelist[j]; if(face.facetype & skip) { continue; } bool valid = true; bool bvalid = false; Vec3f p[3]; Vec2f uv[3]; for(size_t i = 0; i < 3; i++) { unsigned short v = face.vid[i]; valid = valid && v < entity->obj->vertexlist3.size(); if(valid) { if(entity->animlayer[0].cur_anim) { p[i] = entity->obj->vertexlist3[v].vert.p; uv[i] = entity->obj->vertexlist3[v].vert.uv; } else { p[i] = entity->obj->vertexlist[v].vert.p; uv[i] = entity->obj->vertexlist[v].vert.uv; } valid = valid && (p[i].z > 0.000001f); bvalid = bvalid || (p[i].x >= g_size.left && p[i].x < g_size.right && p[i].y >= g_size.top && p[i].y < g_size.bottom); } } if(!valid || !bvalid) { continue; } float z = pointInTriangle(point, p[0], p[1], p[2]); if(z > 0 && z <= minz) { count = 3; for(size_t i = 0; i < count; i++) { pp[i] = Vec2f(p[i].x, p[i].y); puv[i] = uv[i]; } if(face.texid >= 0 && size_t(face.texid) < entity->obj->texturecontainer.size()) { material = entity->obj->texturecontainer[face.texid]; } else { material = NULL; } owner = entity; minz = z; flags = face.facetype & ~(POLY_WATER | POLY_LAVA); } } } for(short z = 0; z < ACTIVEBKG->Zsize; z++) for(short x = 0; x < ACTIVEBKG->Xsize; x++) { const EERIE_BKG_INFO & feg = ACTIVEBKG->fastdata[x][z]; if(!feg.treat) { continue; } for(long l = 0; l < feg.nbpolyin; l++) { EERIEPOLY * ep = feg.polyin[l]; if(!ep) { continue; } if(ep->type & skip) { continue; } bool valid = true; bool bvalid = false; Vec3f p[4]; for(size_t i = 0; i < ((ep->type & POLY_QUAD) ? 4u : 3u); i++) { TexturedVertex tv; tv.p = EE_RT(ep->v[i].p); valid = valid && (tv.p.z > 0.000001f); EE_P(tv.p, tv); bvalid = bvalid || (tv.p.x >= g_size.left && tv.p.x < g_size.right && tv.p.y >= g_size.top && tv.p.y < g_size.bottom); p[i] = tv.p; } if(!valid || !bvalid) { continue; } float z = pointInTriangle(point, p[0], p[1], p[2]); if(z <= 0 && (ep->type & POLY_QUAD)) { z = pointInTriangle(point, p[1], p[3], p[2]); } if(z > 0 && z <= minz) { count = ((ep->type & POLY_QUAD) ? 4 : 3); for(size_t i = 0; i < count; i++) { pp[i] = Vec2f(p[i].x, p[i].y); puv[i] = ep->v[i].uv; } material = ep->tex; owner = NULL; minz = z; flags = ep->type; } } } if(count) { GRenderer->SetRenderState(Renderer::DepthTest, false); drawLine2D(pp[0], pp[1], 0.1f, Color::magenta); drawLine2D(pp[2], pp[0], 0.1f, Color::magenta); if(count == 4) { drawLine2D(pp[2], pp[3], 0.1f, Color::magenta); drawLine2D(pp[3], pp[1], 0.1f, Color::magenta); } else { drawLine2D(pp[1], pp[2], 0.1f, Color::magenta); } Vec2f c = Vec2f(0.f); float miny = std::numeric_limits<float>::max(); float maxy = std::numeric_limits<float>::min(); for(size_t i = 0; i < count; i++) { c += pp[i]; miny = std::min(miny, pp[i].y); maxy = std::max(maxy, pp[i].y); } c *= 1.f / count; Vec2f textpos(c.x, miny - 2 * hFontDebug->getLineHeight()); std::ostringstream oss; if(owner) { textpos.y -= hFontDebug->getLineHeight(); } if(material && material->m_pTexture) { textpos.y -= hFontDebug->getLineHeight(); } if((flags & (POLY_WATER | POLY_LAVA)) && enviro && enviro->m_pTexture) { textpos.y -= hFontDebug->getLineHeight(); } if(textpos.y < g_size.top + 5) { textpos.y = maxy + 2 * hFontDebug->getLineHeight(); } if(owner) { drawTextCentered(hFontDebug, textpos, owner->idString(), Color::cyan); textpos.y += hFontDebug->getLineHeight(); } if(material && material->m_pTexture) { drawDebugMaterialTexture(textpos, "Diffuse: ", *material->m_pTexture, Color::green); } if((flags & (POLY_WATER | POLY_LAVA)) && enviro && enviro->m_pTexture) { oss.str(std::string()); oss << "Animation: "; oss << ((flags & (POLY_LAVA)) ? "lava" : "water"); if(flags & POLY_FALL) { oss << " (flowing)"; } drawDebugMaterialTexture(textpos, oss.str(), *enviro->m_pTexture, Color::yellow); } (void)textpos; for(size_t i = 0; i < count; i++) { oss.str(std::string()); oss.setf(std::ios_base::fixed, std::ios_base::floatfield); oss.precision(2); oss << '(' << puv[i].x << ',' << puv[i].y << ')'; std::string text = oss.str(); Vec2f textpos = pp[i]; if(pp[i].y < c.y) { textpos.y -= hFontDebug->getLineHeight(); } if(pp[i].x < c.x) { Vec2i size = hFontDebug->getTextSize(text); textpos.x -= size.x; } hFontDebug->draw(textpos.x, textpos.y, text, Color::gray(0.7f)); } GRenderer->SetRenderState(Renderer::DepthTest, true); } }
bool hasPoint(glm::vec3 point) const { return pointInTriangle(point, firstTriangle()) || pointInTriangle(point, secondTriangle()); };
short int delaunay(){ Point * point, * p; Triangle * T, * A, * B, * C; int i, e, m; float a, b; short int len; for(e=0, p=pHead; p; ++e, p=p->next){ if(ABS(p->x) > ABS(p->y)){ i = ABS(p->x) > i ? ABS(p->x) : i; } else{ i = ABS(p->y) > i ? ABS(p->y) : i; } } len = e; if(e==2) return -100; T = tHead = NEWT; T->next = NULL; P0 = NEWP; P0->id = -1; P0->x = i * 3 + 1; P0->y = 0; P0->next = pHead; pHead = P0; P1 = NEWP; P1->id = -2; P1->x = 0; P1->y = i * 3 + 1; P1->next = pHead; pHead = P1; P2 = NEWP; P2->id = -3; P2->x = P2->y = -(3 * i) - 1; P2->next = pHead; pHead = P2; for(point = pHead->next->next->next; point; point = point->next){ for(T=tHead; T; T = T->next){ e = pointInTriangle(point, T); switch(e){ case -2: continue; case -1: goto pit; default: goto poe; } } return -200; poe: ADJACENT(T, T->points[e], T->points[NEXT(e)], A) if(!A) return -300; for(m=0; m<3 && A->points[m] != T->points[e]; ++m); if(m==3) return -400; B = NEWT; B->next = tHead; tHead = B; C = NEWT; C->next = tHead; tHead = C; B->points[0] = C->points[0] = T->points[e]; B->points[1] = T->points[PREV(e)]; C->points[1] = A->points[NEXT(m)] == T->points[NEXT(e)] ? A->points[PREV(m)] : A->points[NEXT(m)]; T->points[e] = A->points[m] = B->points[2] = C->points[2] = point; if((i=legalizeEdge(point, T))<0) return i-510; if((i=legalizeEdge(point, A))<0) return i-520; if((i=legalizeEdge(point, B))<0) return i-530; if((i=legalizeEdge(point, C))<0) return i-540; continue; pit: A = NEWT; B = NEWT; A->next=tHead; tHead = A; B->next = tHead; tHead=B; A0 = P1; A1 = B->points[0] = P2; B->points[1] = P0; P2 = A2 = B->points[2] = point; if((i=legalizeEdge(point, T))<0) return i-610; if((i=legalizeEdge(point, A))<0) return i-620; if((i=legalizeEdge(point, B))<0) return i-630; } /*Calculate peak memory allocation*/ mem=0; for(T=tHead, i=0; T; T=T->next, ++i); for(point=pHead, e=0; point; point=point->next, ++e); mem = i*sizeof(Triangle) + e*sizeof(Point); /*Patch*/ for(T=tHead; T; T = T->next){ /*Find # of external points*/ for(i=0, e=0; i<3; e+=(T->points[i]->id < 0 ? 1 : 0), ++i); /*If # of external points is not equal to 1 continue*/ if(e != 1) continue; check: /*Find external point*/ for(e=0; e<3 && T->points[e]->id > -1; e++); /*Next mutual case*/ /*Find the adjacent triangle*/ ADJACENT(T, T->points[e], T->points[NEXT(e)], A) if(!A) return -710; /*Find the # of external points in the adjacent triangle*/ for(i=0, m=0; i<3; m+=(A->points[i]->id < 0 ? 1 : 0), ++i); if(m==1){ /*Find adjacent triangles external point*/ for(m=0; m<3 && A->points[m]->id > -1; m++); /*Check whether the convex hull criteria apply*/ a = CCW(T->points[PREV(e)], T->points[e], A->points[T->points[NEXT(e)] == A->points[NEXT(m)] ? PREV(m) : NEXT(m)]); b = CCW(T->points[PREV(e)], T->points[NEXT(e)], A->points[T->points[NEXT(e)] == A->points[NEXT(m)] ? PREV(m) : NEXT(m)]); a*=b; if(a<0){ if((i=swap(T, A))<0) return -711; T = P0->id<0 || P1->id<0 || P2->id<0 ? T : A; goto check; } } /*Find external point*/ for(e=0; e<3 && T->points[e]->id > -1; e++); /*Prev mutual case*/ /*Find the adjacent triangle*/ ADJACENT(T, T->points[e], T->points[PREV(e)], A) if(!A) return -720; /*Find the external point in the adjacent triangle*/ for(i=0, m=0; i<3; m+=(A->points[i]->id < 0 ? 1 : 0), ++i); if(m==1){ /*Find adjacent triangles external point*/ for(m=0; m<3 && A->points[m]->id > -1; m++); /*Check whether the convex hull criteria apply*/ a = CCW(T->points[NEXT(e)], T->points[e], A->points[T->points[NEXT(e)] == A->points[NEXT(m)] ? NEXT(m) : PREV(m)]); b = CCW(T->points[NEXT(e)], T->points[PREV(e)], A->points[T->points[NEXT(e)] == A->points[NEXT(m)] ? NEXT(m) : PREV(m)]); a*=b; if(a<0){ if((i=swap(T, A))<0)return -721;; T = P0->id<0 || P1->id<0 || P2->id<0 ? T : A; goto check; } } } for(T=tHead, A=NULL; T; A=T, T=(A==NULL?T:T->next)){ for(i=0, e=0; i<3; e+=(T->points[i]->id<0?1:0), ++i); if(e==0) continue; if(!A){ A=T; T=T->next; free(A); A=NULL; tHead=T; } else { A->next = T->next; free(T); T=A; } } for(i=0; i<3; ++i){ point=pHead; pHead=pHead->next; free(point); } //return 1; return len; }