467 lines
11 KiB
C
467 lines
11 KiB
C
#include <stdio.h>
|
|
#include <cu/cu.h>
|
|
|
|
#include <ccd/ccd.h>
|
|
#include "support.h"
|
|
#include "../dbg.h"
|
|
#include "common.h"
|
|
|
|
|
|
TEST(boxboxSetUp)
|
|
{
|
|
}
|
|
|
|
TEST(boxboxTearDown)
|
|
{
|
|
}
|
|
|
|
TEST(boxboxAlignedX)
|
|
{
|
|
size_t i;
|
|
ccd_t ccd;
|
|
CCD_BOX(box1);
|
|
CCD_BOX(box2);
|
|
int res;
|
|
|
|
CCD_INIT(&ccd);
|
|
ccd.support1 = ccdSupport;
|
|
ccd.support2 = ccdSupport;
|
|
//ccd.max_iterations = 20;
|
|
|
|
box1.x = 1;
|
|
box1.y = 2;
|
|
box1.z = 1;
|
|
box2.x = 2;
|
|
box2.y = 1;
|
|
box2.z = 2;
|
|
|
|
ccdVec3Set(&box1.pos, -5., 0., 0.);
|
|
ccdVec3Set(&box2.pos, 0., 0., 0.);
|
|
ccdQuatSet(&box1.quat, 0., 0., 0., 1.);
|
|
ccdQuatSet(&box2.quat, 0., 0., 0., 1.);
|
|
for (i = 0; i < 100; i++){
|
|
res = ccdGJKIntersect(&box1, &box2, &ccd);
|
|
if (i < 35 || i > 65){
|
|
assertFalse(res);
|
|
}else if (i != 35 && i != 65){
|
|
assertTrue(res);
|
|
}
|
|
|
|
box1.pos.v[0] += 0.1;
|
|
}
|
|
|
|
|
|
box1.x = 0.1;
|
|
box1.y = 0.2;
|
|
box1.z = 0.1;
|
|
box2.x = 0.2;
|
|
box2.y = 0.1;
|
|
box2.z = 0.2;
|
|
|
|
ccdVec3Set(&box1.pos, -0.5, 0., 0.);
|
|
ccdVec3Set(&box2.pos, 0., 0., 0.);
|
|
ccdQuatSet(&box1.quat, 0., 0., 0., 1.);
|
|
ccdQuatSet(&box2.quat, 0., 0., 0., 1.);
|
|
for (i = 0; i < 100; i++){
|
|
res = ccdGJKIntersect(&box1, &box2, &ccd);
|
|
|
|
if (i < 35 || i > 65){
|
|
assertFalse(res);
|
|
}else if (i != 35 && i != 65){
|
|
assertTrue(res);
|
|
}
|
|
|
|
box1.pos.v[0] += 0.01;
|
|
}
|
|
|
|
|
|
box1.x = 1;
|
|
box1.y = 2;
|
|
box1.z = 1;
|
|
box2.x = 2;
|
|
box2.y = 1;
|
|
box2.z = 2;
|
|
|
|
ccdVec3Set(&box1.pos, -5., -0.1, 0.);
|
|
ccdVec3Set(&box2.pos, 0., 0., 0.);
|
|
ccdQuatSet(&box1.quat, 0., 0., 0., 1.);
|
|
ccdQuatSet(&box2.quat, 0., 0., 0., 1.);
|
|
for (i = 0; i < 100; i++){
|
|
res = ccdGJKIntersect(&box1, &box2, &ccd);
|
|
|
|
if (i < 35 || i > 65){
|
|
assertFalse(res);
|
|
}else if (i != 35 && i != 65){
|
|
assertTrue(res);
|
|
}
|
|
|
|
box1.pos.v[0] += 0.1;
|
|
}
|
|
}
|
|
|
|
TEST(boxboxAlignedY)
|
|
{
|
|
size_t i;
|
|
ccd_t ccd;
|
|
CCD_BOX(box1);
|
|
CCD_BOX(box2);
|
|
int res;
|
|
|
|
CCD_INIT(&ccd);
|
|
ccd.support1 = ccdSupport;
|
|
ccd.support2 = ccdSupport;
|
|
|
|
box1.x = 1;
|
|
box1.y = 2;
|
|
box1.z = 1;
|
|
box2.x = 2;
|
|
box2.y = 1;
|
|
box2.z = 2;
|
|
|
|
ccdVec3Set(&box1.pos, 0., -5., 0.);
|
|
ccdVec3Set(&box2.pos, 0., 0., 0.);
|
|
ccdQuatSet(&box1.quat, 0., 0., 0., 1.);
|
|
ccdQuatSet(&box2.quat, 0., 0., 0., 1.);
|
|
for (i = 0; i < 100; i++){
|
|
res = ccdGJKIntersect(&box1, &box2, &ccd);
|
|
|
|
if (i < 35 || i > 65){
|
|
assertFalse(res);
|
|
}else if (i != 35 && i != 65){
|
|
assertTrue(res);
|
|
}
|
|
|
|
box1.pos.v[1] += 0.1;
|
|
}
|
|
}
|
|
|
|
TEST(boxboxAlignedZ)
|
|
{
|
|
size_t i;
|
|
ccd_t ccd;
|
|
CCD_BOX(box1);
|
|
CCD_BOX(box2);
|
|
int res;
|
|
|
|
CCD_INIT(&ccd);
|
|
ccd.support1 = ccdSupport;
|
|
ccd.support2 = ccdSupport;
|
|
|
|
box1.x = 1;
|
|
box1.y = 2;
|
|
box1.z = 1;
|
|
box2.x = 2;
|
|
box2.y = 1;
|
|
box2.z = 2;
|
|
|
|
ccdVec3Set(&box1.pos, 0., 0., -5.);
|
|
ccdVec3Set(&box2.pos, 0., 0., 0.);
|
|
ccdQuatSet(&box1.quat, 0., 0., 0., 1.);
|
|
ccdQuatSet(&box2.quat, 0., 0., 0., 1.);
|
|
for (i = 0; i < 100; i++){
|
|
res = ccdGJKIntersect(&box1, &box2, &ccd);
|
|
|
|
if (i < 35 || i > 65){
|
|
assertFalse(res);
|
|
}else if (i != 35 && i != 65){
|
|
assertTrue(res);
|
|
}
|
|
|
|
box1.pos.v[2] += 0.1;
|
|
}
|
|
}
|
|
|
|
|
|
TEST(boxboxRot)
|
|
{
|
|
size_t i;
|
|
ccd_t ccd;
|
|
CCD_BOX(box1);
|
|
CCD_BOX(box2);
|
|
int res;
|
|
ccd_vec3_t axis;
|
|
ccd_real_t angle;
|
|
|
|
CCD_INIT(&ccd);
|
|
ccd.support1 = ccdSupport;
|
|
ccd.support2 = ccdSupport;
|
|
|
|
box1.x = 1;
|
|
box1.y = 2;
|
|
box1.z = 1;
|
|
box2.x = 2;
|
|
box2.y = 1;
|
|
box2.z = 2;
|
|
|
|
ccdVec3Set(&box1.pos, -5., 0.5, 0.);
|
|
ccdVec3Set(&box2.pos, 0., 0., 0.);
|
|
ccdQuatSet(&box2.quat, 0., 0., 0., 1.);
|
|
ccdVec3Set(&axis, 0., 1., 0.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
|
|
for (i = 0; i < 100; i++){
|
|
res = ccdGJKIntersect(&box1, &box2, &ccd);
|
|
|
|
if (i < 33 || i > 67){
|
|
assertFalse(res);
|
|
}else if (i != 33 && i != 67){
|
|
assertTrue(res);
|
|
}
|
|
|
|
box1.pos.v[0] += 0.1;
|
|
}
|
|
|
|
box1.x = 1;
|
|
box1.y = 1;
|
|
box1.z = 1;
|
|
box2.x = 1;
|
|
box2.y = 1;
|
|
box2.z = 1;
|
|
|
|
ccdVec3Set(&box1.pos, -1.01, 0., 0.);
|
|
ccdVec3Set(&box2.pos, 0., 0., 0.);
|
|
ccdQuatSet(&box1.quat, 0., 0., 0., 1.);
|
|
ccdQuatSet(&box2.quat, 0., 0., 0., 1.);
|
|
|
|
ccdVec3Set(&axis, 0., 1., 0.);
|
|
angle = 0.;
|
|
for (i = 0; i < 30; i++){
|
|
res = ccdGJKIntersect(&box1, &box2, &ccd);
|
|
|
|
if (i != 0 && i != 10 && i != 20){
|
|
assertTrue(res);
|
|
}else{
|
|
assertFalse(res);
|
|
}
|
|
|
|
angle += M_PI / 20.;
|
|
ccdQuatSetAngleAxis(&box1.quat, angle, &axis);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pConf(ccd_box_t *box1, ccd_box_t *box2, const ccd_vec3_t *v)
|
|
{
|
|
fprintf(stdout, "# box1.pos: [%lf %lf %lf]\n",
|
|
ccdVec3X(&box1->pos), ccdVec3Y(&box1->pos), ccdVec3Z(&box1->pos));
|
|
fprintf(stdout, "# box1->quat: [%lf %lf %lf %lf]\n",
|
|
box1->quat.q[0], box1->quat.q[1], box1->quat.q[2], box1->quat.q[3]);
|
|
fprintf(stdout, "# box2->pos: [%lf %lf %lf]\n",
|
|
ccdVec3X(&box2->pos), ccdVec3Y(&box2->pos), ccdVec3Z(&box2->pos));
|
|
fprintf(stdout, "# box2->quat: [%lf %lf %lf %lf]\n",
|
|
box2->quat.q[0], box2->quat.q[1], box2->quat.q[2], box2->quat.q[3]);
|
|
fprintf(stdout, "# sep: [%lf %lf %lf]\n",
|
|
ccdVec3X(v), ccdVec3Y(v), ccdVec3Z(v));
|
|
fprintf(stdout, "#\n");
|
|
}
|
|
|
|
TEST(boxboxSeparate)
|
|
{
|
|
ccd_t ccd;
|
|
CCD_BOX(box1);
|
|
CCD_BOX(box2);
|
|
int res;
|
|
ccd_vec3_t sep, expsep, expsep2, axis;
|
|
|
|
fprintf(stderr, "\n\n\n---- boxboxSeparate ----\n\n\n");
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
box2.x = 0.5;
|
|
box2.y = 1.;
|
|
box2.z = 1.5;
|
|
|
|
|
|
CCD_INIT(&ccd);
|
|
ccd.support1 = ccdSupport;
|
|
ccd.support2 = ccdSupport;
|
|
|
|
ccdVec3Set(&box1.pos, -0.5, 0.5, 0.2);
|
|
res = ccdGJKIntersect(&box1, &box2, &ccd);
|
|
assertTrue(res);
|
|
|
|
res = ccdGJKSeparate(&box1, &box2, &ccd, &sep);
|
|
assertTrue(res == 0);
|
|
ccdVec3Set(&expsep, 0.25, 0., 0.);
|
|
assertTrue(ccdVec3Eq(&sep, &expsep));
|
|
|
|
ccdVec3Scale(&sep, -1.);
|
|
ccdVec3Add(&box1.pos, &sep);
|
|
res = ccdGJKSeparate(&box1, &box2, &ccd, &sep);
|
|
assertTrue(res == 0);
|
|
ccdVec3Set(&expsep, 0., 0., 0.);
|
|
assertTrue(ccdVec3Eq(&sep, &expsep));
|
|
|
|
|
|
ccdVec3Set(&box1.pos, -0.3, 0.5, 1.);
|
|
res = ccdGJKSeparate(&box1, &box2, &ccd, &sep);
|
|
assertTrue(res == 0);
|
|
ccdVec3Set(&expsep, 0., 0., -0.25);
|
|
assertTrue(ccdVec3Eq(&sep, &expsep));
|
|
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
box2.x = box2.y = box2.z = 1.;
|
|
ccdVec3Set(&axis, 0., 0., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&box1.pos, 0., 0., 0.);
|
|
|
|
res = ccdGJKSeparate(&box1, &box2, &ccd, &sep);
|
|
assertTrue(res == 0);
|
|
ccdVec3Set(&expsep, 0., 0., 1.);
|
|
ccdVec3Set(&expsep2, 0., 0., -1.);
|
|
assertTrue(ccdVec3Eq(&sep, &expsep) || ccdVec3Eq(&sep, &expsep2));
|
|
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
ccdVec3Set(&axis, 0., 0., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&box1.pos, -0.5, 0., 0.);
|
|
|
|
res = ccdGJKSeparate(&box1, &box2, &ccd, &sep);
|
|
assertTrue(res == 0);
|
|
pConf(&box1, &box2, &sep);
|
|
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
ccdVec3Set(&axis, 0., 1., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4);
|
|
|
|
res = ccdGJKSeparate(&box1, &box2, &ccd, &sep);
|
|
assertTrue(res == 0);
|
|
pConf(&box1, &box2, &sep);
|
|
}
|
|
|
|
|
|
#define TOSVT() \
|
|
svtObjPen(&box1, &box2, stdout, "Pen 1", depth, &dir, &pos); \
|
|
ccdVec3Scale(&dir, depth); \
|
|
ccdVec3Add(&box2.pos, &dir); \
|
|
svtObjPen(&box1, &box2, stdout, "Pen 1", depth, &dir, &pos)
|
|
|
|
TEST(boxboxPenetration)
|
|
{
|
|
ccd_t ccd;
|
|
CCD_BOX(box1);
|
|
CCD_BOX(box2);
|
|
int res;
|
|
ccd_vec3_t axis;
|
|
ccd_quat_t rot;
|
|
ccd_real_t depth;
|
|
ccd_vec3_t dir, pos;
|
|
|
|
fprintf(stderr, "\n\n\n---- boxboxPenetration ----\n\n\n");
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
box2.x = 0.5;
|
|
box2.y = 1.;
|
|
box2.z = 1.5;
|
|
|
|
|
|
CCD_INIT(&ccd);
|
|
ccd.support1 = ccdSupport;
|
|
ccd.support2 = ccdSupport;
|
|
|
|
ccdVec3Set(&box2.pos, 0.1, 0., 0.);
|
|
res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos);
|
|
assertTrue(res == 0);
|
|
recPen(depth, &dir, &pos, stdout, "Pen 1");
|
|
//TOSVT();
|
|
|
|
|
|
ccdVec3Set(&box1.pos, -0.3, 0.5, 1.);
|
|
res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos);
|
|
assertTrue(res == 0);
|
|
recPen(depth, &dir, &pos, stdout, "Pen 2");
|
|
//TOSVT(); <<<
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
box2.x = box2.y = box2.z = 1.;
|
|
ccdVec3Set(&axis, 0., 0., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&box1.pos, 0.1, 0., 0.1);
|
|
|
|
res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos);
|
|
assertTrue(res == 0);
|
|
recPen(depth, &dir, &pos, stdout, "Pen 3");
|
|
//TOSVT();
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
box2.x = box2.y = box2.z = 1.;
|
|
ccdVec3Set(&axis, 0., 0., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&box1.pos, -0.5, 0., 0.);
|
|
|
|
res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos);
|
|
assertTrue(res == 0);
|
|
recPen(depth, &dir, &pos, stdout, "Pen 4");
|
|
//TOSVT();
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
box2.x = box2.y = box2.z = 1.;
|
|
ccdVec3Set(&axis, 0., 0., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&box1.pos, -0.5, 0.5, 0.);
|
|
|
|
res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos);
|
|
assertTrue(res == 0);
|
|
recPen(depth, &dir, &pos, stdout, "Pen 5");
|
|
//TOSVT();
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
box2.x = box2.y = box2.z = 1.;
|
|
ccdVec3Set(&box2.pos, 0.1, 0., 0.);
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
ccdVec3Set(&axis, 0., 1., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4);
|
|
|
|
res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos);
|
|
assertTrue(res == 0);
|
|
recPen(depth, &dir, &pos, stdout, "Pen 6");
|
|
//TOSVT();
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
ccdVec3Set(&axis, 0., 1., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&axis, 1., 1., 1.);
|
|
ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis);
|
|
ccdQuatMul(&box1.quat, &rot);
|
|
ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4);
|
|
|
|
res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos);
|
|
assertTrue(res == 0);
|
|
recPen(depth, &dir, &pos, stdout, "Pen 7");
|
|
//TOSVT(); <<<
|
|
|
|
|
|
box1.x = box1.y = box1.z = 1.;
|
|
box2.x = 0.2; box2.y = 0.5; box2.z = 1.;
|
|
box2.x = box2.y = box2.z = 1.;
|
|
|
|
ccdVec3Set(&axis, 0., 0., 1.);
|
|
ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis);
|
|
ccdVec3Set(&axis, 1., 0., 0.);
|
|
ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis);
|
|
ccdQuatMul(&box1.quat, &rot);
|
|
ccdVec3Set(&box1.pos, -1.3, 0., 0.);
|
|
|
|
ccdVec3Set(&box2.pos, 0., 0., 0.);
|
|
|
|
res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos);
|
|
assertTrue(res == 0);
|
|
recPen(depth, &dir, &pos, stdout, "Pen 8");
|
|
//TOSVT();
|
|
}
|