Sigamos ... Hemos empezado con un rapido vistazo a cada COMPOUND dentro del DENT, pero ahora toca mirar dentro de esos compounds.
Nota: Voy a saltarme el SET DATA, pues no hay mucho mas que añadir.- Desmontando PERFORM RAYCAST - Aparentemente no tiene mucha complicación pero este punto me ha sorprendido por una pequeña genialidad. El RAYCAST Coge cada punto de nuestro grid y partiendo de este, lanza un rayo hacia la dirección que previamente ha sido asignada como "abajo". Si toca la pelota, hay premio y nos devuelve la posición en la que el rayo ya tocado el borde de la pelota. Si no, pues nada.
Tardé un rato en comprender porque funcionaba. Si la pelota esta "arriba", ¿ porque lanza los rayos hacia abajo ?. Pues la respuesta es tan simple como ingeniosa. Lo hace porque nos interesa detectar los puntos que ya han atravesado el grid, y esos puntos están POR DEBAJO del grid. De forma que mientras la pelota se mantiene por encima, el HIT del RAYCAST da siempre resultados nulos. Pero en cuando la pelota empieza a atravesar el grid, los primeros empiezan a detectarla y a reaccionar.
Como vemos al final, hay un FILTER. De forma que si el punto no encuentra la pelota, no pasa nada. Pero si ha habido contacto, el SET DATA asigna a la variable "DeformDistance", la distancia que hay entre el punto del grid que estamos tratando en ese momento y el punto que el RAYCAST ha encontrado en el borde de la pelota.
El NEGATE, si no lo he entendido mal, también tiene su razón de ser. Cuando calculamos la distancia mediante el GET DISTANCE BETWEEN, el resultado es positivo(obviamente). Pero nuestra intención es desplazar los puntos hacia "abajo", así que nos interesa guardar ese valor invertido.
Si anulamos este nodo, cuando los puntos tocan la pelota, estos son lanzados hacia arriba, en lugar de abajo.
- Desmontando CALCULATE BULGE - Esto es lo primero que nos encontramos. Vemos que se trata de un FILTER que controla la modificación final de la variable "DeformDistance". Junto con el AND, tenemos que si se falla alguna delas dos siguientes condiciones, el FILTER se "cierra" y la variable permenecerá intacta manteniendo el valor que se le ha asignado previamente en el paso PERFORM RAYCAST.
· Condición 1; Que la variable "DeformDistance" sea mayor o igual que 0. En realidad, es imposible que encontremos valores superiores a 0. Recordemos que en al inicio la variable fue definida a 0, y que después, lo único que hemos hecho, ha sido restarle un valor X, a aquellos vértices que quedaron engullidos por la esfera. En otras palabras. Todos los vértices que han sido tocados por la esfera, tendrán un "DeformDistance" inferior a 0. Por lo que devolverán un resultado FALSE, quedarán libres del CALCULATE BULGE. Fin.
· Condición 2; Que los puntos se encuentren lejos de la esfera. Como dice el propio COMMENT del a imagen, esto se hace para limitar los cálculos, ya que los puntos lejanos son rápidamente descartados del resto de cálculos. Eliminar esta condición solo relentiza la máquina, pero sigue funcionando igual.
Si nos desplazamos un poquito mas abajo, tenemos mas ...
Para saber si un punto tenemos que elevarlo mucho o no (el Bulge), lo que necesitamos es saber como esta de lejos o de cerca, de los puntos que han sido aplastados por la esfera. Por ello montan el tingalado que hay en la imagen de arriba.
Para empezar un GET NEARBY POINTS nos da todos los puntos que se encuentran dentro del área de influencia, a 2 unidades de distancia. Con esos puntos obtenemos varias cosas.
Primero una ARRAY de SCALARS PER POINT con el valor de la variable "DeformDistance" de cada uno de estos puntos.
Segundo, mediante un GET POINT POSITION, tenemos una ARRAY de 3D VECTORS con la posición de cada uno de estos puntos.
Y tercero, el GET ARRAY SUB INDICES nos crea una ARRAY con los INDICES de la ARRAY de puntos. Un poco confuso, pero no tanto como puede parecer al principio. Si no lo imagino mal, supongo que al tratarse de una array de indices de una array recien creada, lo que tenemos en su interior es ... [0, 1, 2, 3, 4, 5, 6, ... etc].
Bien, para lograr hallar el punto aplastado mas cercano, lo primero que tenemos que hacer es obtener la distancia de todos y cada uno de los puntos cercanos. Por eso tenemos un GET DISTANCE BETWEEN, que nos calcula la distancia entre el punto que estamos tratando en ese momento y cada uno de los puntos del array que obtuvimos con el GET NEARBY POINTS -> GET POINTPOSITION. El resultado es un array de SCALARS, donde cada SCALAR nos da la distancia.
Ahora, usando ese array de distancias ordenamos el array de SUB INDICES que hemos generado prebiamente. Por ello tenemos el SORT ARRAY WHIT KEY. Supongo que lo que hace, es colocar las dos tablas una al lado de la otra (tablas que deben ser del mismo tipo y tamaño), y después mientras ordena una, la que esta en "Key Away" repite los mismos pasos en la otra, en "Array". Al final, obtenemos una array de sub indices, ordenada segun la distancia. Debe de tener un aspecto parecido a esto ... [6, 0, 2, 1, 5, 3, 4, ... etc].
Ahora, usando ese nuevo array de sub indices ordenado, sacamos los valores de uno en uno con el SELECT IN ARRAY y los comparamos con el FIND IN ARRAY. Los vamos chequeando uno tras otro, para comprobar si el "DeformDistance" es inferior a 0 o no (Recuerda que si es inferior a 0, significa que la pelota lo ya aplastado).
El primer punto que encontremos, será el mas cercano. Lo que queríamos, ya que gracias a haber ordenado previamente el array de sub indices por distancia, los chequeamos siempre en orden de cerca a lejos.
Teniendo ya el sub indice del punto aplastado mas cercano, usamo un nuevo SELECT IN ARRAY para mirar en la array de distancias y obtener asi la distancia que separa el punto que estamos tratando con el punto aplastado mas cercano.
Juder ... como se las saben. Pero lo mas curioso de este ultimo tocho, es que no sirve par nada. Pero ahí esta ^_^.
Nota: Voy subiendo esporadicamente lo que escribo, para que no se me pete y lo pierda. Seria un palo.