예제 #1
0
        static void SmearDirection(VoxelSet <float> voxels, float transference, Vec3i dir)
        {
            Vec3i dx = new Vec3i(Math.Abs(dir.y), Math.Abs(dir.z), Math.Abs(dir.x));
            Vec3i dy = new Vec3i(Math.Abs(dir.z), Math.Abs(dir.x), Math.Abs(dir.y));

            Vec3i start = new Vec3i(0);

            if (Vec3i.Dot(dir, new Vec3i(1)) < 0)
            {
                start = voxels.Size.Dot(dir) * dir + dir;
            }

            int y = 0;

            while (voxels.IsValid(start + y * dy))
            {
                int x = 0;
                while (voxels.IsValid(start + y * dy + x * dx))
                {
                    SmearLine(voxels, transference, dir, start + y * dy + x * dx);
                    x++;
                }
                y++;
            }
        }
예제 #2
0
    bool LayerMarch(Vector3 startPoint, Vector3 dir, out Vec3i hitIdx, out Vec3i lastIdx, ref float t)
    {
        dir = Vector3.Normalize(dir);

        Vector3 voxelGridSize = new Vector3(voxels.Size.x, voxels.Size.y, voxels.Size.z);

        Vector3 p0   = startPoint;
        float   endT = VecUtil.MinComp(Vector3.Max(
                                           VecUtil.Div(voxelGridSize - p0, dir),
                                           VecUtil.Div(-p0, dir)
                                           ));

        Vector3 dirAbs = VecUtil.Abs(dir);

        // TODO: This is making invalid assumptions about p0
        //Vector3 p0abs = VecUtil.Mul(Vector3.one - VecUtil.Step(0, dir), voxelGridSize)
        //    + VecUtil.Mul(VecUtil.Sign(dir), p0);

        //Vector3 negativeDimensions = Vector3.one - VecUtil.Step(0, dir);
        //Vector3 p0abs = VecUtil.Mul(negativeDimensions, voxelGridSize) - VecUtil.Mul(negativeDimensions, p0)
        //+ VecUtil.Mul(VecUtil.Step(0, dir), p0);

        Vector3 p0abs = p0;

        for (int i = 0; i < 3; ++i)
        {
            if (dir[i] < 0)
            {
                p0abs[i] = voxelGridSize[i] - p0[i];
            }
        }

        //float t = 0;
        //t = 0;
        lastIdx = ToIndex(p0 + dir * (t - kEps));
        int            iterationCount = 0;
        List <Vector3> debugPos       = new List <Vector3>();
        List <Vector3> debugPosAbs    = new List <Vector3>();

        t += kEps;

        while (t <= endT)
        {
            Vec3i idx = ToIndex(p0 + dir * (t + kEps));
            debugPos.Add(p0 + dir * (t + kEps));
            //Vec3i idx = ToIndex(p0 + dir * t);

            debugPosAbs.Add(p0abs + dirAbs * (t + kEps));
            Vector3 pAbs = p0abs + dirAbs * (t + kEps);

            ////////////////
            // DEBUG CODE
            Vec3i delta = idx - lastIdx;
            if (Vec3i.Dot(delta, delta) > 1)
            {
                Debug.LogWarning("Skipped a voxel");
            }

            if (!voxels.IsValid(idx))
            {
                break;
            }

            Color32 c = voxels[idx];
            if (c.a > 0)
            {
                hitIdx = idx;
                return(true);
            }

            lastIdx = idx;

            // Pretend we came in from a positive direction

            //Vector3 pAbs = p0abs + dirAbs * (t);
            Vector3 deltas = VecUtil.Div(Vector3.one - VecUtil.Fract(pAbs), dirAbs);
            //t += Mathf.Max(VecUtil.MinComp(deltas), float.Epsilon);
            //t += Mathf.Max(VecUtil.MinComp(deltas), 0.0005f);
            t += Mathf.Max(VecUtil.MinComp(deltas), kEps) + kEps;

            //Vector3 pAbs = p0abs + dirAbs * t;
            //Vector3 deltas = VecUtil.Div(Vector3.one - VecUtil.Fract(pAbs), dirAbs);
            //t += Mathf.Max(VecUtil.MinComp(deltas), float.Epsilon);

            //Vector3 pAbs = p0abs + dirAbs * t;
            //Vector3 p = p0 + dir * t;
            //Vector3 deltas = VecUtil.Div(VecUtil.Step(0, dir) - VecUtil.Fract(p), dir);
            //t += Mathf.Max(VecUtil.MinComp(deltas), 0.0005f);
            //t += Mathf.Max(VecUtil.MinComp(deltas), float.Epsilon);
            iterationCount++;
        }

        hitIdx = new Vec3i(-1);
        return(false);
    }
예제 #3
0
    ////////////////////////////////////////////////////////////////////////////



    // Adds all faces for the given index of the given voxels to the list of quads.
    static void AddFaces(VoxelSet <Vec4b> voxels, List <Quad> quads, Vec3i idx)
    {
        Vec3i[] normals =
        {
            new Vec3i(1,   0, 0),
            new Vec3i(-1,  0, 0),

            new Vec3i(0,   1, 0),
            new Vec3i(0,  -1, 0),

            new Vec3i(0,   0, 1),
            new Vec3i(0,   0, -1)
        };

        bool transparent = IsTransparent(voxels, idx);

        for (int i = 0; i < normals.Length; ++i)
        {
            Vec3i normal   = normals[i];
            Vec3i neighbor = idx + normal;
            if (voxels.IsValid(neighbor) && (voxels[neighbor].w > 0))
            {
                if (transparent && IsTransparent(voxels, neighbor))
                {
                    // Two transparent voxels - face is hidden.
                    continue;
                }

                if (transparent && voxels[neighbor].w == 255)
                {
                    // Transparent self and opaque neighbor - hidden to avoid z-fighting.
                    continue;
                }

                if (!transparent && voxels[neighbor].w == 255)
                {
                    // Two opaque voxels - face is hidden.
                    continue;
                }
            }

            var  c = voxels[idx];
            Quad q = new Quad();

            q.color = new Color32(c.x, c.y, c.z, c.w);

            Vec3i pos = idx;

            if (Vec3i.Dot(normal, new Vec3i(1)) > 0)
            {
                pos += normal;
            }

            q.position = new Vector3(pos.x, pos.y, pos.z);
            q.uv       = new Vector2(i, 0);

            quads.Add(q);

            if (transparent)
            {
                // Add back facing as well for transparent quads
                //q.uv = new Vector2((i - (i % 2)) + ((i + 1) % 2), 0);
                q.uv = new Vector2(i ^ 1, 0);
                //q.position += new Vector3(normal.x, normal.y, normal.z);
                quads.Add(q);
            }
        }
    }