예제 #1
0
    public float RadiusScaleAtPoint(Vector3 xyz)
    {
        if (surface == null)
        {
            var fill = new SGT_Internal.SGT_FillGameObject();

            SendMessage("FillSurfaceGameObject", fill, SendMessageOptions.DontRequireReceiver);

            surface = fill.GameObject;
        }

        if (surface != null && displacementTexture != null)
        {
            switch (DisplacementConfiguration)
            {
            case SGT_SurfaceConfiguration.Sphere:
            {
                var texture = displacementTexture.GetTexture2D(0);

                if (texture != null)
                {
                    xyz = surface.transform.InverseTransformPoint(xyz);

                    var pixelUV      = SGT_Helper.PixelUV(texture);
                    var uv           = SGT_Helper.CartesianToPolarUV(xyz); uv.y = SGT_Helper.ClampUV(uv.y, pixelUV.y);
                    var displacement = texture.GetPixelBilinear(uv.x, uv.y).r;
                    var scale        = Mathf.Lerp(scaleMin, scaleMax, displacement);

                    return(scale);
                }
            }
            break;

            case SGT_SurfaceConfiguration.Cube:
            {
                xyz = surface.transform.InverseTransformPoint(xyz);

                var face    = SGT_Helper.CubeFace(xyz);
                var texture = displacementTexture.GetTexture2D(face);

                if (texture != null)
                {
                    var uv           = SGT_Helper.CubeUV(face, xyz, true);
                    var displacement = texture.GetPixelBilinear(uv.x, uv.y).r;
                    var scale        = Mathf.Lerp(scaleMin, scaleMax, displacement);

                    return(scale);
                }
            }
            break;
            }
        }

        return(1.0f);
    }
예제 #2
0
    public void Regenerate()
    {
        if (modified == false)
        {
            CheckForModifications();
        }

        if (modified == true)
        {
            if (displacementTexture != null && sourceSurfaceMesh != null)
            {
                if (generatedSurfaceMesh == null)
                {
                    generatedSurfaceMesh = new SGT_SurfaceMultiMesh();
                }

                // Destroy old meshes
                generatedSurfaceMesh.DestroyAllMeshes();

                sourceSurfaceMesh.CopyMeshesInto(generatedSurfaceMesh);

                var surfaceCount = generatedSurfaceMesh.Count;

                for (var i = 0; i < surfaceCount; i++)
                {
                    var multiMesh = generatedSurfaceMesh.GetMultiMesh(i);

                    if (multiMesh != null)
                    {
                        for (var j = 0; j < multiMesh.Count; j++)
                        {
                            var mesh = multiMesh.GetSharedMesh(j);

                            if (mesh != null)
                            {
                                mesh           = SGT_Helper.CloneObject(mesh);
                                mesh.hideFlags = HideFlags.DontSave;

                                var positions      = mesh.vertices;
                                var uv0s           = mesh.uv;
                                var newPositions   = new Vector3[positions.Length];
                                var displacementUV = Vector2.zero;

                                for (var k = 0; k < positions.Length; k++)
                                {
                                    var texture  = (Texture2D)null;
                                    var position = positions[k];

                                    switch (displacementTexture.Configuration)
                                    {
                                    case SGT_SurfaceConfiguration.Sphere:
                                    {
                                        texture = displacementTexture.GetTexture2D(0);

                                        if (texture != null)
                                        {
                                            displacementUV = useUV == true ? uv0s[k] : SGT_Helper.CartesianToPolarUV(position);

                                            if (clamp == true)
                                            {
                                                displacementUV = SGT_Helper.ClampCollapseV(displacementUV, SGT_Helper.PixelUV(texture));
                                            }
                                        }
                                    }
                                    break;

                                    case SGT_SurfaceConfiguration.Cube:
                                    {
                                        texture = displacementTexture.GetTexture2D(position);

                                        if (texture != null)
                                        {
                                            displacementUV = useUV == true ? uv0s[k] : SGT_Helper.CubeUV(position, true);

                                            if (clamp == true)
                                            {
                                                displacementUV = SGT_Helper.ClampUV(displacementUV, SGT_Helper.PixelUV(texture));
                                            }
                                        }
                                    }
                                    break;
                                    }

                                    var displacement = texture != null?texture.GetPixelBilinear(displacementUV.x, displacementUV.y).r : 0.0f;

                                    newPositions[k] = position * Mathf.Lerp(scaleMin, scaleMax, displacement);
                                }

                                mesh.name    += "(Displaced)";
                                mesh.vertices = newPositions;
                                mesh.bounds   = new Bounds(mesh.bounds.center, mesh.bounds.size * scaleMax);
                                mesh.RecalculateNormals();

                                multiMesh.SetSharedMesh(mesh, j);
                            }
                        }
                    }
                }

                MarkAsUnmodified();

                SendMessage("SetSurfaceMultiMesh", generatedSurfaceMesh, SendMessageOptions.DontRequireReceiver);
            }
        }
    }
    private Patch GeneratePatch(Patch parent, CubemapFace face, int level, int quadrant, Vector2 cornerLocal, Vector3 corner, Vector3 axis1, Vector3 axis2)
    {
        var patchResolution2 = patchResolution + 1;
        var positions        = new Vector3[patchResolution2 * patchResolution2];
        var uv0s             = new Vector2[patchResolution2 * patchResolution2];
        var uv1s             = new Vector2[patchResolution2 * patchResolution2];
        var normals          = new Vector3[patchResolution2 * patchResolution2];
        var tangents         = new Vector4[patchResolution2 * patchResolution2];

        var axis1Step = axis1 / patchResolution;
        var axis2Step = axis2 / patchResolution;
        var uvSCorner = (cornerLocal * 0.5f + new Vector2(0.5f, 0.5f));
        var uv1Corner = uvSCorner;
        var uvSStep   = ((levelSize[level] * 0.5f) / patchResolution);
        var uv1Step   = uvSStep;

        for (var z = 0; z < patchResolution2; z++)
        {
            for (var x = 0; x < patchResolution2; x++)
            {
                var vertexIndex = z * patchResolution2 + x;

                // Calculate stuff
                var position0 = (corner + axis1Step * x + axis2Step * z).normalized;
                var position1 = (corner + axis1Step * (x + 1) + axis2Step * z).normalized;
                var position2 = (corner + axis1Step * x + axis2Step * (z + 1)).normalized;
                var position  = position0;

                var displacement0   = 0.0f;
                var displacement1   = 0.0f;
                var displacement2   = 0.0f;
                var displacementUV0 = Vector2.zero;

                switch (DisplacementConfiguration)
                {
                case SGT_SurfaceConfiguration.Sphere:
                {
                    var texture = displacementTexture.GetTexture2D(0);

                    displacementUV0 = SGT_Helper.CartesianToPolarUV(position0);

                    if (texture != null)
                    {
                        var pixelUV         = SGT_Helper.PixelUV(texture);
                        var displacementUV1 = SGT_Helper.CartesianToPolarUV(position1);
                        var displacementUV2 = SGT_Helper.CartesianToPolarUV(position2);

                        displacementUV0.y = SGT_Helper.ClampUV(displacementUV0.y, pixelUV.y);
                        displacementUV1.y = SGT_Helper.ClampUV(displacementUV1.y, pixelUV.y);
                        displacementUV2.y = SGT_Helper.ClampUV(displacementUV2.y, pixelUV.y);

                        displacement0 = texture.GetPixelBilinear(displacementUV0.x, displacementUV0.y).r;
                        displacement1 = texture.GetPixelBilinear(displacementUV1.x, displacementUV1.y).r;
                        displacement2 = texture.GetPixelBilinear(displacementUV2.x, displacementUV2.y).r;
                    }
                }
                break;

                case SGT_SurfaceConfiguration.Cube:
                {
                    var face0    = SGT_Helper.CubeFace(position0);
                    var face1    = SGT_Helper.CubeFace(position1);
                    var face2    = SGT_Helper.CubeFace(position2);
                    var texture0 = displacementTexture.GetTexture2D(face0);
                    var texture1 = displacementTexture.GetTexture2D(face1);
                    var texture2 = displacementTexture.GetTexture2D(face2);

                    displacementUV0 = SGT_Helper.CubeUV(face0, position0, true);

                    if (texture0 != null)
                    {
                        displacement0 = texture0.GetPixelBilinear(displacementUV0.x, displacementUV0.y).r;
                    }

                    if (texture1 != null)
                    {
                        var displacementUV1 = SGT_Helper.CubeUV(face1, position1, true);

                        displacement1 = texture1.GetPixelBilinear(displacementUV1.x, displacementUV1.y).r;
                    }

                    if (texture2 != null)
                    {
                        var displacementUV2 = SGT_Helper.CubeUV(face2, position2, true);

                        displacement2 = texture2.GetPixelBilinear(displacementUV2.x, displacementUV2.y).r;
                    }
                }
                break;
                }

                position0 *= Mathf.Lerp(scaleMin, scaleMax, displacement0);
                position1 *= Mathf.Lerp(scaleMin, scaleMax, displacement1);
                position2 *= Mathf.Lerp(scaleMin, scaleMax, displacement2);

                var vec1 = (position1 - position0).normalized;
                var vec2 = (position2 - position0).normalized;

                // Write vertex data
                positions[vertexIndex] = position0;
                normals[vertexIndex]   = Vector3.Cross(vec2, vec1);
                tangents[vertexIndex]  = SGT_Helper.NewVector4(-vec2, 1.0f);

                if (DisplacementConfiguration == surfaceConfiguration)
                {
                    switch (surfaceConfiguration)
                    {
                    case SGT_SurfaceConfiguration.Sphere: uv0s[vertexIndex] = displacementUV0;                         break;

                    case SGT_SurfaceConfiguration.Cube:   uv0s[vertexIndex] = SGT_Helper.CubeUV(face, position, true); break;
                    }
                }
                else
                {
                    switch (surfaceConfiguration)
                    {
                    case SGT_SurfaceConfiguration.Sphere: uv0s[vertexIndex] = SGT_Helper.CartesianToPolarUV(position0); break;

                    case SGT_SurfaceConfiguration.Cube:   uv0s[vertexIndex] = SGT_Helper.CubeUV(face, position0, true); break;
                    }
                }

                uv1s[vertexIndex] = uv1Corner + new Vector2(uv1Step * x, uv1Step * z);
            }
        }

        // Remove wrapping seam
        if (surfaceConfiguration == SGT_SurfaceConfiguration.Sphere)
        {
            var indices = patchIndices[0];

            for (var i = 0; i < indices.Length; i += 3)
            {
                var index1 = indices[i + 0];
                var index2 = indices[i + 1];
                var index3 = indices[i + 2];
                var mid    = (positions[index1] + positions[index2] + positions[index3]) / 3.0f;

                if (mid.x < 0.0f && mid.z < 0.0f)
                {
                    for (var j = 0; j < 3; j++)
                    {
                        var index = indices[i + j];
                        var pos   = positions[index];

                        if (pos.z < 0.0f && Mathf.Approximately(pos.x, 0.0f) == true)
                        {
                            uv0s[index].x = 1.0f;
                        }
                    }
                }
            }
        }

        var bounds = new Bounds(positions[0], Vector3.zero);

        for (var i = 1; i < patchResolution2 * patchResolution2; i++)
        {
            bounds.Encapsulate(positions[i]);
        }

        var patch = new Patch();

        patch.parent      = parent;
        patch.face        = face;
        patch.level       = level;
        patch.quadrant    = quadrant;
        patch.cornerLocal = cornerLocal;
        patch.corner      = corner;
        patch.axis1       = axis1;
        patch.axis2       = axis2;
        patch.positions   = positions;
        patch.uv0s        = uv0s;
        patch.uv1s        = uv1s;
        patch.normals     = normals;
        patch.tangents    = tangents;
        patch.bounds      = bounds;

        return(patch);
    }