コード例 #1
0
ファイル: GTerrainChunk.cs プロジェクト: ComradeCrunchy/Ranch
        internal NativeArray <bool> GetVertexMarkerFromMeshUV(int lod)
        {
            int dimension = GGeometryJobUtilities.VERTEX_MARKER_DIMENSION;
            NativeArray <bool> markers = new NativeArray <bool>(dimension * dimension, Allocator.TempJob);

            Mesh m = GetMesh(lod);

            Vector2[] uvs = m.uv;
            int       x   = 0;
            int       y   = 0;
            Vector2   uv  = Vector2.zero;

            for (int i = 0; i < uvs.Length; ++i)
            {
                uv = uvs[i];
                x  = (int)(uv.x * (dimension - 1));
                y  = (int)(uv.y * (dimension - 1));
                markers[GGeometryJobUtilities.To1DIndex(ref x, ref y, ref dimension)] = true;
            }

            GUtilities.EnsureArrayLength(ref vertexMarker_Cache, markers.Length);
            markers.CopyTo(vertexMarker_Cache);

            return(markers);
        }
コード例 #2
0
        public static void MarkVertex(ref NativeArray <bool> markerArray, ref Vector2 p)
        {
            int dimension = VERTEX_MARKER_DIMENSION;
            int x         = (int)(p.x * (dimension - 1));
            int y         = (int)(p.y * (dimension - 1));

            markerArray[GGeometryJobUtilities.To1DIndex(ref x, ref y, ref dimension)] = true;
        }
コード例 #3
0
        private bool CheckMarkNeighbor(Vector2 p)
        {
            if (p.x > 0 && p.x < 1 &&
                p.y > 0 && p.y < 1)
            {
                return(false);
            }

            if (p.x == 0)
            {
                if (hasLeftMarker)
                {
                    return(GGeometryJobUtilities.GetVertexMark(vertexMarkerLeft, p, true, false));
                }
                else
                {
                    return(false);
                }
            }

            if (p.x == 1)
            {
                if (hasRightMarker)
                {
                    return(GGeometryJobUtilities.GetVertexMark(vertexMarkerRight, p, true, false));
                }
                else
                {
                    return(false);
                }
            }

            if (p.y == 0)
            {
                if (hasBottomMarker)
                {
                    return(GGeometryJobUtilities.GetVertexMark(vertexMarkerBottom, p, false, true));
                }
                else
                {
                    return(false);
                }
            }

            if (p.y == 1)
            {
                if (hasTopMarker)
                {
                    return(GGeometryJobUtilities.GetVertexMark(vertexMarkerTop, p, false, true));
                }
                else
                {
                    return(false);
                }
            }

            return(false);
        }
コード例 #4
0
        public void Execute()
        {
            int     startIndex     = 0;
            int     endIndex       = 0;
            int     leftNodeIndex  = 0;
            int     rightNodeIndex = 0;
            bool    mark0          = false;
            bool    mark1          = false;
            bool    mark2          = false;
            bool    mark3          = false;
            bool    mark4          = false;
            bool    mark5          = false;
            Vector2 v12            = Vector2.zero;

            GSubdivNode currentNode;
            GSubdivNode leftNode  = new GSubdivNode();
            GSubdivNode rightNode = new GSubdivNode();

            meshBaseResolution = Mathf.Max(0, meshBaseResolution - lod);

            metadata[GGeometryJobUtilities.METADATA_NEW_VERTEX_CREATED] = 0;
            for (int res = meshBaseResolution; res < meshResolution; ++res)
            {
                startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
                endIndex   = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
                for (int i = startIndex; i <= endIndex; ++i)
                {
                    GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
                    if (creationState[leftNodeIndex] != GGeometryJobUtilities.STATE_NOT_CREATED ||
                        creationState[rightNodeIndex] != GGeometryJobUtilities.STATE_NOT_CREATED)
                    {
                        continue;
                    }
                    currentNode = nodes[i];
                    mark0       = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v01);
                    mark1       = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v12);
                    mark2       = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v20);
                    mark3       = CheckMarkLOD0(currentNode.v01);
                    mark4       = CheckMarkLOD0(currentNode.v12);
                    mark5       = CheckMarkLOD0(currentNode.v20);

                    if (mark0 || mark1 || mark2 ||
                        mark3 || mark4 || mark5)
                    {
                        currentNode.Split(ref leftNode, ref rightNode);
                        nodes[leftNodeIndex]          = leftNode;
                        nodes[rightNodeIndex]         = rightNode;
                        creationState[leftNodeIndex]  = GGeometryJobUtilities.STATE_CREATED;
                        creationState[rightNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
                        GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref leftNode);
                        GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref rightNode);

                        metadata[GGeometryJobUtilities.METADATA_NEW_VERTEX_CREATED] = 1;
                    }
                }
            }
        }
コード例 #5
0
 private bool CheckMarkLOD0(Vector2 p)
 {
     if (p.x > 0 && p.x < 1 && p.y > 0 && p.y < 1)
     {
         return(false);
     }
     else
     {
         return(GGeometryJobUtilities.GetVertexMark(vertexMarker_LOD0, p));
     }
 }
コード例 #6
0
        public void Execute()
        {
            GSubdivNode n;
            Vector3     v0 = Vector3.zero;
            Vector3     v1 = Vector3.zero;
            Vector3     v2 = Vector3.zero;

            Vector2 uv0 = Vector2.zero;
            Vector2 uv1 = Vector2.zero;
            Vector2 uv2 = Vector2.zero;
            Vector2 uvc = Vector2.zero;

            Vector3 normal = Vector3.zero;
            Color32 color  = new Color32();

            int i0 = 0;
            int i1 = 0;
            int i2 = 0;

            Color hmData0      = Color.black;
            Color hmData1      = Color.black;
            Color hmData2      = Color.black;
            float heightSample = 0;

            meshBaseResolution = Mathf.Max(0, meshBaseResolution - lod);

            int length           = nodes.Length;
            int leafIndex        = 0;
            int startIndex       = GGeometryJobUtilities.GetStartIndex(ref meshBaseResolution);
            int removedLeafCount = 0;

            for (int i = startIndex; i < length; ++i)
            {
                if (creationState[i] != GGeometryJobUtilities.STATE_LEAF)
                {
                    continue;
                }
                n = nodes[i];
                ProcessTriangle(
                    ref n, ref leafIndex,
                    ref uv0, ref uv1, ref uv2, ref uvc,
                    ref v0, ref v1, ref v2,
                    ref i0, ref i1, ref i2,
                    ref normal, ref color,
                    ref hmData0, ref hmData1, ref hmData2,
                    ref heightSample, ref removedLeafCount);
                leafIndex += 1;
            }

            metadata[GGeometryJobUtilities.METADATA_LEAF_REMOVED] = removedLeafCount;
        }
コード例 #7
0
        public static bool GetVertexMark(NativeArray <bool> markers, Vector2 p, bool flipX = false, bool flipY = false)
        {
            if (flipX)
            {
                p.x = 1 - p.x;
            }
            if (flipY)
            {
                p.y = 1 - p.y;
            }

            int dimension = VERTEX_MARKER_DIMENSION;
            int x         = (int)(p.x * (dimension - 1));
            int y         = (int)(p.y * (dimension - 1));

            //mark = markerArray[GGeometryJobUtilities.To1DIndex(ref x, ref y, ref dimension)];
            return(markers[GGeometryJobUtilities.To1DIndex(ref x, ref y, ref dimension)]);
        }
コード例 #8
0
        public void Execute()
        {
            int startIndex     = 0;
            int endIndex       = 0;
            int leftNodeIndex  = 0;
            int rightNodeIndex = 0;
            int count          = 0;
            int length         = creationState.Length;

            baseResolution = Mathf.Max(0, baseResolution - lod);

            for (int res = baseResolution; res <= resolution; ++res)
            {
                startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
                endIndex   = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
                for (int i = startIndex; i <= endIndex; ++i)
                {
                    if (creationState[i] != GGeometryJobUtilities.STATE_CREATED)
                    {
                        continue;
                    }
                    GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
                    if (leftNodeIndex >= length || rightNodeIndex >= length)
                    {
                        creationState[i] = GGeometryJobUtilities.STATE_LEAF;
                        count           += 1;
                        continue;
                    }
                    if (creationState[leftNodeIndex] == GGeometryJobUtilities.STATE_NOT_CREATED ||
                        creationState[rightNodeIndex] == GGeometryJobUtilities.STATE_NOT_CREATED)
                    {
                        creationState[i] = GGeometryJobUtilities.STATE_LEAF;
                        count           += 1;
                        continue;
                    }
                }
            }
            metadata[0] = count;
        }
コード例 #9
0
 private float GetSmoothNormalMask(ref Vector2 uv)
 {
     return(GGeometryJobUtilities.GetColorPoint(maskMap, uv).g);
 }
コード例 #10
0
        private void GetHeightMapData(ref Color data, ref Vector2 uv)
        {
            Color sample      = Vector4.zero;
            float sampleCount = 0f;

            sample      += GGeometryJobUtilities.GetColorBilinear(hmC, ref uv);
            sampleCount += 1;

            if (uv.x == 0 && uv.y == 0) //bottom left corner
            {
                if (hmB.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
                if (hmL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
                if (hmBL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmBL, Flip(ref uv, true, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 0 && uv.y == 1) //top left corner
            {
                if (hmT.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
                if (hmL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
                if (hmTL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmTL, Flip(ref uv, true, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 1 && uv.y == 1) //top right corner
            {
                if (hmT.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
                if (hmR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
                if (hmTR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmTR, Flip(ref uv, true, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 1 && uv.y == 0) //bottom right corner
            {
                if (hmB.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
                if (hmR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
                if (hmBR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmBR, Flip(ref uv, true, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 0) //left edge
            {
                if (hmL.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
            }
            else if (uv.y == 1) //top edge
            {
                if (hmT.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
            }
            else if (uv.x == 1) //right edge
            {
                if (hmR.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
                    sampleCount += 1;
                }
            }
            else if (uv.y == 0) //bottom edge
            {
                if (hmB.IsValid)
                {
                    sample      += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
                    sampleCount += 1;
                }
            }

            data = sample / sampleCount;
        }
コード例 #11
0
        private void ProcessTriangle(
            ref GSubdivNode n, ref int leafIndex,
            ref Vector2 uv0, ref Vector2 uv1, ref Vector2 uv2, ref Vector2 uvc,
            ref Vector3 v0, ref Vector3 v1, ref Vector3 v2,
            ref int i0, ref int i1, ref int i2,
            ref Vector3 normal, ref Color32 color,
            ref Color hmData0, ref Color hmData1, ref Color hmData2,
            ref float heightSample, ref int removedLeafCount)
        {
            GGeometryJobUtilities.NormalizeToPoint(ref uv0, ref chunkUvRect, ref n.v0);
            GGeometryJobUtilities.NormalizeToPoint(ref uv1, ref chunkUvRect, ref n.v1);
            GGeometryJobUtilities.NormalizeToPoint(ref uv2, ref chunkUvRect, ref n.v2);

            if (displacementStrength > 0)
            {
                DisplaceUV(ref uv0);
                DisplaceUV(ref uv1);
                DisplaceUV(ref uv2);
            }

            GetHeightMapData(ref hmData0, ref uv0);
            GetHeightMapData(ref hmData1, ref uv1);
            GetHeightMapData(ref hmData2, ref uv2);

            GetHeightSample(ref heightSample, ref hmData0);
            v0.Set(
                uv0.x * terrainSize.x - chunkLocalPosition.x,
                heightSample * terrainSize.y,
                uv0.y * terrainSize.z - chunkLocalPosition.z);

            GetHeightSample(ref heightSample, ref hmData1);
            v1.Set(
                uv1.x * terrainSize.x - chunkLocalPosition.x,
                heightSample * terrainSize.y,
                uv1.y * terrainSize.z - chunkLocalPosition.z);

            GetHeightSample(ref heightSample, ref hmData2);
            v2.Set(
                uv2.x * terrainSize.x - chunkLocalPosition.x,
                heightSample * terrainSize.y,
                uv2.y * terrainSize.z - chunkLocalPosition.z);

            i0 = leafIndex * 3 + 0;
            i1 = leafIndex * 3 + 1;
            i2 = leafIndex * 3 + 2;

            vertices[i0] = v0;
            vertices[i1] = v1;
            vertices[i2] = v2;

            uvs[i0] = uv0;
            uvs[i1] = uv1;
            uvs[i2] = uv2;

            if (!smoothNormal)
            {
                normal      = Vector3.Cross(v1 - v0, v2 - v0).normalized;
                normals[i0] = normal;
                normals[i1] = normal;
                normals[i2] = normal;
            }
            else if (smoothNormal && !useSmoothNormalMask)
            {
                normals[i0] = GetSmoothNormal(ref uv0, ref v0).normalized;
                normals[i1] = GetSmoothNormal(ref uv1, ref v1).normalized;
                normals[i2] = GetSmoothNormal(ref uv2, ref v2).normalized;
            }
            else if (smoothNormal && useSmoothNormalMask)
            {
                normal = Vector3.Cross(v1 - v0, v2 - v0);
                Vector3 smoothNormal;
                float   mask;

                smoothNormal = GetSmoothNormal(ref uv0, ref v0);
                mask         = GetSmoothNormalMask(ref uv0);
                normals[i0]  = Vector3.Lerp(normal, smoothNormal, mask).normalized;

                smoothNormal = GetSmoothNormal(ref uv1, ref v1);
                mask         = GetSmoothNormalMask(ref uv1);
                normals[i1]  = Vector3.Lerp(normal, smoothNormal, mask).normalized;

                smoothNormal = GetSmoothNormal(ref uv2, ref v2);
                mask         = GetSmoothNormalMask(ref uv2);
                normals[i2]  = Vector3.Lerp(normal, smoothNormal, mask).normalized;
            }

            if (hmData0.a >= 0.5 || hmData1.a >= 0.5 || hmData2.a >= 0.5)
            {
                triangles[i0]     = i0;
                triangles[i1]     = i0;
                triangles[i2]     = i0;
                removedLeafCount += 1;
            }
            else
            {
                triangles[i0] = i0;
                triangles[i1] = i1;
                triangles[i2] = i2;
            }

            if (albedoToVertexColorMode == GAlbedoToVertexColorMode.Sharp)
            {
                uvc        = (uv0 + uv1 + uv2) / 3f;
                color      = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uvc);
                colors[i0] = color;
                colors[i1] = color;
                colors[i2] = color;
            }
            else if (albedoToVertexColorMode == GAlbedoToVertexColorMode.Smooth)
            {
                colors[i0] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv0);
                colors[i1] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv1);
                colors[i2] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv2);
            }
        }
コード例 #12
0
        public void Execute()
        {
            int startIndex     = 0;
            int endIndex       = 0;
            int leftNodeIndex  = 0;
            int rightNodeIndex = 0;

            GSubdivNode currentNode;
            GSubdivNode leftNode  = new GSubdivNode();
            GSubdivNode rightNode = new GSubdivNode();

            Vector2 uv0 = Vector2.zero;
            Vector2 uv1 = Vector2.zero;
            Vector2 uv2 = Vector2.zero;
            Vector2 uvc = Vector2.zero;

            float r0          = 0;
            float r1          = 0;
            float r2          = 0;
            float rc          = 0;
            float rMax        = 0;
            int   subDivLevel = 0;

            baseResolution = Mathf.Max(0, baseResolution - lod);
            resolution     = Mathf.Max(0, resolution - lod);

            int maxLevel = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GGeometryJobUtilities.SUB_DIV_STEP), resolution - baseResolution);

            for (int res = baseResolution; res < maxLevel; ++res)
            {
                startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
                endIndex   = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
                for (int i = startIndex; i <= endIndex; ++i)
                {
                    if (creationState[i] != GGeometryJobUtilities.STATE_CREATED)
                    {
                        continue;
                    }
                    currentNode = baseTree[i];
                    GGeometryJobUtilities.NormalizeToPoint(ref uv0, ref uvRect, ref currentNode.v0);
                    GGeometryJobUtilities.NormalizeToPoint(ref uv1, ref uvRect, ref currentNode.v1);
                    GGeometryJobUtilities.NormalizeToPoint(ref uv2, ref uvRect, ref currentNode.v2);
                    uvc = (uv0 + uv1 + uv2) / 3;

                    r0 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv0).r;
                    r1 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv1).r;
                    r2 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv2).r;
                    rc = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uvc).r;

                    rMax = Mathf.Max(Mathf.Max(r0, r1), Mathf.Max(r2, rc));

                    subDivLevel = baseResolution + (int)(rMax / GGeometryJobUtilities.SUB_DIV_STEP);
                    if (subDivLevel <= res)
                    {
                        continue;
                    }

                    GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
                    currentNode.Split(ref leftNode, ref rightNode);

                    baseTree[leftNodeIndex]      = leftNode;
                    creationState[leftNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
                    GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref leftNode);

                    baseTree[rightNodeIndex]      = rightNode;
                    creationState[rightNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
                    GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref rightNode);
                }
            }
        }
コード例 #13
0
        public void Execute()
        {
            ResetMetadata();
            ResetStates();
            ResetMarker();

            GSubdivNode nodes0 = new GSubdivNode()
            {
                v0 = Vector2.up,
                v1 = Vector2.one,
                v2 = Vector2.zero
            };

            nodes[0]         = nodes0;
            creationState[0] = GGeometryJobUtilities.STATE_CREATED;
            GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref nodes0);

            GSubdivNode nodes1 = new GSubdivNode()
            {
                v0 = Vector2.right,
                v1 = Vector2.zero,
                v2 = Vector2.one
            };

            nodes[1]         = nodes1;
            creationState[1] = GGeometryJobUtilities.STATE_CREATED;
            GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref nodes1);

            int         startIndex     = 0;
            int         endIndex       = 0;
            int         leftNodeIndex  = 0;
            int         rightNodeIndex = 0;
            GSubdivNode currentNode;
            GSubdivNode leftNode  = new GSubdivNode();
            GSubdivNode rightNode = new GSubdivNode();

            for (int res = 0; res < resolution; ++res)
            {
                startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
                endIndex   = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
                for (int i = startIndex; i <= endIndex; ++i)
                {
                    currentNode = nodes[i];
                    currentNode.Split(ref leftNode, ref rightNode);
                    GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);

                    nodes[leftNodeIndex]  = leftNode;
                    nodes[rightNodeIndex] = rightNode;
                }
            }

            baseResolution = Mathf.Max(0, baseResolution - lod);
            for (int res = 0; res <= baseResolution; ++res)
            {
                startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
                endIndex   = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
                for (int i = startIndex; i <= endIndex; ++i)
                {
                    currentNode      = nodes[i];
                    creationState[i] = GGeometryJobUtilities.STATE_CREATED;
                    GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref currentNode);
                }
            }
        }