Exemplo n.º 1
0
        private bool FindHorizonParallel(ref List <int> foundFaces, ref List <int> horizonEdges, int currentFace, int currentHalfEdge, Vec3 normal)
        {
            Face current  = faces[currentFace];
            int  halfEdge = current.halfEdge;

            Vec3 normalOnFace = current.normal;

            if (normalOnFace.dot(normal) >= 1f - epsilon2)
            {
                foundFaces.Add(currentFace);
                for (int i = 1; i <= 3; ++i)
                {
                    currentFace = edges[edges[currentHalfEdge].opposite].face;
                    if (!foundFaces.Contains(currentFace))
                    {
                        if (!FindHorizonParallel(ref foundFaces, ref horizonEdges, currentFace, edges[currentHalfEdge].opposite, normalOnFace))
                        {
                            horizonEdges.Add(currentHalfEdge);
                        }
                    }
                    currentHalfEdge = halfEdge + ((currentHalfEdge + 1) % 3);
                }

                return(true);
            }
            return(false);
        }
Exemplo n.º 2
0
        private bool CheckIntersection(Vec3 p, Vec3 direction, Vec3 edge1, Vec3 edge2, Vec3 v0, Vec3 h, float f, ref float t, ref float u, ref float v)
        {
            Vec3 s = p - v0;

            u = f * s.dot(h);
            if (u < 0f || u > 1f)
            {
                return(false);
            }

            Vec3 q = s.Cross(edge1);

            v = f * direction.dot(q);
            if (v < 0f || v > 1f)
            {
                return(false);
            }
            if (u + v > 1f)
            {
                return(false);
            }
            t = f * edge2.dot(q);
            return(true);
        }
Exemplo n.º 3
0
        public List <Vec3> GetAllVoxelOnPlane(Vec3 p1, Vec3 p2, Vec3 p3, bool getAll)
        {
            List <Vec3> result = new List <Vec3>();

            Vec3  normal = (p2 - p1).Cross((p3 - p1));
            float d      = -p1.dot(normal);

            uint resolution = xResolution;

            Vec3 mainDirection = new Vec3(1, 0, 0);

            if (Math.Abs(normal.x) < Math.Abs(normal.y))
            {
                if (Math.Abs(normal.z) < Math.Abs(normal.y))
                {
                    resolution    = yResolution;
                    mainDirection = new Vec3(0, 1, 0);
                }
                else
                {
                    resolution    = zResolution;
                    mainDirection = new Vec3(0, 0, 1);
                }
            }
            else if (Math.Abs(normal.x) < Math.Abs(normal.z))
            {
                resolution    = zResolution;
                mainDirection = new Vec3(0, 0, 1);
            }
            Vec3  planeCoord1 = new Vec3(mainDirection.z, mainDirection.x, mainDirection.y);
            Vec3  planeCoord2 = new Vec3(mainDirection.y, mainDirection.z, mainDirection.x);
            float min         = -d / mainDirection.dot(normal);
            float max         = min;
            float tmp         = -(d + (planeCoord1 * resolution).dot(normal)) / mainDirection.dot(normal);

            min = tmp < min ? tmp : min;
            max = tmp > max ? tmp : max;
            tmp = -(d + (planeCoord2 * resolution).dot(normal)) / mainDirection.dot(normal);
            min = tmp < min ? tmp : min;
            max = tmp > max ? tmp : max;
            tmp = -(d + (planeCoord1 * resolution + planeCoord2 * resolution).dot(normal)) / mainDirection.dot(normal);
            min = tmp < min ? tmp : min;
            max = tmp > max ? tmp : max;

            min = (float)Math.Floor(min);
            max = (float)Math.Ceiling(max);
            min = min < 0 ? 0 : min;
            max = max > resolution ? resolution : max;
            Vec3 maxHeightVector = mainDirection * max;

            if (max - min > 1)
            {
                Vec3 point1 = new Vec3();
                Vec3 point2 = new Vec3();

                Vec3 maxVector1 = planeCoord1 * resolution;
                Vec3 minVector1 = new Vec3(0, 0, 0);

                Vec3 minVector2 = new Vec3();
                Vec3 maxVector2 = new Vec3();

                Vec3 lineNormal = normal.Cross(mainDirection);
                lineNormal.Normalize();

                float t;
                float dotTmp;
                Vec3  tmpVec;
                Vec3  tmpResult = new Vec3();

                if (lineNormal.dot(planeCoord1) == 0)
                {
                    tmpVec      = planeCoord1;
                    planeCoord1 = planeCoord2;
                    planeCoord2 = tmpVec;

                    maxVector1 = planeCoord1 * resolution;
                    minVector1 = new Vec3(0, 0, 0);
                }

                for (Vec3 mainVec = mainDirection * min; mainVec != maxHeightVector; mainVec = mainVec + mainDirection)
                {
                    if (normal.dot(planeCoord1) != 0)
                    {
                        point1 = planeCoord1 * -(mainVec.dot(normal) + d) / (normal.dot(planeCoord1)) + mainVec;
                        point2 = planeCoord1 * -((mainVec + mainDirection).dot(normal) + d) / (normal.dot(planeCoord1)) + (mainVec + mainDirection);
                    }
                    else
                    {
                        point1 = planeCoord2 * -(mainVec.dot(normal) + d) / (normal.dot(planeCoord2)) + mainVec;
                        point2 = planeCoord2 * -((mainVec + mainDirection).dot(normal) + d) / (normal.dot(planeCoord2)) + (mainVec + mainDirection);
                    }
                    for (Vec3 direction1 = minVector1; direction1 != maxVector1; direction1 += planeCoord1)
                    {
                        dotTmp     = lineNormal.dot(planeCoord1);
                        t          = (direction1 + mainVec - point1).dot(planeCoord1) / dotTmp;
                        minVector2 = point1 + lineNormal * t;
                        t          = (direction1 + mainVec + mainDirection - point2).dot(planeCoord1) / dotTmp;
                        maxVector2 = point2 + lineNormal * t;
                        dotTmp     = maxVector2.dot(planeCoord2);
                        if (dotTmp < minVector2.dot(planeCoord2))
                        {
                            tmpVec     = minVector2;
                            minVector2 = maxVector2;
                            maxVector2 = tmpVec;
                            dotTmp     = maxVector2.dot(planeCoord2);
                        }
                        if (dotTmp < 0)
                        {
                            continue;
                        }
                        if ((dotTmp + 1) > resolution)
                        {
                            maxVector2 = planeCoord1 * maxVector2.dot(planeCoord1) + planeCoord2 * resolution + mainVec;
                        }
                        else
                        {
                            maxVector2 = planeCoord1 * maxVector2.dot(planeCoord1) + planeCoord2 * (dotTmp + 1) + mainVec;
                        }
                        dotTmp = minVector2.dot(planeCoord2);
                        if (dotTmp > resolution)
                        {
                            continue;
                        }
                        if (dotTmp < 0)
                        {
                            minVector2 = planeCoord1 * (minVector2.dot(planeCoord1)) + mainVec;
                        }
                        minVector2 = direction1 + mainVec + planeCoord2 * (float)Math.Floor(planeCoord2.dot(minVector2));
                        maxVector2 = direction1 + mainVec + planeCoord2 * (float)Math.Ceiling(planeCoord2.dot(maxVector2));
                        for (Vec3 direction2 = minVector2; direction2 != maxVector2; direction2 += planeCoord2)
                        {
                            tmpResult.x = (float)Math.Floor(direction2.x);
                            tmpResult.y = (float)Math.Floor(direction2.y);
                            tmpResult.z = (float)Math.Floor(direction2.z);
                            if (grid[(int)tmpResult.x, (int)tmpResult.y, (int)tmpResult.z].set || getAll)
                            {
                                result.Add(tmpResult);
                            }
                        }
                    }
                }
            }
            else
            {
                Vec3 pos;
                for (int i = 0; i < resolution; ++i)
                {
                    for (int j = 0; j < resolution; ++j)
                    {
                        pos = planeCoord1 * i + planeCoord2 * j + maxHeightVector;
                        if (grid[(int)pos.x, (int)pos.y, (int)pos.z].set || getAll)
                        {
                            result.Add(pos);
                        }
                    }
                }
            }
            return(result);
        }
Exemplo n.º 4
0
        private void FindOverlappedIndices(Vec3[] face, Vec3 normal)
        {
            Vec3[] newCoord = new Vec3[3];
            uint   i;

            Vec3[] projectedCoord = new Vec3[3];
            for (i = 0; i < 3; ++i)
            {
                newCoord[i]   = new Vec3();
                newCoord[i].x = (face[i].x - minOffset.x) / sizeVoxel;
                newCoord[i].y = (face[i].y - minOffset.y) / sizeVoxel;
                newCoord[i].z = (face[i].z - minOffset.z) / sizeVoxel;

                projectedCoord[i] = newCoord[i].outer(planeCoord1) + newCoord[i].outer(planeCoord2);
            }
            float normalSign = normal.dot(direction);
            Vec3  min = new Vec3(), max = new Vec3();

            Utility.CalcBoundingBox(projectedCoord, ref min, ref max);

            Vec3  edge1 = newCoord[1] - newCoord[0];
            Vec3  edge2 = newCoord[2] - newCoord[0];
            Vec3  h     = direction.Cross(edge2);
            float f     = 1f / edge1.dot(h);

            Vec3[] normals   = new Vec3[3];
            Vec3[] normals3d = new Vec3[3];

            float t = 0;
            float u = 0;
            float v = 0;

            for (i = 0; i < 3; ++i)
            {
                if (normalSign >= 0)
                {
                    normals[i] = planeCoord1 * (projectedCoord[i].dot(planeCoord2) - projectedCoord[(i + 1) % 3].dot(planeCoord2)) + planeCoord2 * (projectedCoord[(i + 1) % 3].dot(planeCoord1) - projectedCoord[i].dot(planeCoord1));
                }
                else
                {
                    normals[i] = planeCoord1 * (projectedCoord[(i + 1) % 3].dot(planeCoord2) - projectedCoord[i].dot(planeCoord2)) + planeCoord2 * (projectedCoord[i].dot(planeCoord1) - projectedCoord[(i + 1) % 3].dot(planeCoord1));
                }
                normals[i].Normalize();
            }

            min.x = (float)Math.Floor(min.x);
            min.y = (float)Math.Floor(min.y);
            min.z = (float)Math.Floor(min.z);
            max.x = (float)Math.Ceiling(max.x);
            max.y = (float)Math.Ceiling(max.y);
            max.z = (float)Math.Ceiling(max.z);


            Vec3 min1 = new Vec3();
            Vec3 min2 = new Vec3();
            Vec3 max1 = new Vec3();
            Vec3 max2 = new Vec3();


            min1.x = min.x * planeCoord1.x;
            min1.y = min.y * planeCoord1.y;
            min1.z = min.z * planeCoord1.z;
            min2.x = min.x * planeCoord2.x;
            min2.y = min.y * planeCoord2.y;
            min2.z = min.z * planeCoord2.z;

            max1.x = max.x * planeCoord1.x;
            max1.y = max.y * planeCoord1.y;
            max1.z = max.z * planeCoord1.z;
            max2.x = max.x * planeCoord2.x;
            max2.y = max.y * planeCoord2.y;
            max2.z = max.z * planeCoord2.z;
            Vec3 tmp;
            Vec3 pos;

            bool[] leftEdge = new bool[3];
            for (i = 0; i < 3; ++i)
            {
                leftEdge[i]  = normals[i].compareGreater(0, planeCoord1);
                leftEdge[i] |= normals[i].compareEqual(0, planeCoord1) && normals[i].compareSmaller(0, planeCoord2);
            }

            float epsilon = 0.00000001f;
            bool  edge    = true;

            for (Vec3 dir1 = min1; dir1 != max1; dir1 += planeCoord1)
            {
                for (Vec3 dir2 = min2; dir2 != max2; dir2 += planeCoord2)
                {
                    edge = true;
                    tmp  = dir1 + dir2 + planeCoord1 * 0.5f + planeCoord2 * 0.5f;
                    if (CheckIntersection(tmp, direction, edge1, edge2, newCoord[0], h, f, ref t, ref u, ref v))
                    {
                        if (u < (0f + epsilon))
                        {
                            edge = edge && leftEdge[2];
                        }
                        if (v < (0f + epsilon))
                        {
                            edge = edge && leftEdge[0];
                        }
                        if ((u + v - 1f) < (0f + epsilon) && (u + v - 1f) > (0f - epsilon))
                        {
                            edge = edge && leftEdge[1];
                        }
                        if (edge)
                        {
                            pos = tmp + direction * t;
                            grid[(int)Math.Floor(pos.x), (int)Math.Floor(pos.y), (int)Math.Floor(pos.z)].set ^= true;
                        }
                    }
                }
            }
        }
Exemplo n.º 5
0
        private void CreateStart()
        {
            float lowestX = points[0].x, highestX = points[0].x;
            float lowestY = points[0].y, highestY = points[0].y;
            float lowestZ = points[0].z, highestZ = points[0].z;

            int[] lowest  = new int[3];
            int[] highest = new int[3];

            int  listSize = points.Count;
            Vec3 point;

            for (int i = 0; i < listSize; ++i)
            {
                point = points[i];
                if (point.x < lowestX)
                {
                    lowestX   = point.x;
                    lowest[0] = i;
                }
                if (point.x > highestX)
                {
                    highestX   = point.x;
                    highest[0] = i;
                }
                if (point.y < lowestY)
                {
                    lowestY   = point.y;
                    lowest[1] = i;
                }
                if (point.y > highestY)
                {
                    highestY   = point.y;
                    highest[1] = i;
                }
                if (point.z < lowestZ)
                {
                    lowestZ   = point.z;
                    lowest[2] = i;
                }
                if (point.z > highestZ)
                {
                    highestZ   = point.z;
                    highest[2] = i;
                }
            }

            int   greatestDistanceUp   = lowest[0];
            int   greatestDistanceDown = highest[0];
            Vec3  distanceVec          = points[greatestDistanceDown] - points[greatestDistanceUp];
            float maxDistance          = distanceVec.dot(distanceVec);
            float tmpDistance          = 0;

            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    distanceVec = points[lowest[i]] - points[highest[j]];
                    tmpDistance = distanceVec.dot(distanceVec);
                    if (tmpDistance > maxDistance)
                    {
                        greatestDistanceUp   = lowest[i];
                        greatestDistanceDown = highest[j];
                        maxDistance          = tmpDistance;
                    }
                }
            }

            distanceVec = points[greatestDistanceDown] - points[greatestDistanceUp];
            int   distanceIdx = 0;
            Vec3  tmpVec;
            float newMaxDistance = 0;

            for (int i = 0; i < 3; ++i)
            {
                tmpVec      = distanceVec.Cross(points[greatestDistanceUp] - points[lowest[i]]);
                tmpDistance = (tmpVec).dot(tmpVec) / maxDistance;
                if (tmpDistance > newMaxDistance)
                {
                    distanceIdx    = lowest[i];
                    newMaxDistance = tmpDistance;
                }
            }

            for (int i = 0; i < 3; ++i)
            {
                tmpVec      = distanceVec.Cross(points[greatestDistanceUp] - points[highest[i]]);
                tmpDistance = (tmpVec).dot(tmpVec) / maxDistance;
                if (tmpDistance > newMaxDistance)
                {
                    distanceIdx    = highest[i];
                    newMaxDistance = tmpDistance;
                }
            }

            Vec3 normal = (distanceVec.Cross(points[greatestDistanceDown] - points[distanceIdx]));

            normal.Normalize();

            newMaxDistance = 0;
            int distanceIdx2 = 0;

            for (int i = 0; i < 3; ++i)
            {
                tmpDistance = Math.Abs(normal.dot(points[distanceIdx] - points[lowest[i]]));
                if (tmpDistance > newMaxDistance)
                {
                    distanceIdx2   = lowest[i];
                    newMaxDistance = tmpDistance;
                }
            }

            for (int i = 0; i < 3; ++i)
            {
                tmpDistance = Math.Abs(normal.dot(points[distanceIdx] - points[highest[i]]));
                if (tmpDistance > newMaxDistance)
                {
                    distanceIdx2   = highest[i];
                    newMaxDistance = tmpDistance;
                }
            }

            if (normal.dot(points[distanceIdx2] - points[distanceIdx]) > 0)
            {
                //Face 0
                HalfEdge newHalfEdge = new HalfEdge();
                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 3;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 6;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 9;
                edges.Add(newHalfEdge);

                //Face 1
                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 0;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 11;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 7;
                edges.Add(newHalfEdge);

                //Face2
                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 1;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 5;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 10;
                edges.Add(newHalfEdge);

                //Face3
                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 2;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 8;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 4;
                edges.Add(newHalfEdge);
            }

            else
            {
                //Face 0
                HalfEdge newHalfEdge = new HalfEdge();
                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 11;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 8;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 5;
                edges.Add(newHalfEdge);

                //Face 1
                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 7;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 9;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 2;
                edges.Add(newHalfEdge);

                //Face2
                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 10;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 3;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 1;
                edges.Add(newHalfEdge);

                //Face3
                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 4;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 6;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 0;
                edges.Add(newHalfEdge);
            }

            Face newFace = new Face();

            for (int i = 0; i < 4; ++i)
            {
                newFace.halfEdge = i * 3;
                newFace.normal   = ((points[edges[i * 3 + 2].vertex] - points[edges[i * 3].vertex]).Cross(points[edges[i * 3 + 1].vertex] - points[edges[i * 3].vertex]));
                newFace.normal.Normalize();
                newFace.pointList = -1;
                faces.Add(newFace);
            }
        }