//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); }
//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])); }