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++; } }
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); }
//////////////////////////////////////////////////////////////////////////// // 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); } } }