La suite en C# !
Pour rendre l'expérience plus amusante je me suis focalisé sur l'idée de créer un paysage virtuel avec pour commencer : un sol, de l'herbe et quelques arbres, le tout généré et modifié depuis le son.
-j'ai intégré un timer public pour modifier le temps entre deux changement de valeurs des mesh.
-les 3 types d'objets sont dans des fonctions séparées (sol : triangles ,tronc : mesh à base de lignes ,branches: GLDebug ici, merci d'ailleurs, c'est génial comme outil)
-les dimensions du "sol" sont paramétrable
Fatalement j'ai de nouvelles questions existentielles : 2 vraiment en rapport avec Unity, une sur GLDebug et la dernière plus avec le code en lui même (désolé d'avance pour celle là
)
UNITY :
-est-il possible d'interpoler deux "positions" du mesh afin de créer une transition plus douce, même lorsqu'on augmente le temps de refresh ?
->j'ai commencé à regarder du coté de Lerp, que j'ai utilisé pour la couleur, mais il ne semble s'appliquer qu'aux transformations (position,localscale). Comment faire dans le cadre de changements de coordonnées ?
-le "sol" est constitué de deux triangles (jusqu'ici rien de folichon - dans le void genSol ligne 182). Les dimensions sont paramétrables, mais le nombre de triangle reste le même. La déclaration du mesh par ligne était assez claire, j'ai plus de mal avec les triangles.
->J'ai essayé de dire "1 surface = 4 points = 6 valeurs(soit 2 triangles)" en rendant le nombre de "surfaces" publiques. Mais ça ne marche pas beaucoup du tout. Quelqu'un aurait déjà réussi à faire un plan paramétrique dont on peut choisir le nombre de triangle ?
GLDebug :
Qu'est-ce que c'est pratique, mais j'ai une question. Peut-on instancier/Lister les lignes produites avec ? Ou le fait qu'elles viennent direct Renderer rend ça impossible ?
Scripter en C# :
J'ai commencé à déchiffrer l'exemple posté plus haut qui permet de créer de la sphère à l'icosaèdre comme on crée des formes primitives. J'aimerai faire le même genre de chose : pouvoir créer plusieurs fonctions genX (générant chacune un mesh) et pouvoir les activer/désactiver depuis le GUI, c'est possible ? Quelqu'un aurait un petit exemple/tuto ?
Merci d'avance à ceux qui ont lu jusque là, et encore plus à ceux qui liront la suite (j'ai essayé de faire ça propre)
Le script :
Code : Tout sélectionner
using UnityEngine;
using System.Collections;
public class SonC2 : MonoBehaviour {
//Le son
public int channel;
float[] volume;
float[] spectrum;
private int numSamples=1024;
private float minSpectrum;
private float maxSpectrum;
private float logSpectrum;
private float Volume;
//activateur
private bool playAtStartup = false;
public float interval;
private bool disableScript = false;
private float trackedTime = 0.0f;
private bool playedAtStartup = false;
//le sol-Topology:Triangles
private GameObject sol;
public int longSol;
public int largSol;
public int solSurfaceCount;
int[] solIndices;
private Vector3[] solVertices;
//private Vector2[] solUV;
private MeshFilter solFilter;
private Mesh solMesh;
private MeshRenderer solRenderer;
//les "troncs"-Topology:Lines
private GameObject tronc;
private int troncLinesCount;
int[] troncIndices;
private Vector3[] troncVertices;
//private Vector2[] troncUV;
private MeshFilter troncFilter;
private Mesh troncMesh;
private MeshRenderer troncRenderer;
//les branches avec GL debug
private GLDebug branche;
private Vector3 brancheVecteur1;
private Vector3 brancheVecteur2;
//les couleurs
private Color couleur1;
private Color couleur2;
private Color couleurSol;
private float lerp;
private float colorSpectrumMax;
private float colorSpectrumMin;
public float duration;
void Start () {
volume = new float[numSamples];
spectrum = new float[numSamples];
//initialise le sol
solSurfaceCount=1;
solIndices=new int[solSurfaceCount*6];
solVertices=new Vector3[solSurfaceCount*4];
sol=new GameObject();
sol.name="sol";
solMesh=new Mesh();
solFilter=sol.AddComponent<MeshFilter>();
solRenderer=sol.AddComponent<MeshRenderer>();
solFilter.mesh=solMesh;
//initialise les troncs
troncLinesCount=largSol;
troncIndices=new int[troncLinesCount*2];
troncVertices=new Vector3[troncLinesCount*2];
tronc=new GameObject();
tronc.name="tronc";
troncMesh=new Mesh();
troncFilter=tronc.AddComponent<MeshFilter>();
troncRenderer=tronc.AddComponent<MeshRenderer>();
troncFilter.mesh=troncMesh;
//lance le compteur
if (interval < 1.0f) {
disableScript=true;
}
}
void Update () {
//Récupère les données audio dans 2 tableaux, lance une boucle strictement positive
audio.GetOutputData (volume,channel);
audio.GetSpectrumData(spectrum,channel,FFTWindow.BlackmanHarris);
for (int i=1;i<1023;i++) {
if (volume[i]>0) {
if (spectrum[i]>0) {
//Debug.Log (Volume); //**valeurs du spectre et du (V)olume entre 0 et 10 /**/
logSpectrum=Mathf.Log (spectrum[i])+15;
maxSpectrum=Mathf.Max (logSpectrum);
minSpectrum=Mathf.Min (logSpectrum);
Volume=(volume[i]*100)/2;
//attribue les couleurs
colorSpectrumMax=Mathf.Clamp(maxSpectrum,0,255);
colorSpectrumMin=Mathf.Clamp (minSpectrum,0,255);
lerp=Mathf.PingPong(Time.time,duration)/duration;
couleur1=new Color(colorSpectrumMax,Volume,colorSpectrumMin);
couleur2=new Color(Volume,colorSpectrumMin,colorSpectrumMax);
couleurSol=new Color(125,90,180,Volume);
troncRenderer.material.color=Color.Lerp (couleur1,couleur2,lerp);
//solRenderer.material.color=couleurSol;
//lance les mesh selon le compteur
if (!disableScript) {
if (playAtStartup && !playedAtStartup) {
genTronc();
genSol ();
genBranche ();
playedAtStartup=true;
}
trackedTime += Time.deltaTime;
if (trackedTime >= interval) {
genTronc();
genSol ();
genBranche ();
trackedTime=0.0f;
}
}}}else{}
}
}
void genSol () {
for (var j=0;j<solSurfaceCount;j++) {
solVertices[j*4+0]=new Vector3(0,0,0);
solVertices[j*4+1]=new Vector3(longSol,0,largSol);
solVertices[j*4+2]=new Vector3(0,Volume/10,largSol);
solVertices[j*4+3]=new Vector3(longSol,0,0);
solIndices[j*3+0]=0+j;
solIndices[j*3+1]=1+j;
solIndices[j*3+2]=3+j;
solIndices[j*3+3]=1+j;
solIndices[j*3+4]=2+j;
solIndices[j*3+5]=0+j;
}
solMesh.SetIndices(solIndices,MeshTopology.Triangles,0);
solMesh.vertices=solVertices;
}
void genTronc () {
for(var j=0;j<troncLinesCount;j++) {
troncVertices[j*2+0]=new Vector3(spectrum[j+1]*10,Volume/20,0);
troncVertices[j*2+1]=new Vector3(spectrum[j],0,0);
}
for (var j=0;j<troncLinesCount*2;j++) {
troncIndices[j]=j;
troncMesh.vertices=troncVertices;
troncMesh.subMeshCount=1;
troncMesh.SetIndices (troncIndices,MeshTopology.Lines,0);
}
if(Volume>6) {
for (var j=0;j<largSol;j++) {
GameObject cloneTronc = Instantiate(tronc,new Vector3(j+1,0,(1/Volume)), transform.rotation) as GameObject ;
Destroy (cloneTronc,5f);
}
}else{}
}
void genBranche() {
for (var i=1;i<longSol;i++) {
//Vecteurs des branches
brancheVecteur1=new Vector3(spectrum[i],Mathf.Log (i),0);
brancheVecteur2=new Vector3(spectrum[i-1],Mathf.Log (i-1),0);
//Dessin
GLDebug.DrawLine (brancheVecteur1,brancheVecteur2,Color.Lerp (couleur1,couleur2,lerp),Mathf.Infinity);
GLDebug.DrawLine (new Vector3(spectrum[i],Mathf.Log (i),2),new Vector3(spectrum[i-1],Mathf.Log (i-1),2),Color.Lerp (couleur1,couleur2,lerp),5.0f);
GLDebug.DrawLine (new Vector3(spectrum[i],Mathf.Log (i),4),new Vector3(spectrum[i-1],Mathf.Log (i-1),4),Color.Lerp (couleur1,couleur2,lerp),10.0f);
GLDebug.DrawLine (new Vector3(spectrum[i],Mathf.Log (i),6),new Vector3(spectrum[i-1],Mathf.Log (i-1),6),Color.Lerp (couleur1,couleur2,lerp),15.0f);
GLDebug.DrawLine (new Vector3(spectrum[i],Mathf.Log (i),8),new Vector3(spectrum[i-1],Mathf.Log (i-1),8),Color.Lerp (couleur1,couleur2,lerp),20.0f);
GLDebug.DrawLine (new Vector3(spectrum[i],Mathf.Log (i),10),new Vector3(spectrum[i-1],Mathf.Log (i-1),10),Color.Lerp (couleur1,couleur2,lerp),30.0f);
}
}
}