Automatizando una locomotora
Este Nessito es un monstruo.
Ojalá todos pensasen igual (vuelvo a estar sin curro). Bueno freevision, a ver si te lo cuento, pero es bastante simple.
Consideraciones previas.
Todo lo que te ha comentado IkerClon.
Los inherits son un poco un arma de doble filo, son una manera rápida y fácil de restringir movimientos, rotaciones y tal, pero no discriminan. En el caso del pistón/viela/cigueñal, es fácil no heredar la rotación y solo un eje de movimiento del pistón con respecto al cigueñal y todo rula. Hasta que quieres mover y, sobre todo, rotar todo el conjunto, ya sea enlazando a otro objeto, ya sea a pelo. Si seteas el pistón para que solo herede un eje, no lo hace respecto de su ancestro directo, si no de toda la jerarquía que tenga por encima. Resultado: cagada. Conclusión: los inherits solo para cosas, digamos, globales.
Para que hablemos de lo mismo:
Jerarquia.

El tema.

Ningún objeto tiene desactivados inherits de ninguna clase.
Las dos vielas tienen el pivote en el mismo sitio (la x marca el lugar) y son hijas de la rueda trasera. Las dos tienen un look at constraint, una al point01 y otra al point02 (está claro cual a cual). Al asignar el constraint, lo normal es que se descabalen por el tema de los ejes. Soluciones hay dos:
-O te pones en el constraint los ejes como dios manda (lo que hice yo)o.
Le das al checkbox kep initial offset (más simple y rápido pienso yo).
El point01 es hijo de la rueda delantera y el point02 es hijo del point03 (que es el que controla el movimiento de toda la locomotora).
El point02 tiene un script controller en el eje X para que siga el movimiento en ese eje del point01 tomando como referencia el point03. Básicamente dice:
La posición en x es la posición en x del point01 respecto de point03.
Esto es lo mismo que te comentaba IkerClon de hacer con un helper ExposeTm.
Al ExposeTm le das como nodo el point01 y como nodo de referencia el point03, y en local position el valor x muestra exactamente lo mismo que el resultado de mi controlador script.
El point03 tiene un Path constraint a la forma del recorrido (forma que deberías usar como Path para hacerte un Loft para las vías).
Las dos ruedas son hijas del point03 (como debería serlo el resto de tu locomotora) y tienen un controlador script (instanciado) en el eje y (dependerá del eje sobre el que deban girar), que dice (copio/pego).
Código:
Degtorad(((Pathlength/ruedalength)*-(pathpoint/100.0))*360.0)
Relación de variables:
-Pathlength = longitud del Path (sacado de poner en el Listener curvelength $ con el Path seleccionado).
Ruedalength = longitud de la circunferencia de la rueda (2*pi*r).
Pathpoint = el punto del recorrido en el que se encuentra el point03 (esto es, una variable asignada al controlador Percent del Path constraint del point03).
Por tanto:
-(Pathlength/ruedalength) = número de vueltas que las ruedas deben hacer para completar el recorrido.
-(pathpoint/100.0) = posición del point03 sobre el recorrido en el rango 0-1. El menos que tiene delante es para invertir el sentido de giro, porque en mi caso las ruedas Iván al revés de lo que deberían (depende de la orientación de los ejes de las ruedas y del sentido del Path).
Multiplicando estas dos expresiones se obtiene la rotación que deberían tener las ruedas en un punto cualquiera del Path en número fraccional de vueltas, por eso.
Multiplicamos este valor por 360.0, para obtener el valor en grados.
Y todo este chorizo se lo pasamos a la función Degtorad que nos lo humilde en radianes (que es como lo necesita el controlador eulerxyz para que rule bien).
Consideraciones y mejoras.
En vez de multiplicar el número de vueltas por 360 y pasarlo a radianes con la función Degtorad, se podría multiplicar por (2*pi) y listo (recordemos: 360 grados son 2 pi radianes). Pero lo he dejado así en favor de la claridad (no sé tú, pero a mí me cuesta pensar directamente en radianes).
Si quieres que la cosa sea un poco más flexible, se puede sustituir la variable Pathlength por simplemente Path y asignarla al nodo del Path.
Quedando la formula de esta guisa:
Código:
(((curvelength Path)/ruedalength)*-(pathpoint/100.0))*2*pi
De ese modo si quieres cambiar el recorrido que sigue la locomotora, cambias el shape del Path constraint y apuntas la variable al nuevo Path y listo, sin tocar el script para nada. La desventaja es que para cada fotograma se tiene que calcular la longitud del Path, pero es una función bastante rápida, así que, no creo que ralentice mucho el tema.
Bueno, espero que esté todo claro.
-- IMÁGENES ADJUNTAS --

Aquel que pregunta, es tonto un rato. Aquel que no pregunta, es tonto toda la vida.