MoGraph: Die Effektoren – Der C.O.F.F.E.E.-Effektor

Tutorials 15. August 2016 – 0 Kommentare

Gerade hatte ich noch groß getönt, dass das Schlimmste in Sachen Effektoren schon erledigt sei und dann das hier: Ein Effektor, der selbst programmiert werden muss. Aber halb so wild. Schließlich ist dies nur ein Angebot an Sie, falls Sie sich nicht scheuen, etwas tiefer in die Mathematik und die interne Verarbeitung von Klonen einzusteigen. Es lohnt sich auf jeden Fall!
Wie bereits an anderer Stelle erwähnt, fehlt in diesem Buch schlicht der Platz, Ihnen die diversen Programmiersprachen, wie C.O.F.F.E.E., Python oder gar C++ näher zu bringen. Ein paar Brocken möchte ich Ihnen aber dennoch zumuten. Vielleicht motiviert es Sie ja, sich die SDKs der Programmiersprachen von der MAXON-Homepage zu laden. Das Eigenstudium ist damit durchaus möglich, zumal für C.O.F.F.E.E. und Python keine separaten Compiler benötigt werden. Spezielle Videolehrgänge zu C.O.F.F.E.E. und Python sind von mir ebenfalls bei Video2Brain erhältlich, falls Sie dabei Starthilfe benötigen. Grundsätzlich funktioniert auch der C.O.F.F.E.E.-Effektor wie der Simpel-Effektor, Sie müssen den Effektor also z. B. in die Effektoren-Liste eines Klon-Objekts aufnehmen. Die Einstellungen für Parameter, Deformation und Abnahme sind ansonsten identisch mit denen des Simpel-Effektors.

Animation in Cinema 4D - Beispielszene mit einem Klon-Objekt

Abbildung 5.74: Beispielszene mit einem Klon-Objekt

Beginnen wir daher mit einer neuen Szene und versuchen uns daran die Funktionsweise dieses Effektors zu erarbeiten. Wie in Abbildung 5.74 zu sehen, erstelle ich hierfür ein Klon-Objekt und ordne diesem einen Würfel unter. Der Würfel hat eine Kantenlänge von je 100 cm, damit der Turm nicht ganz so hoch wird. Stellen Sie eine beliebige Anzahl an Klonen ein und lassen Sie diese im Modus Pro Schritt mit P.Y 100 cm exakt aufeinander stapeln. Um die einzelnen Würfel dabei besser sehen zu können, habe ich dem Würfel-Grundobjekt eine zusätzliche Rundung mitgegeben. Sie sehen das Resultat auf der rechten Seite von Abbildung 5.74.

Animation in Cinema 4D - Grundeinstellungen eines C.O.F.F.E.E.-Effektors

Abbildung 5.75: Grundeinstellungen eines C.O.F.F.E.E.-Effektors

Nun erstellen Sie einen C.O.F.F.E.E.-Effektor und werfen einen Blick in dessen Effektor-Einstellungen (siehe Abbildung 5.75). Hier steckt der eigentliche Kern dieses Effektors, der Code. Mit Code ist Programmcode gemeint. Dabei bringt der Effektor bereits ein kleines Programm mit, das wir in der Code-Rubrik erkennen können. Daran lassen sich schon die Grundfunktionen derartiger Programme erkennen. Lassen Sie uns daher diesen mitgelieferten Code zuerst einmal ansehen und verstehen. Dann fällt später auch das Schreiben eigener Befehle einfacher, da sich viele Elemente recyceln lassen.

Um eigenen Effektor-Code zu verfassen können Sie diesen direkt in das Code-Feld tippen. Praktischer ist jedoch die Arbeit mit dem separaten Expression-Editor, der sich nach einem Klick auf Expression-Editor öffnen zeigt. Dieser Dialog erleichtert uns zudem die Fehlersuche durch farbige Hervorhebungen von bekannten Schlüsselbegriffen der C.O.F.F.E.E.-Programmiersprache. Zudem erhalten alle Zeilen eine vorangestellte Nummer. Sollten später beim Kompilieren Fehler auftreten, werden diese zumeist mit der entsprechenden Zeilennummer ausgeworfen. Fehler lassen sich so leichter aufspüren und korrigieren. Zudem kann der Expression-Editor frei platziert und skaliert werden, was bei längeren Programmen sehr hilfreich ist, um alles im Blick zu behalten.

Gängige C.O.F.F.E.E.-Befehle und Schlüsselbegriffe

Ich werde mich hier auf einige wenige Erläuterungen beschränken. Die C.O.F.F.E.E.-Programmiersprache ist recht vielseitig verwendbar, auch außerhalb von MoGraph, z. B. in XPresso-Schaltungen oder Cinema 4D-Skripten. Das verfügbare SDK gibt daher eine vollständige Liste aller Befehle wieder. Wir schauen uns hier nur einige wenige davon an, die jedoch sehr häufig benötigt werden.
Der Code wird normalerweise zwischen geschweifte Klammern geschrieben, die unter dem Begriff main(doc, op) zu finden sind. Dies ist die Main-Routine, die uns die Variablen doc und op zur Verfügung stellt. Dabei steht doc für das aktuell geöffnete Dokument, also die aktive Cinema 4D-Szene und op ist identisch mit unserem Effektor. Über diese beiden Begriffe haben wir dadurch Zugriff auf alle Eigenschaften dieser Elemente. Würden wir unseren Code außerhalb der main-Routine platzieren, wären dort diese Variablen nicht bekannt.

Der erste Befehl innerhalb der main-Routine nennt sich var und steht für Variable. Eine Variable ist einfach nur ein Name oder Begriff, den wir uns selbst ausdenken können. So eine Variable kann dann mit einer Zahl, einem Text, einer Farbe oder wie im Fall unseres Listings mit allen Daten des Effektors gefüllt werden. Dieses Abfragen aller Effektor-Daten verbirgt sich hinter dem Begriff GeGetMoData(op). Das op steht bekanntlich für unseren Effektor. Die Zeile füllt somit alle Effektor-Daten in die Variable mit dem Namen md.

Die nächste Zeile überprüft, ob bei diesem Füllen der Variable etwas schief gelaufen ist. Wenn die Variable nämlich leer bleibt, dann machen die folgenden Programmzeilen keinen Sinn mehr. Wir wollen schließlich etwas an dem Effektor auswerten oder verändern. Der Befehl if (!md) überprüft daher, ob die Variable etwas enthält. Sollte diese Überprüfung positiv ausfallen folgt der angehängte Befehl return 1.0; Dieser Befehl beendet im Prinzip die weitere Ausfügung des Codes und gibt die Zahl 1.0 an Cinema 4D bzw. den Effektor zurück. Warum nun ausgerechnet 1.0 muss ich kurz erläutern. Der C.O.F.F.E.E.-Effektor kennt nämlich zwei unterschiedliche Arten von Programmen. Diese Wahl treffen Sie über das Modus-Menü, das Sie direkt über dem Code-Feld finden. Eingestellt ist dort momentan Parameterkontrolle. Dies bedeutet, dass der Code eigentlich nur dafür gut ist, die Eingaben am Effektor auszulesen und ggf. etwas daran zu verändern. Dieser Modus ist praktisch, wenn Sie z. B. die Position, Skalierung, Winkel oder z. B. die Farbe der Klone basierend auf den Vorgaben auf der Parameter-Seite des Effektors verändern möchten. Diese Veränderung basiert auf einer Multiplikation mit den Einstellungen auf der Parameter-Seite. Daher geben wir an dieser Stelle den Wert 1.0 zurück. Werden die Einstellungen mit 1.0 multipliziert, bleibt alles unverändert. Der Code hat dann also keine Wirkung auf die Klone. Der Effektor funktioniert in diesem Fall exakt wie der Simpel-Effektor. Diese if-Programmzeile wird aus reiner Vorsicht benutzt. Normalerweise sollte es keine Probleme beim Abfragen der MoGraph-Daten geben.

Schauen wir uns die beiden bereits besprochenen Befehlszeilen an, so erkennen wir daran, dass normale Befehlszeilen generell mit einem Semikolon abgeschlossen werden müssen. Fehlt dies, bekommen wir später eine Fehlermeldung. Andere Befehlszeilen, wie z. B. main(doc, op) oder später der switch()-Befehl haben kein Semikolon am Ende. Dies sind einige der wenigen Ausnahmen, die Sie einfach lernen müssen. Streng genommen bekommt auch der if()-Befehl kein Semikolon. In diesem Fall gehört das Semikolon zum return-Befehl der dahinter geschrieben wurde. Dieser Befehl kann aber auch in eine separate Zeile geschrieben werden. Zudem müssen Fließkommazahlen mit einem Punkt geschrieben werden. Die Zahl 1,2345 würde also nur im Format 1.2345 richtig erkannt.

Die nächste Programmzeile füllt wieder eine Variable mit einem Inhalt. Diesmal nennt sich die Variable index und erhält mit dem Befehl ->GetCurrentIndex() aus der Variable md die aktuelle Nummer des Klons, der gerade durch den Effektor bearbeitet wird. Diese Indexnummer startet in Ihrer Zählweise immer bei 0. Der erste Klon hat also die Nummer 0, der zweite die Nummer 1 usw. Wenn Sie die folgenden Programmzeilen betrachten, so erscheint dort nirgendwo wieder der Begriff index. Dies bedeutet, dass diese Programmzeile auch problemlos gelöscht werden könnte. Die Information der index-Variable wird nirgendwo verwertet. Wir lassen die Zeile dennoch im Script. Vielleicht fällt uns später noch ein Nutzen dafür ein.

Der switch()-Befehl funktioniert wie ein Schalter. Der Begriff in seiner Klammer gibt an, welche Elemente er dabei berücksichtigen soll. Mit md->GetBlendID() holt er sich praktisch nacheinander alle Parameter des Effektors aus der Variable md. Unter dem switch-Befehl folgt ein eingerückter Bereich, der wieder durch geschweifte Klammern abgegrenzt wird. Darin stehen nun die Befehle, die auf die Auswertung des switch-Befehls zugreifen wollen. Eingeleitet wird dies jeweils durch die Anweisung case, gefolgt von dem Namen des Effektor-Parameters und einem Doppelpunkt am Ende. Wir können dies also verkürzt so lesen: „Schaue Dir nacheinander alle Parameter des Effektors an. Wenn Du dabei an den Position-Werten aus den Parametern des Effektors vorbeikommst, mache etwas“. Alles was also nach der case-Befehlszeile folgt hat mit den Positionen zu tun. Dies liegt an dem Schlüsselwort ID_MG_BASEEFFECTOR_POSITION. Derartige Begriffe müssen Sie sich nicht selbst ausdenken. Ziehen Sie einfach den Namen eines Parameters am Effektor direkt aus dem Attribute-Manager in den Expression-Editor hinein. So steht z. B. ID_MG_BASEEFFECTOR_ROTATION für die drei Winkel-Werte des Effektors.

Was in diesem Fall getan wird ist, die drei Position-Werte zu halbieren. Das Skript gibt an den Effektor mit einem return-Befehl den vector (0.5, 0.5, 0.5) zurück. Dies sind nicht absolute Werte, sondern dieser Vektor wird mit den Originalwerten multipliziert. Es halbiert sich dadurch also die Wirkung von P.X, P.Y und P.Z. Der anschließende break-Befehl beendet die Ausführung der switch-Anweisung und verhindert dadurch, dass die nachfolgenden Programmzeilen zum Zuge kommen.

Sollen andere Parameter als die Position durch den switch()-Befehl gefunden werden, wird der case-Befehl übersprungen und wir landen bei default:. Dies ist der Schlüsselbegriff für alle anderen Fälle, die nicht über case-Befehle abgedeckt werden. In diesen Fällen wird einfach der Wert 1.0 zurückgegeben und anschließend über break wieder der switch()-Befehl beendet. Die Rückgabe von 1.0 lässt die Originalwerte aus dem Dialog des Effektors unverändert. Wir kennen dies bereits aus der Zeile if (!md) return 1.0; Eine geschlossene geschweifte Klammer grenzt den Wirkungsbereich von switch() nach unten ab.

Die nachfolgenden Befehle kommen daher erst dann zum Einsatz, wenn der switch()-Befehl nicht funktioniert hat. Wir haben es daher hier wieder mit einer Sicherheitsmaßnahme zu tun, die in der Regel wohl nicht zum Zuge kommen wird. mit return 1.0; geben wir auch hier wieder die Originalwerte an den Effektor zurück und neutralisieren dadurch die Wirkung des Codes. Wenn Sie nun den Effektor in die Effektoren-Liste des Klon-Objekts ziehen, sollten Sie beobachten können, wie die Würfel gemeinschaftlich etwas nach oben rutschen. Allerdingst nicht um den vollen Betrag, den Sie bei P.Y eingetragen haben, sondern nur um exakt die Hälfte. Dafür war ja die Zeile return vector(0.5, 0.5, 0.5); verantwortlich. Lassen Sie uns einmal schauen, was wir daran noch spannender machen können.

Das Skript erweitern

Die Abbildung 5.76 deutet bereits an, was ich mit Ihnen vorhabe.

Animation in Cinema 4D - Erweiterung des Standard-Codes eine C.O.F.F.E.E.-Effektors

Abbildung 5.76: Erweiterung des Standard-Codes eine C.O.F.F.E.E.-Effektors

Ich möchte, dass ein Winkel aus den Parametern zufällig auf die Klon-Würfel angewendet wird. Die Klone drehen sich dadurch höchstens so stark, wie bei Winkel angegeben. Dies ist mit ein paar Programmzeilen erledigt. Zur Übersicht hier zuerst das komplette Skript mit den ergänzten Zeilen in Fettschritt:
main(doc,op)
{
var md = GeGetMoData(op);
if (!md) return 1.0;
var index = md->GetCurrentIndex();
var Zufall=new(Random);

switch (md->GetBlendID())
{
case ID_MG_BASEEFFECTOR_POSITION:
return vector(0.5,0.5,0.5);
break;
case ID_MG_BASEEFFECTOR_ROTATION:
Zufall->Init(index*8746+93871);
return vector(Zufall->Get01());
break;
default: return 1.0; break;
}
return 1.0;
}
Die Zeile var Zufall=new(Random); definiert eine neue Variable mit dem Namen Zufall.

Diese wird so präpariert, dass Sie zufällige Zahlenreihen erzeugen kann. Dafür steht der Befehl new(Random).

Innerhalb der switch()-Gruppe wird eine neue case-Anweisung ergänzt, die diesmal ID_MG_BASEFFECTOR_ROTATION aufs Korn nimmt. Das sind die drei Winkelwerte, die wir auf der Parameterseite des Effektors eintragen können. Wenn also die Abarbeitung des Codes an diesen Parametern vorbeikommt sorgt Zufall->Init() dafür, dass eine neue Zufallszahl berechnet wird. Da es in Programmen nie einen wirklich echten Zufall gibt, hilft man sich durch Vorgabe eines Startwerts. Diesen kennen Sie bereits u. a aus den Dynamics-Voreinstellungen oder auch den Partikelsystemen. Immer wenn ein neuer Startwert verwendet wird, kommen auch neue Zufallswerte heraus. Damit dieser Zufall jedoch reproduzierbar bleibt und sich z. B. nicht von Bild zu Bild verändert, verbinden wir den Startwert hier einfach mit der Indexnummer der Klone.

Die benutzte Formel multipliziert zuerst die Nummer des gerade berechneten Klons mit einer Zahl und addiert noch etwas hinzu. Letztendlich ist es fast egal, welche Zahlen Sie verwenden. Grundsätzlich macht es jedoch Sinn, die Veränderungen der Startwerte zwischen den Klonen nicht zu klein zu machen. Die Zufallswerte sollen sich ja ruhig stark voneinander unterscheiden können. Der Befehl ->Get01() pickt sich dann aus der Zufallsvariable eine Zahl zwischen Null und Eins heraus. Von dieser Art gibt es noch weitere Befehle. So z. B. ->Get11(), der eine Zahl zwischen -1 und +1 ausgibt. Lesen Sie dazu bei Interesse einfach im C.O.F.F.E.E.-SDK nach. Hier lassen wir diese Zahl einfach per vector-Befehl gleichzeitig auf W.X, W.Y und W.Z als Multiplikator wirken.

Das ist alles schon recht spannend, aber es bleiben auch einige Bereiche verborgen, die in diesem Effektor-Modus nicht ausgelesen oder angesprochen werden können. So lassen sich hier z. B. nicht die Klone selbst ansprechen. Alles läuft weiterhin über die Einstellungen des Effektors. Für diese „volle Kontrolle“ müssen Sie zuerst Modus Volle Kontrolle in den Effektor-Einstellungen wählen.

Auch dies bringt wird einen neuen Programmcode zum Vorschein, der einige der neuen Optionen demonstriert. So können wir nun über ->GetCount() die Anzahl der vorhandenen Klone abfragen oder auch mit ->GetArray(MODATA_MATRIX) die Matrizen der Klone auslesen. Dies bringt uns dann tatsächlich die volle Kontrolle über die Position, Größe und Ausrichtung der Klone, ganz unabhängig von irgendwelchen Einstellungen am Effektor.

Mit ->GetFalloffs() lässt sich sogar die Position jedes Klons im Bereich der Abnahme berücksichtigen und auf einen Multiplikator umrechnen. Diesen Falloff-Multiplikator können Sie dann an beliebiger Stelle z. B. in einer Formel verwenden, um die Beeinflussung der Klone auch von der Abnahme des Effektors abhängig zu machen. Da Sie nun selbst die volle Kontrolle über alles haben, verschwinden in diesem Modus auch alle Einstellungen der Parameter-Rubrik am Effektor. Wie wäre es z. B. wenn wir uns zum Ausgleich selbst einen Dialog über Benutzerdaten bauen und darüber den Effektor steuern? Sollten das böhmische Dörfer für Sie sein, schlagen Sie kurz im Kapitel zu XPresso nach. Wir hatten dort bereits mit Benutzerdaten zu tun.

Über Benutzerdaten können Sie beliebigen Objekten oder auch Tags eigene Dialogelemente anheften und diese z. B. über XPresso auslesen. Dies funktioniert aber auch ohne den Umweg über XPresso direkt in C.O.F.F.E.E. oder z. B. Python. Lassen Sie uns dies ausprobieren. Selektieren Sie den C.O.F.F.E.E.-Effektor und stellen Sie sicher, dass dieser den Modus Volle Kontrolle benutzt. Im Attribute-Manager öffnen Sie dann das Benutzer-Menü und wählen dort den Befehl Benutzerdaten verwalten aus. Legen Sie insgesamt zwei Benutzerdaten vom Datentyp Farbe an. Die eine Farbe nennen Sie Startfarbe und die andere Endfarbe. Die folgende Abbildung 5.77 gibt diesen Arbeitsschritt wieder und zeigt auf der rechten Seite das Resultat. Wir haben nun in der Benutzerdaten-Rubrik des Effektors die Möglichkeit, zwei Farbwerte einzustellen.

Animation in Cinema 4D - Anlegen von Benutzerdaten für den C.O.F.F.E.E.-Effektor

Abbildung 5.77: Anlegen von Benutzerdaten für den C.O.F.F.E.E.-Effektor

Diese Farben bzw. diese Benutzerdaten lassen sich direkt in unserem Code am Effektor auslesen. Dazu müssen Sie nur den Namen der Objektvariablen angeben, an der die Daten hängen. Darauf folgt das Raute-Zeichen und der Schlüsselbegriff ID_USERDATA: mit der angehängten Indexnummer des jeweiligen Datenfelds. Diese Nummern können Sie auch direkt im Verwaltungsfenster der Benutzerdaten ablesen.

Noch viel einfacher wird dies dadurch, dass Sie die Namen der Benutzerdaten auch wieder direkt in den Code am Effektor ziehen können. Sie brauchen dann nur noch die Variable op vor der Raute zu ergänzen und haben dann schon einen Term vor sich, mit dem Sie die Daten abfragen können. Nachfolgend finden Sie wieder das komplette Script vorweg.
main(doc,op)

{
var md = GeGetMoData(op);
if (!md) return false;
var Anzahl = float(md->GetCount());
if (Anzahl <= 1) return false; var Farben = md->GetArray(MODATA_COLOR);
var Startfarbe=op#ID_USERDATA:1;
var Endfarbe=op#ID_USERDATA:2;
var Farbdifferenz=Endfarbe-Startfarbe;
var i;
for (i = 0; i < Anzahl; ++i) { Farben[i]=Startfarbe+(i/(Anzahl-1))*Farbdifferenz; } md->SetArray(MODATA_COLOR, Farben);
return true;
}

In diesem Listing habe ich extra die Zeilen in Fettschritt hervorgehoben, mit den die beiden Benutzerdaten ausgelesen und auf die Variablen Startfarbe und Endfarbe übertragen werden.
Neu ist hier zudem der Befehl ->GetCount(), mit dem wir aus der Variable md, die alle Klon-Daten enthält, die jeweils aktuelle Anzahl an Klonen abfragen können. Dieser Wert ist daher mit der eingestellten Anzahl am Klon-Objekt identisch. Dieser Wert ist natürlich immer ein ganzzahliger Wert, also z. B. 7. Da wir diesen Wert später noch für eine kleine Berechnung benötigen, macht es jedoch Sinn, diesen Wert in das Datenformat Float umzuwandeln. Aus 7 wird dadurch 7.0, was uns z. B. das exakte Dividieren ermöglicht. Ansonsten kann es sein, dass z. B. beim Teilen von 1 durch 7 C.O.F.F.E.E. zum Ergebnis Null kommt, da auch das Ergebnis automatisch wieder als ganzzahliger Wert berechnet wird. Der Nachkommaanteil wird also weggelassen. Bei der Berechnung von 1.0/7.0 kann das nicht passieren. Wir erhalten dann korrekter Weise 0.14286 als Ergebnis. Die Umwandlung eines Integer-Wert (ganzzahliger Wert) zu einem Float-Wert (Fließkommazahl) wird durch den Befehl float erreicht, der in den nachgestellten runden Klammern den gewünschten Wert enthält. Zur Sicherheit überprüfen wir anschließend, ob wirklich Klone vorhanden sind mit dem Befehl if (Anzahl <= 1) return false; Dies lässt sich übersetzen mit: „Wenn die Variable Anzahl kleiner oder gleich dem Wert 1 ist, dann bricht die weitere Ausführung des Codes ab.“ Da wir zwei Farben mischen wollen, macht es keinen Sinn nur einen einzelnen Klon zu benutzen. Es müssen also mindestens zwei Klone vorhanden sein. Über den Befehl ->GetArray() können wir uns aus der Variablen mit den Klondaten bestimmte Informationen holen. Ein Array entspricht dabei immer mehreren Werten auf einmal, die in einer Art durchnummerierten Liste abgerufen werden können. Welche Daten wir gerne hätten, geben wir in der Klammer des ->GetArray()-Befehls an. Hier eine Liste der verfügbaren Namen und eine kurze Beschreibung dazu:

MODATA_MATRIX – Enthält alle Matrizen der Klone
MODATA_COLOR – Enthält die Farben der Klone im Format Vektor (R-, G-, B-Farbanteile)
MODATA_TIME – Die Zeitverschiebung der Klone als Fließkommawert
MODATA_CLONE – Der interne Index der Klone als Fließkommawert zwischen 0.0 und 1.0
MODATA_UVW – Der UVW-Vektor jedes Klons
MODATA_WEIGHT – Die Wichtung jedes Klons als Fließkommawert

Über die Befehlszeile var Farben = md->GetArray(MODATA_COLOR); holen wir uns also alle Farbwerte der Klone und speichern diese Informationen in der Variablen Farben ab. Mit dem Befehl md->SetArray(MODATA_COLOR, Farben); schreiben wir diese Informationen am Ende des Codes wieder zurück und übertragen die Farben damit wieder auf die Klone. Das macht natürlich nur Sinn, wenn wir die Farben in der Variablen verändert haben. Das passiert innerhalb der for-Schleife.

Eine for-Schleife benutzt in der Regel geschweifte Klammern. Alle Befehle, die dazwischen stehen werden so oft wiederholt, wie es durch den Inhalt der runden Klammern hinter dem for-Befehl angegeben wird. Diese Beschreibung besteht immer aus drei Blöcken, die durch Semikolons voneinander getrennt werden. Der erste Block heißt hier i=0. Die Variable i wurde eine Zeile zuvor definiert, aber noch mit keinem Wert versehen. Das passiert nun also hier als Erstes. Die Variable i nennt man in diesem Zusammenhang Zählvariable, da Sie gleich noch mit jedem Durchlauf der Schleife um den Wert 1 erhöht wird. Dafür sorgt nämlich der dritte Block hinter dem for-Befehl, der sich hier ++i nennt. Dieses Kürzel steht für eine Erhöhung der Variablen i um eins nach jedem Durchlauf. Damit die for-Schleife aber weiß, wann sie damit aufhören soll, brauchen wir noch eine Abbruchbedingung. Diese bildet den zweiten Block in der runden Klammer. Mit i < Anzahl wird i nur solange erhöht, bis es den gleichen Wert hat wie unsere Anzahl-Variable. In dem Fall bricht der for-Befehl automatisch ab und der Code springt zu der Befehlszeile nach der geschlossenen geschweiften Klammer nach dem for-Befehl. Da unsere Zählvariable mit dem Wert 0 startet, erhalten wir also z. B. bei einer Klon-Anzahl von 3 die Werte 0, 1 und 2 für die Variable i innerhalb der for-Schleife.

Die eigentliche Magie liegt nun in dieser Zeile, die ein Mal für jeden Klon berechnet wird:

Farben[i]=Startfarbe+(i/(Anzahl-1))*Farbdifferenz;

Die Variable Farben steht bekanntlich für alle Farben der Klone. Durch das Anhängen eckiger Klammern, können wir den bestimmten Farbwert eines Klons auslesen oder auch setzen. Da die Zählvariable i in diesen eckigen Klammern steht, werden nach und nach alle Klone mit neuen Farben belegt. Diese Farbwerte ergeben sich aus der Startfarbe, zu der je nach Nummer des Klons (Zählvariable i) die Differenz zur Endfarbe hinzuaddiert wird. Diese Farbdifferenz haben wir zuvor schon als Variable Farbdifferenz definiert als Subtraktion der Startfarbe von der Endfarbe. Das ist es schon. Die Klone nehmen nun entsprechend Ihrer Reihenfolge automatisch Mischfarben zwischen unseren vorgegebenen Farbwerten an. Ich möchte es bei diesem kleinen Beispiel belassen, um Ihnen eine Idee davon zu geben, wie mächtig die direkte Beeinflussung der Klone sein kann. Natürlich ist dies nicht jedermanns Sache. Das ist auch kein Problem. Wir haben ja noch genügend andere Effektoren zur Auswahl, die ebenfalls viele spannende Manipulationen an den Klonen zur Folge haben können. Die nachfolgende Abbildung 5.78 zeigt noch einmal das Resultat unseres kleinen C.O.F.F.E.E.-Codes.

Animation in Cinema 4D - Individueller Farbverlauf zwischen den Klonen mit einem C.O.F.F.E.E.-Effektor

Abbildung 5.78: Individueller Farbverlauf zwischen den Klonen mit einem C.O.F.F.E.E.-Effektor

Über den Autor

Dieses Tutorial ist ein Auszug aus dem CINEMA 4D-Kompendium zur Animation von Arndt von Koenigsmarck. Das komplette C4D-Kompendium mit über 950 Seiten Know-how als Download (PDF) gibt es hier: CINEMA 4D-Kompendium – Die Animation.

Wir empfehlen:
Maxon BodyPaint 3D-Video-Training

Unsere Empfehlung für dich

Cinema 4D für Einsteiger – für R16/R17/R18

Cinema 4D für Einsteiger – für R16/R17/R18

Überschreite mit unserem neuen und sagenhaften Standardwerk für Cinema 4D die Grenzen der Wahrnehmung. Das Release 16 ist das beste Update, das Maxon je herausgebracht hat!

  • Neue Funktionen von R16, R17 und R18 im Detail erklärt
  • In über 15,5 Stunden Video-Training Cinema 4D von A bis Z ergründen
  • PLUS 850 PDF-Seiten und Arbeitsmaterialien
  • Maximales Kreativtraining: Nachbau des Covermotivs

Zum Training

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Folgende HTML-Elemente sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>