protected override void addExternal(FluidCellIndex index, float densityChange, float densityChangeRadius, Vector3 force, float forceRadius) { if (densityChange < externalAdditionMin && force.sqrMagnitude < externalAdditionMin) { return; } int densityCellRadius = (int)Mathf.Max(densityChangeRadius / cellParameters.cellSize, 0); int forceCellRadius = (int)Mathf.Max(forceRadius / cellParameters.cellSize, 0); int applyCellRadius = Mathf.Max(densityCellRadius, forceCellRadius); float densityFalloff = densityChange / (densityCellRadius + 1); Vector3 forceFalloff = force / (forceCellRadius + 1); // TODO We can calculate which cells should be affected in the compute shader. Though will it save us much? for (int j = (int)Mathf.Max(index.y - applyCellRadius, 1); j < Mathf.Min(index.y + applyCellRadius + 1, fluidParameters.gridSize - 1); j++) { for (int i = (int)Mathf.Max(index.x - applyCellRadius, 1); i < Mathf.Min(index.x + applyCellRadius + 1, fluidParameters.gridSize - 1); i++) { int distance = Mathf.Max(Mathf.Abs(i - index.x), Mathf.Abs(j - index.y)); if (distance <= densityCellRadius) { externalAdditions[j, i].density = densityChange - (densityFalloff * distance); } if (distance <= forceCellRadius) { externalAdditions[j, i].velocity = force - (forceFalloff * distance); } } } }
protected override void addExternal(FluidCellIndex index, float densityChange, float densityChangeRadius, Vector3 force, float forceRadius) { if (densityChange == 0 && force.sqrMagnitude == 0) { return; } int densityCellRadius = (int)Mathf.Max(densityChangeRadius / cellParameters.cellSize, 0); int forceCellRadius = (int)Mathf.Max(forceRadius / cellParameters.cellSize, 0); int applyCellRadius = Mathf.Max(densityCellRadius, forceCellRadius); float densityFalloff = densityChange / (densityCellRadius + 1); Vector3 forceFalloff = force / (forceCellRadius + 1); for (int i = (int)Mathf.Max(index.x - applyCellRadius, 0); i < Mathf.Min(index.x + applyCellRadius, fluidParameters.gridSize - 1); i++) { for (int j = (int)Mathf.Max(index.y - applyCellRadius, 0); j < Mathf.Min(index.y + applyCellRadius, fluidParameters.gridSize - 1); j++) { int distance = Mathf.Max(Mathf.Abs(i - index.x), Mathf.Abs(j - index.y)); if (distance <= densityCellRadius) { externalAdditions[i, j].density = densityChange - (densityFalloff * distance); } if (distance <= forceCellRadius) { externalAdditions[i, j].velocity = force - (forceFalloff * distance); } } } }
void ShowCellData(string cellName, FluidSimulator simulator, FluidCellIndex cellIndex, ref bool showCell, bool showOperationData) { return; int gridSize = simulator.fluidParameters.gridSize; if (cellIndex.x >= 0 && cellIndex.y >= 0 && cellIndex.z >= 0 && cellIndex.x < gridSize && cellIndex.y < gridSize && cellIndex.z < gridSize) { FluidCell cell = simulator.GetCell(cellIndex); showCell = EditorGUILayout.Foldout(showCell, string.Format("{0} {1}", cellName, cellIndex.ToString())); if (showCell) { EditorGUILayout.LabelField("Density", "" + cell.density); EditorGUILayout.LabelField("Velocity", "" + cell.velocity); EditorGUILayout.LabelField("Raw Divergence", "" + cell.rawDivergence); EditorGUILayout.LabelField("Relaxed Divergence", "" + cell.relaxedDivergence); if (showOperationData) { FluidCellOperationData operationData = simulator.GetCellOperationData(cellIndex); EditorGUILayout.LabelField("Advect Index Velocity", "" + operationData.advectIdVelocity.ToString()); EditorGUILayout.LabelField("Advect Past Index", "" + operationData.advectPastId.ToString()); EditorGUILayout.LabelField("Advect SamplePercentages", "" + operationData.advectSamplePercentages); } EditorGUILayout.Space(); } } }
public void AddExternal(FluidCellIndex index, float densityChange, float densityChangeRadius, Vector3 force, float forceRadius) { if (densityChange < externalAdditionMin && force.sqrMagnitude < externalAdditionMin) { return; } Profiler.BeginSample("AddExternal"); addExternal(index, densityChange, densityChangeRadius, force, forceRadius); Profiler.EndSample(); }
FluidCellIndex FindIndex(Vector3 focalPoint) { if (focalPoint == recentFocalPoint) { return(recentFoundIndex); } Vector3 localFocus = transform.InverseTransformPoint(focalPoint); int gridSize = Simulator.fluidParameters.gridSize; recentFoundIndex = new FluidCellIndex((int)((localFocus.x + 0.5f) * gridSize), (int)((localFocus.y + 0.5f) * gridSize), 0); return(recentFoundIndex); }
public override void OnInspectorGUI() { FluidSimulator simulator = (FluidSimulator)target; GUILayout.BeginHorizontal(); if (GUILayout.Button("Reset")) { simulator.resetFluid = true; } if (GUILayout.Button(!simulator.pauseFluid ? "Pause" : "Resume")) { simulator.pauseFluid = !simulator.pauseFluid; } if (GUILayout.Button("Step")) { simulator.stepFluid = true; } GUILayout.EndHorizontal(); EditorGUILayout.LabelField("Family", simulator.FamilyName); // Default Inspector Rendering. base.OnInspectorGUI(); if (Application.isPlaying && simulator.isActiveAndEnabled) { EditorGUILayout.LabelField("Global Density", "" + simulator.GlobalDensity); // TODO Display cell and cell data in a layout //EditorGUILayout.LabelField("Selected Cell", simulator.SelectedCell.ToString()); EditorGUILayout.Space(); GUILayout.Label("Cell Data", EditorStyles.boldLabel); FluidCellIndex selectedIndex = simulator.SelectedCellIndex; FluidCellOperationData operationData = simulator.GetCellOperationData(selectedIndex); ShowCellData("Selected", simulator, selectedIndex, ref showSelected, true); ShowCellData("Left", simulator, operationData.leftId, ref showLeft, false); ShowCellData("Right", simulator, operationData.rightId, ref showRight, false); ShowCellData("Down", simulator, operationData.downId, ref showDown, false); ShowCellData("Up", simulator, operationData.upId, ref showUp, false); } }
protected override FluidCellOperationData getCellOperationData(FluidCellIndex index) { return(operationData[index.y, index.x]); }
protected override FluidCell getExternal(FluidCellIndex index) { return(externalAdditions[index.y, index.x]); }
protected abstract void setExternal(FluidCellIndex index, FluidCell applyCell);
protected abstract void addExternal(FluidCellIndex index, float densityChange, float densityChangeRadius, Vector3 force, float forceRadius);
public FluidCellOperationData GetCellOperationData(FluidCellIndex index) { return(getCellOperationData(index)); }
public FluidCell GetCell(FluidCellIndex index) { return(getCell(index)); }
public FluidCell GetExternal(FluidCellIndex index) { return(getExternal(index)); }
public void SetExternal(FluidCellIndex index, FluidCell applyCell) { setExternal(index, applyCell); }
protected abstract FluidCell getExternal(FluidCellIndex index);
protected override void setExternal(FluidCellIndex index, FluidCell applyCell) { externalAdditions[index.y, index.x].density = applyCell.density; externalAdditions[index.y, index.x].velocity = applyCell.velocity; }
protected abstract FluidCell getCell(FluidCellIndex index);
protected override FluidCell getCell(FluidCellIndex index) { return(inCells[index.y, index.x]); }
protected abstract FluidCellOperationData getCellOperationData(FluidCellIndex index);
public void Initialize(FluidSimulator simulator, FluidCellIndex index) { this.index = index; base.Initialize(simulator); }
void Update() { if (mouseInput != null && mouseInput.SelectedFluid != null) { FluidCellIndex selectedIndex = mouseInput.SelectedFluid.SelectedCellIndex; foreach (var member in members) { if (member.Simulator != mouseInput.SelectedFluid) { member.Simulator.SelectedCellIndex = selectedIndex; } } } for (int i = 0; i < sharedInfo.fluidParameters.gridSize; i++) { for (int j = 0; j < sharedInfo.fluidParameters.gridSize; j++) { sharedExternals[i, j].density = 0; sharedExternals[i, j].velocity = Vector3.zero; } } // Sum up external additions of all member simulators. FluidCellIndex index = new FluidCellIndex(); foreach (var member in members) { for (int i = 0; i < sharedInfo.fluidParameters.gridSize; i++) { for (int j = 0; j < sharedInfo.fluidParameters.gridSize; j++) { index.x = i; index.y = j; index.z = 0; FluidCell memberCell = member.Simulator.GetExternal(index); sharedExternals[i, j].density += memberCell.density; sharedExternals[i, j].velocity += memberCell.velocity; } } } // Apply summed externals to member simulators to ensure identical input. foreach (var member in members) { for (int i = 0; i < sharedInfo.fluidParameters.gridSize; i++) { for (int j = 0; j < sharedInfo.fluidParameters.gridSize; j++) { index.x = i; index.y = j; index.z = 0; member.Simulator.SetExternal(index, sharedExternals[i, j]); } } } foreach (var member in members) { member.Simulator.Simulate(); } }