⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3dsimport_co.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 2 页
字号:

/*
 *  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 + -