📄 3dsimport_co.cxx
字号:
/*
* Object converter/optimizer
*/
#include <ivp_physics.hxx>
#include <ctype.h>
#ifndef WIN32
# pragma implementation "ivp_surbuild_3ds.hxx"
#endif
#include <ivp_surbuild_3ds.hxx>
#include <ivu_geometry.hxx>
#include <ivp_convex_decompositor.hxx>
#include <ivp_surbuild_polyhdrn_cncv.hxx>
#include <3dsimport_load.hxx>
typedef struct
{
dword ix,iy,iz;
float x,y,z;
dword iu,iv;
byte marked;
} H3dsMapVert;
#include "3dsimport_load.cxx"
#include "3dsimport_out.cxx"
IVP_Template_SurfaceBuilder_3ds::IVP_Template_SurfaceBuilder_3ds(){
this->scale = 1.0f;
}
// OK, that was ugly but this way I
// don't have to mess with the linker.
// Default object name to set as public label
#define DEFNAME "rawobj"
int flags = 0;
#define VERBOSE 0x0001 /* Verbose mode on */
#define OVERWR 0x0002 /* Don't sak for file overwrite */
#define BINARY 0x0004 /* Binary output */
#define ASSEMBLY 0x0008 /* Assembly source output */
#define CENTRE 0x0010 /* Centre objects */
#define SCALE 0x0020 /* Scale objects */
#define NOMAPFIX 0x0040 /* Don't fix bad mapping values */
#define NORMNULL 0x0080 /* Don't remove null faces */
#define NORMUNUSED 0x0100 /* Don't remove unused vertices */
#define NORMDUP 0x0200 /* Don't remove duplicated vertices */
#define NOMAPPING 0x0400 /* Don't output mapping values */
void FixMaps(H3dsScene * scene)
{
for(int n=0; n<scene->meshobjs; n++) {
H3dsMeshObj * mo = &scene->meshobjlist[n];
if(mo->maps) {
// Find maximum mapping value
float32 max=0.0;
for(int m=0; m<mo->maps; m++) {
H3dsMap * map = &mo->maplist[m];
if(map->u > max) max=map->u;
if(map->v > max) max=map->v;
}
if(max > 1.0) {
if(flags & VERBOSE)
ivp_message("%-14s bad mapping %.3f, scaling...\n",
mo->name, max);
float32 scale=1.0/max;
for(int mm=0; mm<mo->maps; mm++) {
H3dsMap * mmap = &mo->maplist[mm];
mmap->u *= scale;
mmap->v *= scale;
}
}
}
}
}
void ScaleMaps(H3dsScene * scene, float32 us, float32 vs)
{
for(int n=0; n<scene->meshobjs; n++) {
H3dsMeshObj * mo = &scene->meshobjlist[n];
for(int m=0; m<mo->maps; m++) {
H3dsMap * map = &mo->maplist[m];
map->u *= us;
map->v *= vs;
}
}
}
void FindCentrePoints(H3dsScene * scene)
{
float32 xmino= 1e30f, ymino= 1e30f, zmino= 1e30f;
float32 xmaxo=-1e30f, ymaxo=-1e30f, zmaxo=-1e30f;
for(int n=0; n<scene->meshobjs; n++) {
float32 xmin= 1e30f, ymin= 1e30f, zmin= 1e30f;
float32 xmax=-1e30f, ymax=-1e30f, zmax=-1e30f;
H3dsMeshObj * mo = &scene->meshobjlist[n];
for(int v=0; v<mo->verts; v++) {
H3dsVert * vrt=&mo->vertlist[v];
if(vrt->x > xmax) xmax=vrt->x;
if(vrt->x < xmin) xmin=vrt->x;
if(vrt->y > ymax) ymax=vrt->y;
if(vrt->y < ymin) ymin=vrt->y;
if(vrt->z > zmax) zmax=vrt->z;
if(vrt->z < zmin) zmin=vrt->z;
}
mo->centre.x = xmax-(xmax-xmin)*0.5;
mo->centre.y = ymax-(ymax-ymin)*0.5;
mo->centre.z = zmax-(zmax-zmin)*0.5;
if(mo->centre.x > xmaxo) xmaxo=mo->centre.x;
if(mo->centre.x < xmino) xmino=mo->centre.x;
if(mo->centre.y > ymaxo) ymaxo=mo->centre.y;
if(mo->centre.y < ymino) ymino=mo->centre.y;
if(mo->centre.z > zmaxo) zmaxo=mo->centre.z;
if(mo->centre.z < zmino) zmino=mo->centre.z;
}
scene->centre.x = xmaxo-(xmaxo-xmino)*0.5;
scene->centre.y = ymaxo-(ymaxo-ymino)*0.5;
scene->centre.z = zmaxo-(zmaxo-zmino)*0.5;
}
void Move(H3dsScene * scene, float32 x, float32 y, float32 z)
{
scene->centre.x+=x;
scene->centre.y+=y;
scene->centre.z+=z;
for(int n=0; n<scene->meshobjs; n++) {
H3dsMeshObj * mo = &scene->meshobjlist[n];
mo->centre.x+=x;
mo->centre.y+=y;
mo->centre.z+=z;
for(int v=0; v<mo->verts; v++) {
H3dsVert * vrt=&mo->vertlist[v];
vrt->x+=x;
vrt->y+=y;
vrt->z+=z;
}
}
}
void Scale(H3dsScene * scene, float32 x, float32 y, float32 z)
{
scene->centre.x*=x;
scene->centre.y*=y;
scene->centre.z*=z;
for(int n=0; n<scene->meshobjs; n++) {
H3dsMeshObj * mo = &scene->meshobjlist[n];
mo->centre.x*=x;
mo->centre.y*=y;
mo->centre.z*=z;
for(int v=0; v<mo->verts; v++) {
H3dsVert * vrt=&mo->vertlist[v];
vrt->x*=x;
vrt->y*=y;
vrt->z*=z;
}
}
}
void ConvertFloatsToInts(H3dsScene * scene)
{
for(int n=0; n<scene->meshobjs; n++) {
H3dsMeshObj * mo = &scene->meshobjlist[n];
for(int v=0; v<mo->verts; v++) {
H3dsVert * vrt = &mo->vertlist[v];
vrt->ix = (dword) vrt->x;
vrt->iy = (dword) vrt->y;
vrt->iz = (dword) vrt->z;
}
for(int m=0; m<mo->maps; m++) {
H3dsMap * map = &mo->maplist[m];
map->iu = (dword) map->u;
map->iv = (dword) map->v;
}
mo->centre.ix = (dword) mo->centre.x;
mo->centre.iy = (dword) mo->centre.y;
mo->centre.iz = (dword) mo->centre.z;
}
scene->centre.ix = (dword) scene->centre.x;
scene->centre.iy = (dword) scene->centre.y;
scene->centre.iz = (dword) scene->centre.z;
}
int RemoveNullFaces(H3dsScene * scene)
{
int bad=0;
for(int o=0; o<scene->meshobjs; o++) {
H3dsMeshObj * mo = &scene->meshobjlist[o];
for(int f=0; f<mo->faces; f++) {
int p0 = (int) mo->facelist[f].p0;
int p1 = (int) mo->facelist[f].p1;
int p2 = (int) mo->facelist[f].p2;
dword p0x = mo->vertlist[p0].ix;
dword p0y = mo->vertlist[p0].iy;
dword p0z = mo->vertlist[p0].iz;
dword p1x = mo->vertlist[p1].ix;
dword p1y = mo->vertlist[p1].iy;
dword p1z = mo->vertlist[p1].iz;
dword p2x = mo->vertlist[p2].ix;
dword p2y = mo->vertlist[p2].iy;
dword p2z = mo->vertlist[p2].iz;
if((p0x==p1x && p0y==p1y && p0z==p1z) ||
(p0x==p2x && p0y==p2y && p0z==p2z) ||
(p1x==p2x && p1y==p2y && p1z==p2z)) {
// We found a null face! I.e. a line or just a point.
bad++;
mo->faces--;
// Insert the other faces a slot down
for(int ff=f; ff<mo->faces; ff++) {
mo->facelist[ff] = mo->facelist[ff+1];
}
}
}
}
return bad;
}
int RemoveUnusedVerts(H3dsScene * scene)
{
int bad=0;
for(int o=0; o<scene->meshobjs; o++) {
H3dsMeshObj * mo = &scene->meshobjlist[o];
for(int v=0; v<mo->verts; v++) {
// Check if vertice v is used in any of the faces
int used=0;
for(int f=0; f<mo->faces; f++) {
H3dsFace * fac = &mo->facelist[f];
if((int)fac->p0==v || (int)fac->p1==v || (int)fac->p2==v) {
// This vertice is used here
used=1;
break;
}
}
if(!used) {
// We found a vertice that is not used in any face.
bad++;
mo->verts--;
// Insert the other vertices a slot down
for(int vv=v; vv<mo->verts; vv++)
mo->vertlist[vv] = mo->vertlist[vv+1];
// Also move the mapping vertices
if(mo->maps) {
mo->maps--;
for(int mm=v; mm<mo->maps; mm++)
mo->maplist[mm] = mo->maplist[mm+1];
}
// Modify the faces to reflect the moved vertices
for(int ff=0; ff<mo->faces; ff++) {
H3dsFace * ffac = &mo->facelist[ff];
if(ffac->p0 >= v) ffac->p0--;
if(ffac->p1 >= v) ffac->p1--;
if(ffac->p2 >= v) ffac->p2--;
}
}
}
}
return bad;
}
void FindExchange(H3dsScene * scene, int find, int exchange)
{
// Find all references to the 'find' vertice and replace
// them with references to the 'exchange' vertice
for(int o=0; o<scene->meshobjs; o++) {
H3dsMeshObj * mo = &scene->meshobjlist[o];
for(int f=0; f<mo->faces; f++) {
H3dsFace * fa = &mo->facelist[f];
if(fa->p0 == find) fa->p0 = exchange;
if(fa->p1 == find) fa->p1 = exchange;
if(fa->p2 == find) fa->p2 = exchange;
}
}
}
int RemoveDupVerts(H3dsScene * scene, H3dsMapVert * vrtmap, int verts)
{
int vrttop=0, dot=0;
for(int currvtx=0; currvtx<verts; currvtx++) {
// Only process those vertices that has not been
// processed already.
if(vrtmap[currvtx].marked == 0) {
// OK, we have a vertex, currvtx. Try to find all other
// vertices that have the same x,y,z values.
for(int runvtx=currvtx+1; runvtx<verts; runvtx++) {
// Skip all vertices that has been processed already.
// We already know that they don't have the same values.
if(vrtmap[runvtx].marked == 1)
continue;
// If we find another vertex with the same x,y,z values
// we must find and adjust all the indexes that point
// to that vertex so that they point to currvtx.
if(vrtmap[runvtx].ix == vrtmap[currvtx].ix &&
vrtmap[runvtx].iy == vrtmap[currvtx].iy &&
vrtmap[runvtx].iz == vrtmap[currvtx].iz)
{
// Make them point to the top of our optimized array
FindExchange(scene, runvtx, vrttop);
// Mark it so we don't process it again.
vrtmap[runvtx].marked=1;
}
}
// Now find all other indexes that points to currvtx
// and adjust them to the top of our optimized array, vrttop.
FindExchange(scene, currvtx, vrttop);
// Put currvtx on top of our optimized array.
vrtmap[vrttop] = vrtmap[currvtx];
vrttop++;
}
// Print some dots so that the user don't fall asleep
if((flags & VERBOSE) && dot++>20) {
ivp_message( ".");
dot=0;
}
}
return vrttop;
}
void AdjustFaceIndexes(H3dsScene * scene)
{
int m=0;
for(int n=0; n<scene->meshobjs; n++) {
H3dsMeshObj * mo = &scene->meshobjlist[n];
for(int f=0; f<mo->faces; f++) {
H3dsFace * fa = &mo->facelist[f];
fa->p0 += m;
fa->p1 += m;
fa->p2 += m;
}
m+=mo->verts;
}
}
void CollectVertsAndMaps(H3dsScene * scene, H3dsMapVert * vrtmap)
{
int vn=0, mn;
for(int n=0; n<scene->meshobjs; n++) {
H3dsMeshObj * mo = &scene->meshobjlist[n];
// H3dsMeshObj * mo = &scene->meshobjlist[0];
mn=vn;
for(int v=0; v<mo->verts; v++) {
vrtmap[vn].ix=mo->vertlist[v].ix;
vrtmap[vn].iy=mo->vertlist[v].iy;
vrtmap[vn].iz=mo->vertlist[v].iz;
vrtmap[vn].x=mo->vertlist[v].x;
vrtmap[vn].y=mo->vertlist[v].y;
vrtmap[vn].z=mo->vertlist[v].z;
vn++;
}
for(int m=0; m<mo->maps; m++) {
vrtmap[mn].iu=mo->maplist[m].iu;
vrtmap[mn].iv=mo->maplist[m].iv;
mn++;
}
if(mn<vn) {
if(flags & VERBOSE)
ivp_message( "%-14s missing mapping, set to zero...\n",
mo->name);
for(int mmn=mn; mmn<vn; mmn++) {
vrtmap[mmn].iu=0;
vrtmap[mmn].iv=0;
}
}
}
}
#define IVP_MERGE_EPS 10e-4
IVP_DOUBLE ipoe_calc_s_val(const IVP_U_Point *p_world, const IVP_U_Point *vec, const IVP_U_Point *tp, const IVP_U_Point *tp_next)
{
// calcs intersect pos
// von lot von p auf this (rel. zu this)
// IVP_U_Point *tp = give_world_coords_AT(edge, m_cache_edge);
// IVP_U_Point *tp_next = give_world_coords_AT(edge->get_next(), m_cache_edge);
IVP_U_Point vec1, vec2;
vec1.subtract(tp_next, tp);
vec2.subtract(p_world, tp);
IVP_DOUBLE i_len = 1.0 / vec->fast_real_length();
i_len *= i_len;
IVP_DOUBLE s = vec1.dot_product(&vec2);
s *= i_len;
return s;
}
IVP_BOOL is_point_on_edge(IVP_U_Point *point, IVP_U_Point *edge_startpoint, IVP_U_Point *edge_endpoint) {
IVP_U_Point vec(edge_endpoint);
vec.subtract(edge_startpoint, &vec);
IVP_U_Straight edge(edge_startpoint, &vec);
if ( edge.get_quad_dist_to_point(point) < IVP_MERGE_EPS*IVP_MERGE_EPS ) {
IVP_DOUBLE s_val = ipoe_calc_s_val(point, &vec, edge_startpoint, edge_endpoint);
if ( (0.0 < s_val) && (s_val < 1.0) ) {
return(IVP_TRUE);
}
else {
return(IVP_FALSE);
}
}
else {
return(IVP_FALSE);
}
}
void repair_geometry(IVP_Concave_Polyhedron *concave_polyhedron) {
// process all points in object.
int x;
for (x=0; x<concave_polyhedron->points.len(); x++) {
IVP_U_Point *p = concave_polyhedron->points.element_at(x);
// for each point: process all faces in object.
int y;
for (y=0; y<concave_polyhedron->faces.len(); y++) {
IVP_Concave_Polyhedron_Face *face = concave_polyhedron->faces.element_at(y);
int first_point = face->point_offset.element_at(0)->offset;
// for each face process all edges in face.
int z;
int n_points = face->point_offset.len();
for (z=0; z<n_points; z++) {
int start, end;
if ( z == n_points-1 ) {
start = face->point_offset.element_at(z+0)->offset;
end = first_point;
}
else {
start = face->point_offset.element_at(z+0)->offset;
end = face->point_offset.element_at(z+1)->offset;
}
// if current point is either start or end point of current edge we can
// gladly skip it.
if ( p == concave_polyhedron->points.element_at(start) ) {
continue;
}
if ( p == concave_polyhedron->points.element_at(end) ) {
continue;
}
if ( is_point_on_edge(p, concave_polyhedron->points.element_at(start), concave_polyhedron->points.element_at(end)) ) {
printf("T-Junction found for point with offset <%d>\n", concave_polyhedron->points.index_of(p));
IVP_Concave_Polyhedron_Face_Pointoffset *new_offset = new IVP_Concave_Polyhedron_Face_Pointoffset();
new_offset->offset = concave_polyhedron->points.index_of(p);
face->point_offset.insert_after(z, new_offset);
n_points++;
}
// else {
// printf("Valid point\n");
// }
}
}
}
return;
}
IVP_Concave_Polyhedron * IVP_SurfaceBuilder_3ds::convert_3ds_to_concave(const char *filename, IVP_Template_SurfaceBuilder_3ds *params){
//****
#ifndef GEKKO
//****
char * infn=0, * outfn=0; // , * name=DEFNAME;
FILE * inf, * outf;
int n;
H3dsScene * scene;
// float32 xscale, yscale, zscale;
#if 0
argc--;
argv++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -