T-VIR-901_EpiLeARn/Assets/ActiveScoppedElements.cs
2024-02-02 15:29:49 +01:00

425 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
public class ActiveScoppedElements : MonoBehaviour
{
[Serializable]
public struct ObjectToInstantiate {
public List<String> elements;
public GameObject obj;
}
public enum AnimationState
{
IDLE,
GORIGHT,
GOLEFT
}
public TextAsset jsonFile;
public TextAsset atomJsonFile;
public HashSet<String> actives = new HashSet<String>();
public HashSet<GameObject> InstantiatesObject = new HashSet<GameObject>();
public HashSet<GameObject> AtomInstantiatesObjects = new HashSet<GameObject>();
public TextMeshProUGUI textToUpdate;
public TextMeshProUGUI objectInstantiateText;
public HashSet<GameObject> DisableGameObjects = new HashSet<GameObject>();
public GameObject[] InformationObjs;
public GameObject[] DebugObjs;
private AnimationState _animationState = AnimationState.IDLE;
private float _animationSpeed = 1.0f;
public GameObject atomPrefabToInstantiate;
private bool IsLock = false;
private AtomeFactory _atomFactory;
void Start()
{
_atomFactory = new AtomeFactory(this.atomJsonFile);
Debug.Log("AtomFactory created !");
/*if (button != null)
{
button.onClick.AddListener(this.Center);
}*/
if (this.textToUpdate != null)
{
textToUpdate.text = "Scanner des Markers...";
}
}
public void AddScoppedElement(String name)
{
Debug.Log("Added " + name);
if (!actives.Contains(name))
{
actives.Add(name);
RefreshText();
RefreshAtom(name, true);
}
}
public void Center()
{
Debug.Log("Center called !");
foreach (var obj in InstantiatesObject)
{
if (Camera.main == null)
{
throw new Exception("NO MAIN CAMERA DEFINED ");
}
Vector3 cameraPosition = Camera.main.transform.position;
// Obtenez la rotation de la caméra sans inclure la rotation autour de l'axe Y
Quaternion cameraRotation = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0);
// Calculez la position finale en ajoutant la direction vers l'avant multipliée par la distance désirée
Vector3 position = cameraPosition + cameraRotation * Vector3.forward * 0.35f;
//var instantiatedObj = Instantiate(objt.obj, position, cameraRotation);
obj.transform.position = position;
obj.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
obj.transform.rotation = cameraRotation;
}
}
public void onClickStopAnimation()
{
Quaternion cameraRotation = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0);
this._animationState = AnimationState.IDLE;
foreach (var obj in InstantiatesObject)
{
obj.transform.rotation = cameraRotation;
}
}
public void onClickPauseAnimation()
{
this._animationState = AnimationState.IDLE;
}
public void onClickStartAnimation()
{
this._animationState = AnimationState.GORIGHT;
}
public void onClickRightAnimation()
{
this._animationState = AnimationState.GORIGHT;
}
public void onClickGoLeftAnimation()
{
this._animationState = AnimationState.GOLEFT;
}
public void onClickSpeedUp()
{
this._animationSpeed += 0.5f;
}
public void onClickSpeedDown()
{
this._animationSpeed -= 0.5f;
}
public void onClickToggleLockMode()
{
this.IsLock = !this.IsLock;
}
void Update()
{
if (this._animationState == AnimationState.GORIGHT)
{
foreach (var obj in InstantiatesObject)
{
obj.transform.Rotate(0, this._animationSpeed, 0, Space.Self);
/*Vector3 position = obj.GetComponent<SphereCollider>().bounds.center;
obj.transform.RotateAround(position, new Vector3(0, 0.1f, 0), 30 * Time.deltaTime);*/
}
}
}
private void RefreshText()
{
if (this.textToUpdate != null)
{
this.textToUpdate.text = String.Join(", ", this.actives);
}
}
static IEnumerable<string> GetPermutations(List<string> list)
{
if (list.Count == 1)
{
// Cas de base : une seule chaîne
yield return list[0];
}
else
{
// Récursion pour obtenir les permutations du reste de la liste
foreach (var item in list)
{
var remaining = new List<string>(list);
remaining.Remove(item);
foreach (var subPermutation in GetPermutations(remaining))
{
// Concaténer l'élément actuel avec les permutations du reste
yield return item + subPermutation;
}
}
}
}
private void DisableAllMarkerModel()
{
foreach (var o in GameObject.FindGameObjectsWithTag("OBJ"))
{
o.SetActive(false);
DisableGameObjects.Add(o);
}
}
private void EnableAllMarkerModel()
{
foreach (var o in DisableGameObjects)
{
o.SetActive(true);
}
DisableGameObjects.Clear();
}
private GameObject FindGameObjectWithFormula()
{
var factory = MoleculeFactory.getInstrance(this.jsonFile);
factory.setAtomFactory(this._atomFactory);
Debug.Log("ACTIVES ELEMENTS:");
Debug.Log(this.actives);
foreach (var formula in GetPermutations(this.actives.ToList()))
{
Debug.Log("FORMULA: " + String.Join("", formula));
if (factory.hasMolecule(String.Join("", formula)))
{
return factory.createMolecule(String.Join("", formula));
}
}
return null;
}
private String GetFormula()
{
var factory = MoleculeFactory.getInstrance(this.jsonFile);
factory.setAtomFactory(this._atomFactory);
foreach (var formula in GetPermutations(this.actives.ToList()))
{
Debug.Log("FORMULA: " + String.Join("", formula));
if (factory.hasMolecule(String.Join("", formula)))
{
return String.Join("", formula);
}
}
return null;
}
private void RenderAtom(String elementName, bool toAdd)
{
var cleanedElement = CleanStringOfDigits(elementName);
if (!toAdd)
{
try
{
var a = AtomInstantiatesObjects.First(t => t.name == ("ATOM_" + cleanedElement));
if (a != null)
{
AtomInstantiatesObjects.Remove(a);
Destroy(a);
Debug.Log("AtomInstantiatesObjects.Remove(a) called !");
return;
}
}
catch (Exception ex)
{
Debug.Log("pas trouvé");
return;
}
}
var atomObject = GameObject.Find(elementName);
if (atomObject == null) {
Debug.Log("atomObject=null");
return;
}
if (atomObject.transform.childCount >= 1) {
//atomObject.transform.GetChild(0).GetComponent<GameObject>().SetActive(true);
Debug.Log("Object already created !");
return;
}
var factory = MoleculeFactory.getInstrance(this.jsonFile);
factory.setAtomFactory(this._atomFactory);
if (!factory.GetAtomFactory().hasAtome(cleanedElement))
{
Debug.Log("No atom found with this formula '" + cleanedElement + "'");
return;
}
var obj = this._atomFactory.createAnimatedAtome(cleanedElement);
obj.name = "ATOM_" + cleanedElement;
obj.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
Quaternion cameraRotation = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0);
obj.transform.localPosition = new Vector3(0, 0, 0);
obj.transform.SetParent(atomObject.transform, false);
obj.transform.rotation = cameraRotation;
AtomInstantiatesObjects.Add(obj);
//var obj = Instantiate(atomPrefabToInstantiate, new Vector3(0, 0, 0), Quaternion.identity);
//AtomPrefab objPrefab = obj.GetComponent<AtomPrefab>();
//AtomeInformation info = factory.GetAtomFactory().createAtome(cleanedElement);
//objPrefab.Render(info);
}
private void RefreshAtom(String elementName, bool toAdd)
{
var objToFind = FindGameObjectWithFormula();
if (objToFind != null)
{
Debug.Log("Object to instantiate found !");
if (Camera.main == null)
{
throw new Exception("NO MAIN CAMERA DEFINED ");
}
foreach (var atomInstantiatesObject in AtomInstantiatesObjects)
{
Destroy(atomInstantiatesObject);
}
AtomInstantiatesObjects.Clear();
Vector3 cameraPosition = Camera.main.transform.position;
Quaternion cameraRotation = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0);
Vector3 position = cameraPosition + cameraRotation * Vector3.forward * 0.35f;
objToFind.transform.position = position;
objToFind.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
objToFind.transform.rotation = cameraRotation;
MeshRenderer meshRenderer = objToFind.GetComponent<MeshRenderer>();
if (meshRenderer != null)
{
float sizeInDirection = meshRenderer.bounds.size.x; // Pour la hauteur, ajustez selon votre besoin
Debug.Log("SizeInDirection: " + sizeInDirection);
objToFind.transform.position -= objToFind.transform.right * sizeInDirection * 0.175f;
}
Debug.Log("RefreshAtom(): Created " + objToFind.name);
objToFind.name = "[N] " + objToFind.name;
InstantiatesObject.Add(objToFind);
this.OnInstantiateObject(objToFind);
Debug.Log("Instantiate " + objToFind.name);
DisableAllMarkerModel();
} else {
foreach (var o in InstantiatesObject) {
Destroy(o);
OnDestroyObject(o);
}
InstantiatesObject.Clear();
EnableAllMarkerModel();
RenderAtom(elementName, toAdd);
}
if (InstantiatesObject.Count > 0 && objectInstantiateText != null) {
objectInstantiateText.text = String.Join(", ", InstantiatesObject.Select((s) => s.name));
} else if (objectInstantiateText != null) {
objectInstantiateText.text = "En attente...";
}
}
private void SetMoleculeInfo(String formula)
{
if (formula == null) {
return;
}
var factory = MoleculeFactory.getInstrance(this.jsonFile);
factory.setAtomFactory(this._atomFactory);
Molecule mol = factory.GetMoleculeByFormula(formula);
var descriptionGO = GameObject.Find("TXT_DESC").GetComponent<TextMeshProUGUI>();
var atomNbGO = GameObject.Find("TXT_ATOM_NB").GetComponent<TextMeshProUGUI>();
var symGO = GameObject.Find("TXT_SYM").GetComponent<TextMeshProUGUI>();
var nameGO = GameObject.Find("TXT_NAME").GetComponent<TextMeshProUGUI>();
nameGO.text = mol.name;
symGO.text = mol.formula;
descriptionGO.text = "Masse moleculaire: ";
atomNbGO.text = mol.atoms.Length + " Atomes";
}
private void OnInstantiateObject(GameObject obj)
{
foreach (var informationObj in InformationObjs)
{
informationObj.SetActive(true);
}
SetMoleculeInfo(GetFormula());
foreach (var debugObj in DebugObjs)
{
debugObj.SetActive(false);
}
}
private void OnDestroyObject(GameObject obj)
{
foreach (var informationObj in InformationObjs)
{
informationObj.SetActive(false);
}
foreach (var debugObj in DebugObjs)
{
debugObj.SetActive(true);
}
}
private string CleanStringOfNonDigits( string s )
{
if (string.IsNullOrEmpty(s)) return s;
StringBuilder sb = new StringBuilder(s.Length) ;
for (int i = 0; i < s.Length; ++i)
{
char c = s[i];
if ( c < '0' ) continue ;
if ( c > '9' ) continue ;
sb.Append(s[i]);
}
string cleaned = sb.ToString();
return cleaned;
}
private string CleanStringOfDigits(string s)
{
return new String(s.Where(Char.IsLetter).ToArray());
}
public void RemoveUnscoppedElement(String elementName)
{
if (this.IsLock)
{
return;
}
Debug.Log("Removed " + elementName);
actives.Remove(elementName);
RefreshText();
RefreshAtom(elementName, false);
}
}