69 #define STANDALONE 1 // This #define is used when tranferring this source code to other projects
76 #define NX_ALLOC(x,y) malloc(x)
77 #define NX_FREE(x) free(x)
80 #include "Allocateable.h"
91 template <
class Type>
class Array
119 template <
class Type>
class ArrayRet:
public Array<Type>
140 for(
int i=0;i<array.
count;i++)
154 array_size = array.array_size;
155 element = array.element;
166 for(
int i=0;i<array.
count;i++)
179 count=0;array_size=0;element=NULL;
188 element = (Type *)
NX_ALLOC(
sizeof(Type)*array_size, CONVEX_TEMP );
190 for(
int i=0;i<count;i++)
225 assert(count<=array_size);
226 if(count==array_size)
228 allocate((array_size)?array_size *2:16);
230 element[count++] = t;
231 return element[count-1];
240 if(element[i] == t) found++;
247 if(!Contains(t)) Add(t);
257 element[i] = element[i+1];
276 assert(element[i] != t);
286 element[i]=element[i-1];
311 #ifndef PLUGIN_3DSMAX
312 #define PI (3.1415926535897932384626433832795f)
315 #define DEG2RAD (PI / 180.0f)
316 #define RAD2DEG (180.0f / PI)
317 #define SQRT_OF_2 (1.4142135f)
318 #define OFFSET(Class,Member) (((char*) (&(((Class*)NULL)-> Member )))- ((char*)NULL))
322 int argmin(
double a[],
int n);
323 double sqr(
double a);
325 double Round(
double a,
double precision);
326 double Interpolate(
const double &f0,
const double &f1,
double alpha) ;
339 T
Max(
const T &a,
const T &b)
345 T
Min(
const T &a,
const T &b)
371 double&
operator[](
int i) {assert(i>=0&&i<2);
return ((
double*)
this)[i];}
372 const double&
operator[](
int i)
const {assert(i>=0&&i<2);
return ((
double*)
this)[i];}
386 double&
operator[](
int i) {assert(i>=0&&i<3);
return ((
double*)
this)[i];}
387 const double&
operator[](
int i)
const {assert(i>=0&&i<3);
return ((
double*)
this)[i];}
388 # ifdef PLUGIN_3DSMAX
390 operator Point3(){
return *((Point3*)
this);}
395 double3&
operator+=( double3 &a,
const double3& b );
396 double3&
operator-=( double3 &a ,
const double3& b );
397 double3&
operator*=( double3 &v ,
const double s );
398 double3&
operator/=( double3 &v,
const double s );
403 double3
vabs(
const double3 &v);
404 double3
operator+(
const double3& a,
const double3& b );
405 double3
operator-(
const double3& a,
const double3& b );
407 double3
operator*(
const double3& v,
const double s );
408 double3
operator*(
const double s,
const double3& v );
409 double3
operator/(
const double3& v,
const double s );
413 double dot(
const double3& a,
const double3& b );
414 double3
cmul(
const double3 &a,
const double3 &b);
415 double3
cross(
const double3& a,
const double3& b );
416 double3
Interpolate(
const double3 &v0,
const double3 &v1,
double alpha);
417 double3
Round(
const double3& a,
double precision);
418 double3
VectorMax(
const double3 &a,
const double3 &b);
419 double3
VectorMin(
const double3 &a,
const double3 &b);
428 double3x3(
double xx,
double xy,
double xz,
double yx,
double yy,
double yz,
double zx,
double zy,
double zz):
x(xx,xy,xz),
y(yx,yy,yz),
z(zx,zy,zz){}
432 double&
operator()(
int r,
int c) {assert(r>=0&&r<3&&c>=0&&c<3);
return ((&
x)[r])[c];}
433 const double&
operator()(
int r,
int c)
const {assert(r>=0&&r<3&&c>=0&&c<3);
return ((&
x)[r])[c];}
435 double3x3
Transpose(
const double3x3& m );
436 double3
operator*(
const double3& v ,
const double3x3& m );
437 double3
operator*(
const double3x3& m ,
const double3& v );
438 double3x3
operator*(
const double3x3& m ,
const double& s );
439 double3x3
operator*(
const double3x3& ma,
const double3x3& mb );
440 double3x3
operator/(
const double3x3& a,
const double& s ) ;
441 double3x3
operator+(
const double3x3& a,
const double3x3& b );
442 double3x3
operator-(
const double3x3& a,
const double3x3& b );
443 double3x3 &
operator+=( double3x3& a,
const double3x3& b );
444 double3x3 &
operator-=( double3x3& a,
const double3x3& b );
445 double3x3 &
operator*=( double3x3& a,
const double& s );
447 double3x3
Inverse(
const double3x3& a);
457 double4(
double _x,
double _y,
double _z,
double _w){
x=_x;
y=_y;
z=_z;
w=_w;}
460 double&
operator[](
int i) {assert(i>=0&&i<4);
return ((
double*)
this)[i];}
461 const double&
operator[](
int i)
const {assert(i>=0&&i<4);
return ((
double*)
this)[i];}
475 double4x4(
double m00,
double m01,
double m02,
double m03,
476 double m10,
double m11,
double m12,
double m13,
477 double m20,
double m21,
double m22,
double m23,
478 double m30,
double m31,
double m32,
double m33 )
479 :
x(m00,m01,m02,m03),
y(m10,m11,m12,m13),
z(m20,m21,m22,m23),
w(m30,m31,m32,m33){}
480 double&
operator()(
int r,
int c) {assert(r>=0&&r<4&&c>=0&&c<4);
return ((&
x)[r])[c];}
481 const double&
operator()(
int r,
int c)
const {assert(r>=0&&r<4&&c>=0&&c<4);
return ((&
x)[r])[c];}
482 operator double* () {
return &
x.
x;}
483 operator const double* ()
const {
return &
x.
x;}
484 operator struct D3DXMATRIX* () {
return (
struct D3DXMATRIX*)
this;}
485 operator const struct D3DXMATRIX* ()
const {
return (
struct D3DXMATRIX*)
this;}
489 int operator==(
const double4 &a,
const double4 &b );
490 double4
Homogenize(
const double3 &v3,
const double &w=1.0f);
491 double4
cmul(
const double4 &a,
const double4 &b);
492 double4
operator*(
const double4 &v,
double s);
493 double4
operator*(
double s,
const double4 &v);
494 double4
operator+(
const double4 &a,
const double4 &b);
495 double4
operator-(
const double4 &a,
const double4 &b);
496 double4x4
operator*(
const double4x4& a,
const double4x4& b );
497 double4
operator*(
const double4& v,
const double4x4& m );
498 double4x4
Inverse(
const double4x4 &m);
504 double4x4
MatrixLookAt(
const double3& eye,
const double3& at,
const double3& up);
505 int operator==(
const double4x4 &a,
const double4x4 &b );
516 double angle()
const {
return acos(
w)*2.0f; }
526 Quaternion&
operator*=(Quaternion& a,
double s );
527 Quaternion
operator*(
const Quaternion& a,
double s );
528 Quaternion
operator*(
const Quaternion& a,
const Quaternion& b);
529 Quaternion
operator+(
const Quaternion& a,
const Quaternion& b );
531 double dot(
const Quaternion &a,
const Quaternion &b );
532 double3
operator*(
const Quaternion& q,
const double3& v );
533 double3
operator*(
const double3& v,
const Quaternion& q );
534 Quaternion
slerp( Quaternion a,
const Quaternion& b,
double interp );
535 Quaternion
Interpolate(
const Quaternion &q0,
const Quaternion &q1,
double alpha);
537 Quaternion
Inverse(
const Quaternion &q);
543 Quaternion
YawPitchRoll(
double yaw,
double pitch,
double roll );
544 double Yaw(
const Quaternion& q );
545 double Pitch(
const Quaternion& q );
546 double Roll( Quaternion q );
547 double Yaw(
const double3& v );
548 double Pitch(
const double3& v );
571 double3
PlaneProject(
const Plane &plane,
const double3 &point);
572 double3
LineProject(
const double3 &p0,
const double3 &p1,
const double3 &a);
573 double LineProjectTime(
const double3 &p0,
const double3 &p1,
const double3 &a);
575 int PolyHit(
const double3 *vert,
const int n,
const double3 &v0,
const double3 &v1, double3 *impact=NULL, double3 *normal=NULL);
576 int BoxInside(
const double3 &p,
const double3 &bmin,
const double3 &bmax) ;
577 int BoxIntersect(
const double3 &v0,
const double3 &v1,
const double3 &bmin,
const double3 &bmax, double3 *impact);
578 double DistanceBetweenLines(
const double3 &ustart,
const double3 &udir,
const double3 &vstart,
const double3 &vdir, double3 *upoint=NULL, double3 *vpoint=NULL);
579 double3
TriNormal(
const double3 &v0,
const double3 &v1,
const double3 &v2);
580 double3
NormalOf(
const double3 *vert,
const int n);
581 Quaternion
VirtualTrackBall(
const double3 &cop,
const double3 &cor,
const double3 &dir0,
const double3 &dir1);
591 double sqr(
double a) {
return a*a;}
595 double Round(
double a,
double precision)
597 return floor(0.5f+a/precision)*precision;
601 double Interpolate(
const double &f0,
const double &f1,
double alpha)
603 return f0*(1-alpha) + f1*alpha;
663 return a.
x*b.
x + a.
y*b.
y + a.
z*b.
z;
711 double sinv = 1.0f / s;
720 return double3(fabs(v.
x),fabs(v.
y),fabs(v.
z));
737 printf(
"Cant normalize ZERO vector\n");
762 return v0*(1-alpha) + v1*alpha;
806 b[j][i] = (a[i1][j1]*a[i2][j2]-a[i1][j2]*a[i2][j1])/d;
890 return v.
x*m.
x + v.
y*m.
y + v.
z*m.
z + v.
w*m.
w;
895 return (a.
x==b.
x && a.
y==b.
y && a.
z==b.
z && a.
w==b.
w);
971 double h = 1.0f/tan(fovy/2.0f);
972 double w = h / aspect ;
976 0, 0, zf/(zn-zf) , -1,
977 0, 0, zn*zf/(zn-zf) , 0 );
1006 double s = sin(angle_radians);
1007 double c = cos(angle_radians);
1019 return (a.
x==b.
x && a.
y==b.
y && a.
z==b.
z && a.
w==b.
w);
1026 double *dst = &d.
x.
x;
1031 for (
int i = 0; i < 4; i++) {
1033 src[i + 4] = m(i,1);
1034 src[i + 8] = m(i,2);
1035 src[i + 12] = m(i,3);
1038 tmp[0] = src[10] * src[15];
1039 tmp[1] = src[11] * src[14];
1040 tmp[2] = src[9] * src[15];
1041 tmp[3] = src[11] * src[13];
1042 tmp[4] = src[9] * src[14];
1043 tmp[5] = src[10] * src[13];
1044 tmp[6] = src[8] * src[15];
1045 tmp[7] = src[11] * src[12];
1046 tmp[8] = src[8] * src[14];
1047 tmp[9] = src[10] * src[12];
1048 tmp[10] = src[8] * src[13];
1049 tmp[11] = src[9] * src[12];
1051 dst[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7];
1052 dst[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7];
1053 dst[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7];
1054 dst[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7];
1055 dst[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7];
1056 dst[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7];
1057 dst[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6];
1058 dst[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6];
1059 dst[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3];
1060 dst[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3];
1061 dst[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3];
1062 dst[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3];
1063 dst[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3];
1064 dst[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3];
1065 dst[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2];
1066 dst[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2];
1068 tmp[0] = src[2]*src[7];
1069 tmp[1] = src[3]*src[6];
1070 tmp[2] = src[1]*src[7];
1071 tmp[3] = src[3]*src[5];
1072 tmp[4] = src[1]*src[6];
1073 tmp[5] = src[2]*src[5];
1074 tmp[6] = src[0]*src[7];
1075 tmp[7] = src[3]*src[4];
1076 tmp[8] = src[0]*src[6];
1077 tmp[9] = src[2]*src[4];
1078 tmp[10] = src[0]*src[5];
1079 tmp[11] = src[1]*src[4];
1081 dst[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15];
1082 dst[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15];
1083 dst[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15];
1084 dst[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15];
1085 dst[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15];
1086 dst[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15];
1087 dst[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14];
1088 dst[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14];
1089 dst[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9];
1090 dst[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10];
1091 dst[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10];
1092 dst[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8];
1093 dst[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8];
1094 dst[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9];
1095 dst[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9];
1096 dst[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8];
1098 det=src[0]*dst[0]+src[1]*dst[1]+src[2]*dst[2]+src[3]*dst[3];
1101 for (
int j = 0; j < 16; j++)
1112 c.
w = a.
w*b.
w - a.
x*b.
x - a.
y*b.
y - a.
z*b.
z;
1113 c.
x = a.
w*b.
x + a.
x*b.
w + a.
y*b.
z - a.
z*b.
y;
1114 c.
y = a.
w*b.
y - a.
x*b.
z + a.
y*b.
w + a.
z*b.
x;
1115 c.
z = a.
w*b.
z + a.
x*b.
y - a.
y*b.
x + a.
z*b.
w;
1141 if(m<0.000000001f) {
1146 (*this) *= (1.0f/m);
1153 double qx2 = q.
x*q.
x;
1154 double qy2 = q.
y*q.
y;
1155 double qz2 = q.
z*q.
z;
1157 double qxqy = q.
x*q.
y;
1158 double qxqz = q.
x*q.
z;
1159 double qxqw = q.
x*q.
w;
1160 double qyqz = q.
y*q.
z;
1161 double qyqw = q.
y*q.
w;
1162 double qzqw = q.
z*q.
w;
1164 (1-2*(qy2+qz2))*v.
x + (2*(qxqy-qzqw))*v.
y + (2*(qxqz+qyqw))*v.
z ,
1165 (2*(qxqy+qzqw))*v.
x + (1-2*(qx2+qz2))*v.
y + (2*(qyqz-qxqw))*v.
z ,
1166 (2*(qxqz-qyqw))*v.
x + (2*(qyqz+qxqw))*v.
y + (1-2*(qx2+qy2))*v.
z );
1172 return double3(0.0f,0.0f,0.0f);
1182 return (a.
w*b.
w + a.
x*b.
x + a.
y*b.
y + a.
z*b.
z);
1206 double d =
dot(a,b);
1210 double theta = acos(d);
1211 if(theta==0.0f) {
return(a);}
1212 return a*(sin(theta-interp*theta)/sin(theta)) + b*(sin(interp*theta)/sin(theta));
1217 return slerp(q0,q1,alpha);
1233 return (v.
y==0.0&&v.
x==0.0) ? 0.0: atan2(-v.
x,v.
y)*
RAD2DEG;
1252 return (v.
y==0.0&&v.
x==0.0) ? 0.0f: atan2(-v.
x,v.
y)*
RAD2DEG;
1274 dist = -
dot(newnormal, origin);
1291 double d =
dot(v0,v1);
1293 double s = sqrt((1+d)*2);
1305 double qx2 = q.
x*q.
x;
1306 double qy2 = q.
y*q.
y;
1307 double qz2 = q.
z*q.
z;
1309 double qxqy = q.
x*q.
y;
1310 double qxqz = q.
x*q.
z;
1311 double qxqw = q.
x*q.
w;
1312 double qyqz = q.
y*q.
z;
1313 double qyqw = q.
y*q.
w;
1314 double qzqw = q.
z*q.
w;
1343 return p0 + (dif*t);
1376 if(m==0)
return double3(1,0,0);
1384 return (p.
x >= bmin.
x && p.
x <=bmax.
x &&
1385 p.
y >= bmin.
y && p.
y <=bmax.
y &&
1386 p.
z >= bmin.
z && p.
z <=bmax.
z );
1397 if(v0.
x<=bmin.
x && v1.
x>=bmin.
x)
1399 double a = (bmin.
x-v0.
x)/(v1.
x-v0.
x);
1401 double vy = (1-a) *v0.
y + a*v1.
y;
1402 double vz = (1-a) *v0.
z + a*v1.
z;
1403 if(vy>=bmin.
y && vy<=bmax.y && vz>=bmin.
z && vz<=bmax.
z)
1411 else if(v0.
x >= bmax.
x && v1.
x <= bmax.
x)
1413 double a = (bmax.
x-v0.
x)/(v1.
x-v0.
x);
1415 double vy = (1-a) *v0.
y + a*v1.
y;
1416 double vz = (1-a) *v0.
z + a*v1.
z;
1417 if(vy>=bmin.
y && vy<=bmax.y && vz>=bmin.
z && vz<=bmax.
z)
1425 if(v0.
y<=bmin.
y && v1.
y>=bmin.
y)
1427 double a = (bmin.
y-v0.
y)/(v1.
y-v0.
y);
1428 double vx = (1-a) *v0.
x + a*v1.
x;
1430 double vz = (1-a) *v0.
z + a*v1.
z;
1431 if(vx>=bmin.
x && vx<=bmax.x && vz>=bmin.
z && vz<=bmax.
z)
1439 else if(v0.
y >= bmax.
y && v1.
y <= bmax.
y)
1441 double a = (bmax.
y-v0.
y)/(v1.
y-v0.
y);
1442 double vx = (1-a) *v0.
x + a*v1.
x;
1444 double vz = (1-a) *v0.
z + a*v1.
z;
1445 if(vx>=bmin.
x && vx<=bmax.x && vz>=bmin.
z && vz<=bmax.
z)
1453 if(v0.
z<=bmin.
z && v1.
z>=bmin.
z)
1455 double a = (bmin.
z-v0.
z)/(v1.
z-v0.
z);
1456 double vx = (1-a) *v0.
x + a*v1.
x;
1457 double vy = (1-a) *v0.
y + a*v1.
y;
1459 if(vy>=bmin.
y && vy<=bmax.y && vx>=bmin.
x && vx<=bmax.
x)
1467 else if(v0.
z >= bmax.
z && v1.
z <= bmax.
z)
1469 double a = (bmax.
z-v0.
z)/(v1.
z-v0.
z);
1470 double vx = (1-a) *v0.
x + a*v1.
x;
1471 double vy = (1-a) *v0.
y + a*v1.
y;
1473 if(vy>=bmin.
y && vy<=bmax.y && vx>=bmin.
x && vx<=bmax.
x)
1490 double distu = -
dot(cp,ustart);
1491 double distv = -
dot(cp,vstart);
1492 double dist = (double)fabs(distu-distv);
1525 double fudgefactor = 1.0f/(
magnitude(nrml) * 0.25f);
1527 double dist = -
dot(nrml,cor);
1538 u=u - (nrml * sqrt(1-m*m));
1550 v=v - (nrml * sqrt(1-m*m));
1566 nrml = nrml +
cross(vert[i1]-vert[i],vert[i2]-vert[i1]);
1574 nrml = nrml * (1.0f/m);
1575 double dist = -
dot(nrml,vert[0]);
1577 if((d0=
dot(v0,nrml)+dist) <0 || (d1=
dot(v1,nrml)+dist) >0)
1586 double a = d0/(d0-d1);
1587 the_point = v0*(1-a) + v1*a;
1591 for(
int j=0;inside && j<n;j++)
1596 pp2 = vert[(j+1)%n];
1597 side =
cross((pp2-pp1),(the_point-pp1));
1598 inside = (
dot(nrml,side) >= 0.0);
1602 if(normal){*normal=nrml;}
1603 if(impact){*impact=the_point;}
1631 bool ComputeHull(
unsigned int vcount,
const double *vertices,
PHullResult &result,
unsigned int maxverts,
double inflate);
1639 #define REAL3 double3
1642 #define COPLANAR (0)
1645 #define SPLIT (OVER|UNDER)
1646 #define PAPERWIDTH (0.001f)
1647 #define VOLUME_EPSILON (1e-20f)
1654 class
ConvexH :
public NxFoundation::NxAllocateable
1665 HalfEdge(
short _ea,
unsigned char _v,
unsigned char _p):
ea(_ea),
v(_v),
p(_p){}
1670 ConvexH(
int vertices_size,
int edges_size,
int facets_size);
1676 :vertices(vertices_size)
1678 ,facets(facets_size)
1681 edges.count = edges_size;
1682 facets.count = facets_size;
1746 for(i=0;i<convex.
edges.count;i++) {
1747 if(convex.
edges[estart].p!= convex.
edges[i].p) {
1751 if(inext>= convex.
edges.count || convex.
edges[inext].p != convex.
edges[i].p) {
1754 assert(convex.
edges[inext].p == convex.
edges[i].p);
1756 int nb = convex.
edges[i].ea;
1758 if(nb==255 || nb==-1)
return 0;
1760 assert(i== convex.
edges[nb].ea);
1762 for(i=0;i<convex.
edges.count;i++) {
1765 if(convex.
edges[estart].p!= convex.
edges[i].p) {
1769 if(i1>= convex.
edges.count || convex.
edges[i1].p != convex.
edges[i].p) {
1773 if(i2>= convex.
edges.count || convex.
edges[i2].p != convex.
edges[i].p) {
1781 if(
dot(localnormal,convex.
facets[convex.
edges[i].p].normal)<=0)
return 0;
1893 int vertcountunder=0;
1894 int vertcountover =0;
1895 int edgecountunder=0;
1896 int edgecountover =0;
1897 int planecountunder=0;
1898 int planecountover =0;
1900 vertscoplanar.
count=0;
1904 assert(convex.
edges.count<480);
1910 Plane tmpunderplanes[128];
1912 int coplanaredges_num=0;
1918 if(vertflag[i].planetest ==
COPLANAR) {
1920 vertflag[i].
undermap = vertcountunder++;
1921 vertflag[i].
overmap = vertcountover++;
1923 else if(vertflag[i].planetest ==
UNDER) {
1924 vertflag[i].
undermap = vertcountunder++;
1927 assert(vertflag[i].planetest ==
OVER);
1928 vertflag[i].
overmap = vertcountover++;
1929 vertflag[i].
undermap = (
unsigned char)-1;
1932 int vertcountunderold = vertcountunder;
1934 int under_edge_count =0;
1935 int underplanescount=0;
1938 for(
int currentplane=0; currentplane<convex.
facets.count; currentplane++) {
1947 int coplanaredge = -1;
1950 if(e1 >= convex.
edges.count || convex.
edges[e1].p!=currentplane) {
1973 edgeflag[e0].
undermap = under_edge_count;
1974 tmpunderedges[under_edge_count].
v = vertflag[edge0.
v].
undermap;
1975 tmpunderedges[under_edge_count].
p = underplanescount;
1979 tmpunderedges[under_edge_count].
ea = edgeflag[edge0.
ea].
undermap;
1980 tmpunderedges[edgeflag[edge0.
ea].
undermap].
ea = under_edge_count;
1988 if(e2>=convex.
edges.count || convex.
edges[e2].p!=currentplane) {
1991 assert(convex.
edges[e2].p==currentplane);
1995 edgeflag[e0].
undermap = under_edge_count;
1996 tmpunderedges[under_edge_count].
v = vertflag[edge0.
v].
undermap;
1997 tmpunderedges[under_edge_count].
p = underplanescount;
1998 tmpunderedges[under_edge_count].
ea = -1;
2000 coplanaredge = under_edge_count;
2012 edgeflag[e0].
undermap = under_edge_count;
2013 tmpunderedges[under_edge_count].
v = vertflag[edge0.
v].
undermap;
2014 tmpunderedges[under_edge_count].
p = underplanescount;
2018 tmpunderedges[under_edge_count].
ea = edgeflag[edge0.
ea].
undermap;
2019 tmpunderedges[edgeflag[edge0.
ea].
undermap].
ea = under_edge_count;
2020 vout = tmpunderedges[edgeflag[edge0.
ea].
undermap].
v;
2028 vout = vertcountunder++;
2033 tmpunderedges[under_edge_count].
v = vout;
2034 tmpunderedges[under_edge_count].
p = underplanescount;
2035 tmpunderedges[under_edge_count].
ea = -1;
2036 coplanaredge = under_edge_count;
2054 assert(edge0.
p == currentplane);
2055 while(!(planeside&
UNDER) && k<convex.
edges.count && convex.
edges[k].p==edge0.
p) {
2059 if(planeside&
UNDER){
2060 tmpunderedges[under_edge_count].
v = vout;
2061 tmpunderedges[under_edge_count].
p = underplanescount;
2062 tmpunderedges[under_edge_count].
ea = -1;
2063 coplanaredge = under_edge_count;
2071 if (vin!=-1)
return NULL;
2078 vin = vertcountunder++;
2083 assert(tmpunderedges[nea].p==tmpunderedges[nea+1].p);
2084 vin = tmpunderedges[nea+1].
v;
2085 assert(vin < vertcountunder);
2086 assert(vin >= vertcountunderold);
2094 tmpunderedges[under_edge_count].
v = vin;
2095 tmpunderedges[under_edge_count].
p = underplanescount;
2096 edgeflag[e0].
undermap = under_edge_count;
2100 tmpunderedges[under_edge_count].
ea = edgeflag[edge0.
ea].
undermap;
2101 tmpunderedges[edgeflag[edge0.
ea].
undermap].
ea = under_edge_count;
2103 assert(edgeflag[e0].undermap == under_edge_count);
2111 if (vin==-1)
return NULL;
2127 }
while(e0!=estart) ;
2129 if(planeside&
UNDER) {
2130 planeflag[currentplane].
undermap = underplanescount;
2131 tmpunderplanes[underplanescount] = convex.
facets[currentplane];
2135 planeflag[currentplane].
undermap = 0;
2137 if(vout>=0 && (planeside&
UNDER)) {
2139 assert(coplanaredge>=0);
2140 assert(coplanaredge!=511);
2141 coplanaredges[coplanaredges_num].
ea = coplanaredge;
2142 coplanaredges[coplanaredges_num].
v0 = vin;
2143 coplanaredges[coplanaredges_num].
v1 = vout;
2144 coplanaredges_num++;
2149 if(coplanaredges_num>0) {
2150 tmpunderplanes[underplanescount++]=slice;
2152 for(i=0;i<coplanaredges_num-1;i++) {
2153 if(coplanaredges[i].v1 != coplanaredges[i+1].v0) {
2155 for(j=i+2;j<coplanaredges_num;j++) {
2156 if(coplanaredges[i].v1 == coplanaredges[j].v0) {
2158 coplanaredges[i+1] = coplanaredges[j];
2159 coplanaredges[j] = tmp;
2163 if(j>=coplanaredges_num)
2171 ConvexH *punder =
new ConvexH(vertcountunder,under_edge_count+coplanaredges_num,underplanescount);
2173 ConvexH *punder = NX_NEW_MEM(
ConvexH(vertcountunder,under_edge_count+coplanaredges_num,underplanescount), CONVEX_TEMP);
2179 if(vertflag[i].planetest !=
OVER){
2184 while(k<vertcountunder) {
2185 under.
vertices[k++] = createdverts[i++];
2187 assert(i==createdverts.
count);
2189 for(i=0;i<coplanaredges_num;i++) {
2190 under.
edges[under_edge_count+i].p = underplanescount-1;
2191 under.
edges[under_edge_count+i].ea = coplanaredges[i].
ea;
2192 tmpunderedges[coplanaredges[i].
ea].
ea = under_edge_count+i;
2193 under.
edges[under_edge_count+i].v = coplanaredges[i].
v0;
2196 memcpy(under.
edges.element,tmpunderedges,
sizeof(
HalfEdge)*under_edge_count);
2197 memcpy(under.
facets.element,tmpunderplanes,
sizeof(
Plane)*underplanescount);
2209 for(i=0;i<planes_count;i++)
2219 double dr = dmax-dmin;
2223 for(j=0;j<convex->
facets.count;j++)
2225 if(planes[i]==convex->
facets[j])
2229 if(
dot(planes[i].normal,convex->
facets[j].normal)>maxdot_minang)
2231 for(
int k=0;k<convex->
edges.count;k++)
2233 if(convex->
edges[k].p!=j)
continue;
2248 return (md>epsilon)?p:-1;
2254 inline int maxdir(
const T *p,
int count,
const T &dir)
2258 for(
int i=1;i<count;i++)
2260 if(
dot(p[i],dir)>
dot(p[m],dir)) m=i;
2271 for(
int i=0;i<count;i++)
if(allow[i])
2273 if(m==-1 ||
dot(p[i],dir)>
dot(p[m],dir)) m=i;
2294 if(allow[m]==3)
return m;
2298 for(
double x = 0.0f ; x<= 360.0f ; x+= 45.0f)
2308 if(ma!=-1 && ma!=mb)
2311 for(
double xx = x-40.0f ; xx <= x ; xx+= 5.0f)
2338 for(
int i=0;i<3;i++)
2340 if(a[i]!=b[i])
return 0;
2355 return ( a==b ||
roll3(a)==b || a==
roll3(b) );
2359 return isa(a,
int3(b[2],b[1],b[0]));
2364 return (
dot(n,p-vertices[t[0]]) > epsilon);
2368 for(
int i=0;i<3;i++)
2371 if(t[i]==a && t[i1]==b)
return 1;
2377 return (t[0]==v || t[1]==v || t[2]==v) ;
2385 if(
hasedge(a,b[i1],b[i]))
return 1;
2397 class
Tri :
public int3,
public NxFoundation::NxAllocateable
2414 assert(
tris[
id]==
this);
2417 int &
neib(
int a,
int b);
2429 if((*
this)[i]==a && (*this)[i1]==b)
return n[i2];
2430 if((*
this)[i]==b && (*this)[i1]==a)
return n[i2];
2444 assert(
tris[s->
neib(a,b)]->neib(b,a) == s->
id);
2445 assert(
tris[t->
neib(a,b)]->neib(b,a) == t->
id);
2469 assert(
tris[t->
n[i]]->neib(b,a) == t->
id);
2477 Tri* ta =
new Tri(v,t[1],t[2]);
2479 Tri* ta = NX_NEW_MEM(
Tri(v,t[1],t[2]), CONVEX_TEMP);
2481 ta->
n =
int3(t0->
n[0],n+1,n+2);
2482 tris[t0->
n[0]]->neib(t[1],t[2]) = n+0;
2484 Tri* tb =
new Tri(v,t[2],t[0]);
2486 Tri* tb = NX_NEW_MEM(
Tri(v,t[2],t[0]), CONVEX_TEMP);
2488 tb->
n =
int3(t0->
n[1],n+2,n+0);
2489 tris[t0->
n[1]]->neib(t[2],t[0]) = n+1;
2491 Tri* tc =
new Tri(v,t[0],t[1]);
2493 Tri* tc = NX_NEW_MEM(
Tri(v,t[0],t[1]), CONVEX_TEMP);
2495 tc->
n =
int3(t0->
n[2],n+0,n+1);
2496 tris[t0->
n[2]]->neib(t[0],t[1]) = n+2;
2511 for(i=0;i<
tris.count;i++)
2518 return (t->
rise >epsilon)?t:NULL ;
2526 int4(
int _x,
int _y,
int _z,
int _w){
x=_x;
y=_y;
z=_z;
w=_w;}
2535 double3 result3 =
cross(verts[p1]-verts[p0], verts[p2]-verts[p0]);
2538 double result =
dot(
normalize(result3), verts[p3]-verts[p0]);
2545 basis[0] =
double3( 0.01f, 0.02f, 1.0f );
2546 int p0 =
maxdirsterid(verts,verts_count, basis[0],allow);
2547 int p1 =
maxdirsterid(verts,verts_count,-basis[0],allow);
2548 basis[0] = verts[p0]-verts[p1];
2549 if(p0==p1 || basis[0]==
double3(0,0,0))
2550 return int4(-1,-1,-1,-1);
2554 int p2 =
maxdirsterid(verts,verts_count,basis[1],allow);
2555 if(p2 == p0 || p2 == p1)
2559 if(p2 == p0 || p2 == p1)
2560 return int4(-1,-1,-1,-1);
2561 basis[1] = verts[p2] - verts[p0];
2563 int p3 =
maxdirsterid(verts,verts_count,basis[2],allow);
2564 if(p3==p0||p3==p1||p3==p2||!
hasVolume(verts, p0, p1, p2, p3)) p3 =
maxdirsterid(verts,verts_count,-basis[2],allow);
2565 if(p3==p0||p3==p1||p3==p2)
2566 return int4(-1,-1,-1,-1);
2567 assert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3));
2568 if(
dot(verts[p3]-verts[p0],
cross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {
Swap(p2,p3);}
2569 return int4(p0,p1,p2,p3);
2574 if(verts_count <4)
return 0;
2575 if(vlimit==0) vlimit=1000000000;
2577 double3 bmin(*verts),bmax(*verts);
2580 for(j=0;j<verts_count;j++)
2587 double epsilon =
magnitude(bmax-bmin) * 0.001f;
2591 if(p.
x==-1)
return 0;
2595 double3 center = (verts[p[0]]+verts[p[1]]+verts[p[2]]+verts[p[3]]) /4.0f;
2597 Tri *t0 =
new Tri(p[2],p[3],p[1]); t0->
n=
int3(2,3,1);
2598 Tri *t1 =
new Tri(p[3],p[2],p[0]); t1->
n=
int3(3,2,0);
2599 Tri *t2 =
new Tri(p[0],p[1],p[3]); t2->
n=
int3(0,1,3);
2600 Tri *t3 =
new Tri(p[1],p[0],p[2]); t3->
n=
int3(1,0,2);
2602 Tri *t0 = NX_NEW_MEM(
Tri(p[2],p[3],p[1]); t0->
n=
int3(2,3,1), CONVEX_TEMP);
2603 Tri *t1 = NX_NEW_MEM(
Tri(p[3],p[2],p[0]); t1->
n=
int3(3,2,0), CONVEX_TEMP);
2604 Tri *t2 = NX_NEW_MEM(
Tri(p[0],p[1],p[3]); t2->
n=
int3(0,1,3), CONVEX_TEMP);
2605 Tri *t3 = NX_NEW_MEM(
Tri(p[1],p[0],p[2]); t3->
n=
int3(1,0,2), CONVEX_TEMP);
2607 isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1;
2610 for(j=0;j<
tris.count;j++)
2625 assert(!isextreme[v]);
2631 if(!
tris[j])
continue;
2633 if(
above(verts,t,verts[v],0.01f*epsilon))
2642 if(!
tris[j])
continue;
2645 if(
above(verts,nt,center,0.01f*epsilon) ||
magnitude(
cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]))< epsilon*epsilon*0.1f )
2648 assert(nb);assert(!
hasvert(*nb,v));assert(nb->
id<j);
2658 if(t->
vmax>=0)
break;
2661 if(isextreme[t->
vmax])
2680 for(
int i=0;i<
tris.count;i++)
if(
tris[i])
2682 for(
int j=0;j<3;j++)ts.
Add((*
tris[i])[j]);
2685 tris_count = ts.
count/3;
2707 for(i=0;i<
tris.count;i++)
if(
tris[i])
2715 if(t->
n[j]<t->
id)
continue;
2717 REAL3 snormal =
TriNormal(verts[(*s)[0]],verts[(*s)[1]],verts[(*s)[2]]);
2719 REAL3 e = verts[(*t)[(j+2)%3]] - verts[(*t)[(j+1)%3]];
2721 assert(n!=
REAL3(0,0,0));
2722 if(n==
REAL3(0,0,0))
return 0;
2731 REAL3 ni =
TriNormal(verts[(*ti)[0]],verts[(*ti)[1]],verts[(*ti)[2]]);
2732 REAL3 nj =
TriNormal(verts[(*tj)[0]],verts[(*tj)[1]],verts[(*tj)[2]]);
2733 if(
dot(ni,nj)>maxdot_minang)
2736 if(
area2(verts[(*ti)[0]],verts[(*ti)[1]],verts[(*ti)[2]]) <
area2(verts[(*tj)[0]],verts[(*tj)[1]],verts[(*tj)[2]]))
2746 for(i=0;i<
tris.count;i++)
if(
tris[i])
2754 for(i=0;i<bplanes.
count;i++)
2756 for(j=0;j<planes.
count;j++)
2758 if(
dot(bplanes[i].normal,planes[j].normal)>maxdot_minang)
break;
2762 planes.
Add(bplanes[i]);
2765 for(i=0;i<
tris.count;i++)
if(
tris[i])
2774 double3 *&verts_out,
int &verts_count_out,
int *&faces_out,
int &faces_count_out ,
double inflate)
2777 if(verts_count <4)
return 0;
2778 maxplanes =
Min(maxplanes,planes_count);
2779 double3 bmin(verts[0]),bmax(verts[0]);
2780 for(i=0;i<verts_count;i++)
2787 bmin -=
double3(inflate*2.5f,inflate*2.5f,inflate*2.5f);
2788 bmax +=
double3(inflate*2.5f,inflate*2.5f,inflate*2.5f);
2796 for(i=0;i<planes_count;i++)
2798 planes[i].
dist -= inflate;
2802 double epsilon = 0.01f;
2810 n[j/2] = (j%2)? 1.0f : -1.0f;
2811 for(i=0;i<planes_count;i++)
2813 if(
dot(n,planes[i].normal)> maxdot_minang)
2815 (*((j%2)?&bmax:&bmin)) += n * (diameter*0.5f);
2822 while(maxplanes-- && (k=
candidateplane(planes,planes_count,c,epsilon))>=0)
2826 if(c==NULL) {c=tmp;
break;}
2836 faces_out[faces_count_out++]=-1;
2838 while(i<c->edges.count)
2841 while(j+i<c->edges.count && c->
edges[i].p==c->
edges[i+j].p) { j++; }
2842 faces_out[faces_count_out++]=j;
2845 faces_out[faces_count_out++] = c->
edges[i].v;
2851 assert(k==c->
facets.count);
2852 assert(faces_count_out == 1+c->
facets.count+c->
edges.count);
2865 double3 *&verts_out,
int &verts_count_out,
int *&faces_out,
int &faces_count_out ,
double inflate,
double bevangle,
int vlimit)
2867 if(!verts_count)
return 0;
2870 int rc=
calchullpbev(verts,verts_count,vlimit,planes,bevangle) ;
2872 return overhull(planes.
element,planes.
count,verts,verts_count,maxplanes,verts_out,verts_count_out,faces_out,faces_count_out,inflate);
2886 int verts_count_out;
2892 int ret =
calchull( (
double3 *) vertices, (
int) vcount, tris_out, tris_count, vlimit );
2893 if(!ret)
return false;
2894 result.
mIndexCount = (
unsigned int) (tris_count*3);
2895 result.
mFaceCount = (
unsigned int) tris_count;
2897 result.
mVcount = (
unsigned int) vcount;
2898 result.
mIndices = (
unsigned int *) tris_out;
2902 int ret =
overhullv((
double3*)vertices,vcount,35,verts_out,verts_count_out,faces,index_count,inflate,120.0f,vlimit);
2911 for(
int i=0;i<n;i++)
2913 int pn = faces[k++];
2914 for(
int j=2;j<pn;j++)
tris.Add(
int3(faces[k],faces[k+j-1],faces[k+j]));
2917 assert(
tris.count == index_count-1-(n*3));
2923 result.
mVcount = (
unsigned int) verts_count_out;
2956 unsigned int vcount = desc.
mVcount;
2957 if ( vcount < 8 ) vcount = 8;
2959 double *vsource = (
double *)
NX_ALLOC(
sizeof(
double)*vcount*3, CONVEX_TEMP );
2964 unsigned int ovcount;
2977 for (
unsigned int i=0; i<ovcount; i++)
2979 double *v = &vsource[i*3];
2986 bmin[0] = bmax[0] = v[0];
2987 bmin[1] = bmax[1] = v[1];
2988 bmin[2] = bmax[2] = v[2];
2992 if ( v[0] < bmin[0] ) bmin[0] = v[0];
2993 if ( v[1] < bmin[1] ) bmin[1] = v[1];
2994 if ( v[2] < bmin[2] ) bmin[2] = v[2];
2995 if ( v[0] > bmax[0] ) bmax[0] = v[0];
2996 if ( v[1] > bmax[1] ) bmax[1] = v[1];
2997 if ( v[2] > bmax[2] ) bmax[2] = v[2];
3003 double skinwidth = 0;
3008 if ( skinwidth < 0 )
3012 center[0] = (bmax[0] - bmin[0])*0.5f + bmin[0];
3013 center[1] = (bmax[1] - bmin[1])*0.5f + bmin[1];
3014 center[2] = (bmax[2] - bmin[2])*0.5f + bmin[2];
3016 double dx = (bmax[0]-bmin[0])*0.5f;
3017 double dy = (bmax[1]-bmin[1])*0.5f;
3018 double dz = (bmax[2]-bmin[2])*0.5f;
3019 double dist = sqrt(dx*dx+dy*dy+dz*dz);
3023 double scale = 1.0f - (skinwidth/dist);
3024 if ( scale < 0.3f ) scale = 0.3f;
3025 for (
unsigned int i=0; i<ovcount; i++)
3027 double *v = &vsource[i*3];
3051 double *vscratch = (
double *)
NX_ALLOC(
sizeof(
double)*hr.
mVcount*3, CONVEX_TEMP );
3071 const unsigned int *source = hr.
mIndices;
3072 unsigned int *dest = result.
mIndices;
3076 dest[0] = source[2];
3077 dest[1] = source[1];
3078 dest[2] = source[0];
3101 const unsigned int *source = hr.
mIndices;
3102 unsigned int *dest = result.
mIndices;
3108 dest[1] = source[2];
3109 dest[2] = source[1];
3110 dest[3] = source[0];
3114 dest[1] = source[0];
3115 dest[2] = source[1];
3116 dest[3] = source[2];
3126 if ( hr.
mVertices == vsource) vsource = NULL;
3165 static void AddPoint(
unsigned int &vcount,
double *p,
double x,
double y,
double z)
3167 double *dest = &p[vcount*3];
3175 double GetDist(
double px,
double py,
double pz,
const double *p2)
3178 double dx = px - p2[0];
3179 double dy = py - p2[1];
3180 double dz = pz - p2[2];
3182 return dx*dx+dy*dy+dz*dz;
3188 const double *svertices,
3189 unsigned int stride,
3190 unsigned int &vcount,
3192 double normalepsilon,
3195 if ( svcount == 0 )
return false;
3198 #define EPSILON 0.000001f // close enough to consider two doubleing point numbers to be 'the same'.
3213 double bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
3214 double bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
3216 const char *vtx = (
const char *) svertices;
3220 for (
unsigned int i=0; i<svcount; i++)
3222 const double *p = (
const double *) vtx;
3226 for (
int j=0; j<3; j++)
3228 if ( p[j] < bmin[j] ) bmin[j] = p[j];
3229 if ( p[j] > bmax[j] ) bmax[j] = p[j];
3234 double dx = bmax[0] - bmin[0];
3235 double dy = bmax[1] - bmin[1];
3236 double dz = bmax[2] - bmin[2];
3240 center[0] = dx*0.5f + bmin[0];
3241 center[1] = dy*0.5f + bmin[1];
3242 center[2] = dz*0.5f + bmin[2];
3247 double len = FLT_MAX;
3249 if ( dx >
EPSILON && dx < len ) len = dx;
3250 if ( dy >
EPSILON && dy < len ) len = dy;
3251 if ( dz >
EPSILON && dz < len ) len = dz;
3253 if ( len == FLT_MAX )
3255 dx = dy = dz = 0.01f;
3259 if ( dx <
EPSILON ) dx = len * 0.05f;
3260 if ( dy <
EPSILON ) dy = len * 0.05f;
3261 if ( dz <
EPSILON ) dz = len * 0.05f;
3264 double x1 = center[0] - dx;
3265 double x2 = center[0] + dx;
3267 double y1 = center[1] - dy;
3268 double y2 = center[1] + dy;
3270 double z1 = center[2] - dz;
3271 double z2 = center[2] + dz;
3273 AddPoint(vcount,vertices,x1,y1,z1);
3274 AddPoint(vcount,vertices,x2,y1,z1);
3275 AddPoint(vcount,vertices,x2,y2,z1);
3276 AddPoint(vcount,vertices,x1,y2,z1);
3277 AddPoint(vcount,vertices,x1,y1,z2);
3278 AddPoint(vcount,vertices,x2,y1,z2);
3279 AddPoint(vcount,vertices,x2,y2,z2);
3280 AddPoint(vcount,vertices,x1,y2,z2);
3298 center[0]*=recip[0];
3299 center[1]*=recip[1];
3300 center[2]*=recip[2];
3308 vtx = (
const char *) svertices;
3310 for (
unsigned int i=0; i<svcount; i++)
3313 const double *p = (
const double *)vtx;
3331 for (j=0; j<vcount; j++)
3333 double *v = &vertices[j*3];
3339 double dx = fabs(x - px );
3340 double dy = fabs(y - py );
3341 double dz = fabs(z - pz );
3343 if ( dx < normalepsilon && dy < normalepsilon && dz < normalepsilon )
3349 double dist1 =
GetDist(px,py,pz,center);
3350 double dist2 =
GetDist(v[0],v[1],v[2],center);
3352 if ( dist1 > dist2 )
3365 double *dest = &vertices[vcount*3];
3377 double bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
3378 double bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
3380 for (
unsigned int i=0; i<vcount; i++)
3382 const double *p = &vertices[i*3];
3383 for (
int j=0; j<3; j++)
3385 if ( p[j] < bmin[j] ) bmin[j] = p[j];
3386 if ( p[j] > bmax[j] ) bmax[j] = p[j];
3390 double dx = bmax[0] - bmin[0];
3391 double dy = bmax[1] - bmin[1];
3392 double dz = bmax[2] - bmin[2];
3396 double cx = dx*0.5f + bmin[0];
3397 double cy = dy*0.5f + bmin[1];
3398 double cz = dz*0.5f + bmin[2];
3400 double len = FLT_MAX;
3402 if ( dx >=
EPSILON && dx < len ) len = dx;
3403 if ( dy >=
EPSILON && dy < len ) len = dy;
3404 if ( dz >=
EPSILON && dz < len ) len = dz;
3406 if ( len == FLT_MAX )
3408 dx = dy = dz = 0.01f;
3412 if ( dx <
EPSILON ) dx = len * 0.05f;
3413 if ( dy <
EPSILON ) dy = len * 0.05f;
3414 if ( dz <
EPSILON ) dz = len * 0.05f;
3417 double x1 = cx - dx;
3418 double x2 = cx + dx;
3420 double y1 = cy - dy;
3421 double y2 = cy + dy;
3423 double z1 = cz - dz;
3424 double z2 = cz + dz;
3428 AddPoint(vcount,vertices,x1,y1,z1);
3429 AddPoint(vcount,vertices,x2,y1,z1);
3430 AddPoint(vcount,vertices,x2,y2,z1);
3431 AddPoint(vcount,vertices,x1,y2,z1);
3432 AddPoint(vcount,vertices,x1,y1,z2);
3433 AddPoint(vcount,vertices,x2,y1,z2);
3434 AddPoint(vcount,vertices,x2,y2,z2);
3435 AddPoint(vcount,vertices,x1,y2,z2);
3446 unsigned int *used = (
unsigned int *)
NX_ALLOC(
sizeof(
unsigned int)*vcount, CONVEX_TEMP );
3447 memset(used,0,
sizeof(
unsigned int)*vcount);
3451 for (
unsigned int i=0; i<indexcount; i++)
3453 unsigned int v = indices[i];
3455 assert( v >= 0 && v < vcount );
3459 indices[i] = used[v]-1;
3464 indices[i] = ocount;
3466 overts[ocount*3+0] = verts[v*3+0];
3467 overts[ocount*3+1] = verts[v*3+1];
3468 overts[ocount*3+2] = verts[v*3+2];
3472 assert( ocount >=0 && ocount <= vcount );
3489 const unsigned int *idx = answer.
mIndices;
3492 if ( p && idx && fcount )
3496 for (
unsigned int i=0; i<fcount; i++)
3498 unsigned int pcount = *idx++;
3500 unsigned int i1 = *idx++;
3501 unsigned int i2 = *idx++;
3502 unsigned int i3 = *idx++;
3504 const double *p1 = &p[i1*3];
3505 const double *p2 = &p[i2*3];
3506 const double *p3 = &p[i3*3];
3532 #define TSCALE1 (1.0f/4.0f)
3561 const double *tp1 = p1;
3562 const double *tp2 = p2;
3563 const double *tp3 = p3;
3568 double nx = fabs(n[0]);
3569 double ny = fabs(n[1]);
3570 double nz = fabs(n[2]);
3572 if ( nx <= ny && nx <= nz )
3574 if ( ny <= nx && ny <= nz )
3576 if ( nz <= nx && nz <= ny )
3616 double vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag;
3626 vw_x = vy * wz - vz * wy;
3627 vw_y = vz * wx - vx * wz;
3628 vw_z = vx * wy - vy * wx;
3630 mag = sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z));
3632 if ( mag < 0.000001f )