Go Back   Steam Users' Forums > Steam Tool Discussions > Source Coding

Reply
 
Thread Tools Display Modes
Old 02-06-2012, 08:08 PM   #1
shawnolson
 
 
 
Join Date: Nov 2009
Reputation: 41
Posts: 191
VMF Brush Side U/V axis, translation and scale

I'm winding down on the development of a VMF Exporter for 3ds Max. I've gotten almost everything nailed down. But I've reached a wall with one element: brush side uaxis and vaxis.

What I'm unable to figure out is how to take a face in Max and get the following bit of code for the VMF:

Code:
"uaxis" "[1 0 0 0] 0.25"
"vaxis" "[0 1 0 0] 0.25"
I've read the docs and picked the brains of most of the smart people I know. Others have been as confused as me... But I just can't figure it out. Here is the relevant explanation in the VMF docs:

Quote:
U/V Axis
The u-axis and v-axis are the texture specific axes. They hold their own designations as they are independent of the true x-axis and y-axis, but it's easier to think of them in terms of x and y. The u-axis represents the x-axis and the v-axis represents the y-axis. These two code lines work together to define how the texture is displayed upon a face.

"uaxis" "[1 0 0 0] 0.25""vaxis" "[0 1 0 0] 0.25"
  • u/v axis ([x y z dec] dec)
The x, y, and z are decimal values representing that axis. The following value is the translation and the last decimal is the total scaling. The values for the x y z set represent the amount of the texture to be shown in that axis. They modify how much of the texture is shown within the normal space the texture would occupy on the face. A value of one means one repetition in the normal space, a value of two would mean two repetitions in the normal space. The key is that this only applies to one axis of the texture and is applied relative to true x, y, and z axes. That means that it is possible to set the texture to appear along an axis the plane doesn't exist in. With a flat plane in the x-axis and the y-axis definitions are only needed for those axes as any definition in the z-axis has no surface to appear on. The code sample shows how this would be generated by Hammer. The texture's x-axis (the u-axis) is displayed in the real x-axis and the texture's y-axis (v-axis) is displayed in the real y-axis. Which of the x, y, and z axes are showing the axes of the texture depends entirely upon the faces orientation. Negative values will flip textures and Hammer will generate errors about textures shown in a plane the surface does not occupy. The second to last value is the simple translation of the textures origin within that axis; this value is actually a decimal though Hammer will round it up when displaying Hammer will still save the correct decimal value. The last decimal is the overall scaling of the entire axis including what is defined in the x y z group.
I can always get the Texture vertices in a face... but I can't figure out how to translate the vertex positions into the uaxis, vaxis or their translation and scale.

Any help would be appreciated.
shawnolson is offline  
Reply With Quote
Old 02-06-2012, 09:49 PM   #2
episoder
 
Join Date: Aug 2011
Reputation: 112
Posts: 1,814
ugh... I'm not good at vector/matrix math - I like generic - but this mostly planes on cubes. it's usually alot more about 2D/3D spaces and their matrix representations. especially on slant surfaces.

anyway, this just a wild theoretical explanation as help.

Code:
"plane" "(-128 -448 -384) (-128 -64 -384) (128 -64 -384)"

"uaxis" "[1 0 0 0] 0.25"
"vaxis" "[0 -1 0 0] 0.25"

a z-normal axis plane
dunno why the uv matrix is upside down but I guess this a leftover from the inverse matrix GL portation.

uaxis should be the vector in that direction >> normalize(p2-p1)
vaxis should be the vector in that direction >> normalize(p2-p0)

the scale and translation values can be obtained from a calculation on generated texcoords you get from max I guess.

I hope it helps. it might not work for all on the first try. but I guess it's a tip in the direction you have to search for.

Last edited by episoder: 02-06-2012 at 09:53 PM.
episoder is offline   Reply With Quote
Old 02-07-2012, 09:10 AM   #3
zombie@computer
 
Join Date: Aug 2008
Reputation: 416
Posts: 908
PM'ed
zombie@computer is offline   Reply With Quote
Old 02-07-2012, 11:05 AM   #4
shawnolson
 
 
 
Join Date: Nov 2009
Reputation: 41
Posts: 191
Quote:
Originally Posted by episoder View Post
uaxis should be the vector in that direction >> normalize(p2-p1)
vaxis should be the vector in that direction >> normalize(p2-p0)
@episoder... that is exactly the answer! Thank you.

For some reason the introduction of matrix math and vectors turns my brain to mush. The irony is that I essentially solved a very similar dilemma when working out ways to map displacements. The only real difference is that this is looking for two unit vectors instead of one... and this is dealing with uvw coordinates; my brain didn't want to reuse any of the same kind of thinking because I'm 1) untrained and 2) not naturally mathematically inclined.

Again, thank you I was half expecting for this thread to go unanswered for weeks (or forever) but now I can probably get this out tonight or tomorrow.

Last edited by shawnolson: 02-07-2012 at 11:05 AM. Reason: typo
shawnolson is offline   Reply With Quote
Old 02-07-2012, 10:29 PM   #5
shawnolson
 
 
 
Join Date: Nov 2009
Reputation: 41
Posts: 191
Actually... it looks like my excitement was premature. The formula above assumes that the UVW is aligned to the Plane (side of a brush). But that is not always true. In Hammer... it is not so easy to manipulate that... but in Max it is very easy to control the uvw.

Since my goal is to translate exactly what you see in Max world brushes into the game, I cannot use that formula. For example, the X and Y axis of a face might be [1 0 0] and [0 1 0] when the U/V axis might be something different.

Unless, of course, I'm simply missing some basic concept (which I don't find hard to believe ).

Still, I appreciate the input. Hopefully I can make a breakthrough as the VMF exporter I've got will export entire scenes as brushes/models/entities/displacements/textures and the sky--all in one environment... which has been my goal for several years!

Last edited by shawnolson: 02-07-2012 at 10:30 PM. Reason: typo
shawnolson is offline   Reply With Quote
Old 02-08-2012, 09:15 AM   #6
shawnolson
 
 
 
Join Date: Nov 2009
Reputation: 41
Posts: 191
I am even further behind than I thought in solving this Not to make duplicate content everywhere, here is the link to the extended description of the expanding dilemma: http://forums.cgsociety.org/showthre...f=98&t=1034253

I emailed Valve directly via the SDK address on their contact page. My guess is that it will go unanswered as I sent an email last year that also went unanswered.
shawnolson is offline   Reply With Quote
Old 02-08-2012, 10:38 AM   #7
zombie@computer
 
Join Date: Aug 2008
Reputation: 416
Posts: 908
hmm. I think this code is what you are after:

Code:
//transforms uaxis and vaxis into per-point texture coordinates
for each point on the face
	float uax = dot(uaxisVector, point) / texturescaleUaxis + textureOffsetUaxis
	float vax = dot(vaxisVector, point) / texturescaleVaxis + textureOffsetVaxis

	point.XCoord = uax / texture.Width
	point.YCoord = vax / texture.Height
next point

*texturescaleUaxis is Uaxisscale
*uaxisVector is Vector(Uaxis[0], Uaxis[1], Uaxis[2])
*textureOffsetUaxis is Uaxis[3];
Haven't tested it, still, hope it helps. My vector maths is abysmal. I guess you *simply* need to do the inverse of this
zombie@computer is offline   Reply With Quote
Old 02-08-2012, 02:53 PM   #8
episoder
 
Join Date: Aug 2011
Reputation: 112
Posts: 1,814
ugh... sorry but...

Quote:
it might not work for all on the first try. but I guess it's a tip in the direction you have to search for.
I told you. so... I'm still fine. and I would never post a full solution. life is for learning. but... trust me... in that case here I don't even have one complete thing working for that. just some generic reverse and infer based on what I can visualize.

and here's the other one.

Quote:
the scale and translation values can be obtained from a calculation on generated texcoords you get from max I guess.
same goes for rotations. but they hard to get right. this where you have to be smart. if you don't have the max uvw projection matrix to rotate the uv-axis vectors you might wanna take the already projected uvs and create some sort of mapping from there. or reverse calculate them to get some sort of a matrix to transform the uv-axises.

notes on error: reversing some vmfs: the uv axis seems to just mirror the mapping on 2 opposing brush faces. this might be different looking or go wrong with max. also consider the fact that explicit texture mapping brushes are not working as you might want it to be. this' where your textures usually be squary and sheared and nothing else.
episoder is offline   Reply With Quote
Old 02-08-2012, 03:13 PM   #9
shawnolson
 
 
 
Join Date: Nov 2009
Reputation: 41
Posts: 191
Quote:
Originally Posted by episoder View Post
ugh... sorry but... I told you. so... I'm still fine. and I would never post a full solution. life is for learning.
Yes, you did Sorry if the consequent reply seemed less than gratefull. Far from it, I have been very grateful with all help anyone has given me.

And yes, life is for learning. My frustration is simply in my own lack of understanding and intuition regarding any 3D math. With most things I am a very quick learner; this is a situation that my brain isn't wired to solve naturally.

With all of the help I've gotten so far, I have gotten "closer" to the answer (I think ... ). My optimisim about solving it in hours/days is less, though... more like weeks at this rate. I will release a version probably tomorrow that is no longer spitting out textures perpendicular to the faces but still not always rotated correctly and not yet scaled/translated correctly.

As much as I'd like to have solved this on my own, though, I am not averse to help and solutions. Sometimes being given an answer isn't always a bad thing, just like sometimes it's good to stew in the frustration of trying to figure things out! Being as it is that I've been actively releasing all these tools for everyone freely, a little free help in return isn't too much to ask, aye?

I want to use this thing--not spend forever trying to figure out how to make it

Again, thank you all.
shawnolson is offline   Reply With Quote
Old 02-23-2012, 08:12 AM   #10
shawnolson
 
 
 
Join Date: Nov 2009
Reputation: 41
Posts: 191
So I've been struggling on this for weeks now. All along I've known that the problem is that my fundamental trigonometry skills/knowledge are exceptionally poor. Nonetheless, solving this is important to me so I'm keeping at it... and slowly getting a better feeling for the math behind the scenes.

But I'm still not there. I keep coming back to Zombie's code above and the variables are starting to "feel" more meaningful ... but still I cannot figure it out. How to reverse engineer that and use the data I have available is not coming easily.

Essentially, I am iterating over each face of a brush... getting three vertexes that I use to define the plane.

Quote:
V1 = [0, 0, 0] --Vertex 1 (located at world origin)
V2 = [0, 0, 16] --Vertex 2 (located 16 units above world origin)
V3 = [16, 16, 32] --Vertex 3 located out in space

I then get the corresponding texture coordinates:

Quote:
TV1 [0,0,0]
TV2 [1,0,0]
TV3 [1,1,0]
The TV coordinates might look like that a lot in many faces that have not had their UVWs modified, but it could just as easily be something like:

Quote:
TV1 [0.0310643,-0.167913,0.212782]
TV2 [0.777293,0.270012,-0.286585]
TV3 [0.413342,1.16791,-0.0430335]
These kinds of values could be from moving a UVW Map's gizmo or simply Unwrap UVW.

So far, the best I've done is to use the face verts to create a uaxis and vaxis:

Quote:
uaxis = normalize (v2-v1)
vaxis = normalize (v3-v2)
But the problem here is that that formula is simply wrong. The axis can't be based off the mesh face because of two things: 1) Except with cubes, vaxis is very likely not going to be perpendicular to uaxis (but we can get a perpendicular axis by using the cross () function with the uaxis and the faceNormal); 2) these vertexes don't actually contain any information on the axis of the textures--as that information is all in the texture coordinates.

However, using the texture coordinates is also not correct. In fact, using just the mesh verts to create the u/v axis looks better (even though incorrect).

So the dilemma is simply this: how to take V1,V2,V3 and TV1,TV2,TV3 and convert them into the uaxis/vaxis in the VMF. Somehow the mesh verts and uv verts have to be factored in together. Once there, I will factor in any extra offsetting of a face's individual texture (since the textures have have even more offsetting beyond this... but right now I can't even get past the basic UVW stage).

Ideas?
shawnolson is offline   Reply With Quote
Old 02-23-2012, 09:00 AM   #11
episoder
 
Join Date: Aug 2011
Reputation: 112
Posts: 1,814
have you already tried tangent space computation?

like this:

uaxis = cross(normal,up);
vaxis = cross(normal,uaxis);

it may come off distorted or upside down or shifted and the orientation is based on the surface again but it's legit.

edit:
for the reversing from uvw coords you'd also just calculate the direction of u and v per face and use a few bits of that projection for the translation and scale. that should do best for not the cubic but rotated uv orientation.

Last edited by episoder: 02-23-2012 at 09:43 AM.
episoder is offline   Reply With Quote
Old 02-23-2012, 09:40 AM   #12
shawnolson
 
 
 
Join Date: Nov 2009
Reputation: 41
Posts: 191
Quote:
Originally Posted by episoder View Post
have you already tried tangent space computation?

like this:

uaxis = cross(normal,up);
vaxis = cross(normal,uaxis);

it may come off distorted or upside down or shifted and the orientation is based on the surface again but it's legit.
I've tried this ... but if this is where to start... I don't know where to go from there... as pumping the results of this directly into the VMF fails to have accurate results. For example, when using this for standard cubes with cube UVW maps... the sides seem to be oriented correctly but the tops and bottoms result in u/v axis that are both [0 0 0] .. which is obviously not correct.

Maybe it is because the upVector needs to be defined differently? I have simply made it [0,0,1] but the problem is that the normal on up/down faces in this example are parallel with that vector.

Last edited by shawnolson: 02-23-2012 at 09:40 AM. Reason: typo
shawnolson is offline   Reply With Quote
Old 02-29-2012, 08:35 AM   #13
shawnolson
 
 
 
Join Date: Nov 2009
Reputation: 41
Posts: 191
Well I need to share the good news. The problem is solved. I'll be loading the updated version of WW tools with proper VMF UVW support in the next week.

I was personally unable to solve it. Luckily a good friend (Andrew Penry) took up the challenge... and he figured out in a week what I couldn't figure out in about two months!

I had half-expected the formula to be simple--and that I would yell DOH! when I saw it. But, as it turns out, the logic and formula is a little complex... so I'm not going to explain it here. But I will ask Andrew to write up a little overview of it for adding to the VMF docs on the wiki or on the WW docs site so that anyone interested in this problem can get an explanation.

For me, now that it's solved... I'm running onto the next set of WW functions and finishing some levels.
shawnolson is offline   Reply With Quote
Reply

Go Back   Steam Users' Forums > Steam Tool Discussions > Source Coding


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT -7. The time now is 01:23 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site Content Copyright Valve Corporation 1998-2014, All Rights Reserved.