int map_mesh_combine(map_type *map,int mesh_1_idx,int mesh_2_idx) { int mesh_idx; map_mesh_type *mesh,*mesh_1,*mesh_2; // create new combined mesh mesh_idx=map_mesh_add(map); if (mesh_idx==-1) return(-1); // get combined meshes // need to get after mesh add as mesh add can change mesh pointers mesh_1=&map->mesh.meshes[mesh_1_idx]; mesh_2=&map->mesh.meshes[mesh_2_idx]; // setup enough vertexes and polys for new mesh if (!map_mesh_set_vertex_count(map,mesh_idx,(mesh_1->nvertex+mesh_2->nvertex))) { map_mesh_delete(map,mesh_idx); return(-1); } if (!map_mesh_set_poly_count(map,mesh_idx,(mesh_1->npoly+mesh_2->npoly))) { map_mesh_delete(map,mesh_idx); return(-1); } // combined meshes mesh=&map->mesh.meshes[mesh_idx]; mesh->npoly=0; mesh->nvertex=0; map_mesh_combine_single_mesh(mesh,mesh_1); map_mesh_combine_single_mesh(mesh,mesh_2); // get back to correct size // ignore failures as it's just a waste of space that // will be reclaimed later map_mesh_set_vertex_count(map,mesh_idx,mesh->nvertex); map_mesh_set_poly_count(map,mesh_idx,mesh->npoly); // delete original meshes, making sure to // change delete index depending on first delete // and return mesh index minus the two // deleted meshes map_mesh_delete(map,mesh_1_idx); if (mesh_1_idx<mesh_2_idx) mesh_2_idx--; map_mesh_delete(map,mesh_2_idx); return(mesh_idx-2); }
void map_undo_pull(void) { int n,idx,nmesh,old_nmesh, nliquid,old_nliquid; map_undo_type *undo; map_mesh_type *old_meshes,*org_mesh,*mesh; map_liquid_type *old_liquids,*org_liq,*liq; if (map_undo_level==0) return; undo=&map_undos[0]; // free VBOs view_vbo_map_free(); // backup old meshes // and clear mesh list old_nmesh=map.mesh.nmesh; old_meshes=map.mesh.meshes; free(map.mesh.meshes); map.mesh.nmesh=0; map.mesh.meshes=NULL; // restore all meshes nmesh=undo->mesh.count; if (nmesh!=0) { org_mesh=(map_mesh_type*)undo->mesh.data; for (n=0;n!=nmesh;n++) { // new mesh // if it fails, put everything back // and return idx=map_mesh_add(&map); if (idx==-1) { free(map.mesh.meshes); map.mesh.nmesh=old_nmesh; map.mesh.meshes=old_meshes; return; } mesh=&map.mesh.meshes[idx]; // just copy over from backup mesh // and then null out the pointers // so close doesn't erase them if (mesh->vertexes!=NULL) free(mesh->vertexes); if (mesh->polys!=NULL) free(mesh->polys); memmove(mesh,org_mesh,sizeof(map_mesh_type)); org_mesh->vertexes=NULL; org_mesh->polys=NULL; org_mesh++; } } map.mesh.nmesh=nmesh; // backup old liquids // and clear liquid list old_nliquid=map.liquid.nliquid; old_liquids=map.liquid.liquids; free(map.liquid.liquids); map.liquid.nliquid=0; map.liquid.liquids=NULL; // restore all meshes nliquid=undo->liquid.count; if (nliquid!=0) { org_liq=(map_liquid_type*)undo->liquid.data; for (n=0;n!=nliquid;n++) { // new liquid // if it fails, put everything back // and return idx=map_liquid_add(&map); if (idx==-1) { free(map.liquid.liquids); map.liquid.nliquid=old_nliquid; map.liquid.liquids=old_liquids; return; } liq=&map.liquid.liquids[idx]; memmove(liq,org_liq,sizeof(map_liquid_type)); org_liq++; } } map.liquid.nliquid=nliquid; // restore other chunks map.nspot=map_undo_pull_chunk(sizeof(spot_type),(unsigned char*)map.spots,&undo->spot); map.nscenery=map_undo_pull_chunk(sizeof(map_scenery_type),(unsigned char*)map.sceneries,&undo->scenery); map.nnode=map_undo_pull_chunk(sizeof(node_type),(unsigned char*)map.nodes,&undo->node); map.nlight=map_undo_pull_chunk(sizeof(map_light_type),(unsigned char*)map.lights,&undo->light); map.nsound=map_undo_pull_chunk(sizeof(map_sound_type),(unsigned char*)map.sounds,&undo->sound); map.nparticle=map_undo_pull_chunk(sizeof(map_particle_type),(unsigned char*)map.particles,&undo->particle); nselect_item=map_undo_pull_chunk(sizeof(select_item_type),(unsigned char*)select_items,&undo->selection); // clear level // and move stack up map_undo_clear_single(&map_undos[0]); for (n=1;n!=max_map_undo_level;n++) { undo_copy(&map_undos[n-1],&map_undos[n]); } if (max_map_undo_level>1) map_undo_initialize_single(&map_undos[max_map_undo_level-1]); // move down undo level map_undo_level--; if (map_undo_level==0) os_menu_enable_item(map_menu_edit,1,FALSE); // rebuild VBOs view_vbo_map_initialize(); // redraw windows map_palette_reset(); main_wind_draw(); }
bool map_convert_segment_section_to_mesh(map_type *map,int seg_cnt,segment_type *seg_list,int rn,int primitive_uid,int seg_type,d3pnt *vlist,int vlist_sz) { int n,nvertex,npoly,mesh_idx; segment_type *seg; map_mesh_type *map_mesh; // clear vertex list bzero(vlist,vlist_sz); // count the vertexes and polys nvertex=npoly=0; for (n=0;n!=seg_cnt;n++) { seg=&seg_list[n]; if (seg->rn!=rn) continue; if (seg->primitive_uid[0]!=primitive_uid) continue; if ((seg_type!=-1) && (seg->type!=seg_type)) continue; switch (seg->type) { case sg_wall: nvertex=map_convert_segment_to_mesh_add_poly_vlist(nvertex,vlist,seg->data.wall.ptsz,seg->data.wall.x,seg->data.wall.y,seg->data.wall.z); npoly++; break; case sg_floor: case sg_ceiling: nvertex=map_convert_segment_to_mesh_add_poly_vlist(nvertex,vlist,seg->data.fc.ptsz,seg->data.fc.x,seg->data.fc.y,seg->data.fc.z); npoly++; break; case sg_ambient_wall: nvertex=map_convert_segment_to_mesh_add_poly_vlist(nvertex,vlist,seg->data.ambient_wall.ptsz,seg->data.ambient_wall.x,seg->data.ambient_wall.y,seg->data.ambient_wall.z); npoly++; break; case sg_ambient_fc: nvertex=map_convert_segment_to_mesh_add_poly_vlist(nvertex,vlist,seg->data.ambient_fc.ptsz,seg->data.ambient_fc.x,seg->data.ambient_fc.y,seg->data.ambient_fc.z); npoly++; break; } } if ((nvertex==0) || (npoly==0)) return(TRUE); // create new mesh mesh_idx=map_mesh_add(map); if (mesh_idx==-1) return(FALSE); if (!map_mesh_set_vertex_count(map,mesh_idx,nvertex)) { map_mesh_delete(map,mesh_idx); return(FALSE); } if (!map_mesh_set_poly_count(map,mesh_idx,npoly)) { map_mesh_delete(map,mesh_idx); return(FALSE); } map_mesh=&map->mesh.meshes[mesh_idx]; // move over vertexes map_mesh->nvertex=nvertex; memmove(map_mesh->vertexes,vlist,(sizeof(d3pnt)*nvertex)); // add polys map_mesh->npoly=0; for (n=0;n!=seg_cnt;n++) { seg=&seg_list[n]; if (seg->rn!=rn) continue; if (seg->primitive_uid[0]!=primitive_uid) continue; if ((seg_type!=-1) && (seg->type!=seg_type)) continue; switch (seg->type) { case sg_wall: map_convert_segment_to_mesh_add_mesh_poly(map_mesh,seg->data.wall.ptsz,seg->data.wall.x,seg->data.wall.y,seg->data.wall.z,seg->draw.gx,seg->draw.gy,seg); break; case sg_floor: case sg_ceiling: map_convert_segment_to_mesh_add_mesh_poly(map_mesh,seg->data.fc.ptsz,seg->data.fc.x,seg->data.fc.y,seg->data.fc.z,seg->draw.gx,seg->draw.gy,seg); break; case sg_ambient_wall: map_convert_segment_to_mesh_add_mesh_poly(map_mesh,seg->data.ambient_wall.ptsz,seg->data.ambient_wall.x,seg->data.ambient_wall.y,seg->data.ambient_wall.z,seg->draw.gx,seg->draw.gy,seg); break; case sg_ambient_fc: map_convert_segment_to_mesh_add_mesh_poly(map_mesh,seg->data.ambient_fc.ptsz,seg->data.ambient_fc.x,seg->data.ambient_fc.y,seg->data.ambient_fc.z,seg->draw.gx,seg->draw.gy,seg); break; } // groups are sorted together into meshes // so tranfer any groups to mesh map_mesh->group_idx=seg->group_idx; } return(TRUE); }