// Use this for initialization void Start() { print("Melting demo."); float w_step = width / (num_w - 1); float h_step = height / (num_h - 1); float d_step = depth / (num_d - 1); spheres = new GameObject[num_w, num_h, num_d]; // Initialize spheres. for (int i = 0; i < num_w; i++) { for (int j = 0; j < num_h; j++) { for (int k = 0; k < num_d; k++) { s = GameObject.CreatePrimitive(PrimitiveType.Sphere); Vector3 new_position = GetComponent <Transform>().position + new Vector3(i * w_step, j * h_step, k * d_step); s.transform.position = new_position; s.transform.localScale += new Vector3(2f, 2f, 2f); MeshRenderer mr = s.GetComponent <MeshRenderer>(); Material[] mats = mr.materials; mats[0] = (Material)Resources.Load("pattern 27/Metal pattern 27", typeof(Material)) as Material; mats[0].shader = Shader.Find("Particles/Standard Surface"); mats[0].EnableKeyword("_EMISSION"); mr.materials = mats; Rigidbody r = s.AddComponent(typeof(Rigidbody)) as Rigidbody; r.mass = 20; SphereTemp t = s.AddComponent(typeof(SphereTemp)) as SphereTemp; t.temp = 0; t.rate_change = 0; r.useGravity = true; spheres[i, j, k] = s; } } } // Initialize springs. springs = new List <SpringJoint>(); springFactors = new List <float>(); for (int i = 0; i < num_w; i++) { for (int j = 0; j < num_h; j++) { for (int k = 0; k < num_d; k++) { s = spheres[i, j, k]; for (int u = -1; u <= 1; u++) { for (int v = -1; v <= 1; v++) { for (int w = -1; w <= 1; w++) { float divide = Math.Abs(u) + Math.Abs(v) + Math.Abs(w); if (divide == 0) { continue; } if (inRange(i + u, j + v, k + w)) { SpringJoint sj = s.AddComponent(typeof(SpringJoint)) as SpringJoint; // SpringFactor sf = sj.AddComponent(typeof(SpringFactor)) as SpringFactor; sj.connectedBody = spheres[i + u, j + v, k + w].GetComponent <Rigidbody>(); sj.spring = SPRING_CONSTANT / divide; // sf.spring_original = SPRING_CONSTANT / divide; springs.Add(sj); springFactors.Add(divide); } } } } } } } // Set initial fixed point and update color. for (int i = 3; i < num_w - 3; i++) { for (int k = 1; k < num_d - 1; k++) { spheres[i, num_h - 1, k].GetComponent <SphereTemp>().temp = 100f; } } updateColors(); }
// Update temperature of each point mass. void updateTemps() { // Calculate temperature updates and store them in the rate_change attribute of SphereTemp component. for (int i = 0; i < num_w; i++) { for (int j = 0; j < num_h; j++) { for (int k = 0; k < num_d; k++) { GameObject m1 = spheres[i, j, k]; SphereTemp t1 = m1.GetComponent <SphereTemp>(); float weightedTemps = 0; float distanceSum = 0; for (int u = -1; u <= 1; u++) { for (int v = -1; v <= 1; v++) { for (int w = -1; w <= 1; w++) { if (u == 0 && v == 0 && w == 0) { continue; } /* HEAT EQUATION * The rate of temperature change is proportional to how much hotter or cooler the surrounding material is. * 1. Calculate weighted average of temperatures. * 2. Set direct proportion to rate of temperature change. * 3. Lerp it. */ if (inRange(i + u, j + v, k + w)) { GameObject m2 = spheres[i + u, j + v, k + w]; SphereTemp t2 = m2.GetComponent <SphereTemp>(); float weight = 1f / (m1.transform.position - m2.transform.position).sqrMagnitude; distanceSum += weight; weightedTemps += weight * t2.temp; } } } } float weightedAvgTemp = weightedTemps / distanceSum; float deltaTemp = weightedAvgTemp - t1.temp; t1.rate_change = deltaTemp * 10; t1.weighted_avg_temp = weightedAvgTemp; } } } // Apply temperature updates to the current temp of each sphere. for (int i = 0; i < num_w; i++) { for (int j = 0; j < num_h; j++) { for (int k = 0; k < num_d; k++) { SphereTemp t = spheres[i, j, k].GetComponent <SphereTemp>(); t.temp += t.rate_change * timeStep; } } } // Update fixed point(s). for (int i = 3; i < num_w - 3; i++) { for (int k = 1; k < num_d - 1; k++) { spheres[i, num_h - 1, k].GetComponent <SphereTemp>().temp = 100f; } } }