//void CUiSkin9GridImage::drawBorder(QPainter* p, QRect rc) const void CUiSkin9GridImage::drawBorder(QPainter* p, QRect rc) { QRect arrayDest[9]; m_rcSrc = rc;//save data m_ptTopLeft_InRcSrc = m_arrayRcImage9Grid[0].bottomRight();//save data // splitRect(rc, m_arrayRcImage9Grid[0].bottomRight(), arrayDest, 9); // //0 1 2 //3 4 5 //6 7 8 for (int nIndex = 0; nIndex < 9; nIndex++) { m_arrayRcSrc9Grid[nIndex] = arrayDest[nIndex];//save data //4 is client area if (nIndex == 4) continue; // const QRect& rcSrc = m_arrayRcImage9Grid[nIndex]; const QRect& rcDest = arrayDest[nIndex]; // p->drawImage(rcDest, m_imge, rcSrc); } }
//void CUiSkin9GridImage::draw(QPainter* p, QRect rc, int nAlpha) const void CUiSkin9GridImage::draw(QPainter* p, QRect rc, int nAlpha) { QRect arrayDest[9]; m_rcSrc = rc;//save data m_ptTopLeft_InRcSrc = m_arrayRcImage9Grid[0].bottomRight();//save data // splitRect(rc, m_arrayRcImage9Grid[0].bottomRight(), arrayDest, 9); // for (int nIndex = 0; nIndex < 9; nIndex++) { m_arrayRcSrc9Grid[nIndex] = arrayDest[nIndex];//save data const QRect& rcSrc = m_arrayRcImage9Grid[nIndex]; const QRect& rcDest = arrayDest[nIndex]; // if (nAlpha > 0 && nAlpha <= 255) { p->drawImage(rcDest, m_imge, rcSrc); } else { p->drawImage(rcDest, m_imge, rcSrc); } } }
void testApp::splitRect(ofRectangle r) { static char min = 4; int size = (int) r.width >> 1; static unsigned int* p = (unsigned int*)img.getPixels(); if( r.width < min) return; int x1, x2, x3, y1, y2, y3; x1 = r.x; x2= r.x+size, x3 = r.x+size*2; y1 = r.y; y2= r.y+size, y3 = r.y+size*2; int i0 = p[x1+y1*4096]+p[(x2-1)+(y2-1)*4096]-p[x1+(y2-1)*4096]-p[(x2-1)+y1*4096]; int i1 = p[x2+y1*4096]+p[(x3-1)+(y2-1)*4096]-p[x2+(y2-1)*4096]-p[(x3-1)+y1*4096]; int i2 = p[x1+y2*4096]+p[(x2-1)+(y3-1)*4096]-p[x1+(y3-1)*4096]-p[(x2-1)+y2*4096]; int i3 = p[x2+y2*4096]+p[(x3-1)+(y3-1)*4096]-p[x2+(y3-1)*4096]-p[(x3-1)+y2*4096]; ofRectangle r0(x1, y1, size, size); ofRectangle r1(x2, y1, size, size); ofRectangle r2(x1, y2, size, size); ofRectangle r3(x2, y2, size, size); if(i0) { if (i0 >= 8) splitRect(r0); else { rects.push_back(r0); integrals.push_back(i0); }} if(i1) { if (i1 >= 8) splitRect(r1); else { rects.push_back(r1); integrals.push_back(i1); }} if(i2) { if (i2 >= 8) splitRect(r2); else { rects.push_back(r2); integrals.push_back(i2); }} if(i3) { if (i3 >= 8) splitRect(r3); else { rects.push_back(r3); integrals.push_back(i3); }} }
bool CUiSkin9GridImage::setImage(const QString& strImageFileName, QPoint ptTopLeft) { _Clear(); // if (false == m_imge.load(strImageFileName)) { return false; } // int nImageWidth = m_imge.width(); int nImageHeight = m_imge.height(); // //将图片分割成9块,边缘部分以后有用 return splitRect(QRect(0, 0, nImageWidth, nImageHeight), ptTopLeft, m_arrayRcImage9Grid, 9); }
void CUiSkin9GridImage::draw_const( QPainter* p, QRect rc, int nAlpha ) const { QRect arrayDest[9]; // splitRect(rc, m_arrayRcImage9Grid[0].bottomRight(), arrayDest, 9); // for (int nIndex = 0; nIndex < 9; nIndex++) { const QRect& rcSrc = m_arrayRcImage9Grid[nIndex]; const QRect& rcDest = arrayDest[nIndex]; // if (nAlpha > 0 && nAlpha <= 255) { p->drawImage(rcDest, m_imge, rcSrc); } else { p->drawImage(rcDest, m_imge, rcSrc); } } }
bool computeSplitPlane(unsigned int vcount, const float *vertices, unsigned int tcount, const unsigned int *indices, ConvexDecompInterface *callback, float *plane) { bool cret = false; float bmin[3] = { 1e9, 1e9, 1e9 }; float bmax[3] = { -1e9, -1e9, -1e9 }; for (unsigned int i=0; i<vcount; i++) { const float *p = &vertices[i*3]; if ( p[0] < bmin[0] ) bmin[0] = p[0]; if ( p[1] < bmin[1] ) bmin[1] = p[1]; if ( p[2] < bmin[2] ) bmin[2] = p[2]; if ( p[0] > bmax[0] ) bmax[0] = p[0]; if ( p[1] > bmax[1] ) bmax[1] = p[1]; if ( p[2] > bmax[2] ) bmax[2] = p[2]; } float dx = bmax[0] - bmin[0]; float dy = bmax[1] - bmin[1]; float dz = bmax[2] - bmin[2]; float laxis = dx; unsigned int axis = 0; if ( dy > dx ) { axis = 1; laxis = dy; } if ( dz > dx && dz > dy ) { axis = 2; laxis = dz; } float p1[3]; float p2[3]; float p3[3]; p3[0] = p2[0] = p1[0] = bmin[0] + dx*0.5f; p3[1] = p2[1] = p1[1] = bmin[1] + dy*0.5f; p3[2] = p2[2] = p1[2] = bmin[2] + dz*0.5f; Rect3d b(bmin,bmax); Rect3d b1,b2; splitRect(axis,b,b1,b2,p1); // callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00); // callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00); switch ( axis ) { case 0: p2[1] = bmin[1]; p2[2] = bmin[2]; if ( dz > dy ) { p3[1] = bmax[1]; p3[2] = bmin[2]; } else { p3[1] = bmin[1]; p3[2] = bmax[2]; } break; case 1: p2[0] = bmin[0]; p2[2] = bmin[2]; if ( dx > dz ) { p3[0] = bmax[0]; p3[2] = bmin[2]; } else { p3[0] = bmin[0]; p3[2] = bmax[2]; } break; case 2: p2[0] = bmin[0]; p2[1] = bmin[1]; if ( dx > dy ) { p3[0] = bmax[0]; p3[1] = bmin[1]; } else { p3[0] = bmin[0]; p3[1] = bmax[1]; } break; } // callback->ConvexDebugTri(p1,p2,p3,0xFF0000); computePlane(p1,p2,p3,plane); return true; }
bool computeSplitPlane(unsigned int vcount, const double *vertices, unsigned int tcount, const unsigned int *indices, ConvexDecompInterface *callback, double *plane) { bool cret = false; double sides[3]; double matrix[16]; computeBestFitOBB( vcount, vertices, sizeof(double)*3, sides, matrix ); double bmax[3]; double bmin[3]; bmax[0] = sides[0]*0.5f; bmax[1] = sides[1]*0.5f; bmax[2] = sides[2]*0.5f; bmin[0] = -bmax[0]; bmin[1] = -bmax[1]; bmin[2] = -bmax[2]; double dx = sides[0]; double dy = sides[1]; double dz = sides[2]; double laxis = dx; unsigned int axis = 0; if ( dy > dx ) { axis = 1; laxis = dy; } if ( dz > dx && dz > dy ) { axis = 2; laxis = dz; } double p1[3]; double p2[3]; double p3[3]; p3[0] = p2[0] = p1[0] = bmin[0] + dx*0.5f; p3[1] = p2[1] = p1[1] = bmin[1] + dy*0.5f; p3[2] = p2[2] = p1[2] = bmin[2] + dz*0.5f; Rect3d b(bmin,bmax); Rect3d b1,b2; splitRect(axis,b,b1,b2,p1); // callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00); // callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00); switch ( axis ) { case 0: p2[1] = bmin[1]; p2[2] = bmin[2]; if ( dz > dy ) { p3[1] = bmax[1]; p3[2] = bmin[2]; } else { p3[1] = bmin[1]; p3[2] = bmax[2]; } break; case 1: p2[0] = bmin[0]; p2[2] = bmin[2]; if ( dx > dz ) { p3[0] = bmax[0]; p3[2] = bmin[2]; } else { p3[0] = bmin[0]; p3[2] = bmax[2]; } break; case 2: p2[0] = bmin[0]; p2[1] = bmin[1]; if ( dx > dy ) { p3[0] = bmax[0]; p3[1] = bmin[1]; } else { p3[0] = bmin[0]; p3[1] = bmax[1]; } break; } double tp1[3]; double tp2[3]; double tp3[3]; fm_transform(matrix,p1,tp1); fm_transform(matrix,p2,tp2); fm_transform(matrix,p3,tp3); // callback->ConvexDebugTri(p1,p2,p3,0xFF0000); computePlane(tp1,tp2,tp3,plane); return true; }
void drawOccluded(Window* win, Rect* baserect, List* splitrect_list) { if (!splitrect_list) return; int split_count = 0; int total_count = 1; int working_total = 0; List* out_rects; Rect* working_rects = (Rect*)0; int i, j, k; Rect *new_rect, *rect, *split_rect, *out_rect; //If there's nothing occluding us, just render the bitmap and get out of here if (!splitrect_list->count) { drawBmpRect(win, baserect); return; } out_rects = List_new(); if (!out_rects) { return; } rect = Rect_new(baserect->top, baserect->left, baserect->bottom, baserect->right); if (!rect) { List_delete(out_rects, Rect_deleter); return; } if (!List_add(out_rects, (void*)rect)) { free((void*)rect); List_delete(out_rects, Rect_deleter); return; } //For each splitting rect, split each rect in out_rects, delete the rectangle that was split, and add the resultant split rectangles List_for_each(splitrect_list, split_rect, Rect*) { List_for_each(out_rects, out_rect, Rect*) { if ((split_rect->left <= out_rect->right && split_rect->right >= out_rect->left && split_rect->top <= out_rect->bottom && split_rect->bottom >= out_rect->top)) { List* clip_list = splitRect(out_rect, split_rect); if (!clip_list) { List_delete(out_rects, Rect_deleter); return; } //If nothing was returned, we actually want to clip a rectangle in its entirety if (!clip_list->count) { List_remove(out_rects, (void*)out_rect, Rect_deleter); //If we deleted the last output rectangle, we are completely //occluded and can return early if (out_rects->count == 0) { List_delete(clip_list, Rect_deleter); List_delete(out_rects, Rect_deleter); return; } //Otherwise, go back to the top of the loop and test the next out_rect continue; } //Replace the rectangle that got split with the first result rectangle rect = (Rect*)List_get_at(clip_list, 0); out_rect->top = rect->top; out_rect->left = rect->left; out_rect->bottom = rect->bottom; out_rect->right = rect->right; //Append the rest of the result rectangles to the output collection List_for_each_skip(clip_list, rect, Rect*, 1) { new_rect = Rect_new(rect->top, rect->left, rect->bottom, rect->right); if (!new_rect) { List_delete(clip_list, Rect_deleter); List_delete(out_rects, Rect_deleter); return; } if (!List_add(out_rects, (void*)new_rect)){ free((void*)new_rect); List_delete(clip_list, Rect_deleter); List_delete(out_rects, Rect_deleter); return; } } //Free the space that was used for the split List_delete(clip_list, Rect_deleter); //Restart the list List_rewind(out_rects); } }
// here is where we split the mesh.. void split(const TriVector &triangles, uint32 vcount, const float *vertices, uint32 tcount, const uint32 *indices, uint32 depth, uint32 maxDepth, // Maximum recursion depth for the triangle mesh. uint32 minLeafSize, // minimum triangles to treat as a 'leaf' node. float minAxisSize, NodeInterface *callback, TriVector &leafTriangles) // once a particular axis is less than this size, stop sub-dividing. { // Find the longest axis of the bounding volume of this node float dx = mBounds.mMax[0] - mBounds.mMin[0]; float dy = mBounds.mMax[1] - mBounds.mMin[1]; float dz = mBounds.mMax[2] - mBounds.mMin[2]; AxisAABB axis = AABB_XAXIS; float laxis = dx; if ( dy > dx ) { axis = AABB_YAXIS; laxis = dy; } if ( dz > dx && dz > dy ) { axis = AABB_ZAXIS; laxis = dz; } uint32 count = triangles.size(); // if the number of triangles is less than the minimum allowed for a leaf node or... // we have reached the maximum recursion depth or.. // the width of the longest axis is less than the minimum axis size then... // we create the leaf node and copy the triangles into the leaf node triangle array. if ( count < minLeafSize || depth >= maxDepth || laxis < minAxisSize ) { // Copy the triangle indices into the leaf triangles array mLeafTriangleIndex = leafTriangles.size(); // assign the array start location for these leaf triangles. leafTriangles.pushBack(count); for (auto i=triangles.begin(); i!=triangles.end(); ++i) { leafTriangles.pushBack( *i ); } } else { float center[3]; mBounds.getCenter(center); BoundsAABB b1,b2; splitRect(axis,mBounds,b1,b2,center); // Compute two bounding boxes based upon the split of the longest axis BoundsAABB leftBounds,rightBounds; TriVector leftTriangles; TriVector rightTriangles; // Create two arrays; one of all triangles which intersect the 'left' half of the bounding volume node // and another array that includes all triangles which intersect the 'right' half of the bounding volume node. for (auto i=triangles.begin(); i!=triangles.end(); ++i) { uint32 tri = (*i); { uint32 i1 = indices[tri*3+0]; uint32 i2 = indices[tri*3+1]; uint32 i3 = indices[tri*3+2]; const float *p1 = &vertices[i1*3]; const float *p2 = &vertices[i2*3]; const float *p3 = &vertices[i3*3]; if ( b1.containsTriangle(p1,p2,p3)) { if ( leftTriangles.empty() ) { leftBounds.setMin(p1); leftBounds.setMax(p1); } leftBounds.include(p1); leftBounds.include(p2); leftBounds.include(p3); leftTriangles.pushBack(tri); // Add this triangle to the 'left triangles' array and revise the left triangles bounding volume } if ( b2.containsTriangle(p1,p2,p3)) { if ( rightTriangles.empty() ) { rightBounds.setMin(p1); rightBounds.setMax(p1); } rightBounds.include(p1); rightBounds.include(p2); rightBounds.include(p3); rightTriangles.pushBack(tri); // Add this triangle to the 'right triangles' array and revise the right triangles bounding volume. } } } if ( !leftTriangles.empty() ) // If there are triangles in the left half then... { leftBounds.clamp(b1); // we have to clamp the bounding volume so it stays inside the parent volume. mLeft = callback->getNode(); // get a new AABB node new ( mLeft ) NodeAABB(leftBounds); // initialize it to default constructor values. // Then recursively split this node. mLeft->split(leftTriangles,vcount,vertices,tcount,indices,depth+1,maxDepth,minLeafSize,minAxisSize,callback,leafTriangles); } if ( !rightTriangles.empty() ) // If there are triangles in the right half then.. { rightBounds.clamp(b2); // clamps the bounding volume so it stays restricted to the size of the parent volume. mRight = callback->getNode(); // allocate and default initialize a new node new ( mRight ) NodeAABB(rightBounds); // Recursively split this node. mRight->split(rightTriangles,vcount,vertices,tcount,indices,depth+1,maxDepth,minLeafSize,minAxisSize,callback,leafTriangles); } } }