Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

CeDoMain

Alter Hase

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

21

29.09.2014, 19:59

Jap! :) Dafür musst du die Matrix des Elternknochens wissen - um den Ausgangspunkt zu bekommen - dann wird mit der Matrix des aktuellen Bone relativ dazu Transformiert.
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »CeDoMain« (04.10.2014, 16:15)


22

29.09.2014, 21:12

Hmm, fast... Jetzt werden die Knochen an der richtigen Position dargestellt, aber die Größe stimmt noch nicht so ganz. Also die Knochen sind winzig skaliert, statt die richtige Größe zu haben, wodurch man praktisch nur die Verbindungen zwischen den Knochen sieht, die aber auch hauchdünn sind...

Hab das hier hinzugefügt (wird für jeden Keyframe in jeder Animation aufgerufen):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
void FbxLoader::ProcessAnimationMatrices(BoneType* Bone, int AnimationNumber, int FrameNumber, FbxAMatrix ParentTransform){

    Bone->AnimationArray[AnimationNumber].KeyFrameArray[FrameNumber].GlobalTransform = Bone->AnimationArray[AnimationNumber].KeyFrameArray[FrameNumber].GlobalTransform * ParentTransform;

    int i;
    for (i = 0; i < Bone->ChildCount; i++){
        ProcessAnimationMatrices(Bone->Children[i], AnimationNumber, FrameNumber, Bone->AnimationArray[AnimationNumber].KeyFrameArray[FrameNumber].GlobalTransform);
    }
}

Die Funktion setzt außerdem die einzelnen Vektoren für Rotation, Transformation und Skalierung basierend auf der berechneten Matrix, ich habe das hier mal rausgekürzt.

Aber irgendetwas fehlt immer noch. Woran könnte es liegen, dass die Knochen so winzig skaliert sind, die Positionen aber stimmen?

Hier nochmal die geänderten Matrix-Multiplikationen in der Animate-Funktion:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
scaleMatrix = XMMatrixScaling(Animations[0].KeyFrameArray[i][FrameCount].Scale.x, Animations[0].KeyFrameArray[i][FrameCount].Scale.y, Animations[0].KeyFrameArray[i][FrameCount].Scale.z);

rotateMatrixX = XMMatrixRotationX(Animations[0].KeyFrameArray[i][FrameCount].Rotate.x / 180.0f * M_PI);
rotateMatrixY = XMMatrixRotationY(Animations[0].KeyFrameArray[i][FrameCount].Rotate.y / 180.0f * M_PI);
rotateMatrixZ = XMMatrixRotationZ(Animations[0].KeyFrameArray[i][FrameCount].Rotate.z / 180.0f * M_PI);


translationMatrix = XMMatrixTranslation(Animations[0].KeyFrameArray[i][FrameCount].Translate.x, Animations[0].KeyFrameArray[i][FrameCount].Translate.y, Animations[0].KeyFrameArray[i][FrameCount].Translate.z);

finalMatrix = XMMatrixMultiply(rotateMatrixX, rotateMatrixY);
finalMatrix = XMMatrixMultiply(finalMatrix, rotateMatrixZ);
finalMatrix = XMMatrixMultiply(finalMatrix, translationMatrix);
finalMatrix = XMMatrixMultiply(finalMatrix, scaleMatrix);
finalMatrix = XMMatrixMultiply(XMLoadFloat4x4(&BoneArray[i].GlobalBindposeInverse), finalMatrix);
finalMatrix = XMMatrixMultiply(finalMatrix, XMLoadFloat4x4(&BoneArray[i].ToRoot));
finalMatrix = XMMatrixTranspose(finalMatrix);

XMStoreFloat4x4(&(BoneMatrixArray[0].Bonematrix[i]), finalMatrix);


Eigentlich sollte ich jetzt die Hierarchie bedacht haben, aber trotzdem geht das noch nicht so ganz...

----------------------------------------------------------------------------------------------------------------------------

Also gut, jetzt nochmal eine Zusammenfassung:

C-/C++-Quelltext

1
2
3
FbxAMatrix currentTransformOffset = Node->EvaluateGlobalTransform(currTime) * GetGeometryTransformation(Node);
FbxAMatrix GlobalTransform = currCluster->GetLink()->EvaluateGlobalTransform(currTime);
GlobalTransform = currentTransformOffset.Inverse()*GlobalTransform;


Wenn ich das richtig verstanden habe, ist GlobalTransform jetzt also die Matrix, die... ich habe keine Ahnung, was die Matrix macht, aber irgendwie scheint sie den Knochen zu drehen... Auf jeden Fall sind in der GlobalTransform-Matrix alle lokalen Transformationen vom Root bis zum aktuellen Node zusammengefasst, wenn ich die Dokumentation richtig verstehe...

C-/C++-Quelltext

1
2
3
currCluster->GetTransformMatrix(transformMatrix);   // The transformation of the mesh at binding time
currCluster->GetTransformLinkMatrix(transformLinkMatrix);   // The transformation of the cluster(joint) at binding time from joint space to world space
globalBindposeInverseMatrix = transformLinkMatrix.Inverse() * transformMatrix * geometryTransform;


globalBindposeInverse scheint irgendwie die Knochen wieder in den Model Space zu transformieren.

Wenn man beide Matrizen multipliziert, bekommt man Körperteile, die ineinander liegen.

Jetzt bin ich irgendwie nicht wirklich weiter. Ich habe nur herausgefunden, dass das Modell auf den Kopf gestellt wird (also doppelt auf den Kopf gestellt = jetzt richtig herum), wenn ich die Bone-Matrix mit der zugehörigen Default-GlobalMatrix multipliziere (also SkeletonNode->EvaluateGlobalTransform(FBXSDK_TIME_INFINITE)). Dann sind auch nicht mehr die Körperteile ineinander, aber dafür viel zu klein, weil sie auch erneut kleiner skaliert werden...

Ich komme so irgendwie nicht weiter... Ich werde jetzt wohl erstmal für die Prüfungen lernen und dann wohl nochmal das Beispielprogramm ausprobieren... Vielleicht kann ich vom Beispielprogramm lernen, wie ich das Modell rendern muss... Es muss ja irgendwie gehen...
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »Magogan« (29.09.2014, 23:33)


23

04.10.2014, 15:45

AAAAAAAAAAAAAAAAAAAAAAAAARGH!!!

Ich bin jetzt komplett ratlos. Nicht einmal das Beispielprogramm aus dem FBX-SDK kann die Animation richtig abspielen... Was mach ich denn jetzt? Jetzt kann ich nicht mal den Beispielcode angucken und verstehen, wie der die ganzen Informationen aus der Datei liest und verarbeitet, weil der ja auch nicht richtig funktioniert. Wobei... Eigentlich tut er das mit der mitgelieferten FBX-Datei, die Datei, die ich geschickt bekommen habe, ist nur für'n Arsch...

Ich werde jetzt mal mit dem "Modellierer", der mir das zugeschickt hat, reden, der soll das mal fixen und das Modell verdammt nochmal auch triangulieren...

-------------------------------------

Wenn der Code dann fertig ist und funktioniert, werde ich den hier mal irgendwo posten, damit ihr ihn auch nutrzen könnt. Reicht ja schon, wenn ich mich da durchquälen muss.
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

24

04.10.2014, 22:06

Jo, deshalb gibt es ja auch etwas, dass sich "Content-Pipeline" nennt. Im Prinzip ist das die Festlegung, wie man Assets in sein Produkt bekommt. In deinem Fall wird man also testen müssen, was der Exporter kann, welche Features beim Modellieren benutzen darf, wie man sein Modell vor dem Export vorbereiten muss, und was der Loader am Ende alles können muss.
Das macht absolut keinen Spaß, frisst Zeit und man hat die nervigsten Fehler, aber wenn man es einmal raus hat, bekommt man dann halbwegs zuverlässig alles eingebaut. Bis sich irgendeine der Komponenten ändert...
Lieber dumm fragen, als dumm bleiben!

25

14.10.2014, 19:57

Das ist doch jetzt nicht wahr...

Ich quäl mich die ganze Zeit und Visual Studio hat sogar in der Express-Edition ein eingebautes Tool, um FBX-Dateien zu konvertieren, um sie mit dem DirectX Toolkit importieren und darstellen zu können... Ich guck mir das nachher oder morgen mal an...
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Magogan« (14.10.2014, 21:31)


26

26.10.2014, 18:13

So, ich habe jetzt schon mal etwas, das annähernd wie ein Mensch aussieht und sich sogar bewegt, aber einige Dreiecke sind noch falsch:



Die Animation läuft extra so langsam ab, damit ich die einzelnen Keyframes sehe.

Wenn ich die Animation rausnehme, also die Funktion Animate() nicht aufrufe, dann wird das Modell zwar auf dem Kopf, aber immerhin richtig dargestellt. Mit Animation sehe ich diese falschen Dreiecke. Hat jemand eine Idee, woran das liegt?

Hier der Code vom Shader:

HLSL-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
cbuffer MatrixBuffer
{
    matrix globalTransformMatrix;
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
    matrix transformMatrix;
    matrix rotateMatrix;
    float alpha;
    float3 padding;
};

cbuffer BoneMatrixBuffer{
    matrix BoneMatrix[128];
};



struct VertexInputType
{
    float4 position : POSITION;
    float4 normal : NORMAL;
    float2 tex : TEXCOORD;
    float4 boneWeights : BONEWEIGHT;
    uint4 boneIDs : BONEID;
};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float3 normal : NORMAL;
    float4 worldPosition: WORLDPOSITION;
    float2 tex : TEXCOORD0;
    float alpha : ALPHA;
};


////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType AnimatedModelVertexShader(VertexInputType input)
{
    PixelInputType output;
    

    // Change the position vector to be 4 units for proper matrix calculations.
    input.position.w = 1.0f;
    input.normal.w=0.0f;

    float4 positions[4];

    
    positions[0]=mul(input.position,BoneMatrix[input.boneIDs.x]);
    positions[1]=mul(input.position,BoneMatrix[input.boneIDs.y]);
    positions[2]=mul(input.position,BoneMatrix[input.boneIDs.z]);
    positions[3]=mul(input.position,BoneMatrix[input.boneIDs.w]);
    

    if(input.boneWeights.x!=0.0f || input.boneWeights.y!=0.0f || input.boneWeights.z!=0.0f || input.boneWeights.w!=0.0f){
        output.position=input.boneWeights.x*positions[0] + input.boneWeights.y*positions[1] + input.boneWeights.z*positions[2] + input.boneWeights.w*positions[3];
    }
    else{
        output.position=input.position;
    }
    // Calculate the position of the vertex against the world, view, and projection matrices.
    
    output.position = mul(output.position, globalTransformMatrix);
    output.position = mul(output.position, transformMatrix);
    output.worldPosition=output.position;
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);
    
    output.alpha=alpha;

    output.normal=normalize(mul(input.normal,rotateMatrix).xyz);

    output.tex=input.tex;
    
    return output;
}


Ist der soweit korrekt oder habe ich irgendetwas übersehen? Ich bin mir echt nicht sicher, wo das Problem liegen könnte... Einige Vertizes scheinen in der Nähe von (0,0,0) zu liegen, obwohl sie es nicht sollten...
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Magogan« (26.10.2014, 18:23)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

27

26.10.2014, 18:35

Sieht nach falschen bzw. falsch interpretierten Gewichten (Weights) aus.

28

26.10.2014, 19:15

Sieht nach falschen bzw. falsch interpretierten Gewichten (Weights) aus.
Hmm, ja, aber wo kommt das her? Ich nutze inzwischen doch wieder das FBX SDK, aber ich finde das Problem nicht... Egal, ich bin jetzt schon so nahe an einer Lösung wie nie zuvor :D Ich mache jetzt mal was anderes und dann schau ich morgen, ob ich vielleicht den Fehler finde.
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

29

26.10.2014, 19:30

Du könntest für jeden Vertex überprüfen ob die Summe aller Weights gleich 1 ist (Und alle Weights positiv sind). Ist das nicht der Fall, sind deine Daten falsch, also entweder ist das Modell kaputt oder der Importer.

Ist das der Fall könntest du für jede Transformation mal ausgeben, wohin sie transformiert. Was ich nützlich fand war die 3 Basisvektoren (1, 0, 0, 1) (0, 1, 0, 1) und (0, 0, 1, 1) zu transformieren und als Linien darzustellen - dann siehst du das Koordinatensystem, in dass deine Matrizen transformieren. Wenn davon eines am anderen Ende der falschen Dreiecke ist, weißt du, dass die Transformation halt falsch ist.
Lieber dumm fragen, als dumm bleiben!

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

30

26.10.2014, 19:30

Vielleicht sind die Gewichte nicht normalisiert (so dass die Gewichte jedes Vertex sich zu 1 aufaddieren)?
Prüf das mal. Falls nicht, normalisiere sie im Code.

Werbeanzeige