コード例 #1
0
void ConvexVolumeTool::handleClick(const float* /*s*/, const float* p, bool shift)
{
    if (!m_sample) return;
    InputGeom* geom = m_sample->getInputGeom();
    if (!geom) return;
    
    if (shift)
    {
        // Delete
        int nearestIndex = -1;
        const ConvexVolume* vols = geom->getConvexVolumes();
        for (int i = 0; i < geom->getConvexVolumeCount(); ++i)
        {
            if (pointInPoly(vols[i].nverts, vols[i].verts, p) &&
                            p[1] >= vols[i].hmin && p[1] <= vols[i].hmax)
            {
                nearestIndex = i;
            }
        }
        // If end point close enough, delete it.
        if (nearestIndex != -1)
        {
            geom->deleteConvexVolume(nearestIndex);
        }
    }
    else
    {
        // Create

        // If clicked on that last pt, create the shape.
        if (m_npts && rcVdistSqr(p, &m_pts[(m_npts-1)*3]) < rcSqr(0.2f))
        {
            if (m_nhull > 2)
            {
                // Create shape.
                float verts[MAX_PTS*3];
                for (int i = 0; i < m_nhull; ++i)
                    rcVcopy(&verts[i*3], &m_pts[m_hull[i]*3]);
                    
                float minh = FLT_MAX, maxh = 0;
                for (int i = 0; i < m_nhull; ++i)
                    minh = rcMin(minh, verts[i*3+1]);
                minh -= m_boxDescent;
                maxh = minh + m_boxHeight;

                if (m_polyOffset > 0.01f)
                {
                    float offset[MAX_PTS*2*3];
                    int noffset = rcOffsetPoly(verts, m_nhull, m_polyOffset, offset, MAX_PTS*2);
                    if (noffset > 0)
                        geom->addConvexVolume(offset, noffset, minh, maxh, (unsigned char)m_areaType);
                }
                else
                {
                    geom->addConvexVolume(verts, m_nhull, minh, maxh, (unsigned char)m_areaType);
                }
            }
            
            m_npts = 0;
            m_nhull = 0;
        }
        else
        {
            // Add new point 
            if (m_npts < MAX_PTS)
            {
                rcVcopy(&m_pts[m_npts*3], p);
                m_npts++;
                // Update hull.
                if (m_npts > 1)
                    m_nhull = convexhull(m_pts, m_npts, m_hull);
                else
                    m_nhull = 0;
            }
        }        
    }
    
}
コード例 #2
0
// Calculates convex hull on xz-plane of points on 'pts'
ConvexVolume::ConvexVolume(InputGeom* geom, float offset)
{
// TODO protect against too many vectors!

    int hullVertIndices[MAX_CONVEXVOL_PTS];
    float* pts = geom->getVerts();
    int npts = geom->getVertCount();

    // Find lower-leftmost point.
    int hull = 0;
    for (int i = 1; i < npts; ++i)
        if (ConvexVolume::cmppt(&pts[i*3], &pts[hull*3]))
            hull = i;
    // Gift wrap hull.
    int endpt = 0;
    int i = 0;
    do
    {
        hullVertIndices[i++] = hull;
        endpt = 0;
        for (int j = 1; j < npts; ++j)
            if (hull == endpt || ConvexVolume::left(&pts[hull*3], &pts[endpt*3], &pts[j*3]))
                endpt = j;
        hull = endpt;
    }
    while (endpt != hullVertIndices[0] && i < MAX_CONVEXVOL_PTS/2);   // TODO: number of hull points is limited, but in a naive way. In large meshes the best candidate points for the hull might not be selected
                                            // Leave the other half of the points for expanding the hull

    nverts = i;


    // Copy geometry vertices to convex hull
    for (int i = 0; i < nverts; i++)
        rcVcopy(&verts[i*3], &pts[hullVertIndices[i]*3]);



    area = SAMPLE_POLYAREA_DOOR;   // You can choose whatever flag you assing to the poly area

    // Find min and max height of convex hull
    hmin = geom->getMeshBoundsMin()[1];
    hmax = geom->getMeshBoundsMax()[1];

    // 3D mesh min and max bounds
    rcVcopy(bmin, geom->getMeshBoundsMin());
    rcVcopy(bmax, geom->getMeshBoundsMax());

//TODO offsetting is still broken for a lot of shapes! Fix this!
    // Offset convex hull if needed
    if(offset > 0.01f) {
        float offsetVerts[MAX_CONVEXVOL_PTS * 3]; // An offset hull is allowed twice the number of vertices
        int nOffsetVerts = rcOffsetPoly(verts, nverts, offset, offsetVerts, MAX_CONVEXVOL_PTS);

        if (nOffsetVerts <= 0)
            return;

        for(int i = 0; i < nOffsetVerts; i++)
            rcVcopy(&verts[i*3], &offsetVerts[i*3]);

        nverts = nOffsetVerts;

        // Modify the bounds with offset (except height)
        bmin[0] = bmin[0]-offset;
        bmin[2] = bmin[2]-offset;
        bmax[0] = bmax[0]+offset;
        bmax[2] = bmax[2]+offset;
    }

}