430 lines
16 KiB
C++
430 lines
16 KiB
C++
#include "stdafx.h"
|
|
|
|
#include "utils.h"
|
|
#include "primitives.h"
|
|
#include "overlapchecks.h"
|
|
|
|
COverlapChecker g_Overlapper;
|
|
|
|
COverlapChecker::COverlapChecker()
|
|
{
|
|
for(int i=0;i<NPRIMS;i++) for(int j=0;j<NPRIMS;j++)
|
|
table[i][j] = default_overlap_check;
|
|
table[box::type][box::type] = (overlap_check)box_box_overlap_check;
|
|
table[box::type][triangle::type] = (overlap_check)box_tri_overlap_check;
|
|
table[triangle::type][box::type] = (overlap_check)tri_box_overlap_check;
|
|
table[box::type][heightfield::type] = (overlap_check)box_heightfield_overlap_check;
|
|
table[heightfield::type][box::type] = (overlap_check)heightfield_box_overlap_check;
|
|
table[box::type][ray::type] = (overlap_check)box_ray_overlap_check;
|
|
table[ray::type][box::type] = (overlap_check)ray_box_overlap_check;
|
|
table[box::type][sphere::type] = (overlap_check)box_sphere_overlap_check;
|
|
table[sphere::type][box::type] = (overlap_check)sphere_box_overlap_check;
|
|
table[triangle::type][sphere::type] = (overlap_check)tri_sphere_overlap_check;
|
|
table[sphere::type][triangle::type] = (overlap_check)sphere_tri_overlap_check;
|
|
table[sphere::type][sphere::type] = (overlap_check)sphere_sphere_overlap_check;
|
|
table[heightfield::type][sphere::type] = (overlap_check)heightfield_sphere_overlap_check;
|
|
table[sphere::type][heightfield::type] = (overlap_check)sphere_heightfield_overlap_check;
|
|
}
|
|
|
|
int default_overlap_check(const primitive*, const primitive *)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
|
|
int box_box_overlap_check(const box *box1, const box *box2)
|
|
{
|
|
int i;
|
|
matrix3x3RMf &Basis21((matrix3x3RMf&)*(matrix3x3RMf*)g_Overlapper.Basis21);
|
|
|
|
if ((box1->bOriented|box2->bOriented<<16)!=g_Overlapper.iPrevCode) {
|
|
if (!box1->bOriented)
|
|
Basis21 = box2->Basis.T();
|
|
else if (box2->bOriented)
|
|
Basis21 = box1->Basis*box2->Basis.T();
|
|
else
|
|
Basis21 = box1->Basis;
|
|
for(i=0;i<9;i++)
|
|
g_Overlapper.Basis21abs[i] = fabsf(g_Overlapper.Basis21[i]);
|
|
g_Overlapper.iPrevCode = box1->bOriented|box2->bOriented<<16;
|
|
}
|
|
|
|
vectorf center21 = box2->center-box1->center;
|
|
if (box1->bOriented)
|
|
center21 = box1->Basis*center21;
|
|
const vectorf &a=box1->size, &b=box2->size;
|
|
float t1,t2,t3,e=(a.x+a.y+a.z)*1e-4f;
|
|
|
|
// node1 basis vectors
|
|
if (fabsf(center21.x) > a.x+b*vectorf(g_Overlapper.Basis21abs+0))
|
|
return 0;
|
|
if (fabsf(center21.y) > a.y+b*vectorf(g_Overlapper.Basis21abs+3))
|
|
return 0;
|
|
if (fabsf(center21.z) > a.z+b*vectorf(g_Overlapper.Basis21abs+6))
|
|
return 0;
|
|
|
|
// node2 basis vectors
|
|
if (fabsf(center21.x*g_Overlapper.Basis21[0]+center21.y*g_Overlapper.Basis21[3]+center21.z*g_Overlapper.Basis21[6]) >
|
|
a.x*g_Overlapper.Basis21abs[0]+a.y*g_Overlapper.Basis21abs[3]+a.z*g_Overlapper.Basis21abs[6]+b.x)
|
|
return 0;
|
|
if (fabsf(center21.x*g_Overlapper.Basis21[1]+center21.y*g_Overlapper.Basis21[4]+center21.z*g_Overlapper.Basis21[7]) >
|
|
a.x*g_Overlapper.Basis21abs[1]+a.y*g_Overlapper.Basis21abs[4]+a.z*g_Overlapper.Basis21abs[7]+b.y)
|
|
return 0;
|
|
if (fabsf(center21.x*g_Overlapper.Basis21[2]+center21.y*g_Overlapper.Basis21[5]+center21.z*g_Overlapper.Basis21[8]) >
|
|
a.x*g_Overlapper.Basis21abs[2]+a.y*g_Overlapper.Basis21abs[5]+a.z*g_Overlapper.Basis21abs[8]+b.z)
|
|
return 0;
|
|
|
|
// node1->axes[0] x node2->axes[0]
|
|
t1 = a.y*g_Overlapper.Basis21abs[6] + a.z*g_Overlapper.Basis21abs[3];
|
|
t2 = b.y*g_Overlapper.Basis21abs[2] + b.z*g_Overlapper.Basis21abs[1];
|
|
t3 = center21.z*g_Overlapper.Basis21[3] - center21.y*g_Overlapper.Basis21[6];
|
|
if (fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
// node1->axes[0] x node2->axes[1]
|
|
t1 = a.y*g_Overlapper.Basis21abs[7] + a.z*g_Overlapper.Basis21abs[4];
|
|
t2 = b.x*g_Overlapper.Basis21abs[2] + b.z*g_Overlapper.Basis21abs[0];
|
|
t3 = center21.z*g_Overlapper.Basis21[4] - center21.y*g_Overlapper.Basis21[7];;
|
|
if(fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
// node1->axes[0] x node2->axes[2]
|
|
t1 = a.y*g_Overlapper.Basis21abs[8] + a.z*g_Overlapper.Basis21abs[5];
|
|
t2 = b.x*g_Overlapper.Basis21abs[1] + b.y*g_Overlapper.Basis21abs[0];
|
|
t3 = center21.z*g_Overlapper.Basis21[5] - center21.y*g_Overlapper.Basis21[8];
|
|
if(fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
// node1->axes[1] x node2->axes[0]
|
|
t1 = a.x*g_Overlapper.Basis21abs[6] + a.z*g_Overlapper.Basis21abs[0];
|
|
t2 = b.y*g_Overlapper.Basis21abs[5] + b.z*g_Overlapper.Basis21abs[4];
|
|
t3 = center21.x*g_Overlapper.Basis21[6] - center21.z*g_Overlapper.Basis21[0];
|
|
if(fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
// node1->axes[1] x node2->axes[1]
|
|
t1 = a.x*g_Overlapper.Basis21abs[7] + a.z*g_Overlapper.Basis21abs[1];
|
|
t2 = b.x*g_Overlapper.Basis21abs[5] + b.z*g_Overlapper.Basis21abs[3];
|
|
t3 = center21.x*g_Overlapper.Basis21[7] - center21.z*g_Overlapper.Basis21[1];
|
|
if(fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
// node1->axes[1] x node2->axes[2]
|
|
t1 = a.x*g_Overlapper.Basis21abs[8] + a.z*g_Overlapper.Basis21abs[2];
|
|
t2 = b.x*g_Overlapper.Basis21abs[4] + b.y*g_Overlapper.Basis21abs[3];
|
|
t3 = center21.x*g_Overlapper.Basis21[8] - center21.z*g_Overlapper.Basis21[2];
|
|
if(fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
// node1->axes[2] x node2->axes[0]
|
|
t1 = a.x*g_Overlapper.Basis21abs[3] + a.y*g_Overlapper.Basis21abs[0];
|
|
t2 = b.y*g_Overlapper.Basis21abs[8] + b.z*g_Overlapper.Basis21abs[7];
|
|
t3 = center21.y*g_Overlapper.Basis21[0] - center21.x*g_Overlapper.Basis21[3];
|
|
if(fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
// node1->axes[2] x node2->axes[1]
|
|
t1 = a.x*g_Overlapper.Basis21abs[4] + a.y*g_Overlapper.Basis21abs[1];
|
|
t2 = b.x*g_Overlapper.Basis21abs[8] + b.z*g_Overlapper.Basis21abs[6];
|
|
t3 = center21.y*g_Overlapper.Basis21[1] - center21.x*g_Overlapper.Basis21[4];
|
|
if(fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
// node1->axes[2] x node2->axes[2]
|
|
t1 = a.x*g_Overlapper.Basis21abs[5] + a.y*g_Overlapper.Basis21abs[2];
|
|
t2 = b.x*g_Overlapper.Basis21abs[7] + b.y*g_Overlapper.Basis21abs[6];
|
|
t3 = center21.y*g_Overlapper.Basis21[2] - center21.x*g_Overlapper.Basis21[5];
|
|
if(fabsf(t3) > t1+t2+e)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
int box_heightfield_overlap_check(const box *pbox, const heightfield *phf)
|
|
{
|
|
box boxtr;
|
|
vectorf vtx[4];
|
|
triangle hftri;
|
|
vector2df sz,ptmin,ptmax;
|
|
int ix,iy,ix0,iy0,ix1,iy1,icell;
|
|
float hmax;
|
|
|
|
// find the 3 lowest vertices
|
|
if (phf->bOriented) {
|
|
if (pbox->bOriented)
|
|
boxtr.Basis = pbox->Basis*phf->Basis.T();
|
|
else
|
|
boxtr.Basis = phf->Basis.T();
|
|
boxtr.center = phf->Basis*(pbox->center-phf->origin);
|
|
} else {
|
|
boxtr.Basis = pbox->Basis;
|
|
boxtr.center = pbox->center-phf->origin;
|
|
}
|
|
boxtr.bOriented = 1;
|
|
boxtr.Basis.SetRow(0,boxtr.Basis.GetRow(0)*-sgnnz(boxtr.Basis(0,2)));
|
|
boxtr.Basis.SetRow(1,boxtr.Basis.GetRow(1)*-sgnnz(boxtr.Basis(1,2)));
|
|
boxtr.Basis.SetRow(2,boxtr.Basis.GetRow(2)*-sgnnz(boxtr.Basis(2,2)));
|
|
boxtr.size = pbox->size;
|
|
vtx[0] = pbox->size*boxtr.Basis;
|
|
boxtr.Basis.SetRow(0,-boxtr.Basis.GetRow(0)); vtx[1]=pbox->size*boxtr.Basis; boxtr.Basis.SetRow(0,-boxtr.Basis.GetRow(0));
|
|
boxtr.Basis.SetRow(1,-boxtr.Basis.GetRow(1)); vtx[2]=pbox->size*boxtr.Basis; boxtr.Basis.SetRow(1,-boxtr.Basis.GetRow(1));
|
|
boxtr.Basis.SetRow(2,-boxtr.Basis.GetRow(2)); vtx[3]=pbox->size*boxtr.Basis; boxtr.Basis.SetRow(2,-boxtr.Basis.GetRow(2));
|
|
|
|
// find the underlying grid rectangle
|
|
sz.x = sz.y = 0;
|
|
sz.x = max(sz.x, fabsf(vtx[1].x)); sz.y = max(sz.y, fabsf(vtx[1].y));
|
|
sz.x = max(sz.x, fabsf(vtx[2].x)); sz.y = max(sz.y, fabsf(vtx[2].y));
|
|
sz.x = max(sz.x, fabsf(vtx[3].x)); sz.y = max(sz.y, fabsf(vtx[3].y));
|
|
ptmin.x = (boxtr.center.x-sz.x)*phf->stepr.x; ptmin.y = (boxtr.center.y-sz.y)*phf->stepr.y;
|
|
ptmax.x = (boxtr.center.x+sz.x)*phf->stepr.x; ptmax.y = (boxtr.center.y+sz.y)*phf->stepr.y;
|
|
ix0 = float2int(ptmin.x-0.5f); iy0 = float2int(ptmin.y-0.5f); ix0 &= ~(ix0>>31); iy0 &= ~(iy0>>31);
|
|
ix1 = min(float2int(ptmax.x+0.5f),phf->size.x); iy1 = min(float2int(ptmax.y+0.5f),phf->size.y);
|
|
|
|
//if (ix0>ix1 || iy0>iy1 || phf->gettype(ix0,iy0)==-1) // now checks are in CTriMesh on per-tri basis, using materials
|
|
// return 0;
|
|
vtx[0]+=boxtr.center; vtx[1]+=boxtr.center; vtx[2]+=boxtr.center; vtx[3]+=boxtr.center;
|
|
|
|
// check if all heightfield points are below the lowest box point
|
|
for(ix=ix0,hmax=0;ix<=ix1;ix++) for(iy=iy0;iy<=iy1;iy++)
|
|
hmax = max(hmax,phf->getheight(ix,iy));
|
|
if (hmax<vtx[0].z)
|
|
return 0;
|
|
|
|
if ((ix1-ix0)*(iy1-iy0)<=4) {
|
|
// check for intersection with each underlying triangle
|
|
for(ix=ix0;ix<ix1;ix++) for(iy=iy0;iy<iy1;iy++) {
|
|
icell = ix*phf->stride.x+iy*phf->stride.y;
|
|
hftri.pt[0].x=hftri.pt[2].x = ix*phf->step.x; hftri.pt[0].y=hftri.pt[1].y = iy*phf->step.y;
|
|
hftri.pt[1].x = hftri.pt[0].x+phf->step.x; hftri.pt[2].y = hftri.pt[0].y+phf->step.y;
|
|
hftri.pt[0].z = phf->getheight(icell); hftri.pt[1].z = phf->getheight(icell+phf->stride.x);
|
|
hftri.pt[2].z = phf->getheight(icell+phf->stride.y);
|
|
hftri.n = hftri.pt[1]-hftri.pt[0] ^ hftri.pt[2]-hftri.pt[0];
|
|
if (box_tri_overlap_check(&boxtr,&hftri))
|
|
return 1;
|
|
hftri.pt[0] = hftri.pt[2]; hftri.pt[2].x += phf->step.x; hftri.pt[2].z = phf->getheight(icell+phf->stride.x+phf->stride.y);
|
|
hftri.n = hftri.pt[1]-hftri.pt[0] ^ hftri.pt[2]-hftri.pt[0];
|
|
if (box_tri_overlap_check(&boxtr,&hftri))
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int heightfield_box_overlap_check(const heightfield *phf, const box *pbox)
|
|
{
|
|
return box_heightfield_overlap_check(pbox,phf);
|
|
}
|
|
|
|
|
|
int box_tri_overlap_check(const box *pbox, const triangle *ptri)
|
|
{
|
|
vectorf pt[3],n;
|
|
float l1,l2,l3,l,c;
|
|
if (pbox->bOriented) {
|
|
pt[0] = pbox->Basis*(ptri->pt[0]-pbox->center);
|
|
pt[1] = pbox->Basis*(ptri->pt[1]-pbox->center);
|
|
pt[2] = pbox->Basis*(ptri->pt[2]-pbox->center);
|
|
n = pbox->Basis*ptri->n;
|
|
} else {
|
|
pt[0] = ptri->pt[0]-pbox->center;
|
|
pt[1] = ptri->pt[1]-pbox->center;
|
|
pt[2] = ptri->pt[2]-pbox->center;
|
|
n = ptri->n;
|
|
}
|
|
|
|
// check box normals
|
|
l1=fabsf(pt[0].x-pt[1].x); l2=fabsf(pt[1].x-pt[2].x); l3=fabsf(pt[2].x-pt[0].x); l=l1+l2+l3; // half length = l/4
|
|
c = (l1*(pt[0].x+pt[1].x)+l2*(pt[1].x+pt[2].x)+l3*(pt[2].x+pt[0].x))*0.5f; // center = c/l
|
|
if (fabsf(c) > (pbox->size.x+l*0.25f)*l)
|
|
return 0;
|
|
l1=fabsf(pt[0].y-pt[1].y); l2=fabsf(pt[1].y-pt[2].y); l3=fabsf(pt[2].y-pt[0].y); l=l1+l2+l3;
|
|
c = (l1*(pt[0].y+pt[1].y)+l2*(pt[1].y+pt[2].y)+l3*(pt[2].y+pt[0].y))*0.5f;
|
|
if (fabsf(c) > (pbox->size.y+l*0.25f)*l)
|
|
return 0;
|
|
l1=fabsf(pt[0].z-pt[1].z); l2=fabsf(pt[1].z-pt[2].z); l3=fabsf(pt[2].z-pt[0].z); l=l1+l2+l3;
|
|
c = (l1*(pt[0].z+pt[1].z)+l2*(pt[1].z+pt[2].z)+l3*(pt[2].z+pt[0].z))*0.5f;
|
|
if (fabsf(c) > (pbox->size.z+l*0.25f)*l)
|
|
return 0;
|
|
|
|
// check triangle normal
|
|
if (fabsf(n.x)*pbox->size.x+fabsf(n.y)*pbox->size.y+fabsf(n.z)*pbox->size.z < fabsf(n*pt[0]))
|
|
return 0;
|
|
|
|
vectorf edge,triproj1,triproj2;
|
|
float boxproj;
|
|
|
|
// check triangle edges - box edges cross products
|
|
for(int i=0;i<3;i++) {
|
|
edge = pt[inc_mod3[i]]-pt[i]; triproj1 = edge^pt[i]; triproj2 = edge^pt[dec_mod3[i]];
|
|
boxproj = fabsf(pbox->size.y*edge.z) + fabsf(pbox->size.z*edge.y);
|
|
if (fabsf((triproj1.x+triproj2.x)*0.5f) > boxproj+fabsf(triproj1.x-triproj2.x)*0.5f)
|
|
return 0;
|
|
boxproj = fabsf(pbox->size.x*edge.z) + fabsf(pbox->size.z*edge.x);
|
|
if (fabsf((triproj1.y+triproj2.y)*0.5f) > boxproj+fabsf(triproj1.y-triproj2.y)*0.5f)
|
|
return 0;
|
|
boxproj = fabsf(pbox->size.x*edge.y) + fabsf(pbox->size.y*edge.x);
|
|
if (fabsf((triproj1.z+triproj2.z)*0.5f) > boxproj+fabsf(triproj1.z-triproj2.z)*0.5f)
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
int tri_box_overlap_check(const triangle *ptri, const box *pbox)
|
|
{
|
|
return box_tri_overlap_check(pbox,ptri);
|
|
}
|
|
|
|
int box_ray_overlap_check(const box *pbox, const ray *pray)
|
|
{
|
|
vectorf l,m,al;
|
|
if (pbox->bOriented) {
|
|
l = pbox->Basis*pray->dir*0.5f;
|
|
m = pbox->Basis*(pray->origin-pbox->center)+l;
|
|
} else {
|
|
l = pray->dir*0.5f;
|
|
m = pray->origin+l-pbox->center;
|
|
}
|
|
al.x=fabsf(l.x); al.y=fabsf(l.y); al.z=fabsf(l.z);
|
|
|
|
// separating axis check for line and box
|
|
if (fabsf(m.x) > pbox->size.x+al.x)
|
|
return 0;
|
|
if (fabsf(m.y) > pbox->size.y+al.y)
|
|
return 0;
|
|
if (fabsf(m.z) > pbox->size.z+al.z)
|
|
return 0;
|
|
|
|
if (fabsf(m.z*l.y-m.y*l.z) > pbox->size.y*al.z+pbox->size.z*al.y)
|
|
return 0;
|
|
if (fabsf(m.x*l.z-m.z*l.x) > pbox->size.x*al.z+pbox->size.z*al.x)
|
|
return 0;
|
|
if (fabsf(m.x*l.y-m.y*l.x) > pbox->size.x*al.y+pbox->size.y*al.x)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int ray_box_overlap_check(const ray *pray, const box *pbox)
|
|
{
|
|
return box_ray_overlap_check(pbox,pray);
|
|
}
|
|
|
|
|
|
int box_sphere_overlap_check(const box *pbox, const sphere *psph)
|
|
{
|
|
vectorf center=psph->center-pbox->center, dist;
|
|
if (pbox->bOriented)
|
|
center = pbox->Basis*center;
|
|
dist.x = max(0.0f, fabsf(center.x)-pbox->size.x);
|
|
dist.y = max(0.0f, fabsf(center.y)-pbox->size.y);
|
|
dist.z = max(0.0f, fabsf(center.z)-pbox->size.z);
|
|
return isneg(dist.len2()-sqr(psph->r));
|
|
}
|
|
|
|
int sphere_box_overlap_check(const sphere *psph, const box *pbox)
|
|
{
|
|
return box_sphere_overlap_check(pbox,psph);
|
|
}
|
|
|
|
|
|
quotientf tri_sphere_dist2(const triangle* ptri, const sphere* psph, int& bFace)
|
|
{
|
|
int i,bInside[2];
|
|
float rvtx[3],elen2[2],denom;
|
|
vectorf edge[2],dp;
|
|
bFace = 0;
|
|
|
|
rvtx[0] = (ptri->pt[0]-psph->center).len2();
|
|
rvtx[1] = (ptri->pt[1]-psph->center).len2();
|
|
rvtx[2] = (ptri->pt[2]-psph->center).len2();
|
|
|
|
i = idxmin3(rvtx);
|
|
dp = psph->center-ptri->pt[i];
|
|
|
|
edge[0] = ptri->pt[inc_mod3[i]]-ptri->pt[i]; elen2[0] = edge[0].len2();
|
|
edge[1] = ptri->pt[dec_mod3[i]]-ptri->pt[i]; elen2[1] = edge[1].len2();
|
|
bInside[0] = isneg((dp^edge[0])*ptri->n);
|
|
bInside[1] = isneg((edge[1]^dp)*ptri->n);
|
|
rvtx[i] = rvtx[i]*elen2[bInside[0]] - sqr(max(0.0f,dp*edge[bInside[0]]))*(bInside[0]|bInside[1]);
|
|
denom = elen2[bInside[0]];
|
|
|
|
if (bInside[0]&bInside[1]) {
|
|
if (edge[0]*edge[1]<0) {
|
|
edge[0] = ptri->pt[dec_mod3[i]]-ptri->pt[inc_mod3[i]];
|
|
dp = psph->center-ptri->pt[inc_mod3[i]];
|
|
if ((dp^edge[0])*ptri->n>0)
|
|
return quotientf(rvtx[inc_mod3[i]]*edge[0].len2()-sqr(dp*edge[0]), edge[0].len2());
|
|
}
|
|
bFace = 1;
|
|
return quotientf(sqr((psph->center-ptri->pt[0])*ptri->n),1.0f);
|
|
}
|
|
return quotientf(rvtx[i],denom);
|
|
}
|
|
|
|
|
|
int tri_sphere_overlap_check(const triangle *ptri, const sphere *psph)
|
|
{
|
|
int bFace;
|
|
return isneg(tri_sphere_dist2(ptri,psph,bFace)-sqr(psph->r));
|
|
|
|
/*float r2=sqr(psph->r),edgelen2;
|
|
vectorf edge,dp0,dp1;
|
|
|
|
if ((ptri->pt[0]-psph->center).len2()<r2)
|
|
return 1;
|
|
if ((ptri->pt[1]-psph->center).len2()<r2)
|
|
return 1;
|
|
if ((ptri->pt[2]-psph->center).len2()<r2)
|
|
return 1;
|
|
|
|
edgelen2 = (edge = ptri->pt[1]-ptri->pt[0]).len2(); dp0 = ptri->pt[0]-psph->center; dp1 = ptri->pt[1]-psph->center;
|
|
if (isneg((dp0^edge).len2()-r2*edgelen2) & isneg((dp0*edge)*(dp1*edge)))
|
|
return 1;
|
|
edgelen2 = (edge = ptri->pt[2]-ptri->pt[1]).len2(); dp0 = ptri->pt[1]-psph->center; dp1 = ptri->pt[2]-psph->center;
|
|
if (isneg((dp0^edge).len2()-r2*edgelen2) & isneg((dp0*edge)*(dp1*edge)))
|
|
return 1;
|
|
edgelen2 = (edge = ptri->pt[0]-ptri->pt[2]).len2(); dp0 = ptri->pt[2]-psph->center; dp1 = ptri->pt[0]-psph->center;
|
|
if (isneg((dp0^edge).len2()-r2*edgelen2) & isneg((dp0*edge)*(dp1*edge)))
|
|
return 1;
|
|
|
|
return 0;*/
|
|
}
|
|
|
|
int sphere_tri_overlap_check(const sphere *psph, const triangle *ptri)
|
|
{
|
|
return tri_sphere_overlap_check(ptri,psph);
|
|
}
|
|
|
|
|
|
int sphere_sphere_overlap_check(const sphere *psph1, const sphere *psph2)
|
|
{
|
|
return isneg((psph1->center-psph2->center).len2()-sqr(psph1->r+psph2->r));
|
|
}
|
|
|
|
|
|
int heightfield_sphere_overlap_check(const heightfield *phf, const sphere *psph)
|
|
{
|
|
vectorf center;
|
|
vector2di irect[2];
|
|
int ix,iy,bContact=0;
|
|
|
|
center = phf->Basis*(psph->center-phf->origin);
|
|
irect[0].x = min(phf->size.x,max(0,float2int((center.x-psph->r)*phf->stepr.x-0.5f)));
|
|
irect[0].y = min(phf->size.y,max(0,float2int((center.y-psph->r)*phf->stepr.y-0.5f)));
|
|
irect[1].x = min(phf->size.x,max(0,float2int((center.x+psph->r)*phf->stepr.x+0.5f)));
|
|
irect[1].y = min(phf->size.y,max(0,float2int((center.y+psph->r)*phf->stepr.y+0.5f)));
|
|
|
|
for(ix=irect[0].x;ix<irect[1].x;ix++) for(iy=irect[0].y;iy<irect[1].y;iy++)
|
|
bContact |= isneg(center.z-psph->r-phf->getheight(ix,iy));
|
|
|
|
return bContact;
|
|
}
|
|
|
|
int sphere_heightfield_overlap_check(const sphere *psph, const heightfield *phf)
|
|
{
|
|
return heightfield_sphere_overlap_check(phf,psph);
|
|
} |