| | | 1 | | /* |
| | | 2 | | * Code adapted from: |
| | | 3 | | * https://answers.unity.com/questions/52664/how-would-one-calculate-a-3d-mesh-volume-in-unity.html |
| | | 4 | | * by: |
| | | 5 | | * Dimitrios Vlachos |
| | | 6 | | * djv1@student.london.ac.uk |
| | | 7 | | * dimitri.j.vlachos@gmail.com |
| | | 8 | | */ |
| | | 9 | | |
| | | 10 | | using System.Collections; |
| | | 11 | | using System.Collections.Generic; |
| | | 12 | | using UnityEngine; |
| | | 13 | | |
| | | 14 | | public class FoodItem : MonoBehaviour |
| | | 15 | | { |
| | | 16 | | public enum FoodType { Carrot, Cheese, Potato, Other }; |
| | | 17 | | public FoodType type; |
| | | 18 | | |
| | | 19 | | [Header("Nutritional information")] |
| | | 20 | | public float weight; |
| | | 21 | | public float density; |
| | | 22 | | public float calories; |
| | | 23 | | public float protein; |
| | | 24 | | public float carbohydrates; |
| | | 25 | | public float sugar; |
| | | 26 | | public float fibre; |
| | | 27 | | public float fat; |
| | | 28 | | public float modifier; |
| | | 29 | | |
| | | 30 | | [Header("Properties")] |
| | 12 | 31 | | public float lockTimer = 3; |
| | | 32 | | |
| | 12 | 33 | | public bool hasBeenCut = false; |
| | 12 | 34 | | public bool inPot = false; |
| | | 35 | | |
| | | 36 | | |
| | | 37 | | // Start is called before the first frame update |
| | | 38 | | void Start() |
| | 6 | 39 | | { |
| | | 40 | | float volume; |
| | | 41 | | |
| | 6 | 42 | | switch (tag) |
| | | 43 | | { // Nutrition per 100g |
| | | 44 | | case "Carrot": |
| | 1 | 45 | | modifier = 2600f; |
| | 1 | 46 | | volume = MeshVolume(); |
| | 1 | 47 | | type= FoodType.Carrot; |
| | 1 | 48 | | density = 1.04f; // g/cm3 d = g/v g = d*v |
| | 1 | 49 | | calories = 41f; |
| | 1 | 50 | | protein = 0.9f; |
| | 1 | 51 | | carbohydrates = 9.6f; |
| | 1 | 52 | | sugar = 4.7f; |
| | 1 | 53 | | fibre = 2.8f; |
| | 1 | 54 | | fat = 0.2f; |
| | 1 | 55 | | break; |
| | | 56 | | case "Cheese": |
| | 1 | 57 | | modifier = 232f; |
| | 1 | 58 | | volume = MeshVolume(); |
| | 1 | 59 | | type = FoodType.Cheese; |
| | 1 | 60 | | density = 1.075f; // g/cm3 |
| | 1 | 61 | | calories = 404f; |
| | 1 | 62 | | protein = 23f; |
| | 1 | 63 | | carbohydrates = 3.1f; |
| | 1 | 64 | | sugar = 0.5f; |
| | 1 | 65 | | fibre = 0f; |
| | 1 | 66 | | fat = 33f; |
| | 1 | 67 | | break; |
| | | 68 | | case "Potato": |
| | 3 | 69 | | modifier = 1300f; |
| | 3 | 70 | | volume = MeshVolume(); |
| | 3 | 71 | | type = FoodType.Potato; |
| | 3 | 72 | | density = 1.09f; // g/cm3 |
| | 3 | 73 | | calories = 93f; |
| | 3 | 74 | | protein = 2.5f; |
| | 3 | 75 | | carbohydrates = 21f; |
| | 3 | 76 | | sugar = 1.2f; |
| | 3 | 77 | | fibre = 2.2f; |
| | 3 | 78 | | fat = 0.1f; |
| | 3 | 79 | | break; |
| | | 80 | | default: |
| | | 81 | | //Debug.Log("In the default"); |
| | 1 | 82 | | modifier = 0f; |
| | 1 | 83 | | volume = 0f; |
| | 1 | 84 | | density = 0f; |
| | 1 | 85 | | calories = 0f; |
| | 1 | 86 | | protein = 0f; |
| | 1 | 87 | | carbohydrates = 0f; |
| | 1 | 88 | | sugar = 0f; |
| | 1 | 89 | | fibre = 0f; |
| | 1 | 90 | | fat = 0f; |
| | 1 | 91 | | break; |
| | | 92 | | } |
| | | 93 | | |
| | | 94 | | // Guard statement to prevent unecessary calculations |
| | 6 | 95 | | if (tag.Equals("Other")) return; |
| | | 96 | | |
| | 6 | 97 | | weight = density * volume; |
| | 6 | 98 | | float proportion = weight / 100f; // Per 100g |
| | 6 | 99 | | calories *= proportion; |
| | 6 | 100 | | protein *= proportion; |
| | 6 | 101 | | carbohydrates *= proportion; |
| | 6 | 102 | | sugar *= proportion; |
| | 6 | 103 | | fibre *= proportion; |
| | 6 | 104 | | fat *= proportion; |
| | 6 | 105 | | } |
| | | 106 | | |
| | | 107 | | private float MeshVolume() |
| | 5 | 108 | | { |
| | 5 | 109 | | MeshFilter meshFilter = GetComponentInChildren<MeshFilter>(); |
| | 5 | 110 | | Mesh mesh = meshFilter.sharedMesh; |
| | 5 | 111 | | float volume = VolumeOfMesh(mesh);// * modifier; // Convert to cm3 |
| | 5 | 112 | | volume *= modifier; |
| | 5 | 113 | | string msg = "The volume of the mesh is " + volume + " cm3."; |
| | | 114 | | //Debug.Log(msg); |
| | 5 | 115 | | return volume; |
| | 5 | 116 | | } |
| | | 117 | | |
| | | 118 | | private float SignedVolumeOfTriangle(Vector3 p1, Vector3 p2, Vector3 p3) |
| | 8008 | 119 | | { |
| | 8008 | 120 | | float v321 = p3.x * p2.y * p1.z; |
| | 8008 | 121 | | float v231 = p2.x * p3.y * p1.z; |
| | 8008 | 122 | | float v312 = p3.x * p1.y * p2.z; |
| | 8008 | 123 | | float v132 = p1.x * p3.y * p2.z; |
| | 8008 | 124 | | float v213 = p2.x * p1.y * p3.z; |
| | 8008 | 125 | | float v123 = p1.x * p2.y * p3.z; |
| | | 126 | | |
| | 8008 | 127 | | return (1.0f / 6.0f) * (-v321 + v231 + v312 - v132 - v213 + v123); |
| | 8008 | 128 | | } |
| | | 129 | | |
| | | 130 | | private float VolumeOfMesh(Mesh mesh) |
| | 5 | 131 | | { |
| | 5 | 132 | | float volume = 0; |
| | | 133 | | |
| | 5 | 134 | | Vector3[] vertices = mesh.vertices; |
| | 5 | 135 | | int[] triangles = mesh.triangles; |
| | | 136 | | |
| | 16026 | 137 | | for (int i = 0; i < triangles.Length; i += 3) |
| | 8008 | 138 | | { |
| | 8008 | 139 | | Vector3 p1 = vertices[triangles[i + 0]]; |
| | 8008 | 140 | | Vector3 p2 = vertices[triangles[i + 1]]; |
| | 8008 | 141 | | Vector3 p3 = vertices[triangles[i + 2]]; |
| | 8008 | 142 | | volume += SignedVolumeOfTriangle(p1, p2, p3); |
| | 8008 | 143 | | } |
| | 5 | 144 | | return Mathf.Abs(volume); |
| | 5 | 145 | | } |
| | | 146 | | |
| | | 147 | | private Coroutine c; |
| | | 148 | | |
| | | 149 | | public void StartCountdowm(GameObject p) |
| | 4 | 150 | | { |
| | 4 | 151 | | Debug.Log("Countdown begun"); |
| | 4 | 152 | | c = StartCoroutine(LockInPotCountdown(p)); |
| | 4 | 153 | | } |
| | | 154 | | |
| | | 155 | | public void EndCountDown() |
| | 5 | 156 | | { |
| | 5 | 157 | | StopCoroutine(c); |
| | 5 | 158 | | } |
| | | 159 | | |
| | | 160 | | private IEnumerator LockInPotCountdown(GameObject p) |
| | 4 | 161 | | { |
| | 4 | 162 | | yield return new WaitForSeconds(lockTimer); |
| | 2 | 163 | | transform.parent = p.transform; |
| | 2 | 164 | | } |
| | | 165 | | } |