DGL
https://delphigl.com/forum/

Doom 3 - MD5 Format (Version 10)
https://delphigl.com/forum/viewtopic.php?f=19&t=3505
Seite 1 von 2

Autor:  Stucuk [ So Nov 21, 2004 22:57 ]
Betreff des Beitrags:  Doom 3 - MD5 Format (Version 10)

iv struck a problem when trying to render MD5 files. If the models have vertex's that have more than one weight then the model isn't rendered correctly.

Code:
  1. Procedure BuildMD5Mesh(MD5 : TMD5File; Mesh : TMD5Mesh);
  2. var
  3. V,W : Integer;
  4. Pos,Joint : TVector3f;
  5. TM : TMatrix;
  6. Weighting : Single;
  7. begin
  8.  
  9. // Build The Vertex's
  10. For V := 0 to Mesh.Header.NumVerts-1 do
  11. begin
  12. Mesh.Verts[v].Position := SetVector(0,0,0);
  13. Mesh.Verts[v].Colour := TColorToTVector3f(RGB(Random(256),Random(256),Random(256)));
  14.  
  15. For W := 0 to Mesh.Verts[v].WeightCount -1 do
  16. begin
  17. Joint := MD5.Joints[Mesh.Weights[Mesh.Verts[v].WeightId + W].BoneId].Position;
  18. TM := MD5.Joints[Mesh.Weights[Mesh.Verts[v].WeightId + W].BoneId].Matrix;
  19. Weighting := Mesh.Weights[Mesh.Verts[v].WeightId + W].Factor;
  20.  
  21. Pos := Mesh.Weights[Mesh.Verts[v].WeightId + W].Position;
  22. Pos := GetPosWithMatrix(Pos,TM);
  23. Pos := AddVector(Pos,Joint);
  24. Pos := ScaleVector(Pos,Weighting);
  25.  
  26. Mesh.Verts[v].Position := AddVector(Mesh.Verts[v].Position,Pos);
  27.  
  28. end;
  29. end;
  30.  
  31.  
  32. end;
  33.  


Source Attached.

Dateianhänge:
Dateikommentar: Player model - Loads of bones.
model_tex.jpg
model_tex.jpg [ 59.45 KiB | 9805-mal betrachtet ]
Dateikommentar: Light Fixture - 1 bone ( i think)
Light_model_tex.jpg
Light_model_tex.jpg [ 64.25 KiB | 9805-mal betrachtet ]
UnitMD5.zip [3.54 KiB]
391-mal heruntergeladen

Autor:  Stucuk [ Mo Nov 22, 2004 09:13 ]
Betreff des Beitrags: 

Code:
  1.  
  2. Term := 1.0 - (Q.X*Q.X) - (Q.Y*Q.Y) - (Q.Z*Q.Z);
  3. if (term < 0) then
  4.    Q.W := 0
  5. else
  6.    Q.W := - sqrt(term);
  7.  


Modifyed to

Code:
  1.  
  2. Term := 1.0 - (Q.X*Q.X) - (Q.Y*Q.Y) - (Q.Z*Q.Z);
  3. if (term < 0) then
  4.    Q.W := 0
  5. else
  6.    Q.W := {-} sqrt(term);
  7.  


Improves it. Still screwed with some models. Light fixture is the right way around now.

If im correct the probem lies in the quaternion. How its turned into a Matrix, how its applyed to the weight position..... somethign along them lines....... (Look at the storage picture in the screwed image and the one where the quaternion has been ignored, note: the quaternion is needed for alot of models)

Below is some models that seems to work fine (you will note they proberly have few vertex's that have more than one weight) and some models that are screwed(wasn't hard to find good examples of these).

Dateianhänge:
Dateikommentar: Models that look fine
working_model.jpg
working_model.jpg [ 141.14 KiB | 9796-mal betrachtet ]
Dateikommentar: Models that are screwed.
notworking_model.jpg [133.7 KiB]
180-mal heruntergeladen
Dateikommentar: quaternion ignored for this test
hmm.jpg
hmm.jpg [ 57.28 KiB | 9796-mal betrachtet ]

Autor:  Stucuk [ Di Nov 23, 2004 10:16 ]
Betreff des Beitrags: 

Anyone used quaternion's b4?

Autor:  Sascha Willems [ Di Nov 23, 2004 12:37 ]
Betreff des Beitrags: 

I have used quaternions, and I also wrote a simple MD5-Loader. But the loader I wrote was for that leaked E3-Alpha of D3, and the fileformat back then was different than the current one, so I can't help you much on the file format. But this is how I convert a quaternion to a matrix :
Code:
  1. function QuaternionToMatrix(pQ : TQuaternion) : TMatrix;
  2. begin
  3. with pQ do
  4.  begin
  5.  Result[0,0] := 1 - 2*y*y - 2*z*z;
  6.  Result[1,0] := 2*x*y - 2*w*z;
  7.  Result[2,0] := 2*x*z + 2*w*y;
  8.  Result[3,0] := 0;
  9.  
  10.  Result[0,1] := 2*x*y + 2*w*z;
  11.  Result[1,1] := 1 - 2*x*x - 2*z*z;
  12.  Result[2,1] := 2*y*z - 2*w*x;
  13.  Result[3,1] := 0;
  14.  
  15.  Result[0,2] := 2*x*z - 2*w*y;
  16.  Result[1,2] := 2*y*z + 2*w*x;
  17.  Result[2,2] := 1 - 2*x*x - 2*y*y;
  18.  Result[3,2] := 0;
  19.  
  20.  Result[0,3] := 0;
  21.  Result[1,3] := 0;
  22.  Result[2,3] := 0;
  23.  Result[3,3] := 1;
  24.  end;
  25. end;

Maybe it's of help to you.

Autor:  Stucuk [ Fr Nov 26, 2004 16:05 ]
Betreff des Beitrags: 

Thanks, worked like a charm :). On a side note, how hard would it to be to generate all the data nessisary to be able to bumpmap the models (when u only have the vertex information to go on).

Dateianhänge:
Dateikommentar: Now works :)
workingnow_models.jpg [158.44 KiB]
144-mal heruntergeladen

Autor:  Sascha Willems [ Fr Nov 26, 2004 17:31 ]
Betreff des Beitrags: 

It's not to hard to get the basic things needed for bumpmapping : You need the S-Tangent and the T-Tangent for doing bumpmapping, both are derived from the texture coordinates. Take a look at this tutorial, where all those things are described and at the end you'll also have code on how to calculate those values for more complex objects.

Autor:  Stucuk [ Sa Nov 27, 2004 00:31 ]
Betreff des Beitrags: 

The problem is how to work out sTangent and tTangent(Since there 3d coords not 2d) when its not a torus but random vertex's which could form any shape. Once you can work out them values it doesn't seem that hard to do.

Autor:  Magellan [ Sa Nov 27, 2004 11:02 ]
Betreff des Beitrags: 

Try out this page: http://www.terathon.com/index.html
There you'll find an algorithm to calculate the tangent space vectors of an arbitrary mesh, which works very well.

Autor:  Stucuk [ Sa Nov 27, 2004 20:33 ]
Betreff des Beitrags: 

All i can see on that site is images and a form to buy a licence of there engine...

Autor:  Sascha Willems [ Sa Nov 27, 2004 20:53 ]
Betreff des Beitrags: 

http://www.terathon.com/code/tangent.html. But note that this code will not always give you proper tangents. Finding tangents for complex meshes (if you want to do it right, but most of the times users won't notice small errors) is kind of hard and there are many ways to do it, I tried at least three ways and they didn't give proper results under some circumstances, but most of the times they worked (I also used the linked version).

Autor:  Stucuk [ So Nov 28, 2004 17:03 ]
Betreff des Beitrags: 

Code:
  1. Vector3D sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
  2.                 (t2 * z1 - t1 * z2) * r);
  3.         Vector3D tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
  4.                 (s1 * z2 - s2 * z1) * r);


Shouldn't sdir be tdir and visa versa?

Code:
  1. long count = vertexCount;
  2.     for (long a = 0; a < count; a++)
  3.     {
  4.         const Vector3D& n = normal[a];
  5.         const Vector3D& t = tan1[a];
  6.        
  7.         // Gram-Schmidt orthogonalize
  8.         tangent[a] = (t - n * (n * t)).Normalize();
  9.        
  10.         // Calculate handedness
  11.         tangent[a].w = (n % t * tan2[a] < 0.0F) ? -1.0F : 1.0F;
  12.     }


Don't u need a sTangent and a tTangent? rather than a 4d vertex?

Autor:  LarsMiddendorf [ So Nov 28, 2004 17:10 ]
Betreff des Beitrags: 

Instead of storing two tangent vectors you can store only one and the normal vector. The second tangent vector can be calculated in the vertex program, because it is orthogonal to the first tangent and the normal. The only problem is, that there are the two cases where the ttangent is orthogonal two the stangent and normal: ttangent = stangent x normal and ttangent = normal x stangent=- stangent x normal. So you have to store a fourth value.

Autor:  Stucuk [ So Nov 28, 2004 21:45 ]
Betreff des Beitrags: 

Is Tan1 and Tan2, sTangent and tTangent? If so the following should be correct:

Code:
  1.  
  2. Procedure BuildMD5Tangents(var Mesh : TMD5Mesh);
  3. var
  4. x,v1,v2,v3  : Integer;
  5. x1,x2,y1,y2,z1,z2,
  6. s1,s2,t1,t2,
  7. r : Single;
  8. sdir,tdir : TVector3f;
  9. begin
  10.  
  11. for x := 0 to Mesh.Header.NumTris-1 do
  12. begin
  13. v1 := Mesh.Tris[x].V1;
  14. v2 := Mesh.Tris[x].V2;
  15. v3 := Mesh.Tris[x].V3;
  16.  
  17. x1 := Mesh.Verts[v2].Position.X - Mesh.Verts[v1].Position.X;
  18. x2 := Mesh.Verts[v3].Position.X - Mesh.Verts[v1].Position.X;
  19. y1 := Mesh.Verts[v2].Position.Y - Mesh.Verts[v1].Position.Y;
  20. y2 := Mesh.Verts[v3].Position.Y - Mesh.Verts[v1].Position.Y;
  21. z1 := Mesh.Verts[v2].Position.Z - Mesh.Verts[v1].Position.Z;
  22. z2 := Mesh.Verts[v3].Position.Z - Mesh.Verts[v1].Position.Z;
  23.  
  24. s1 := Mesh.Verts[v2].s - Mesh.Verts[v1].s;
  25. s2 := Mesh.Verts[v3].s - Mesh.Verts[v1].s;
  26. t1 := Mesh.Verts[v2].t - Mesh.Verts[v1].t;
  27. t2 := Mesh.Verts[v3].t - Mesh.Verts[v1].t;
  28.  
  29. r := 1 / (s1 * t2 - s2 * t1);
  30.  
  31. sdir := SetVector((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,(s1 * z2 - s2 * z1) * r);
  32. tdir := SetVector((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,(t2 * z1 - t1 * z2) * r);
  33.  
  34. Mesh.Verts[v1].sTangent := AddVector(Mesh.Verts[v1].sTangent,sdir);
  35. Mesh.Verts[v1].tTangent := AddVector(Mesh.Verts[v1].tTangent,tdir);
  36. Mesh.Verts[v2].sTangent := AddVector(Mesh.Verts[v2].sTangent,sdir);
  37. Mesh.Verts[v2].tTangent := AddVector(Mesh.Verts[v2].tTangent,tdir);
  38. Mesh.Verts[v3].sTangent := AddVector(Mesh.Verts[v3].sTangent,sdir);
  39. Mesh.Verts[v3].tTangent := AddVector(Mesh.Verts[v3].tTangent,tdir);
  40. end;
  41.        
  42. end;
  43.  


EDIT:

Render Code(Modifyed Bumpmap v2 demo code):
Code:
  1.  
  2. If Shader.BumpMapID > 0 then
  3. begin
  4.  
  5. glBindProgramARB(GL_VERTEX_PROGRAM_ARB, BumpVP);
  6. glEnable(GL_VERTEX_PROGRAM_ARB);
  7. glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, 0,0,0,0);
  8. glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 1, 0,10,10,0);
  9.  
  10. glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, BumpFP);
  11. glEnable(GL_FRAGMENT_PROGRAM_ARB);
  12. glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 1/50,1/50,1/50,1/50); // invRadius
  13. glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 0,0,0,0);    // ambient
  14.  
  15. // Bind base map to texture unit 0
  16. glActiveTexture(GL_TEXTURE0);
  17. glBindTexture(GL_TEXTURE_2D, Shader.DiffuseMapID);
  18. glEnable(GL_TEXTURE_2D);
  19. // Bind normal map to texture unit 1
  20. glActiveTexture(GL_TEXTURE1);
  21. glBindTexture(GL_TEXTURE_2D, Shader.BumpMapID);
  22. glEnable(GL_TEXTURE_2D);
  23. // Bind specular map to texture unit 2
  24. glActiveTexture(GL_TEXTURE2);
  25.  
  26. glBindTexture(GL_TEXTURE_2D, Shader.SpecularMapID);
  27. glEnable(GL_TEXTURE_2D);
  28.  
  29. glClientActiveTexture(GL_TEXTURE0);
  30.  
  31.       glDisable(GL_CULL_FACE);
  32.       glBegin(GL_TRIANGLES);
  33.       For v := 0 to Vertex_No-1 do
  34.       begin
  35.       glActiveTexture(GL_TEXTURE0);
  36.       glTexCoord2f(Vertexs[v].TextureCoord.X,Vertexs[v].TextureCoord.Y);
  37.       glActiveTexture(GL_TEXTURE1);
  38.       SpaceLight := GetSpaceLight(SetVector(0,0,0),sTan[v],tTan[v],Vertexs[v].Normal);
  39.       glTexCoord3f(SpaceLight.X,SpaceLight.Y,SpaceLight.Z);
  40.       glVertex3f(Vertexs[v].Position.X,Vertexs[v].Position.Y,Vertexs[v].Position.Z);
  41.       end;
  42.       glend;
  43.  
  44. // Disable textures
  45. glActiveTexture(GL_TEXTURE1);
  46. glDisable(GL_TEXTURE_2D);
  47. glActiveTexture(GL_TEXTURE2);
  48. glDisable(GL_TEXTURE_2D);
  49. glActiveTexture(GL_TEXTURE0);
  50. //glDisable(GL_TEXTURE_2D);
  51.  
  52. glDisable(GL_VERTEX_PROGRAM_ARB);
  53. glDisable(GL_FRAGMENT_PROGRAM_ARB);
  54. exit;
  55. end;
  56.  


Code:
  1.  
  2. Function GetSpaceLight(Light,sTan,tTan,Normal : TVector3f) : TVector3f;
  3. begin
  4. Result.X := DotProduct(sTan,light);
  5. Result.Y := DotProduct(tTan,light);
  6. Result.Z := DotProduct(Normal,light);
  7. end;
  8.  


Models are just black....

Autor:  Magellan [ So Nov 28, 2004 22:29 ]
Betreff des Beitrags: 

Zitat:
The code generates a four-component tangent in which the handedness of the local coordinate system is stored as ±1 in the w-coordinate. The bitangent vector B is then given by B = (N × T)Tw.

Autor:  Stucuk [ Mo Nov 29, 2004 00:16 ]
Betreff des Beitrags: 

Clueless. 4D tangent doesn't help, since i know nothing on vertex/fragment programs.

Seite 1 von 2 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/