📄 ivp_surbuild_ledge_soup.cxx
字号:
IVP_IF(1){ /*printf("Compact surface size : %d\n", cs_size);*/ }
this->compact_surface = (IVP_Compact_Surface *)ivp_malloc_aligned(cs_size*sizeof(char), 16);
if ( this->compact_surface == 0 ) {
return(0);
}
if ( number_of_ledges_compiled > 1 && !parameters->link_to_input_compact_ledges){
if ( parameters->merge_points == IVP_SLMP_MERGE_AND_REALLOCATE ||
parameters->merge_points == IVP_SLMP_MERGE_NO_REALLOCATE){
int a = number_of_triangles_compiled; int b = 2;
while (a) { a = a>>1; b = b<<1; }
this->point_hash = new IVP_I_FPoint_VHash( b ); // very rough estimate
this->first_poly_point = (IVP_Compact_Poly_Point *) ( (char *)this->compact_surface + cs_header_size +
number_of_triangles_compiled * sizeof(IVP_Compact_Triangle) + number_of_ledges_compiled * sizeof(IVP_Compact_Ledge));
}
}else{
this->first_poly_point = NULL;
this->point_hash = NULL;
}
n_poly_points_allocated = 0;
// now insert triangles (and maybe points
{
this->first_compact_ledge = (IVP_Compact_Ledge *)((char *)this->compact_surface + cs_header_size);
this->insert_compact_ledges();
}
int cs_ledglelist_size;
if ( this->point_hash ){
P_DELETE ( this->point_hash );
cs_ledglelist_size = number_of_triangles_compiled * sizeof(IVP_Compact_Triangle) +
number_of_ledges_compiled * sizeof(IVP_Compact_Ledge) +
n_poly_points_allocated * sizeof(IVP_Compact_Poly_Point);
}else{
cs_ledglelist_size = cs_estimated_ledglelist_size;
}
// set size values
int cs_real_size = cs_header_size + cs_ledglelist_size + cs_ledgetree_size;
this->compact_surface->byte_size = cs_real_size; // remember size of whole compact surface; useful for e.g. saving to disk
this->compact_surface->offset_ledgetree_root = cs_header_size + cs_ledglelist_size;
this->compact_surface->dummy[0] = 0; // otherwise RUI on SPARC
this->compact_surface->dummy[1] = 0; // otherwise RUI on SPARC
this->compact_surface->dummy[2] = 0; // otherwise RUI on SPARC
// set pointer to first node in ledgetree array
this->ledgetree_work =
(IVP_Compact_Ledgetree_Node *)( (char *)this->compact_surface + this->compact_surface->offset_ledgetree_root);
IVP_IF(1) {
this->clt_lowmem = (char *)this->ledgetree_work;
this->clt_highmem = (char *)compact_surface + cs_real_size;
}
return(compact_surface);
}
int IVP_SurfaceBuilder_Ledge_Soup::recompile_point_indizes_of_compact_ledge(IVP_Compact_Ledge *ledge_source, char *dest){
if ( !point_hash ){
memcpy((void *)dest, ledge_source, ledge_source->get_size());
return ledge_source->get_size();
}
IVP_Compact_Ledge *dl = (IVP_Compact_Ledge *)dest;
int size = sizeof(IVP_Compact_Ledge) + sizeof(IVP_Compact_Triangle) * ledge_source->get_n_triangles();
memcpy((void *)dest, ledge_source, size);
IVP_Compact_Triangle *tri = dl->get_first_triangle();
IVP_Compact_Poly_Point *source_ledge_points = ledge_source->get_point_array();
for (int t = dl->get_n_triangles()-1; t>=0; t--){
IVP_Compact_Edge *edge = tri->get_first_edge();
for (int e = 0; e<3;e++){
int pi = edge->get_start_point_index();
IVP_Compact_Poly_Point *p_in = & source_ledge_points[pi];
IVP_Compact_Poly_Point *p_out = (IVP_Compact_Poly_Point *)point_hash->find_point( p_in);
if (p_out){
edge->set_start_point_index( p_out - first_poly_point);
}else{
edge->set_start_point_index( this->n_poly_points_allocated );
p_out = &first_poly_point[n_poly_points_allocated++];
*p_out = *p_in;
point_hash->add_point( p_out );
}
edge++;
}
tri = tri->get_next_tri();
}
dl->set_offset_ledge_points( (char *)first_poly_point - (char *)dl );
return size;
}
/********************************************************************************
* Name: insert_compact_ledges
* Description: insert compact ledges into compact surface structure
********************************************************************************/
void IVP_SurfaceBuilder_Ledge_Soup::insert_compact_ledges(){
char *dest = (char *)this->first_compact_ledge;
if (parameters->link_to_input_compact_ledges == IVP_FALSE){
for (int i=0; i<this->terminal_spheres.len(); i++) {
IVV_Sphere *sphere = this->terminal_spheres.element_at(i);
IVP_Compact_Ledge *source = sphere->compact_ledge;
IVP_ASSERT((long(dest) & 0xf) == 0);
sphere->compact_ledge = (IVP_Compact_Ledge *)dest;
int ledge_size = recompile_point_indizes_of_compact_ledge(source,dest);
dest += ledge_size;
if (parameters->free_input_compact_ledges == IVP_TRUE){
P_FREE_ALIGNED(source);
}
}
}
for (int j=0; j<this->rec_spheres.len(); j++) {
IVV_Sphere *sphere = this->rec_spheres.element_at(j);
IVP_Compact_Ledge *source = sphere->compact_ledge;
IVP_ASSERT((long(dest) & 0xf) == 0);
sphere->compact_ledge = (IVP_Compact_Ledge *)dest;
int ledge_size = recompile_point_indizes_of_compact_ledge(source,dest);
dest += ledge_size;
P_FREE_ALIGNED(source);
}
this->c_ledge_vec.clear();
IVP_ASSERT( !first_poly_point || dest == (char *)this->first_poly_point );
return;
}
/********************************************************************************
* Name: build_ledgetree
* Description: recursively builds the tree of ledges into allocated
* compact surface memory;
* initiating call by 'create_compact_ledgetree()'
********************************************************************************/
IVP_Compact_Ledgetree_Node *IVP_SurfaceBuilder_Ledge_Soup::build_ledgetree(IVV_Sphere *node) {
IVP_Compact_Ledgetree_Node *current_node = this->ledgetree_work;
IVP_ASSERT((int)current_node < (int)this->clt_highmem); // ledgetree memory overwrite!
IVP_ASSERT((int)current_node >= (int)this->clt_lowmem); // ledgetree memory underwrite!
this->ledgetree_work++;
// fill in generic ledgetree_node data
current_node->center.set(node->center.k);
current_node->radius = (IVP_FLOAT)(node->radius);
for (int x=0; x < IVP_CLT_N_DIRECTIONS; x++) {
current_node->box_sizes[x] = node->box_sizes[x];
}
current_node->free_0 = 0;
if ( node->child_1 ) {
IVP_ASSERT(node->child_2);
if ( node->compact_ledge){
current_node->offset_compact_ledge = (char *)(node->compact_ledge)-(char *)current_node;
node->compact_ledge->ledgetree_node_offset = (char *) current_node - (char *)node->compact_ledge;
node->compact_ledge->has_chilren_flag = IVP_TRUE;
}else{
current_node->offset_compact_ledge = 0;
}
// process child nodes
build_ledgetree(node->child_1);
IVP_Compact_Ledgetree_Node *address_of_right_branch = build_ledgetree(node->child_2);
// fill in specific internal ledgetree_node data
current_node->offset_right_node = (char *)address_of_right_branch - (char *)current_node; // calulcate offset to right branch
} else {
IVP_ASSERT(!node->child_2);
node->compact_ledge->has_chilren_flag = IVP_FALSE;
// fill in specific terminal ledgetree_node data
current_node->offset_compact_ledge = (char *)node->compact_ledge - (char *)current_node; // calculate backward offset to compact ledge
current_node->offset_right_node = 0;
}
IVP_ASSERT(current_node->box_sizes[0]!=0);
return(current_node);
}
/********************************************************************************
* Name: ledgetree_debug_output
* Description: DEBUGGING ONLY
********************************************************************************/
void IVP_SurfaceBuilder_Ledge_Soup::ledgetree_debug_output(const IVP_Compact_Ledgetree_Node *node) const
{
// *** debugging START ******************************************************
IVP_IF(1) {
IVP_ASSERT((int)node < (int)this->clt_highmem); // ledgetree memory overread!
IVP_ASSERT((int)node >= (int)this->clt_lowmem); // ledgetree memory underread!
}
//for (int x=0; x<ivp_debug_sf_indent; x++) {
// printf(" ");
//}
//node->center.print("center");
//printf("Radius: %.6f\n", node->radius);
if (node->offset_right_node==0) return;
//ivp_debug_sf_indent++;
//printf("%d\n", node->offset);
if ( !node->is_terminal() ) {
ledgetree_debug_output(node->left_son());
ledgetree_debug_output(node->right_son());
}
//ivp_debug_sf_indent--;
// *** debugging END ********************************************************
return;
}
/********************************************************************************
* Name: ledgetree_array_debug_output
* Description: DEBUGGING ONLY
********************************************************************************/
void IVP_SurfaceBuilder_Ledge_Soup::ledgetree_array_debug_output() {
// *** debugging START ******************************************************
const IVP_Compact_Ledgetree_Node *node;
const IVP_Compact_Ledgetree_Node *nodes = compact_surface->get_compact_ledge_tree_root();
int i;
for (i=0; i<this->number_of_nodes; i++) {
node = &nodes[i];
printf("Node %d (address: 0x%x / %d)\n", i, (int)node, (int)node);
//node->center.print(" center ");
printf(" radius %.6f)\n", node->radius);
printf(" left branch offset: %d (address: 0x%x / %d)\n", sizeof(*node), (int)(node+1), (int)(node+1));
printf(" right branch offset: %d (address: 0x%x / %d)\n", node->offset_right_node, (int)node+node->offset_right_node, (int)node+node->offset_right_node);
printf("\n");
}
// *** debugging END ********************************************************
return;
}
void IVP_SurfaceBuilder_Ledge_Soup::insert_radius_in_compact_surface() {
IVP_U_Point mass_center;
IVP_U_Point rotation_inertia;
IVP_Rot_Inertia_Solver::calc_mass_center_and_rotation_inertia(this->compact_surface, &mass_center, &rotation_inertia);
IVP_DOUBLE mass_radius, mass_radius_dev;
IVP_CLS.calc_radius_to_given_center( this->compact_surface, &mass_center,
&mass_radius, &mass_radius_dev);
this->compact_surface->rotation_inertia.set(rotation_inertia.k);
this->compact_surface->mass_center.set(mass_center.k);
this->compact_surface->upper_limit_radius = (IVP_FLOAT)mass_radius;
IVP_ASSERT( mass_radius_dev >=0.0f);
IVP_ASSERT( mass_radius_dev <= mass_radius + P_FLOAT_RES);
this->compact_surface->max_factor_surface_deviation = int(1.0f + mass_radius_dev / (mass_radius * IVP_COMPACT_SURFACE_DEVIATION_STEP_SIZE));
}
/********************************************************************************
* Name: create_compact_ledgetree
* Description: creates tree of ledges
********************************************************************************/
IVP_RETURN_TYPE IVP_SurfaceBuilder_Ledge_Soup::create_compact_ledgetree() {
IVV_Sphere *cluster_node = this->spheres_cluster[this->spheres_cluster[0].next].sphere;
// *** debugging START ******************************************************
IVP_IF(0) {
ivp_debug_sf_indent=0;
debug_sphere_output(this->spheres_cluster[this->spheres_cluster[0].next].sphere);
}
// *** debugging END ********************************************************
#ifdef DEBUG
IVP_Compact_Ledgetree_Node *root =
#endif
this->build_ledgetree(cluster_node);
this->spheres_cluster[0].next = 0;
IVP_ASSERT(this->compact_surface->get_compact_ledge_tree_root()==root);
// *** debugging START ******************************************************
IVP_IF(1) {
//ivp_debug_sf_indent=0;
ledgetree_debug_output(this->compact_surface->get_compact_ledge_tree_root());
//ledgetree_array_debug_output();
}
// *** debugging END ********************************************************
return(IVP_OK);
}
#if defined(LINUX) || defined(SUN) || (__MWERKS__ && POWERPC)
void IVP_SurfaceBuilder_Ledge_Soup::convert_ledges_to_templates(IVP_U_BigVector<IVP_Compact_Ledge> &ledges,
IVP_U_Vector<IVP_Template_Polygon> *templates_out)
{
int i;
for (i=0; i<ledges.len(); i++) {
IVP_Compact_Ledge *ledge = ledges.element_at(i);
int n_points_for_ledge = ledge->get_n_points();
// copy all points of ledge (i.e. all points of all triangles) into pointlist
int j;
IVP_U_Vector<IVP_U_Point> points;
const IVP_Compact_Poly_Point *cpp_array = ledge->get_point_array();
for (j=0; j<n_points_for_ledge; j++) {
IVP_U_Point *p = new IVP_U_Point();
p->k[0] = cpp_array[j].k[0];
p->k[1] = cpp_array[j].k[1];
p->k[2] = cpp_array[j].k[2];
points.add(p);
//p->print();
}
// process all triangles in ledge
IVP_U_Vector<IVP_SurMan_PS_Plane> planes;
int n_faces = ledge->get_n_triangles();
const IVP_Compact_Triangle *tri = ledge->get_first_triangle();
int k;
for (k=0; k<n_faces; k++) {
const IVP_Compact_Edge *edge = tri->get_first_edge();
IVP_SurMan_PS_Plane *plane = new IVP_SurMan_PS_Plane();
IVP_CLS.calc_hesse_vec_object_not_normized(edge, ledge, plane);
plane->normize();
planes.add(plane);
int m;
for (m=0; m<3; m++) {
const IVP_Compact_Poly_Point *p = edge->get_start_point(ledge);
int index;
for (index=0; index<n_points_for_ledge; index++) {
if ( &cpp_array[index] == p ) break;
}
plane->points.add(points.element_at(index));
edge = edge->get_prev();
}
tri = tri->get_next_tri();
}
// --------------------------------------------------
// convert convex points & planes to polygon template
// --------------------------------------------------
IVP_Template_Polygon *templ;
templ = IVP_SurfaceBuilder_Pointsoup::planes_to_template(&points, &planes);
templates_out->add(templ);
// -----------------------
// clean up temporary data
// -----------------------
for (j=0; j<points.len(); j++) {
IVP_U_Point *p = points.element_at(j);
P_DELETE(p);
}
for (j=0; j<planes.len(); j++) {
IVP_SurMan_PS_Plane *p = planes.element_at(j);
P_DELETE(p);
}
}
// --------------------------------------------------
// convert convex points & planes to polygon template
// --------------------------------------------------
// *template_out = IVP_SurfaceBuilder_Pointsoup::planes_to_template(&points, &planes);
return;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -