Eigenes Modelformat mit Animationen
-
Was ich jetzt vergessen habe....welchen Weg der Implementierung bevorzugt ihr?
-
Wenns etwas komplexer sein darf würde ich Keyframing komplett vergessen und zu Skinning wechseln.
Du hast, besonders bei größeren Meshes weniger Probleme mit der zu verarbeitenden Datenmenge und kannst mehrere Animationen mixen, bzw diese dynamisch verändern.Die Idee an sich ist recht einfach:
Du hast auf der einen Seite ein normales Vertexmesh und auf der anderen
die Bones und weight-Daten.
Bones sind nichts weiter als Matrizen die mit der Zeit ihre Position,
Rotation und Skalierung verändern.
Jeder Bone weiß genau welche Vertices er im Mesh verändert und welche nicht.
Ein Vertex kann damit von einem oder mehreren Bones verändert werden.
Um zu wissen wie stark sich der Bone auf das Vertex auswirkt gibts es den weight-Parameter.
Für jeden Bone der auf ein Vertex wirkt mußt du also einen weight-Parameter irgendwo bereit halt.Hier etwas Beispielsource den ich aus nem Tutorial kopiert habe:
(Skinning mit 2 Bones je Vertex)struct Vert { Pos p; int bone0; float weight0; int bone1; float weight1; }; void SkinVerts( Matrix const * bones, Vert const * inVerts, Pos * outVerts, int count ) { for( int ix = 0; ix < count; ++ix ) { Pos p0 = bones[ inVerts[ ix ].bone0 ] * inVerts[ ix ].p; Pos p1 = bones[ inVerts[ ix ].bone1 ] * inVerts[ ix ].p; outVerts[ ix ] = p0 * inVerts[ ix ].weight0 + p1 * inVerts[ ix ].weight1; } }
Das größte Problem dass ich bisher mit Skinning hatte war ein gutes 3D-Programm
zu finden dessen Output einigermaßen verständlich war
-
Hallo,
jo das hört sich wohl etwas besser an...habe neben dem Animationsmachprogramm noch ein Tool mit dem ich meine Models verändern kann...hier weiße ich dann einfach Bones zuAber das mit dem weight-parameter habe ich nicht so ganz verstanden.
Angenommen ich habe einen Tiger. Jetzt habe ich 3 Bones. 2 Bones werden jeweils 2 Füßen zugeordnet und 1 Bone dem Schwanz. Jetzt sage ich im Animationsprogramm dass er innerhalb von 1 Sekunden den Fuß nach vorne heben soll und danach wieder zurück....aber dann muss ich diese Bewegung ja nochmal in die andere Richtung bewegen....aber wie?
Wenn jeder Bone nur Richtung/Skalierung/Rotation speichert...wie kann dann der Fuß wieder zurück? Nochmal ein Bone der den Fuß wieder zurücksetzt und danach benutzt wird? Hm...schön unkompliziert :>Aber das reicht doch um zu wissen wie die Bewegung ablaufen soll...wozu benötige ich hier einen weight-Parameter?
Kevin
-
Surkevin schrieb:
Angenommen ich habe einen Tiger. Jetzt habe ich 3 Bones. 2 Bones werden jeweils 2 Füßen zugeordnet
Hier liegt der Fehler.
-
Hä?
Wieso?
2 Bones für jeweils 2 Pfoten damit er diese versetzt bewegt...sonst hopst der jaEin Mensch würde für jeden Fuß mindestens 1 Bone bekommen....aber wo ist hier ein Fehler?
Kevin
-
Jetzt habe ich 3 Bones. 2 Bones werden jeweils 2 Füßen zugeordnet und 1 Bone dem Schwanz.
2-beiniger Tiger? Das arme Tier!
Ich würde dem Tiger übrigens noch ein paar Bones mehr für Schwanz und
Beine spendieren, sonst kannst du den Schwanz ja nicht "mittendrin" etwas
abknicken.
Generell hat man für jedes Gelenk im echten Körper einen Bone im Mesh.Was die Animation angeht:
Du animierst die Bones, d.h. die speicherst den Positions, Rotations und Skalierungsveränderung mit fortschreitender Zeit.
Die fertig animierten Bones wendest du dann auf das Mesh an.Zum weight-Parameter:
Angenommen ein Vertex wird von 3 Bones animiert, dann hat das Vertex 3 weight-Parameter, für jeden Bone einen.
Alle 3 weights addiert ergeben 1, weils ja eine Interpolation ist.
Btw. eigentlich brauchst du nur n-1 weights speichern wenn das Vertex n Bones benutzt. Schließlich kannst du aus den restlichen weights ja den fehlenden weight-Parameter berechnen.Ansonsten Google mal, zu dem Thema gibts ne Menge Beispielsource.
-
oki danke
-
Hab nochmal eine Frage.
Normalerweise würde ich jetzt alle Polygone, die an ein Bone gebunden sind rendern...eben mit den richtigen Scale/Rotate/Transform-Matrizen...aber wenn noch jeder Vertex eine andere Gewichtigkeit hat...dann muss ja jeder Vertex bzw. jedes Polygon einzeln gerendert werden.....frisst das nicht ein BISSCHEN viel Performance?
Kevin
-
Wie läuft das einzelne Rendern der Vertices eigentlich ab? Angenommen ich weiß, dass sich 50 Vertices in 10 Sekunden um 10 Einheiten auf der X-Achse bewegen, ok...dann kann ich einfach die Koordinaten verändern und dann das Objekt ändern. Aber bei Rotationen wirds schon komplizierter. Muss ich das dann selbst berechnen oder gibts da Hilfen von DX? Denn wenn ich einer Kugel ein Bone zuordne und der sich drehen soll, wäre es am einfachsten vor dem Rendern davon die WORLD-Matrix zu verändern, anstatt von jedem Vertex die Position zu verändern...könnt ihr bitte kurz was zum Rendern sagen?
Danke,
Kevin
-
Jo, klar benutzt du immer die World-Matrix. Wär ja schlimm wenn man jedesmal die Vertexbuffer anfassen müsste!
Ein Freund von mir tut im Moment auch Skinned Meshes mit Bones in seinen Editor einbauen. Such mal in der DX9 Doku nach "Geometry Blending". Man kann nämlich mehrere World Matrizen mitgeben und dann bestimmen bis zu welchen grad dieser auf Geomotrie angewendet werden. Das sind dann diese "Weights". Sind wohl genau dafür gedacht.
dx doku schrieb:
// The flexible vertex format (FVF) descriptor for this vertex would be:
// FVF = D3DFVF_XYZB1 | D3DFVF_NORMAL | D3DFVF_TEX1;struct D3DBLENDVERTEX {
D3DVECTOR v;
FLOAT blend;
D3DVECTOR n;
FLOAT tu, tv;
};The blend weight must appear after the position and RHW data in the flexible vertex format (FVF), and before the vertex normal.
Notice that the preceding vertex format contains only one blending weight value. This is because there will be two world matrices, defined in the D3DTS_WORLDMATRIX(0) and D3DTS_WORLDMATRIX(1) transform states. The system blends each vertex between these two matrices using the single weight value. For three matrices, only two weights are required, and so on.
...
Enabling Geometry Blending:
d3dDevice->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS );
-
Hallo!
So hab mir jetzt mal Geometry Blending und Indexed Vertex Blending durchgelesen. Wo ist eigentlich der Unterschied zwischen den beiden? Bei beiden wird doch DirectX gesagt, welche Matrizen alles auf die Vertices angewendet werden sollen und mit welchem Ausmaß, oder? Nur eben auf eine andere Methode. Indexed Vertex Blending sah für mich leichter aus...hat das Nachteile zu Geometry Blending?Ich habe mal eine Frage wie ich das in meinem Animations"studio" umsetzen soll...
Bisher habe ich nur einen Modelmodificator, indem ich den Models Bones zuweisen kann, eben auf bestimmte Teile des Meshes.Ich stelle mir das ganze jetzt im Animationsstudio so vor:
Das statische Mesh wird geladen. dort sieht man alle Bones die das Mesh betreffen markiert. Jetzt kann man jedem Bone bestimmte Rotations/Skalierungs/Transformationswerte angeben, die er in einer bestimmten Zeit durchführen soll.
Über die Zeit berechne ich dann den weightParameter (wenns länger dauern soll, betrifft die Matrix das Vertex eben nicht so stark).Beim Rendern ... ja beim Rendern des Models...wie soll das dann ablaufen?
Durch die ganzen Bones die die Vertices betreffen weiß ich ja welche Matrizen ich den Vertices im VERTEXSTRUCT zuordnen muss.
Dann berechne ich noch den weightparamter und schreibe den ebenfalls dazu...aber wenn ich das rendere habe ich ja noch keine Animation, oder? Muss ich dann pro Sekunde den weightparameter erhöhen?Mal konkretes Beispiel:
Angenommen ich habe einen Ball...der soll rollen (nice). Jetzt markiere ich im Modelmodificator (yeah) den gesamten Ball und füge ihm ein Bone hinzu. Im Animationsstudio sage ich dem Bone, dass auf ihn eine Rotationsmatrix in X Richtung wirkt. Die Zeit bis zur vollständigen Rotation ist 10 Sekunden.Gut, das soll mein Programm jetzt umsetzen. Weight müsste ja eigentlich 1 sein, da nur eine Matrix drauf einwirkt...ok, sagen wir, sie ist 1. Im vertexstruct aller Ballvertices gebe ich an, dass die im Animationsstudio entworfene Rotationsmatrix verwendet werden soll. Und nach jedem gerenderten Bill frage ich die Zeit ab und schaue wie stark ich die Rotation erhöhen muss, damit er nach 10 Sekunden eine komplette Rotation geschafft hat?
Oder wie macht man sowas am besten?
Kevin