int import_phx(const struct import_params* params) { ezxml_t xroot = ezxml_parse_file(params->in_filepath); const char* err = ezxml_error(xroot); g_phx_coord = params->coord; mat3_set_ident(&g_root_mat); /* construct scale mat */ mat3_set_ident(&g_phx_resize_mat); mat3_set_scalef(&g_phx_resize_mat, params->scale, params->scale, params->scale); if (xroot == NULL || !str_isempty(err)) { ezxml_free(xroot); printf(TERM_BOLDRED "Error: RepX XML: %s\n" TERM_RESET, str_isempty(err) ? "File not found" : err); return FALSE; } if (!str_isequal(ezxml_name(xroot), "PhysX30Collection")) { ezxml_free(xroot); printf(TERM_BOLDRED "Error: not a valid RepX file\n" TERM_RESET); return FALSE; } /* find object in the RepX file */ ezxml_t xobj = import_phx_findobj(xroot, params->name); if (xobj == NULL) { ezxml_free(xroot); printf(TERM_BOLDRED "Error: object '%s' not found\n" TERM_RESET, params->name); return FALSE; } /* intialize physx */ class import_phx_alloc alloc; class import_phx_log log; PxFoundation* pxbase = PxCreateFoundation(PX_PHYSICS_VERSION, alloc, log); if (pxbase == NULL) { ezxml_free(xroot); printf(TERM_BOLDRED "Error: could not initalize physx" TERM_RESET); return FALSE; } g_pxcook = PxCreateCooking(PX_PHYSICS_VERSION, *pxbase, PxCookingParams(PxTolerancesScale())); if (g_pxcook == NULL) { ezxml_free(xroot); pxbase->release(); printf(TERM_BOLDRED "Error: could not initalize physx" TERM_RESET); return FALSE; } /* */ struct phx_ext p; memset(&p, 0x00, sizeof(struct phx_ext)); struct array geos, mtls; arr_create(mem_heap(), &geos, sizeof(struct pgeo_ext), 5, 5, 0); arr_create(mem_heap(), &mtls, sizeof(struct h3d_phx_mtl), 5, 5, 0); ASSERT(geos.buffer); ASSERT(mtls.buffer); int result = FALSE; /* determine the type of xobj */ if (str_isequal(ezxml_name(xobj), "PxRigidStatic") || str_isequal(ezxml_name(xobj), "PxRigidDynamic")) { p.rigid = import_phx_createrigid(xobj, xroot, &geos, &mtls); if (p.rigid == NULL) goto cleanup; p.p.rigid_cnt = 1; } p.geos = (struct pgeo_ext*)geos.buffer; p.mtls = (struct h3d_phx_mtl*)mtls.buffer; p.p.geo_cnt = geos.item_cnt; p.p.mtl_cnt = mtls.item_cnt; if (p.p.rigid_cnt > 0) { p.p.total_shapes += p.rigid->r.shape_cnt; for (uint i = 0; i < p.rigid->r.shape_cnt; i++) p.p.total_shape_mtls += p.rigid->shapes[i].s.mtl_cnt; } result = import_writephx(params->out_filepath, &p); if (params->verbose) { printf(TERM_WHITE); printf("Physics report:\n" " geometry count: %d\n" " material count: %d\n", p.p.geo_cnt, p.p.mtl_cnt); switch (p.rigid->r.type) { case H3D_PHX_RIGID_DYN: printf( " rigid-body: dynamic\n"); break; case H3D_PHX_RIGID_ST: printf( " rigid-body: static\n"); break; } for (int i = 0; i < geos.item_cnt; i++) { struct pgeo_ext* geo = &((struct pgeo_ext*)geos.buffer)[i]; switch (geo->g.type) { case H3D_PHX_GEO_CONVEX: printf(" mesh #%d (convex): vertices = %d\n", i+1, geo->g.vert_cnt); break; case H3D_PHX_GEO_TRI: printf(" mesh #%d (tri): vertices = %d, tris = %d\n", i+1, geo->g.vert_cnt, geo->g.tri_cnt); break; } } printf(TERM_RESET); } if (result) printf(TERM_BOLDGREEN "ok, saved: \"%s\".\n" TERM_RESET, params->out_filepath); cleanup: /* cleanup */ if (p.rigid != NULL) import_phx_destroyrigid(p.rigid); for (int i = 0; i < geos.item_cnt; i++) { struct pgeo_ext* geo = &((struct pgeo_ext*)geos.buffer)[i]; if (geo->data != NULL) FREE(geo->data); } arr_destroy(&mtls); arr_destroy(&geos); ezxml_free(xroot); g_pxcook->release(); pxbase->release(); return result; }
void ShutdownPhysX() { gPhysicsSDK->release(); gFoundation->release(); }