Ejemplo n.º 1
0
    //Build a Map with the Soap Bubble / Vonoroï like algo
    private async Task BuildGridMapSoapBubble(List <PointColor2> points, GameObject textureHolder, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        var       textureHolderPositionX = textureHolder.transform.position.x;
        const int pointRadius            = 5;

        //New texture
        var texture      = GetNewTexture(TextureResolution);
        var textureArray = texture.GetPixels32();
        var textureWidth = texture.width;

        //Set pixels
        await Task.Run(() => {
            for (int p = 0; p < textureArray.Length; p++)
            {
                //Convert into coordinates
                var currentPoint = new Vector2(p % textureWidth, (int)(p / textureWidth));

                //if this pixel is INTO a microstructure sphere, set it to white and continue;
                var currentPositionInSpace = PixelToWorldCoordinates(textureHolderPositionX, currentPoint);
                if (SolidBoundariesBuilder.Contains(currentPositionInSpace))
                {
                    textureArray[p] = Color.white;
                    continue;
                }

                //Find the closest point
                PointColor2 closestPoint = null;
                float distanceMin        = float.MaxValue;
                foreach (var point in points)
                {
                    float distance;
                    if ((distance = Vector2.Distance(currentPoint, point.Position)) < distanceMin)
                    {
                        distanceMin  = distance;
                        closestPoint = point;
                    }
                }

                //Apply color to pixel
                textureArray[p] = distanceMin <= pointRadius ? closestPoint.Color : Color.black;
            }
        }, cancellationToken).ConfigureAwait(true);

        //Apply
        texture.SetPixels32(textureArray);
        texture.Apply();
        textureHolder.GetComponent <Renderer>().material.SetTexture("_UnlitColorMap", texture);
    }
Ejemplo n.º 2
0
    //Interpole la vitesse au point p de l'espace donné
    //point : point où l’interpolation est souhaitée
    public static Vector3 GetInterpolatedVelocityAtPosition(Vector3 position)
    {
        if (_velocityField == null)
        {
            Debug.LogError($"{nameof(_velocityField)} must be initiated");
            return(Vector3.zero);
        }

        //1. Trouver les points 8 voisins de p (stockés dans 2 points représentant les extrêmes)
        //Ramener le point p dans l'espace unitaire de speedField
        Vector3 pUnit = position / VelocityFieldSpaceFactor;

        //Point le plus haut
        PointInt3 upperPoint = new PointInt3(Mathf.FloorToInt(pUnit.x), Mathf.FloorToInt(pUnit.y), Mathf.FloorToInt(pUnit.z));

        //Point le plus bas
        PointInt3 lowerPoint = new PointInt3(Mathf.CeilToInt(pUnit.x), Mathf.CeilToInt(pUnit.y), Mathf.CeilToInt(pUnit.z));

        //Vérifier que les points existent
        if (upperPoint.x <= 0 ||
            upperPoint.y <= 0 ||
            upperPoint.z <= 0 ||
            lowerPoint.x <= 0 ||
            lowerPoint.y <= 0 ||
            lowerPoint.z <= 0 ||
            upperPoint.x > _velocityField.GetUpperBound(0) ||
            upperPoint.y > _velocityField.GetUpperBound(1) ||
            upperPoint.z > _velocityField.GetUpperBound(2) ||
            lowerPoint.x > _velocityField.GetUpperBound(0) ||
            lowerPoint.y > _velocityField.GetUpperBound(1) ||
            lowerPoint.z > _velocityField.GetUpperBound(2))
        {
            return(Vector3.zero);
        }

        //Si un des 8 points voisins a une vitesse trop faible ET s'il est contenu dans un solid boundary.
        //Ce skip empêche de potentiels calculs de trajectoire infini (sur certaines résolution, la trajectoire fait des aller-retour entre 2 points et se retrouve coincée).
        //SolidBoundariesBuilder.Contains() étant un peu lourd, la 1ere partie du if permet de ne pas le lancer tout le temps
        if ((IsVelocityTooLow(GetVelocityAtIndex(upperPoint.x, upperPoint.y, upperPoint.z)) ||
             IsVelocityTooLow(GetVelocityAtIndex(lowerPoint.x, upperPoint.y, upperPoint.z)) ||
             IsVelocityTooLow(GetVelocityAtIndex(upperPoint.x, lowerPoint.y, upperPoint.z)) ||
             IsVelocityTooLow(GetVelocityAtIndex(lowerPoint.x, lowerPoint.y, upperPoint.z)) ||
             IsVelocityTooLow(GetVelocityAtIndex(upperPoint.x, upperPoint.y, lowerPoint.z)) ||
             IsVelocityTooLow(GetVelocityAtIndex(lowerPoint.x, upperPoint.y, lowerPoint.z)) ||
             IsVelocityTooLow(GetVelocityAtIndex(upperPoint.x, lowerPoint.y, lowerPoint.z)) ||
             IsVelocityTooLow(GetVelocityAtIndex(lowerPoint.x, lowerPoint.y, lowerPoint.z))) &&
            SolidBoundariesBuilder.Contains(position))
        {
            return(Vector3.zero);
        }

        //Si les deux points sont les mêmes
        if (upperPoint == lowerPoint)
        {
            return(GetVelocityAtIndex(upperPoint.x, upperPoint.y, upperPoint.z));
        }

        //2. Calculer les ratio de positions
        var ratio = pUnit - upperPoint;

        //3. Calculer la vitesse au point voulu
        var interpolatedVelocity = new float[3];

        for (int i = 0; i < 3; i++)
        {
            var speedComponent =
                _velocityField[upperPoint.x, upperPoint.y, upperPoint.z, i] * (1 - ratio.x) * (1 - ratio.y) * (1 - ratio.z) +
                _velocityField[lowerPoint.x, upperPoint.y, upperPoint.z, i] * ratio.x * (1 - ratio.y) * (1 - ratio.z) +
                _velocityField[upperPoint.x, lowerPoint.y, upperPoint.z, i] * (1 - ratio.x) * ratio.y * (1 - ratio.z) +
                _velocityField[lowerPoint.x, lowerPoint.y, upperPoint.z, i] * ratio.x * ratio.y * (1 - ratio.z) +
                _velocityField[upperPoint.x, upperPoint.y, lowerPoint.z, i] * (1 - ratio.x) * (1 - ratio.y) * ratio.z +
                _velocityField[lowerPoint.x, upperPoint.y, lowerPoint.z, i] * ratio.x * (1 - ratio.y) * ratio.z +
                _velocityField[upperPoint.x, lowerPoint.y, lowerPoint.z, i] * (1 - ratio.x) * ratio.y * ratio.z +
                _velocityField[lowerPoint.x, lowerPoint.y, lowerPoint.z, i] * ratio.x * ratio.y * ratio.z;

            interpolatedVelocity[i] = speedComponent;
        }

        return(new Vector3(interpolatedVelocity[0], interpolatedVelocity[1], interpolatedVelocity[2]));
    }