Jump to content
  • Advertisement
Sign in to follow this  

Unreal .T3D Format, Texture U/V

This topic is 4830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can anyone please tell me how to parse the TextureU and TextureV coordinates in the Unreal .T3D map format? Example data: Begin Polygon Item=OUTSIDE Texture=wall_lite1.dds Flags=1074266112 Link=1 Origin +00031.999897,+01216.000000,+00400.000000 Normal +00000.000000,+00000.000000,+00001.000000 TextureU -00002.000000,-00000.000000,+00000.000000 TextureV +00000.000000,-00002.000000,+00000.000000 Vertex +00031.999891,+01280.000000,+00400.000000 Vertex -00032.000107,+01280.000000,+00400.000000 Vertex -00032.000107,+01216.000000,+00400.000000 Vertex +00031.999897,+01216.000000,+00400.000000 End Polygon I know how to parse an entire .t3d file, just cant get the texture u/v to work properly. I have tried 2 methods so far 1 .Verts(UBound(.Verts)).Tu = ((.Verts(UBound(.Verts)).X - VertOrigin.X) * VertTexU.Length) .Verts(UBound(.Verts)).Tv = ((.Verts(UBound(.Verts)).Z - VertOrigin.Z) * VertTexV.Length) Works for vertical surfaces only 2 .Verts(UBound(.Verts)).Tu = (Vector3.Subtract(.Verts(UBound(.Verts)).Position, VertOrigin).Length * VertTexU.Length) .Verts(UBound(.Verts)).Tv = (Vector3.Subtract(.Verts(UBound(.Verts)).Position, VertOrigin).Length * VertTexV.Length) Badly stretched in a random direction I found the equation U = ((vertex - origin) dot textureU + panU)/texW V = ((vertex - origin) dot textureV + panV)/texH And I'm not sure if it works, I tried it as method #2 So, how am I supposed to parse the Texture U/V coordinates?

Share this post

Link to post
Share on other sites
Here is how I do it:

// calucate u,v
// @vert is the current vertex that will be calulated

Vector3 vert_pos( vert.x, vert.y, vert.z );
Vector3 tmp = vert_pos - Origin;

vert.u = tmp * TextureU;
vert.v = tmp * TextureV;

// scale it to 255x255 textures
// you can scale by the size of the tex too. but all my
// textures are 255 anyway
vert.u /= 255;
vert.v /= 255;

Share this post

Link to post
Share on other sites
Your technique works for walls, but not for floors and ceilings...
The code I am using is

VertPos = .Verts(UBound(.Verts)).Position
VertTemp = Vector3.Subtract(VertPos, VertOrigin)
.Verts(UBound(.Verts)).Tu = Vector3.Dot(VertTemp, VertTexU)
.Verts(UBound(.Verts)).Tv = Vector3.Dot(VertTemp, VertTexV)

Also, note, I removed the texture scaling from the code as my .t3d is scaled to 128 of it's original size, so the textures looked blurry if I downsampled them even further.

Share this post

Link to post
Share on other sites

It has been a very long time since I last looked at my t3d loading code and it was fairly hacked [grin]

I basically use a variation of the t3dloader from the humus framework. Check out t3dloader.cpp in his framework here ...get the one that was last updated in january 2005.

origo -= (panU * textureU) / lengthSqr(textureU);
origo -= (panV * textureV) / lengthSqr(textureV);

textureU = fix(textureU);
textureV = fix(textureV);

poly->setTexCoordSystem(fix(origo) + displacement, textureU / (float) sizeU, textureV / (float) sizeV);

and poly->setTexCoordSystem does ...
void Polygon::setTexCoordSystem(const Vertex &Origin, const Vertex &S, const Vertex &T){
origin = Origin;
s = S / (scaleS = length(S));
t = T / (scaleT = length(T));

Then to get a u and v for a vertex the u is the vertex dot producted with (s*scaleS) and likewise the v is the vertex dot producted with t*scaleT

I found this to work with ALMOST all the t3d maps I made with the UnrealEd 3.0 [grin]


Share this post

Link to post
Share on other sites
I'm sorry, I do not fully understand the code. Why is origin used? What does Fix() do? What is displacement? Could I please have pseudo code? Or, if possible, VB.NET code.

Thanks :)

Share this post

Link to post
Share on other sites
Wouldn't be able to help out on the VB.NET side of things as I don't even know vb non-net [lol] ..but I will try to explain that code further.

origo is a Vector3 and is read from lines like "Origin -00128.000000,-00128.000000,-00128.000000" in your .t3d

Fix() swaps the y and z values in the Vector3 and also negates the y.
So -128.0f, -128.0f, -128.0f would become -128.0f, 128.0f, -128.0f (this is used to translate uEd's coordinate system to one where the y-axis is up)

Displacement (I think) is used if you have translated the whole t3d from 0,0,0. Just leave it out for the time being [grin].

It might be a good idea to post some of your code (I think I can read vb ok hehe)

Hope this helps,

Share this post

Link to post
Share on other sites
I didnt use Fix(), instead I load by rotating the entire mesh 90 degrees...

My code to load .t3d meshes(a bit large, and all of it)

Public Function DXLoadT3DMesh(ByVal strT3DContents As String, ByVal strTexDir As String) As udt_UnrealT3DMesh
Dim TempRetMesh As udt_UnrealT3DMesh
ReDim TempRetMesh.Polys(0)

Dim TArr() As String
Dim TLineArr() As String
Dim TPA() As String

Dim VertOrigin As Vector3
Dim VertNormal As Vector3
Dim VertTexU As Vector3
Dim VertTexV As Vector3
Dim VertTemp As Vector3
Dim VertPos As Vector3

Dim MatRot As Matrix
MatRot = Matrix.Identity
MatRot.RotateX(-90 * (3.14 / 180))
Dim VecRot As Vector4
VecRot = New Vector4(0, 0, 0, 0)

Dim I As Long
Dim I2 As Long

For I = 0 To 64
strT3DContents = Replace(strT3DContents, " ", "")

TLineArr = Split(Trim(strT3DContents), vbCrLf)
For I = 0 To UBound(TLineArr)
TArr = Split(Trim(TLineArr(I)))
TArr(0) = Trim(TArr(0))
If TArr(0) = "Origin" Or TArr(0) = "Normal" Or TArr(0) = "TextureU" Or TArr(0) = "TextureV" Or TArr(0) = "Vertex" Then
TPA = Split(TArr(1), ",")
Select Case TArr(0)
Case "Origin"
VertOrigin.X = TPA(0) / 128
VertOrigin.Y = TPA(1) / 128
VertOrigin.Z = TPA(2) / 128
Case "Normal"
VertNormal.X = TPA(0)
VertNormal.Y = TPA(1)
VertNormal.Z = TPA(2)
Case "TextureU"
VertTexU.X = TPA(0)
VertTexU.Y = TPA(1)
VertTexU.Z = TPA(2)
Case "TextureV"
VertTexV.X = TPA(0)
VertTexV.Y = TPA(1)
VertTexV.Z = TPA(2)
Case "Vertex"
With TempRetMesh.Polys(UBound(TempRetMesh.Polys))
.Verts(UBound(.Verts)).X = TPA(0)
.Verts(UBound(.Verts)).Y = TPA(1)
.Verts(UBound(.Verts)).Z = TPA(2)
VecRot.X = .Verts(UBound(.Verts)).X / 128
VecRot.Y = .Verts(UBound(.Verts)).Y / 128
VecRot.Z = .Verts(UBound(.Verts)).Z / 128
.Verts(UBound(.Verts)).X = VecRot.X
.Verts(UBound(.Verts)).Y = VecRot.Y
.Verts(UBound(.Verts)).Z = VecRot.Z
.Verts(UBound(.Verts)).Normal = VertNormal
'.Verts(UBound(.Verts)).Tu = ((.Verts(UBound(.Verts)).X - VertOrigin.X) * VertTexU.Length)
'.Verts(UBound(.Verts)).Tv = ((.Verts(UBound(.Verts)).Z - VertOrigin.Z) * VertTexV.Length)
'.Verts(UBound(.Verts)).Tu = (Vector3.Subtract(.Verts(UBound(.Verts)).Position, VertOrigin).Length * VertTexU.Length)
'.Verts(UBound(.Verts)).Tv = (Vector3.Subtract(.Verts(UBound(.Verts)).Position, VertOrigin).Length * VertTexV.Length)
VertPos = .Verts(UBound(.Verts)).Position
VertTemp = Vector3.Subtract(VertPos, VertOrigin)
ReDim Preserve .Verts(UBound(.Verts) + 1)
End With
End Select
End If
If InStr(TLineArr(I), "Begin Polygon", CompareMethod.Text) > 0 Then
ReDim Preserve TempRetMesh.Polys(UBound(TempRetMesh.Polys) + 1)
ReDim TempRetMesh.Polys(UBound(TempRetMesh.Polys)).Verts(0)
TPA = Split(TLineArr(I), " ")
For I2 = 1 To UBound(TPA)
If Strings.Left(TPA(I2), 5) = "Flags" Then
TempRetMesh.Polys(UBound(TempRetMesh.Polys)).FlagsStr = Strings.Right(TPA(I2), Len(TPA(I2)) - 6)
End If
If Strings.Left(TPA(I2), 7) = "Texture" Then
TempRetMesh.Polys(UBound(TempRetMesh.Polys)).TexName = Strings.Right(TPA(I2), Len(TPA(I2)) - 8)
End If
End If
If InStr(TLineArr(I), "End Polygon", CompareMethod.Text) > 0 Then
With TempRetMesh.Polys(UBound(TempRetMesh.Polys))
ReDim Preserve .Verts(UBound(.Verts) - 1)
End With
VertOrigin = New Vector3(0, 0, 0)
End If
If InStr(TLineArr(I), "End PolyList", CompareMethod.Text) > 0 Then
Exit For
End If

With TempRetMesh
For I = 0 To UBound(.Polys)
DXLoadTexture(.Polys(I).TexName, Color.FromArgb(0, 0, 0, 0).ToArgb, strTexDir)
.Polys(I).TexIndex = DXGetTextureIndex(.Polys(I).TexName)

If (.Polys(I).FlagsStr And 67108864) Or (.Polys(I).FlagsStr And 1) Then
.Polys(I).bCanRender = False
.Polys(I).bCanRender = True
End If
If (.Polys(I).FlagsStr And 2) Or (.Polys(I).FlagsStr And 4) Or (.Polys(I).FlagsStr And 64) Or (.Polys(I).FlagsStr And 134217728) Then
.Polys(I).bCanRender = False
.Polys(I).bCanRenderSecondPass = True
End If
End With

Return TempRetMesh
End Function

[Edited by - CadeF on November 25, 2006 8:29:51 PM]

Share this post

Link to post
Share on other sites
...problem solved, rotate .t3d 90 degress AFTER calculating tex coordinates... oops ;)

If anyone else ever has this problem,
1. Rotate mesh after retrieving tex u/v
2. u/v code is
VertPos = .Verts(UBound(.Verts)).Position
VertTemp = Vector3.Subtract(VertPos, VertOrigin)
.Verts(UBound(.Verts)).Tu = Vector3.Dot(VertTemp, VertTexU)
.Verts(UBound(.Verts)).Tv = Vector3.Dot(VertTemp, VertTexV)

Share this post

Link to post
Share on other sites
Ok ...[lol]

All that code near give me a heart attack straight off so for the sake of the viewers to come you should put it in [ souce ] [ /source] tags (minus the spaces) to keep things neat and tidy.

Does your geometry render fine and the texcoords are the only thing wrong? A screenshot might be nice to narrow things down.

I had a look over my old code and it really was a mess but I tidied it up a bit and hopefully can provide you with some good old pseudo/c++/vb [wink]

First off you should have your origin, normal, TextureU, TextureV, the vertices and possibly even a Pan u and v.

(do this after your geometry has been loaded and translated as messing with the origin vector3 would have nasty effects on the vertices ..or alternatively create a new variable like "origo" ...the original origin)

origin -= ((textureU * panU) / squaredLength(textureU));
origin -= ((textureV * panV) / squaredLength(textureV));

Dim temptU As Vector3
Dim temptV As Vector3

temptU = textureU * rotation; (or fix)
temptV = textureV * rotation;

Dim S As Vector3
Dim T As Vector3

S = temptU / texWidth;
T = temptV / texHeight;

then for the vertices

vertex.Tu = Dot(vertex.Position,S);
vertex.Tv = Dot(vertex.Position,T);

I personally had to do an awful lot of fiddling around with this to get it working and even then it failed on certain faces on spiral stairs. I have no idea what possessed epic to use such a crazy system.

Good luck,

Edit: [flaming] hehe

Share this post

Link to post
Share on other sites
I got it to work, thanks anyway... :)
Everything works fine, now adding in Pan u/v...

Edit: Added in panning
Texture code is
VertPos = .Position
VertTemp = Vector3.Subtract(VertPos, VertOrigin)
.Tu = Vector3.Dot(VertTemp, VertTexU)
.Tv = Vector3.Dot(VertTemp, VertTexV)
---Rotate all vertices -90 degrees on the X axis---
.Tu = (.Tu + .TexPan.X) / (SurfDesc.Width / 128)
.Tv = (.Tv + .TexPan.Y) / (SurfDesc.Height / 128)

TexPan.X=Pan U
TexPan.Y=Pan V

/128 because the entire map is downscaled 128

Each vertex contains the TexPan coordinates, so it can be modified each frame for effects such as moving a texture on the v axis to make it look like a simple waterfall, etc

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!