void Awake() { var waterDisplays = FindObjectsOfType <MonoBehaviour>() .Where(m => m.enabled) .OfType <IWaterDisplay>(); var enumerable = waterDisplays as IWaterDisplay[] ?? waterDisplays.ToArray(); if (enumerable.Any()) { waterDisplay = enumerable[0]; } collider = GetComponent <EdgeCollider2D>(); normals = new List <Vector2>(collider.edgeCount); var points = collider.points; var collTransform = collider.transform; for (var i = 1; i < collider.pointCount; i++) { var edge = collTransform.TransformPoint(points[i]) - collTransform.TransformPoint(points[i - 1]); var normal = new Vector2(-edge.y, edge.x); normals.Add(normal.normalized); } }
void Start() { waterDisplay = GetComponent <WaterDisplay>(); colliders = FindObjectsOfType <EdgeCollider2D>(); var boxColliders = FindObjectsOfType <BoxCollider2D>(); var fans = boxColliders.Where(boxCollider => boxCollider.CompareTag("FanAir")).ToList(); var blobs = waterDisplay.InitialPositions; var waterBlobsNum = waterDisplay.BlobsCount; waterState = new WaterState() { x = new NativeArray <float>(waterBlobsNum, Allocator.Persistent), y = new NativeArray <float>(waterBlobsNum, Allocator.Persistent), oldX = new NativeArray <float>(waterBlobsNum, Allocator.Persistent), oldY = new NativeArray <float>(waterBlobsNum, Allocator.Persistent), vx = new NativeArray <float>(waterBlobsNum, Allocator.Persistent), vy = new NativeArray <float>(waterBlobsNum, Allocator.Persistent), p = new NativeArray <float>(waterBlobsNum, Allocator.Persistent), pNear = new NativeArray <float>(waterBlobsNum, Allocator.Persistent) }; var gridSize = 2 * gridHalfSize; var cellSide = interactionRadius; gridInfo = new GridInfo() { cellSide = cellSide, cellSpace = 10, xCells = (ushort)Mathf.CeilToInt(gridSize.x / cellSide), yCells = (ushort)Mathf.CeilToInt(gridSize.y / cellSide), halfXSize = gridSize.x / 2, halfYSize = gridSize.y / 2 }; grid = new NativeArray <int>( gridInfo.xCells * gridInfo.yCells * gridInfo.cellSpace, Allocator.Persistent); for (var i = 0; i < waterBlobsNum; i++) { waterState.oldX[i] = waterState.x[i] = blobs[i].x; waterState.oldY[i] = waterState.y[i] = blobs[i].y; } // Create colliders arrays var collidersPointsCount = 0; for (var c = 0; c < colliders.Length; c++) { collidersPointsCount += colliders[c].pointCount; } collidersPointsNum = new NativeArray <int>(colliders.Length, Allocator.Persistent); oldColliderPositions = new NativeArray <float2>(colliders.Length, Allocator.Persistent); collidersPoints = new NativeArray <float2>(collidersPointsCount, Allocator.Persistent); var collidersPointsAccumulated = 0; for (var c = 0; c < colliders.Length; c++) { var points = colliders[c].pointCount; collidersPointsNum[c] = points; for (var i = 0; i < points; i++) { var collider = colliders[c]; var point = collider.transform.TransformPoint( new Vector3(collider.points[i].x, collider.points[i].y, 0)); collidersPoints[collidersPointsAccumulated + i] = new float2(point.x, point.y); } collidersPointsAccumulated += points; } // Fans arrays fansCorners = new NativeArray <float4>(fans.Count, Allocator.Persistent); fansDirections = new NativeArray <float2>(fans.Count, Allocator.Persistent); for (var i = 0; i < fans.Count; i++) { var fan = fans[i]; var bounds = fan.bounds; fansCorners[i] = new float4( bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y ); // left because in the prefab the original direction of the air seems to be to the left fansDirections[i] = ((float3)fan.transform.TransformDirection(Vector3.left)).xy; } // Create kernels updateParticles = new UpdateParticles() { gravity = gravity, waterState = waterState }; gridSort = new GridSort() { grid = grid, x = waterState.x, y = waterState.y, gridInfo = gridInfo }; updatePressures = new UpdatePressures() { grid = grid, stiffness = stiffness, stiffnessNear = stiffnessNear, interactionRadius = interactionRadius, restDensity = restDensity, interactionRadiusSq = interactionRadius * interactionRadius, waterState = waterState, gridInfo = gridInfo }; applyRelaxation = new ApplyRelaxation() { grid = grid, interactionRadius = interactionRadius, interactionRadiusSq = interactionRadius * interactionRadius, waterState = waterState, gridInfo = gridInfo }; colliderInteraction = new ColliderInteraction() { waterState = waterState, colliders = collidersPointsNum, colliderPoints = collidersPoints, fansCorners = fansCorners, fansDirections = fansDirections }; }
private void Start() { _waterDisplay = GetComponent <WaterDisplay>(); _colliders = FindObjectsOfType <EdgeCollider2D>(); var blobs = _waterDisplay.InitialPositions; var waterBlobsNum = _waterDisplay.BlobsCount; velocities = new NativeArray <float2>(waterBlobsNum, Allocator.Persistent); positions = new NativeArray <float2>(waterBlobsNum, Allocator.Persistent); newVelocities = new NativeArray <float2>(waterBlobsNum, Allocator.Persistent); newPositions = new NativeArray <float2>(waterBlobsNum, Allocator.Persistent); hasCollided = new NativeArray <uint>(waterBlobsNum, Allocator.Persistent); cellSide = forceRadius; var cameraWidth = Camera.main.orthographicSize * 2; var cameraHeight = cameraWidth / Camera.main.aspect; gridSize = new Vector2(cameraWidth, cameraHeight); xCells = (ushort)Mathf.CeilToInt(gridSize.x / cellSide); yCells = (ushort)Mathf.CeilToInt(gridSize.y / cellSide); cellSpace = 10; grid = new NativeArray <int>(xCells * yCells * cellSpace, Allocator.Persistent); for (var i = 0; i < xCells * yCells; i++) { grid[i * cellSpace] = 0; } for (var i = 0; i < positions.Length; i++) { positions[i] = blobs[i]; velocities[i] = 0; } var collidersPointsCount = 0; for (var c = 0; c < _colliders.Length; c++) { collidersPointsCount += _colliders[c].pointCount; } collidersPointsNum = new NativeArray <int>(_colliders.Length, Allocator.Persistent); _oldColliderPositions = new NativeArray <float2>(_colliders.Length, Allocator.Persistent); collidersPoints = new NativeArray <float2>(collidersPointsCount, Allocator.Persistent); var collidersPointsAccumulated = 0; for (var c = 0; c < _colliders.Length; c++) { var points = _colliders[c].pointCount; collidersPointsNum[c] = points; for (var i = 0; i < points; i++) { var collider = _colliders[c]; var point = collider.transform.TransformPoint(new Vector3(collider.points[i].x, collider.points[i].y, 0)); collidersPoints[collidersPointsAccumulated + i] = new float2(point.x, point.y); } collidersPointsAccumulated += points; } for (var key = 0; key < positions.Length; key++) { // Place key in the grid var gridX = (int)math.floor((positions[key].x + gridSize.x / 2) / cellSide); if (gridX < 0) { gridX = 0; } else if (gridX > xCells - 1) { gridX = xCells - 1; } var gridY = (int)math.floor((positions[key].y + gridSize.y / 2) / cellSide); if (gridY < 0) { gridY = 0; } else if (gridY > yCells - 1) { gridY = yCells - 1; } var cellStart = (gridY * xCells + gridX) * cellSpace; var stored = grid[cellStart]; if (stored < cellSpace - 1) { grid[cellStart + 1 + stored] = key; grid[cellStart] = stored + 1; } } _sortJob = new SortJob { grid = grid, xCells = xCells, yCells = yCells, halfXSize = gridSize.x / 2, halfYSize = gridSize.y / 2, cellSpace = cellSpace, cellSide = cellSide }; _waterJob = new WaterJob { gravity = gravity, forceRadius = forceRadius, waterForce = waterForce, waterDamping = waterDamping, colliders = collidersPointsNum, colliderPoints = collidersPoints, ballSize = ballSize, hasCollided = hasCollided, gridSizeX = gridSize.x, gridSizeY = gridSize.y, grid = grid, xCells = xCells, yCells = yCells, cellSpace = cellSpace, cellSide = cellSide }; }