Esempio n. 1
0
 public InputGeom(List <float> vertexPositions, List <int> meshFaces)
 {
     vertices = new float[vertexPositions.Count];
     for (int i = 0; i < vertices.Length; i++)
     {
         vertices[i] = vertexPositions[i];
     }
     faces = new int[meshFaces.Count];
     for (int i = 0; i < faces.Length; i++)
     {
         faces[i] = meshFaces[i];
     }
     bmin = new float[3];
     bmax = new float[3];
     RecastVectors.copy(bmin, vertices, 0);
     RecastVectors.copy(bmax, vertices, 0);
     for (int i = 1; i < vertices.Length / 3; i++)
     {
         RecastVectors.min(bmin, vertices, i * 3);
         RecastVectors.max(bmax, vertices, i * 3);
     }
 }
Esempio n. 2
0
        /// @par
        ///
        /// The value of spacial parameters are in world units.
        ///
        /// The y-values of the polygon vertices are ignored. So the polygon is effectively
        /// projected onto the xz-plane at @p hmin, then extruded to @p hmax.
        ///
        /// @see rcCompactHeightfield, rcMedianFilterWalkableArea
        public static void markConvexPolyArea(Context ctx, float[] verts, float hmin, float hmax, int areaId, CompactHeightfield chf)
        {
            ctx.startTimer("MARK_CONVEXPOLY_AREA");

            float[] bmin = new float[3]; float[] bmax = new float[3];
            RecastVectors.copy(bmin, verts, 0);
            RecastVectors.copy(bmax, verts, 0);
            for (int i = 1; i < verts.Length; ++i)
            {
                RecastVectors.min(bmin, verts, i * 3);
                RecastVectors.max(bmax, verts, i * 3);
            }
            bmin[1] = hmin;
            bmax[1] = hmax;

            int minx = (int)((bmin[0] - chf.bmin[0]) / chf.cs);
            int miny = (int)((bmin[1] - chf.bmin[1]) / chf.ch);
            int minz = (int)((bmin[2] - chf.bmin[2]) / chf.cs);
            int maxx = (int)((bmax[0] - chf.bmin[0]) / chf.cs);
            int maxy = (int)((bmax[1] - chf.bmin[1]) / chf.ch);
            int maxz = (int)((bmax[2] - chf.bmin[2]) / chf.cs);

            if (maxx < 0)
            {
                return;
            }
            if (minx >= chf.width)
            {
                return;
            }
            if (maxz < 0)
            {
                return;
            }
            if (minz >= chf.height)
            {
                return;
            }

            if (minx < 0)
            {
                minx = 0;
            }
            if (maxx >= chf.width)
            {
                maxx = chf.width - 1;
            }
            if (minz < 0)
            {
                minz = 0;
            }
            if (maxz >= chf.height)
            {
                maxz = chf.height - 1;
            }

            // TODO: Optimize.
            for (int z = minz; z <= maxz; ++z)
            {
                for (int x = minx; x <= maxx; ++x)
                {
                    CompactCell c = chf.cells[x + z * chf.width];
                    for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
                    {
                        CompactSpan s = chf.spans[i];
                        if (chf.areas[i] == RecastConstants.RC_NULL_AREA)
                        {
                            continue;
                        }
                        if (s.y >= miny && s.y <= maxy)
                        {
                            float[] p = new float[3];
                            p[0] = chf.bmin[0] + (x + 0.5f) * chf.cs;
                            p[1] = 0;
                            p[2] = chf.bmin[2] + (z + 0.5f) * chf.cs;

                            if (pointInPoly(verts, p))
                            {
                                chf.areas[i] = areaId;
                            }
                        }
                    }
                }
            }

            ctx.stopTimer("MARK_CONVEXPOLY_AREA");
        }
Esempio n. 3
0
        private static void rasterizeTri(float[] verts, int v0, int v1, int v2, int area, Heightfield hf, float[] bmin, float[] bmax, float cs, float ics, float ich, int flagMergeThr)
        {
            int w = hf.width;
            int h = hf.height;

            float[] tmin = new float[3]; float[] tmax = new float[3];
            float   by = bmax[1] - bmin[1];

            // Calculate the bounding box of the triangle.
            RecastVectors.copy(tmin, verts, v0 * 3);
            RecastVectors.copy(tmax, verts, v0 * 3);
            RecastVectors.min(tmin, verts, v1 * 3);
            RecastVectors.min(tmin, verts, v2 * 3);
            RecastVectors.max(tmax, verts, v1 * 3);
            RecastVectors.max(tmax, verts, v2 * 3);

            // If the triangle does not touch the bbox of the heightfield, skip the triagle.
            if (!overlapBounds(bmin, bmax, tmin, tmax))
            {
                return;
            }

            // Calculate the footprint of the triangle on the grid's y-axis
            int y0 = (int)((tmin[2] - bmin[2]) * ics);
            int y1 = (int)((tmax[2] - bmin[2]) * ics);

            y0 = RecastCommon.clamp(y0, 0, h - 1);
            y1 = RecastCommon.clamp(y1, 0, h - 1);

            // Clip the triangle into all grid cells it touches.
            float[] buf   = new float[7 * 3 * 4];
            int     @in   = 0;
            int     inrow = 7 * 3;
            int     p1    = inrow + 7 * 3;
            int     p2    = p1 + 7 * 3;

            RecastVectors.copy(buf, 0, verts, v0 * 3);
            RecastVectors.copy(buf, 3, verts, v1 * 3);
            RecastVectors.copy(buf, 6, verts, v2 * 3);
            int nvrow, nvIn = 3;

            for (int y = y0; y <= y1; ++y)
            {
                // Clip polygon to row. Store the remaining polygon as well
                float cz      = bmin[2] + y * cs;
                int[] nvrowin = dividePoly(buf, @in, nvIn, inrow, p1, cz + cs, 2);
                nvrow = nvrowin[0];
                nvIn  = nvrowin[1];
                {
                    int temp = @in;
                    @in = p1;
                    p1  = temp;
                }
                if (nvrow < 3)
                {
                    continue;
                }

                // find the horizontal bounds in the row
                float minX = buf[inrow], maxX = buf[inrow];
                for (int i = 1; i < nvrow; ++i)
                {
                    if (minX > buf[inrow + i * 3])
                    {
                        minX = buf[inrow + i * 3];
                    }
                    if (maxX < buf[inrow + i * 3])
                    {
                        maxX = buf[inrow + i * 3];
                    }
                }
                int x0 = (int)((minX - bmin[0]) * ics);
                int x1 = (int)((maxX - bmin[0]) * ics);
                x0 = RecastCommon.clamp(x0, 0, w - 1);
                x1 = RecastCommon.clamp(x1, 0, w - 1);

                int nv, nv2 = nvrow;
                for (int x = x0; x <= x1; ++x)
                {
                    // Clip polygon to column. store the remaining polygon as well
                    float cx    = bmin[0] + x * cs;
                    int[] nvnv2 = dividePoly(buf, inrow, nv2, p1, p2, cx + cs, 0);
                    nv  = nvnv2[0];
                    nv2 = nvnv2[1];
                    {
                        int temp = inrow;
                        inrow = p2;
                        p2    = temp;
                    }
                    if (nv < 3)
                    {
                        continue;
                    }

                    // Calculate min and max of the span.
                    float smin = buf[p1 + 1], smax = buf[p1 + 1];
                    for (int i = 1; i < nv; ++i)
                    {
                        smin = Math.Min(smin, buf[p1 + i * 3 + 1]);
                        smax = Math.Max(smax, buf[p1 + i * 3 + 1]);
                    }
                    smin -= bmin[1];
                    smax -= bmin[1];
                    // Skip the span if it is outside the heightfield bbox
                    if (smax < 0.0f)
                    {
                        continue;
                    }
                    if (smin > by)
                    {
                        continue;
                    }
                    // Clamp the span to the heightfield bbox.
                    if (smin < 0.0f)
                    {
                        smin = 0;
                    }
                    if (smax > by)
                    {
                        smax = by;
                    }

                    // Snap the span to the heightfield height grid.
                    int ismin = RecastCommon.clamp((int)Math.Floor(smin * ich), 0, RecastConstants.RC_SPAN_MAX_HEIGHT);
                    int ismax = RecastCommon.clamp((int)Math.Ceiling(smax * ich), ismin + 1, RecastConstants.RC_SPAN_MAX_HEIGHT);

                    addSpan(hf, x, y, ismin, ismax, area, flagMergeThr);
                }
            }
        }