Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: z3nth10n en 3 Diciembre 2013, 20:52 pm



Título: [C#] Creando un terreno procedural (infinito) en Unity3D con CoherentNoise
Publicado por: z3nth10n en 3 Diciembre 2013, 20:52 pm
Hola buenas, pues hago este tema aquí ya que Unity3D (tiene 3 lenguajes de scripting) y yo he usado C#, y como los de la página no me contestan, pues hago como siempre, pregunto por aquí...

A lo mejor al título le sobraba lo de infinito, ya que bueno, pues un terreno generado proceduralmente suele ser infinito...

Y yendo al tema, pues me gustaría que me dieseis ideas de como podría lograr esto, yo tengo esta Class que me genera el terreno infinitamente:

http://subversion.assembla.com/svn/coherentnoise/

Pues bueno, puede ser el Ruido más coherente del mundo, pero cuando le cambias el Terreno va como pollo sin cabeza.. xD

Y bueno, pues me gustaría retocar un poco esta función: http://subversion.assembla.com/svn/coherentnoise/trunk/CoherentNoise/Generation/Fractal/FractalNoiseBase.cs

Código
  1. public override float GetValue(float x, float y, float z)
  2. {
  3. float value = 0;
  4. float signal = 0;
  5.  
  6. x *= Frequency;
  7. y *= Frequency;
  8. z *= Frequency;
  9.  
  10. for (int curOctave = 0; curOctave < OctaveCount; curOctave++)
  11. {
  12. // Get the coherent-noise value from the input value and add it to the
  13. // final result.
  14. signal = m_Noise.GetValue(x, y, z);
  15. // äåôîëòíûé ïåðëèí - ñêëàäûâàåò âñå çíà÷åíèÿ ñ óìåíüøàþùèìñÿ âåñîì
  16. value = CombineOctave(curOctave, signal, value);
  17.  
  18. // Prepare the next octave.
  19. // scale coords to increase frequency, then rotate to break up lattice pattern
  20. var rotated = s_Rotation*(new Vector3(x, y, z) * Lacunarity);
  21. x = rotated.x;
  22. y = rotated.y;
  23. z = rotated.z;
  24. }
  25.  
  26. return value;
  27. }
  28.  

Y como yo pa esto de las matemáticas soy un poco cazurro (ojo soy bueno, pero a tanto no llego) vosotros que sois mayores que yo, me gustaría que me echaseis una mano, para poder o por o menos intentar que mi Terreno infinito sea coherente por todas partes... El código del terreno infinito os lo dejo por este Pastebin:

http://pastebin.com/E4cZ3nUv

Y el código que lo genera todo:

Código
  1.    static void GenerateHeights(Terrain terrain, int last)
  2.            {
  3.  
  4.                var Pink = seed;
  5.                var n = new CoherentNoise.Generation.Fractal.PinkNoise(Pink) ; //213321
  6.  
  7.                float[,] heights = new float[terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight];
  8.  
  9.                for (int i = 0; i < terrain.terrainData.heightmapWidth; i++) //terrain.terrainData.heightmapWidth * lastChunkCharged
  10.                {
  11.                    for (int k = 0; k < terrain.terrainData.heightmapHeight; k++) //terrain.terrainData.heightmapHeight * lastChunkCharged
  12.                    {
  13.                        var x = n.GetValue((((float)i + terrain.terrainData.heightmapWidth * last) / ((float)terrain.terrainData.heightmapWidth * last)) * tileSize, (((float)k + terrain.terrainData.heightmapHeight * last) / ((float)terrain.terrainData.heightmapHeight * last)) * tileSize, 0);
  14.                        heights[i, k] = x / 5 + baseLine;
  15.                    }
  16.                }
  17.  
  18.                terrain.terrainData.SetHeights(0,0, heights);
  19.  
  20.            }

Os explico como funciona un poco esto de los Noises, el n.GetValue ahí arriba, devuelve un valor entre 0 y 1, y a eso se lo aplica a la altura máxima del mapa con una regla de 3...

Mi lógica es la siguiente (esto lo puedo explicar mejor en Español, por que en inglés me veo negro), se supone que X funciona la de FractalNoiseBase.cs (GetValue) da un valor entre 0 y 1 en relación a las coordenadas, si hago un sistema, en el que se cuenten los terrenos cargados y se aplique a estos pues debería cargar algo ordenador, es que si no, por cada terreno que se cargue empezaría el ciclo desde 0 a contar y si hago eso siempre se va a generar lo mismo siempre, puesto que las posiciones van a ser 0, 1, 2, ..., 125 (resolución maxima de los detalles del apa) y vuelta a empezar con el siguiente mapa, 0, 1, 2, ... 125, entonces, necesito saber porque no va...

Otra cosa curiosa es que tengo un NullReferenceException, en donde antes no lo tenía, (yo creo que ha sido al introducir el nuevo parametro en la función GetHeights llamado last que resulta que por alguna razon no lo introducto bien):

Código
  1. float[,] heights = new float[terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight];

Si le quitamos el parametro last, no nos da ningún error, y es algo que me ralla bastante por no sabe, porque da ese error solo por un parametro...

A ver, si los mas pros del foro en lo que C# se refiere me pueden echar un cable...

Gracias, y un saludo.
:-\


Título: Re: [C#] Creando un terreno procedural (infinito) en Unity3D con CoherentNoise
Publicado por: USLO en 27 Diciembre 2013, 18:23 pm
Hola que pasa Ikillnukes !
Cuando cargas el terreno o cuando llamas a la funcion de carga del terreno.(En que momento lo cargas?En el update en el Load principal? ).
Yo cargaria el mapa en el load.luego hazte tu algoritmo de descargar terreno y cargar nuevo terreno(Cada vez que salga de un extremo .)La mejor forma de hacerlo , es dibujando los terreno y ecribiendo tu metodologia.


Título: Re: [C#] Creando un terreno procedural (infinito) en Unity3D con CoherentNoise
Publicado por: z3nth10n en 28 Diciembre 2013, 15:22 pm
Gracias USLO pero ya solucione el error con otro code de por ahí...