#include <iomanip>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <cmath>
using namespace std;
#include <bridge.hpp>
static __inline dReal _dCalcVectorDot3(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b)
{
return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b];
}
static __inline dReal dCalcVectorDot3 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,1); }
static __inline void dMultiplyHelper0_331(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot3(a, b);
const dReal res_1 = dCalcVectorDot3(a + 4, b);
const dReal res_2 = dCalcVectorDot3(a + 8, b);
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
static __inline void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_331(res, a, b);
}
void dMULTIPLY0_331(dReal *res, const dReal *a, const dReal *b)
{
dMultiply0_331(res, a, b);
}
static __inline dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); }
static __inline void dMultiplyHelper1_331(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot3_41(a, b);
const dReal res_1 = dCalcVectorDot3_41(a + 1, b);
const dReal res_2 = dCalcVectorDot3_41(a + 2, b);
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
static __inline void dMultiplyHelper0_133(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper1_331(res, b, a);
}
static __inline void dMultiply0_333(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_133(res + 0, a + 0, b);
dMultiplyHelper0_133(res + 4, a + 4, b);
dMultiplyHelper0_133(res + 8, a + 8, b);
}
void dMULTIPLY0_333(dReal *res, const dReal *a, const dReal *b)
{
dMultiply0_333(res, a, b);
}
static __inline dReal _dCalcVectorDot4(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b)
{
return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b] + a[3 * step_a] * b[3 * step_b];
}
static __inline dReal dCalcVectorDot4 (const dReal *a, const dReal *b) { return _dCalcVectorDot4(a,b,1,1); }
static __inline void dMultiplyHelper0_441(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot4(a, b);
const dReal res_1 = dCalcVectorDot4(a + 4, b);
const dReal res_2 = dCalcVectorDot4(a + 8, b);
const dReal res_3 = dCalcVectorDot4(a + 12, b);
res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3;
}
static __inline void dMultiply0_441(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_441(res, a, b);
}
void dMULTIPLY0_441(dReal *res, const dReal *a, const dReal *b)
{
dMultiply0_441(res, a, b);
}
static __inline dReal dCalcVectorDot4_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot4(a,b,4,1); }
static __inline void dMultiplyHelper1_441(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot4_41(a, b);
const dReal res_1 = dCalcVectorDot4_41(a + 1, b);
const dReal res_2 = dCalcVectorDot4_41(a + 2, b);
const dReal res_3 = dCalcVectorDot4_41(a + 3, b);
res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3;
}
static __inline void dMultiplyHelper0_144(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper1_441(res, b, a);
}
static __inline void dMultiply0_444(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_144(res + 0, a + 0, b);
dMultiplyHelper0_144(res + 4, a + 4, b);
dMultiplyHelper0_144(res + 8, a + 8, b);
dMultiplyHelper0_144(res + 12, a + 12, b);
}
void dMULTIPLY0_444(dReal *res, const dReal *a, const dReal *b)
{
dMultiply0_444(res, a, b);
}
static dReal scale_min_limit = 1e-5;
inline int isRescale(dReal sc){
dReal f = sc - 1.0;
return (f < -scale_min_limit) || (f > scale_min_limit);
}
void SetScaleLimit(dReal sclim)
{
scale_min_limit = sclim;
}
void Cross3(dReal *c, dReal *a, dReal *b) {
c[0] = a[1] * b[2] - a[2] * b[1];
c[1] = a[2] * b[0] - a[0] * b[2];
c[2] = a[0] * b[1] - a[1] * b[0];
}
void Normal4(dReal *n, dReal *v) {
dReal a[] = {v[3] - v[0], v[4] - v[1], v[5] - v[2]};
dReal b[] = {v[6] - v[0], v[7] - v[1], v[8] - v[2]};
Cross3(n, a, b);
dReal r = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
for(int j = 0; j < 3; ++j) n[j] /= r;
n[3] = dDot(n, v, 3);
}
void RecalcFaces(convexfvp *fvp)
{
dReal *vtx = fvp->vtx;
unsigned int *p = fvp->polygons;
for(int i = 0; i < fvp->faceCount; ++i){
if(*p++ != 3) throw runtime_error("can't recalc not triangle convexfvp");
unsigned int idx[] = {*p++, *p++, *p++};
dReal v[] = {
vtx[idx[0] * 3 + 0], vtx[idx[0] * 3 + 1], vtx[idx[0] * 3 + 2],
vtx[idx[1] * 3 + 0], vtx[idx[1] * 3 + 1], vtx[idx[1] * 3 + 2],
vtx[idx[2] * 3 + 0], vtx[idx[2] * 3 + 1], vtx[idx[2] * 3 + 2]};
Normal4(&fvp->faces[i * 4], v); }
}
void FreeTriMeshVI(trimeshvi *tmv, bool ff)
{
if(!tmv) return;
if(ff){
if(tmv->vtx) delete[] tmv->vtx;
if(tmv->indices) delete[] tmv->indices;
}
delete tmv;
}
void FreeConvexFVP(convexfvp *fvp, bool ff)
{
if(!fvp) return;
if(ff){
if(fvp->faces) delete[] fvp->faces;
if(fvp->vtx) delete[] fvp->vtx;
if(fvp->polygons) delete[] fvp->polygons;
}
delete fvp;
}
trimeshvi *CvtTriMeshVIFromConvexFVP(convexfvp *fvp, dReal sc)
{
trimeshvi *tmv = new trimeshvi;
if(!tmv) throw runtime_error("can't convert to trimeshvi");
tmv->vtxCount = fvp->vtxCount;
tmv->vtx = new dReal[3 * tmv->vtxCount];
if(!tmv->vtx) throw runtime_error("can't convert to trimeshvi.vtx");
memcpy(tmv->vtx, fvp->vtx, sizeof(dReal) * 3 * tmv->vtxCount);
if(isRescale(sc)) ScaleTriMeshVI(tmv, sc);
size_t tcnt = 0;
unsigned int *s = fvp->polygons;
for(int i = 0; i < fvp->faceCount; ++i){
unsigned int n = *s++;
if(n <= 2) throw runtime_error("can't convert to trimeshvi polygon <= 2");
s += n;
tcnt += (n - 2); }
tmv->indexCount = 3 * tcnt;
tmv->indices = new dTriIndex[tmv->indexCount];
if(!tmv->indices) throw runtime_error("can't convert to trimeshvi.indices");
dTriIndex *p = tmv->indices;
s = fvp->polygons;
for(int i = 0; i < fvp->faceCount; ++i){
unsigned int n = *s++;
for(int t = 0; t < (n - 2); ++t){ *p++ = (dTriIndex)*s++; *p++ = (dTriIndex)*s; if(!t) *p++ = (dTriIndex)*++s; else *p++ = (dTriIndex)*(s - 2 - t); }
++s;
}
return tmv;
}
convexfvp *CvtConvexFVPFromTriMeshVI(trimeshvi *tmv, dReal sc)
{
convexfvp *fvp = new convexfvp;
if(!fvp) throw runtime_error("can't convert to convexfvp");
fvp->faceCount = tmv->indexCount / 3;
fvp->faces = new dReal[4 * fvp->faceCount];
if(!fvp->faces) throw runtime_error("can't convert to convexfvp.faces");
fvp->vtxCount = tmv->vtxCount;
fvp->vtx = new dReal[3 * fvp->vtxCount];
if(!fvp->vtx) throw runtime_error("can't convert to convexfvp.vtx");
memcpy(fvp->vtx, tmv->vtx, sizeof(dReal) * 3 * fvp->vtxCount);
if(isRescale(sc)) ScaleConvexFVP(fvp, sc);
fvp->polygons = new unsigned int[4 * fvp->faceCount];
if(!fvp->polygons) throw runtime_error("can't convert to convexfvp.polygons");
dTriIndex *s = tmv->indices;
unsigned int *p = fvp->polygons;
for(int i = 0; i < fvp->faceCount; ++i){
*p++ = 3;
for(int j = 0; j < 3; ++j) *p++ = (unsigned int)*s++;
}
RecalcFaces(fvp);
return fvp;
}
trimeshvi *ScaleTriMeshVI(trimeshvi *tmv, dReal sc)
{
for(int i = 0; i < 3 * tmv->vtxCount; ++i) tmv->vtx[i] *= sc;
return tmv;
}
trimeshvi *CopyTriMeshVI(trimeshvi *dst, trimeshvi *src, dReal sc)
{
#if 0#endif
if(!dst){
dst = new trimeshvi;
if(!dst) throw runtime_error("can't create trimeshvi");
dst->vtx = new dReal[3 * src->vtxCount];
if(!dst->vtx) throw runtime_error("can't create trimeshvi.vtx");
dst->indices = new dTriIndex[src->indexCount];
if(!dst->indices) throw runtime_error("can't create trimeshvi.indices");
}
dst->vtxCount = src->vtxCount;
#if 0#else
memcpy(dst->vtx, src->vtx, sizeof(dReal) * 3 * dst->vtxCount);
if(isRescale(sc)) ScaleTriMeshVI(dst, sc);
#endif
dst->indexCount = src->indexCount;
memcpy(dst->indices, src->indices, sizeof(dTriIndex) * dst->indexCount);
return dst;
}
convexfvp *ScaleConvexFVP(convexfvp *fvp, dReal sc)
{
for(int i = 0; i < 3 * fvp->vtxCount; ++i) fvp->vtx[i] *= sc;
return fvp;
}
convexfvp *CopyConvexFVP(convexfvp *dst, convexfvp *src, dReal sc)
{
size_t count = 0;
unsigned int *s = src->polygons;
for(int i = 0; i < src->faceCount; ++i){
unsigned int n = *s++;
s += n;
count += (1 + n);
}
#if 0#endif
if(!dst){
dst = new convexfvp;
if(!dst) throw runtime_error("can't create convexfvp");
dst->faces = new dReal[4 * src->faceCount];
if(!dst->faces) throw runtime_error("can't create convexfvp.faces");
dst->vtx = new dReal[3 * src->vtxCount];
if(!dst->vtx) throw runtime_error("can't create convexfvp.vtx");
dst->polygons = new unsigned int[count];
if(!dst->polygons) throw runtime_error("can't create convexfvp.polygons");
}
dst->faceCount = src->faceCount;
memcpy(dst->faces, src->faces, sizeof(dReal) * 4 * dst->faceCount);
dst->vtxCount = src->vtxCount;
#if 0#else
memcpy(dst->vtx, src->vtx, sizeof(dReal) * 3 * dst->vtxCount);
if(isRescale(sc)) ScaleConvexFVP(dst, sc);
#endif
memcpy(dst->polygons, src->polygons, sizeof(unsigned int) * count);
return dst;
}