コード例 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="octreeNodeInfo"></param>
        /// <returns></returns>
        private int GetNumberOfNodes(OctreeNodeInfo octreeNodeInfo)
        {
            if (octreeNodeInfo == OctreeNodeInfo.Empty)
            {
                return(0);
            }

            if (octreeNodeInfo == OctreeNodeInfo.Full)
            {
                return(8);
            }

            var count = 0;

            if (octreeNodeInfo.HasFlag(OctreeNodeInfo.x0y0z0))
            {
                count++;
            }

            if (octreeNodeInfo.HasFlag(OctreeNodeInfo.x1y0z0))
            {
                count++;
            }

            if (octreeNodeInfo.HasFlag(OctreeNodeInfo.x1y1z0))
            {
                count++;
            }

            if (octreeNodeInfo.HasFlag(OctreeNodeInfo.x1y1z1))
            {
                count++;
            }

            if (octreeNodeInfo.HasFlag(OctreeNodeInfo.x0y1z1))
            {
                count++;
            }

            if (octreeNodeInfo.HasFlag(OctreeNodeInfo.x0y0z1))
            {
                count++;
            }

            if (octreeNodeInfo.HasFlag(OctreeNodeInfo.x0y1z0))
            {
                count++;
            }

            if (octreeNodeInfo.HasFlag(OctreeNodeInfo.x1y0z1))
            {
                count++;
            }

            return(count);
        }
コード例 #2
0
ファイル: OctreeBuilder.cs プロジェクト: smogpill/transit
    static OctreeNode ConstructLeaf(Shape shape, OctreeNode leaf)
    {
        if (leaf == null)
        {
            return null;
        }

        int corners = 0;
        for (int i = 0; i < 8; ++i)
        {
            Vector3 cornerPos = leaf.min + CHILD_MIN_OFFSETS[i] * leaf.size;
            float density = shape.ComputeDistance(cornerPos);
            int material = density < 0 ? MATERIAL_SOLID : MATERIAL_AIR;
            corners |= material << i;
        }

        if (corners == 0 || corners == 255)
        {
            // voxel is full inside or outside the volume
            return null;
        }

        // otherwise the voxel contains the surface, so find the edge intersections
        const int MAX_CROSSINGS = 6;
        int nbEdges = 0;
        Vector3 normalSum = Vector3.zero;
        QefData qefData = new QefData();

        for (int i = 0; i < 12 && nbEdges < MAX_CROSSINGS; ++i)
        {
            int c1 = edgevmap[i, 0];
            int c2 = edgevmap[i, 1];

            int m1 = (corners >> c1) & 1;
            int m2 = (corners >> c2) & 1;

            if (m1 == m2)
            {
                // no crossing on this edge
                continue;
            }

            Vector3 p1 = leaf.min + CHILD_MIN_OFFSETS[c1] * leaf.size;
            Vector3 p2 = leaf.min + CHILD_MIN_OFFSETS[c2] * leaf.size;
            Vector3 p = ApproximateIntersection(shape, p1, p2);
            Vector3 n = shape.ComputeNormal(p);
            qefData.Add(p, n);

            normalSum += n;

            ++nbEdges;
        }

        Vector3 qefPosition;
        QefSolver.Solve(out qefPosition, qefData, QEF_ERROR, QEF_SWEEPS, QEF_ERROR);

        OctreeNodeInfo nodeInfo = new OctreeNodeInfo();
        nodeInfo.position = qefPosition;
        nodeInfo.qefData = qefData;

        Vector3 min = leaf.min;
        Vector3 max = leaf.min + new Vector3(leaf.size, leaf.size, leaf.size);
        //nodeInfo.position = Vector3.Min(max, Vector3.Max(min, qefData.MassPoint));
        if (nodeInfo.position.x < min.x || nodeInfo.position.x > max.x ||
            nodeInfo.position.y < min.y || nodeInfo.position.y > max.y ||
            nodeInfo.position.z < min.z || nodeInfo.position.z > max.z)
        {
            int x = 0;
            ++x;
            //nodeInfo.position = qefData.MassPoint;
        }

        {
            float tolerance = 1.0f;
            if (qefPosition.x - min.x < -tolerance
                || qefPosition.y - min.y < -tolerance
                || qefPosition.z - min.z < -tolerance
                || qefPosition.x - max.x > tolerance
                || qefPosition.y - max.y > tolerance
                || qefPosition.z - max.z > tolerance)
            {
                int x = 0;
                ++x;
            }
        }

        nodeInfo.averageNormal = Vector3.Normalize(normalSum);
        nodeInfo.corners = corners;

        leaf.type = OctreeNode.Type.Leaf;
        leaf.info = nodeInfo;

        return leaf;
    }