void Explode(reactionInfo ri) { //exp GameObject.Find("tubeBreakAHA").GetComponent <UCE.TubeExplode>().Explode(); GameObject exp = Instantiate((GameObject)Resources.Load("Explode"), gameObject.transform.position, gameObject.transform.rotation); exp.GetComponent <AudioSource>().Play(); //react all float minAmount = 100; foreach (substanceInfoOfReaction sir in ri.reactants) { minAmount = Mathf.Min(minAmount, substance[sir.name].amount[(int)sir.type] / (float)sir.rate); } foreach (substanceInfoOfReaction sir in ri.reactants) { substance[sir.name].amount[(int)sir.type] -= minAmount * sir.rate; } foreach (substanceInfoOfReaction sir in ri.products) { substance[sir.name].amount[(int)sir.type] += minAmount * sir.rate; } ri.phenomenon = null; Destroy(this); return; }
void CalculateReactionRate(reactionInfo rct, Dictionary <string, float> reactionAmounts) { float speed = rct.speedConstant * rct.tempConstant * Mathf.Exp(-1.0f / (environmentTemperature - rct.startTemperature)); if (rct.pressureConstant < 0) { speed *= ((float)environmentPressure / 101); } else if (rct.pressureConstant > 0) { speed /= ((float)environmentPressure / 101); } //Debug.Log(rct.pressureConstant + " " + speed); //Debug.Log(speed); foreach (substanceInfoOfReaction sir in rct.reactants) { //Debug.Log(sir.name); if (sir.name.Equals("H2O")) { continue; } else if (sir.type == substanceType.Gas && openAir) { continue; } else if (sir.name.Equals("HCl")) { continue; } speed *= Mathf.Pow(substance[sir.name].amount[(int)sir.type], sir.rate); } foreach (substanceInfoOfReaction sir in rct.reactants) { reactionAmounts[sir.name] = -speed * 0.02f * sir.rate; } foreach (substanceInfoOfReaction sir in rct.products) { reactionAmounts[sir.name] = speed * 0.02f * sir.rate; } }
// Update is called once per frame void FixedUpdate() { //Debug.Log(-1); GetSubstance(); GetReaction(); //Debug.Log(0); //return; if (!isReacting && Mathf.Abs(gameObject.GetComponent <UCE.UCE_Heatable>().temperature - environmentTemperature) < Mathf.Epsilon) { return; } isReacting = false; environmentTemperature = this.gameObject.GetComponent <UCE.UCE_Heatable>().temperature; //ArrayList endReaction = new ArrayList(); //Debug.Log(1); foreach (string rTag in reactions.Keys) { reactionInfo rctInfo = reactions[rTag]; //Debug.Log(rTag + "1"); if (environmentTemperature < rctInfo.startTemperature) { break; } //Debug.Log(rTag + "2"); //deterine if a single reaction can still react bool isSingleReactionReacting = true; Dictionary <string, float> reactionAmounts = new Dictionary <string, float>(); CalculateReactionRate(rctInfo, reactionAmounts); // Debug.Log(2); foreach (substanceInfoOfReaction sir in rctInfo.reactants) { //Debug.Log(sir.name + " " + substance[sir.name].amount[(int)sir.type] + " " + reactionAmounts[sir.name]); if (substance[sir.name].amount[(int)sir.type] + reactionAmounts[sir.name] <= 0 || (rctInfo.stopConcentration > 0 && substance[sir.name].concentration < rctInfo.stopConcentration) && sir.name.Equals(rctInfo.stopByReactant)) { //the reaction is not deleted after the reactant deplete due to the reversible reaction //endReaction.Add(rTag); isSingleReactionReacting = false; break; } } //Debug.Log(3); if (!isSingleReactionReacting) { continue; } //Debug.Log(3.5); //react string reactInfo = rTag + " : "; foreach (substanceInfoOfReaction sir in rctInfo.reactants) { float reactionAmount = reactionAmounts[sir.name]; if (openAir && sir.name.Equals("O2")) { continue; } substance[sir.name].amount[(int)sir.type] += reactionAmount; reactInfo += sir.rate + sir.name + "(" + substance[sir.name].amount[(int)sir.type] + " mol"; if (sir.type == substanceType.Liquid) { substance[sir.name].concentration += reactionAmount / volumn; reactInfo += ", " + substance[sir.name].concentration + " mol/L"; } reactInfo += ") + "; } //Debug.Log(4); reactInfo = reactInfo.Substring(0, reactInfo.Length - 2); reactInfo += "=== "; foreach (substanceInfoOfReaction sir in rctInfo.products) { float reactionAmount = reactionAmounts[sir.name]; if (openAir && sir.name.Equals("O2")) { continue; } substance[sir.name].amount[(int)sir.type] += reactionAmount; reactInfo += sir.rate + sir.name; if (!sir.name.Equals("H2O")) { reactInfo += "(" + substance[sir.name].amount[(int)sir.type] + " mol"; if (sir.type == substanceType.Liquid) { substance[sir.name].concentration += reactionAmount / volumn; reactInfo += ", " + substance[sir.name].concentration + " mol/L"; } reactInfo += ") + "; } else { reactInfo += " + "; } } //Debug.Log(5); if (rctInfo.phenomenon != null && rctInfo.phenomenon.Equals("Explode")) { Explode(rctInfo); } reactInfo = reactInfo.Substring(0, reactInfo.Length - 2); //if there are still reacting, set true isReacting = true; Debug.Log(reactInfo); //DrawSystem.GetComponent<ReactionPhenomena>().DrawPhenomena(substance, rctInfo, reactionAmounts); } //foreach (string tmpR in endReaction) // reactionsNames.Remove(tmpR); }
public void DrawPhenomena(Dictionary <string, substanceInfo> substances, reactionInfo rctInfo, Dictionary <string, float> reactionAmounts) { ArrayList liquids = new ArrayList(); foreach (substanceInfoOfReaction sir in rctInfo.reactants) { if (sir.type == substanceType.Liquid) { liquids.Add(sir); } else { DrawSubstance(substances[sir.name], reactionAmounts[sir.name], sir.type); } } foreach (substanceInfoOfReaction sir in rctInfo.products) { if (sir.type == substanceType.Liquid) { liquids.Add(sir); } else { DrawSubstance(substances[sir.name], reactionAmounts[sir.name], sir.type); } } //DrawLiquids ArrayList fluids = new ArrayList(); ArrayList colors = new ArrayList(); ArrayList amounts = new ArrayList(); foreach (substanceInfoOfReaction sir in liquids) { substanceInfo substance = substances[sir.name]; ArrayList liqs = substance.objects[(int)substanceType.Liquid]; foreach (GameObject liquid in liqs) { if (liquid.GetComponent <LiquidSimulator>().fluid == null) { ; } if (!fluids.Contains(liquid.GetComponent <LiquidSimulator>().fluid)) { Debug.Log(sir.name + " " + fluids.Count); fluids.Add(liquid.GetComponent <LiquidSimulator>().fluid); amounts.Add((float)0); colors.Add(Color.white); } int i = fluids.IndexOf(liquid.GetComponent <LiquidSimulator>().fluid); float a = (float)amounts[i]; float sa = (float)substance.amount[(int)substanceType.Liquid]; Color c = (Color)colors[i]; Debug.Log(" a" + a + " " + c.r + " " + c.g + " " + c.b + " "); Debug.Log(" sa" + sa + " " + (float)substance.color[0] + " " + substance.color[1] + " " + substance.color[2] + " "); amounts[i] = a + sa; colors[i] = new Color((float)(a * c.r + sa * substance.color[0]) / (a + sa), (float)(a * c.g + sa * substance.color[1]) / (a + sa), (float)(a * c.b + sa * substance.color[2]) / (a + sa), 1.0f); } } foreach (GameObject fluid in fluids) { Color c = (Color)colors[fluids.IndexOf(fluid)]; Debug.Log(c.r + " " + c.g + " " + c.b + " "); fluid.GetComponent <Obi.ObiParticleRenderer>().particleColor = (Color)colors[fluids.IndexOf(fluid)]; } }