u32 VPack(Fvector& V){ u32 P = 0xffffffff; u32 ix,iy,iz; ix = floorf(float(V.x-VMmin.x)/VMscale.x*clpMX); iy = floorf(float(V.y-VMmin.y)/VMscale.y*clpMY); iz = floorf(float(V.z-VMmin.z)/VMscale.z*clpMZ); R_ASSERT(ix<=clpMX && iy<=clpMY && iz<=clpMZ); { U32Vec* vl; vl = &(VM[ix][iy][iz]); for(U32It it=vl->begin();it!=vl->end(); it++) if( verts[*it].similar(V) ) { P = *it; break; } } if (0xffffffff==P){ P = verts.size(); sVert sV; sV.set(V); verts.push_back (sV); VM[ix][iy][iz].push_back(P); u32 ixE,iyE,izE; ixE = floorf(float(V.x+VMeps.x-VMmin.x)/VMscale.x*clpMX); iyE = floorf(float(V.y+VMeps.y-VMmin.y)/VMscale.y*clpMY); izE = floorf(float(V.z+VMeps.z-VMmin.z)/VMscale.z*clpMZ); R_ASSERT(ixE<=clpMX && iyE<=clpMY && izE<=clpMZ); if (ixE!=ix) VM[ixE][iy][iz].push_back (P); if (iyE!=iy) VM[ix][iyE][iz].push_back (P); if (izE!=iz) VM[ix][iy][izE].push_back (P); if ((ixE!=ix)&&(iyE!=iy)) VM[ixE][iyE][iz].push_back (P); if ((ixE!=ix)&&(izE!=iz)) VM[ixE][iy][izE].push_back (P); if ((iyE!=iy)&&(izE!=iz)) VM[ix][iyE][izE].push_back (P); if ((ixE!=ix)&&(iyE!=iy)&&(izE!=iz)) VM[ixE][iyE][izE].push_back (P); } return P; }
bool CEditableMesh::OptimizeFace(st_Face& face){ Fvector points[3]; int mface[3]; int k; for (k=0; k<3; k++){ points[k].set(m_Verts[face.pv[k].pindex]); mface[k] = -1; } // get similar vert idx list for (k=0; k<3; k++){ U32Vec* vl; int ix,iy,iz; ix = iFloor(float(points[k].x-VMmin.x)/VMscale.x*MX); iy = iFloor(float(points[k].y-VMmin.y)/VMscale.y*MY); iz = iFloor(float(points[k].z-VMmin.z)/VMscale.z*MZ); vl = &(VM[ix][iy][iz]); for(U32It it=vl->begin();it!=vl->end(); it++){ FvectorIt v = m_NewPoints.begin()+(*it); if( v->similar(points[k],EPS) ) mface[k] = *it; } } for(k=0; k<3; k++ ){ if( mface[k] == -1 ){ mface[k] = m_NewPoints.size(); m_NewPoints.push_back( points[k] ); int ix,iy,iz; ix = iFloor(float(points[k].x-VMmin.x)/VMscale.x*MX); iy = iFloor(float(points[k].y-VMmin.y)/VMscale.y*MY); iz = iFloor(float(points[k].z-VMmin.z)/VMscale.z*MZ); VM[ix][iy][iz].push_back(mface[k]); int ixE,iyE,izE; ixE = iFloor(float(points[k].x+VMeps.x-VMmin.x)/VMscale.x*MX); iyE = iFloor(float(points[k].y+VMeps.y-VMmin.y)/VMscale.y*MY); izE = iFloor(float(points[k].z+VMeps.z-VMmin.z)/VMscale.z*MZ); if (ixE!=ix) VM[ixE][iy][iz].push_back(mface[k]); if (iyE!=iy) VM[ix][iyE][iz].push_back(mface[k]); if (izE!=iz) VM[ix][iy][izE].push_back(mface[k]); if ((ixE!=ix)&&(iyE!=iy)) VM[ixE][iyE][iz].push_back(mface[k]); if ((ixE!=ix)&&(izE!=iz)) VM[ixE][iy][izE].push_back(mface[k]); if ((iyE!=iy)&&(izE!=iz)) VM[ix][iyE][izE].push_back(mface[k]); if ((ixE!=ix)&&(iyE!=iy)&&(izE!=iz)) VM[ixE][iyE][izE].push_back(mface[k]); } } if ((mface[0]==mface[1])||(mface[1]==mface[2])||(mface[0]==mface[2])){ Msg("!Optimize: Invalid face found. Removed."); return false; }else{ face.pv[0].pindex = mface[0]; face.pv[1].pindex = mface[1]; face.pv[2].pindex = mface[2]; return true; } }