Ce n'est pas l'article que j'ai été à l'origine va poste de n ° 9 de cette série. Cet article va monter en # 10. Avant d'entrer dans OpenGL ES 2.0 et les shaders, cependant, je veux parler de quelque chose de plus fondamental: l'animation.
Mais, comment gérez-vous les animations plus complexes? Dites que vous voulez faire une promenade figure, ou un squish balle comme elle rebondit?
C'est en fait pas si difficile. Il ya deux approches principales à l'animation en OpenGL: animations image clé et squelettique (ou osseuse) des animations basées. Dans cet épisode, nous allons parler des animations image-clé, et dans l'article suivant (9b), nous allons voir à l'animation du squelette.
L'animation est rien de plus que le changement dans la position des sommets au cours du temps. C'est tout. Lorsque vous traduisez, faire pivoter ou redimensionner un objet entier, vous vous déplacez tous les sommets qui composent un objet proportionnellement. Si vous souhaitez animer un objet de manière plus complexe et subtile, vous devez trouver un moyen de déplacer chaque vertex quantités différentes au fil du temps.
Le mécanisme de base utilisé dans les deux types d'animation est de stocker key positions pour chaque vertex dans un objet. En animation par images clés, cela se fait en stockant la position individuelle de chaque vertex pour chaque touche. Pour l'animation du squelette, c'est fait en stockant la position des os virtuel, avec une façon de désigner quel os affectent le mouvement dont les sommets.
Alors, quelles sont les clés? La meilleure façon de les expliquer est de revenir à leur origine, qui est en animation traditionnelle, comme cel le classique (pré-informatique) Disney et Warner Brothers dessins animés. Dans les premiers jours de l'animation, de petites équipes feraient tous les dessins qui composent un court. Mais comme les productions obtenu plus grande, cela est devenu impossible, et ils ont dû commencer à se spécialisant dans des rôles différents. Animateurs les plus expérimentés ont pris sur le rôle des Animateur principal (Parfois appelé animateur clé). Ces animateurs les plus expérimentés ne serait pas dessiner chaque cellule dans une scène, au contraire, ils seraient en tirer les cadres les plus importants. Il s'agit généralement de les extrêmes du mouvement, ou des poses qui a capturé l'essence de la scène. Si elles étaient d'animer un personnage jetant une balle, ils pourraient dessiner, peut-être, l'image où le bras a été le plus en arrière, puis un cadre où le bras est au sommet de l'arc, puis un troisième cadre, où le personnage sorti la balle .
Puis, l'animateur clé serait de passer à une nouvelle scène et un autre animateur a appelé une in-betweener (Parfois appelé bruts dans intervalliste, Car il serait souvent d'emplois d'une autre personne complètement différente pour nettoyer les dessins de intervalliste a) serait alors de savoir combien de temps il y avait entre ces images clés, puis faire tous les dessins intermédiaires. Si la remise a été un lancer d'une seconde, et ils étaient animant moins douze images par seconde, ils auraient à comprendre comment ajouter neuf autres cadres entre les images clés existantes établi par l'animateur principal.
Le concept en trois dimensions keyframe animation est exactement la même. Vous aurez des données de vertex pour les postes clés dans une motion, et vos bruts dans intervalliste sera un algorithme appelé interpolation.
Interpolation est quelques-uns des plus simples de mathématiques que vous allez faire dans les graphiques en trois dimensions. Pour chacune des dimensions cartésiennes (x, y, z), il vous suffit de prendre la différence entre les deux valeurs d'images clés, déterminer combien de temps s'est écoulé animation totale, et de diviser la différence par la partie fractionnaire.
Il serait plus logique si nous faisons un exemple pratique. Disons simplement regarder un sommet. Dans notre première image-clé, nous allons prétendre que c'est à l'origine (0, 0, 0). Pour la deuxième image clé, nous allons supposer que c'est à (5, 5, 5), et la durée entre ces deux images-clés, si cinq secondes (juste pour garder les maths agréable et simple).
Si nous sommes une seconde dans l'animation, nous avons juste à comprendre la différence entre les deux sommets pour chaque axe. Ainsi, dans notre cas, la totalité du déplacement entre les deux images-clés, si cinq unités sur chacun des x, y, et z (cinq moins zéro est égal à cinq). Donc, si nous sommes une seconde dans nos cinq seconde animation, nous sommes 1/5ème de la voie à travers, donc nous ajoutons 1/5ème de cinq à la première image-clé de x, y, et z, pour arriver à une position de (1, 1, 1). Maintenant, les chiffres ne seront pas habituellement que très bien, mais le calcul est exactement le même. Calculez la différence, puis déterminer en fonction du temps écoulé quel pourcentage de la manière à travers cette action, nous sommes, il faut multiplier la différence sur chaque axe par cette fraction, puis ajouter le résultat à la valeur de la première image clé pour cet axe.
C'est la forme la plus simple d'interpolation, appelé interpolation linéaire et c'est très bien pour la plupart des buts. Il existe des algorithmes plus complexes que le poids de l'interpolation basée sur quelle distance dans l'animation que vous êtes. Core Animation, par exemple, offre la possibilité de «facilité à", "ease out», ou «la facilité d'entrée / sortie" lors de la réalisation d'une animation. Peut-être que nous allons couvrir non linéaire d'interpolation dans un futur article, mais pour aujourd'hui, nous allons juste garder les choses simples et de travailler avec une interpolation linéaire. Vous pouvez faire la grande majorité de ce que vous voulez avec cette technique tout en modifiant le nombre d'images clés et la durée entre les deux
Regardons un exemple très simple de l'animation dans OpenGL ES. Lorsque traditionnelle dessinée à la main animateurs sont formés, la première chose qu'ils font est d'animer une balle qui rebondit que squishes comme elle rebondit. Il semble que normal pour nous de faire la même chose, donc voici ce que notre application va ressembler:

Commençons par la création d'une balle dans Blender (Ou tout autre programme 3D que vous voulez utiliser, si vous avez un moyen d'exporter les données de vertex et normale d'une manière utilisable. Dans cet exemple, je vais utiliser mon Blender exporter un script, Qui génère des fichiers d'en-tête avec les données de vertex.
Je commence par la création d'une icosphère à l'origine. Je renommer le maillage à Ball1, Puis-je sauvegarder ce fichier en tant Ball1.blend et à l'exportation Ball1.blend en utilisant mon script d'export. Vous pouvez trouver mon fichier Blender pour cette image clé here.

Maintenant, je fais un Enregistrer sous (F2) et enregistrer une copie du fichier que Ball2.blend. Dans cette copie, je renommer le maillage Ball2 de sorte que le script d'export utilise des noms différents pour les structures de données. Puis j'ai frappé 'tab' pour passer en mode édition, appuyez sur 'A' et déplacer et redimensionner les sommets de la balle afin qu'elle soit déplacée vers le bas et est écrasé. Je sauvegarder la balle écrasée et l'exportation Ball2.h. Vous pouvez trouver mon fichier Blender pour la deuxième image clé here.

À ce point, j'ai deux fichiers. H, chacun contenant les positions des sommets pour une image clé dans mon animation. Travaillant à partir mon modèle OpenGL ESJe définis d'abord quelques valeurs dans le GLViewControler.h pour m'aider à garder la trace de l'animation:
Comme je vais rebondir et-vient entre les deux images clés, j'ai besoin de garder trace de savoir si c'est voyager avant ou en arrière. J'ai également définir une valeur de contrôler à quelle vitesse il se déplace entre les deux images-clés.
Puis, en GLViewController.m, Je interpoler entre les deux images-clés à plusieurs reprises, comme tant d'(ne vous inquiétez pas, je vais vous expliquer):
Tout d'abord, je commence avec une certaine configuration. J'ai créer une variable statique pour garder trace du moment où nous avons touché la dernière image-clé. Ce sera nécessaire pour déterminer combien de temps s'est écoulé. La première fois grâce, nous l'initialiser à l'heure actuelle, nous déclarons une variable pour garder la trace que nous sommes animation avant ou en arrière.
Après cela, nous ne la normale des choses OpenGL ES. La seule chose à noter ici est que nous faisons tourner -90 ^ 0 sur l'axe des abscisses. Nous sommes la comptabilité pour le fait que l'OpenGL ES utilise un système Y-jusqu'à coordonner et Blender utilise un Z-up. Nous aurions aussi pu tourner dans Blender lieu.
Ensuite, je déclare un tableau statique pour contenir les données interpolées:
Juste pour garder les choses simples, j'ai mis une couleur et les matériaux permettant de couleur. Je ne voulais pas encombrer cet exemple avec texture ou ses matériaux.
Maintenant je calcule combien de temps s'est écoulé depuis la dernière image-clé. Si le temps écoulé est supérieure à la durée de l'animation, nous inverser la direction autour de sorte que nous allons dans l'autre sens.
Afin d'accommoder bi-directionnel animation, je déclarer deux pointeurs vers les données source d'images clés et de données de destination keyframe, et le point à chacun de le tableau de données approprié en fonction de la direction que nous sommes actuellement en cours.
Et, enfin, l'interpolation. Voici une application assez générique de cette interpolation linéaire dont nous parlions:
Ensuite, tout ce qui reste à faire est de faire un travail de nettoyage.
Pas si difficile, non? C'est juste la division, la multiplication et l'addition. Par rapport à certaines des choses que nous avons traversé jusqu'ici, ce n'est rien. C'est la technique de base utilisée, par exemple, dans le MD2 format de fichier utilisé par Id dans leurs anciens jeux. Chaque animation utilisée est réalisée en utilisant keyframe animation, tout comme je l'ai fait ici. Les versions ultérieures de formats de support Milkshape autre fichier, mais vous pouvez faire des animations très sophistiquées utilisant des images clés.
Si vous voulez vérifier la boule gonflable, vous pouvez télécharger mes Xcode projet et exécutez-le pour vous-même.
Pas tous d'animation 3D se fait en utilisant des images clés, mais l'interpolation est le mécanisme de base qui permet à tous d'animation complexes. Restez branchés pour le prochain épisode, 9b, où nous utilisons l'interpolation de mettre en œuvre une forme beaucoup plus complexe d'animation appelé animation squelettique.
Note:Vous pouvez trouver le code source qui accompagne cet article here. Une nouvelle version a été téléchargé à l'heure de l'Est 10:14 à celui fixé un problème avec ce pas l'animation (voir les commentaires pour plus de détails).Maintenant, vous avez déjà vu la forme la plus basique de l'animation dans OpenGL ES. En changeant la rotation, translation, et les transformations d'échelle au fil du temps, nous pouvons objets d'animation. Notre tout premier projet - l'icosaèdre filature - est un exemple de cette forme d'animation, souvent appelé animation simple. Ne laissez pas le nom vous tromper, cependant, vous pouvez faire des animations très complexes en utilisant rien de plus changeant des transformations de matrice au cours du temps.
Mais, comment gérez-vous les animations plus complexes? Dites que vous voulez faire une promenade figure, ou un squish balle comme elle rebondit?
C'est en fait pas si difficile. Il ya deux approches principales à l'animation en OpenGL: animations image clé et squelettique (ou osseuse) des animations basées. Dans cet épisode, nous allons parler des animations image-clé, et dans l'article suivant (9b), nous allons voir à l'animation du squelette.
Interpolation et clés
L'animation est rien de plus que le changement dans la position des sommets au cours du temps. C'est tout. Lorsque vous traduisez, faire pivoter ou redimensionner un objet entier, vous vous déplacez tous les sommets qui composent un objet proportionnellement. Si vous souhaitez animer un objet de manière plus complexe et subtile, vous devez trouver un moyen de déplacer chaque vertex quantités différentes au fil du temps.
Le mécanisme de base utilisé dans les deux types d'animation est de stocker key positions pour chaque vertex dans un objet. En animation par images clés, cela se fait en stockant la position individuelle de chaque vertex pour chaque touche. Pour l'animation du squelette, c'est fait en stockant la position des os virtuel, avec une façon de désigner quel os affectent le mouvement dont les sommets.
Alors, quelles sont les clés? La meilleure façon de les expliquer est de revenir à leur origine, qui est en animation traditionnelle, comme cel le classique (pré-informatique) Disney et Warner Brothers dessins animés. Dans les premiers jours de l'animation, de petites équipes feraient tous les dessins qui composent un court. Mais comme les productions obtenu plus grande, cela est devenu impossible, et ils ont dû commencer à se spécialisant dans des rôles différents. Animateurs les plus expérimentés ont pris sur le rôle des Animateur principal (Parfois appelé animateur clé). Ces animateurs les plus expérimentés ne serait pas dessiner chaque cellule dans une scène, au contraire, ils seraient en tirer les cadres les plus importants. Il s'agit généralement de les extrêmes du mouvement, ou des poses qui a capturé l'essence de la scène. Si elles étaient d'animer un personnage jetant une balle, ils pourraient dessiner, peut-être, l'image où le bras a été le plus en arrière, puis un cadre où le bras est au sommet de l'arc, puis un troisième cadre, où le personnage sorti la balle .
Puis, l'animateur clé serait de passer à une nouvelle scène et un autre animateur a appelé une in-betweener (Parfois appelé bruts dans intervalliste, Car il serait souvent d'emplois d'une autre personne complètement différente pour nettoyer les dessins de intervalliste a) serait alors de savoir combien de temps il y avait entre ces images clés, puis faire tous les dessins intermédiaires. Si la remise a été un lancer d'une seconde, et ils étaient animant moins douze images par seconde, ils auraient à comprendre comment ajouter neuf autres cadres entre les images clés existantes établi par l'animateur principal.
Le concept en trois dimensions keyframe animation est exactement la même. Vous aurez des données de vertex pour les postes clés dans une motion, et vos bruts dans intervalliste sera un algorithme appelé interpolation.
Interpolation est quelques-uns des plus simples de mathématiques que vous allez faire dans les graphiques en trois dimensions. Pour chacune des dimensions cartésiennes (x, y, z), il vous suffit de prendre la différence entre les deux valeurs d'images clés, déterminer combien de temps s'est écoulé animation totale, et de diviser la différence par la partie fractionnaire.
Il serait plus logique si nous faisons un exemple pratique. Disons simplement regarder un sommet. Dans notre première image-clé, nous allons prétendre que c'est à l'origine (0, 0, 0). Pour la deuxième image clé, nous allons supposer que c'est à (5, 5, 5), et la durée entre ces deux images-clés, si cinq secondes (juste pour garder les maths agréable et simple).
Si nous sommes une seconde dans l'animation, nous avons juste à comprendre la différence entre les deux sommets pour chaque axe. Ainsi, dans notre cas, la totalité du déplacement entre les deux images-clés, si cinq unités sur chacun des x, y, et z (cinq moins zéro est égal à cinq). Donc, si nous sommes une seconde dans nos cinq seconde animation, nous sommes 1/5ème de la voie à travers, donc nous ajoutons 1/5ème de cinq à la première image-clé de x, y, et z, pour arriver à une position de (1, 1, 1). Maintenant, les chiffres ne seront pas habituellement que très bien, mais le calcul est exactement le même. Calculez la différence, puis déterminer en fonction du temps écoulé quel pourcentage de la manière à travers cette action, nous sommes, il faut multiplier la différence sur chaque axe par cette fraction, puis ajouter le résultat à la valeur de la première image clé pour cet axe.
C'est la forme la plus simple d'interpolation, appelé interpolation linéaire et c'est très bien pour la plupart des buts. Il existe des algorithmes plus complexes que le poids de l'interpolation basée sur quelle distance dans l'animation que vous êtes. Core Animation, par exemple, offre la possibilité de «facilité à", "ease out», ou «la facilité d'entrée / sortie" lors de la réalisation d'une animation. Peut-être que nous allons couvrir non linéaire d'interpolation dans un futur article, mais pour aujourd'hui, nous allons juste garder les choses simples et de travailler avec une interpolation linéaire. Vous pouvez faire la grande majorité de ce que vous voulez avec cette technique tout en modifiant le nombre d'images clés et la durée entre les deux
Animation d'images clés dans OpenGLES
Regardons un exemple très simple de l'animation dans OpenGL ES. Lorsque traditionnelle dessinée à la main animateurs sont formés, la première chose qu'ils font est d'animer une balle qui rebondit que squishes comme elle rebondit. Il semble que normal pour nous de faire la même chose, donc voici ce que notre application va ressembler:

Commençons par la création d'une balle dans Blender (Ou tout autre programme 3D que vous voulez utiliser, si vous avez un moyen d'exporter les données de vertex et normale d'une manière utilisable. Dans cet exemple, je vais utiliser mon Blender exporter un script, Qui génère des fichiers d'en-tête avec les données de vertex.
Je commence par la création d'une icosphère à l'origine. Je renommer le maillage à Ball1, Puis-je sauvegarder ce fichier en tant Ball1.blend et à l'exportation Ball1.blend en utilisant mon script d'export. Vous pouvez trouver mon fichier Blender pour cette image clé here.

Maintenant, je fais un Enregistrer sous (F2) et enregistrer une copie du fichier que Ball2.blend. Dans cette copie, je renommer le maillage Ball2 de sorte que le script d'export utilise des noms différents pour les structures de données. Puis j'ai frappé 'tab' pour passer en mode édition, appuyez sur 'A' et déplacer et redimensionner les sommets de la balle afin qu'elle soit déplacée vers le bas et est écrasé. Je sauvegarder la balle écrasée et l'exportation Ball2.h. Vous pouvez trouver mon fichier Blender pour la deuxième image clé here.

À ce point, j'ai deux fichiers. H, chacun contenant les positions des sommets pour une image clé dans mon animation. Travaillant à partir mon modèle OpenGL ESJe définis d'abord quelques valeurs dans le GLViewControler.h pour m'aider à garder la trace de l'animation:
#define kAnimationDuration 0.3
enum animationDirection {
kAnimationDirectionForward = YES,
kAnimationDirectionBackward = NO
};
typedef BOOL AnimationDirection;Comme je vais rebondir et-vient entre les deux images clés, j'ai besoin de garder trace de savoir si c'est voyager avant ou en arrière. J'ai également définir une valeur de contrôler à quelle vitesse il se déplace entre les deux images-clés.
Puis, en GLViewController.m, Je interpoler entre les deux images-clés à plusieurs reprises, comme tant d'(ne vous inquiétez pas, je vais vous expliquer):
- (void)drawView:(UIView *)theView
{
static NSTimeInterval lastKeyframeTime = 0.0;
if (lastKeyframeTime == 0.0)
lastKeyframeTime = [NSDate timeIntervalSinceReferenceDate];
static AnimationDirection direction = kAnimationDirectionForward;
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,2.2f,-6.0f);
glRotatef(-90.0, 1.0, 0.0, 0.0); // Blender uses Z-up, not Y-up like OpenGL ES
static VertexData3D ballVertexData[kBall1NumberOfVertices];
glColor4f(0.0, 0.3, 1.0, 1.0);
glEnable(GL_COLOR_MATERIAL);
NSTimeInterval timeSinceLastKeyFrame = [NSDate timeIntervalSinceReferenceDate] - lastKeyframeTime;
if (timeSinceLastKeyFrame > kAnimationDuration) {
direction = !direction;
timeSinceLastKeyFrame = timeSinceLastKeyFrame - kAnimationDuration;
lastKeyframeTime = [NSDate timeIntervalSinceReferenceDate];
}
NSTimeInterval percentDone = timeSinceLastKeyFrame / kAnimationDuration;
VertexData3D *source, *dest;
if (direction == kAnimationDirectionForward)
{
source = (VertexData3D *)Ball1VertexData;
dest = (VertexData3D *)Ball2VertexData;
}
else
{
source = (VertexData3D *)Ball2VertexData;
dest = (VertexData3D *)Ball1VertexData;
}
for (int i = 0; i < kBall1NumberOfVertices; i++)
{
GLfloat diffX = dest[i].vertex.x - source[i].vertex.x;
GLfloat diffY = dest[i].vertex.y - source[i].vertex.y;
GLfloat diffZ = dest[i].vertex.z - source[i].vertex.z;
GLfloat diffNormalX = dest[i].normal.x - source[i].normal.x;
GLfloat diffNormalY = dest[i].normal.y - source[i].normal.y;
GLfloat diffNormalZ = dest[i].normal.z - source[i].normal.z;
ballVertexData[i].vertex.x = source[i].vertex.x + (percentDone * diffX);
ballVertexData[i].vertex.y = source[i].vertex.y + (percentDone * diffY);
ballVertexData[i].vertex.z = source[i].vertex.z + (percentDone * diffZ);
ballVertexData[i].normal.x = source[i].normal.x + (percentDone * diffNormalX);
ballVertexData[i].normal.y = source[i].normal.y + (percentDone * diffNormalY);
ballVertexData[i].normal.z = source[i].normal.z + (percentDone * diffNormalZ);
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexData3D), &Ball2VertexData[0].vertex);
glNormalPointer(GL_FLOAT, sizeof(VertexData3D), &Ball2VertexData[0].normal);
glDrawArrays(GL_TRIANGLES, 0, kBall1NumberOfVertices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
Tout d'abord, je commence avec une certaine configuration. J'ai créer une variable statique pour garder trace du moment où nous avons touché la dernière image-clé. Ce sera nécessaire pour déterminer combien de temps s'est écoulé. La première fois grâce, nous l'initialiser à l'heure actuelle, nous déclarons une variable pour garder la trace que nous sommes animation avant ou en arrière.
static NSTimeInterval lastKeyframeTime = 0.0;
if (lastKeyframeTime == 0.0)
lastKeyframeTime = [NSDate timeIntervalSinceReferenceDate];
static AnimationDirection direction = kAnimationDirectionForward;Après cela, nous ne la normale des choses OpenGL ES. La seule chose à noter ici est que nous faisons tourner -90 ^ 0 sur l'axe des abscisses. Nous sommes la comptabilité pour le fait que l'OpenGL ES utilise un système Y-jusqu'à coordonner et Blender utilise un Z-up. Nous aurions aussi pu tourner dans Blender lieu.
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,2.2f,-6.0f);
glRotatef(-90.0, 1.0, 0.0, 0.0); // Blender uses Z-up, not Y-up like OpenGL ESEnsuite, je déclare un tableau statique pour contenir les données interpolées:
static VertexData3D ballVertexData[kBall1NumberOfVertices];Juste pour garder les choses simples, j'ai mis une couleur et les matériaux permettant de couleur. Je ne voulais pas encombrer cet exemple avec texture ou ses matériaux.
glColor4f(0.0, 0.3, 1.0, 1.0);
glEnable(GL_COLOR_MATERIAL);Maintenant je calcule combien de temps s'est écoulé depuis la dernière image-clé. Si le temps écoulé est supérieure à la durée de l'animation, nous inverser la direction autour de sorte que nous allons dans l'autre sens.
NSTimeInterval timeSinceLastKeyFrame = [NSDate timeIntervalSinceReferenceDate] - lastKeyframeTime;
if (timeSinceLastKeyFrame > kAnimationDuration) {
direction = !direction;
timeSinceLastKeyFrame = timeSinceLastKeyFrame - kAnimationDuration;
lastKeyframeTime = [NSDate timeIntervalSinceReferenceDate];
}
NSTimeInterval percentDone = timeSinceLastKeyFrame / kAnimationDuration;Afin d'accommoder bi-directionnel animation, je déclarer deux pointeurs vers les données source d'images clés et de données de destination keyframe, et le point à chacun de le tableau de données approprié en fonction de la direction que nous sommes actuellement en cours.
VertexData3D *source, *dest;
if (direction == kAnimationDirectionForward)
{
source = (VertexData3D *)Ball1VertexData;
dest = (VertexData3D *)Ball2VertexData;
}
else
{
source = (VertexData3D *)Ball2VertexData;
dest = (VertexData3D *)Ball1VertexData;
}Et, enfin, l'interpolation. Voici une application assez générique de cette interpolation linéaire dont nous parlions:
for (int i = 0; i < kBall1NumberOfVertices; i++)
{
GLfloat diffX = dest[i].vertex.x - source[i].vertex.x;
GLfloat diffY = dest[i].vertex.y - source[i].vertex.y;
GLfloat diffZ = dest[i].vertex.z - source[i].vertex.z;
GLfloat diffNormalX = dest[i].normal.x - source[i].normal.x;
GLfloat diffNormalY = dest[i].normal.y - source[i].normal.y;
GLfloat diffNormalZ = dest[i].normal.z - source[i].normal.z;
ballVertexData[i].vertex.x = source[i].vertex.x + (percentDone * diffX);
ballVertexData[i].vertex.y = source[i].vertex.y + (percentDone * diffY);
ballVertexData[i].vertex.z = source[i].vertex.z + (percentDone * diffZ);
ballVertexData[i].normal.x = source[i].normal.x + (percentDone * diffNormalX);
ballVertexData[i].normal.y = source[i].normal.y + (percentDone * diffNormalY);
ballVertexData[i].normal.z = source[i].normal.z + (percentDone * diffNormalZ);
}Ensuite, tout ce qui reste à faire est de faire un travail de nettoyage.
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexData3D), &Ball2VertexData[0].vertex);
glNormalPointer(GL_FLOAT, sizeof(VertexData3D), &Ball2VertexData[0].normal);
glDrawArrays(GL_TRIANGLES, 0, kBall1NumberOfVertices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
Pas si difficile, non? C'est juste la division, la multiplication et l'addition. Par rapport à certaines des choses que nous avons traversé jusqu'ici, ce n'est rien. C'est la technique de base utilisée, par exemple, dans le MD2 format de fichier utilisé par Id dans leurs anciens jeux. Chaque animation utilisée est réalisée en utilisant keyframe animation, tout comme je l'ai fait ici. Les versions ultérieures de formats de support Milkshape autre fichier, mais vous pouvez faire des animations très sophistiquées utilisant des images clés.
Si vous voulez vérifier la boule gonflable, vous pouvez télécharger mes Xcode projet et exécutez-le pour vous-même.
Pas tous d'animation 3D se fait en utilisant des images clés, mais l'interpolation est le mécanisme de base qui permet à tous d'animation complexes. Restez branchés pour le prochain épisode, 9b, où nous utilisons l'interpolation de mettre en œuvre une forme beaucoup plus complexe d'animation appelé animation squelettique.
Aucun commentaire:
Enregistrer un commentaire