- Home /
Question by
Phobos001 · Apr 17, 2018 at 04:53 PM ·
meshprogramminguv
Quake Texture Map Generation in Unity - What am I doing wrong?
Hello! I am working on integrating TrenchBroom .map files in Unity, but I have a problem with generating the correct UVs for each brush. Basically after making the geometry, I go over each Brush, and then each BrushPlane and do this:
Vector3 normal = Vector3.Cross(plane.p3 - plane.p1, plane.p2 - plane.p1);
if (normal == Vector3.zero) continue;
Quaternion rotation = Quaternion.Inverse(Quaternion.LookRotation(normal));
Vector2 matScale = (new Vector2(plane.material.mainTexture.width, plane.material.mainTexture.height));
matScale.x *= plane.uvScale.x;
matScale.y *= plane.uvScale.y;
matScale *= QMC.QUAKE_TO_UNITY_SCALE;
Vector2 offset = plane.uvOffset; // not actually applying the offset yet.
Vector3 upAxis, rightAxis; // Uses ported code from QBSP but doesn't seem to do anything
upAxis = QMC.TextureAxisFromPlane(normal, false);
rightAxis = QMC.TextureAxisFromPlane(normal, true);
uvs = new Vector2[verticies.Length];
for (int i = 0; i < uvs.Length; i++) {
Vector3 v = (rotation*verticies[i]); // Makes vertex flat against the XY axis
float s = (Vector3.Dot(v, rightAxis)) / matScale.x;
float t = (Vector3.Dot(v, upAxis)) / matScale.y;
Vector2 uv = new Vector2(s, t);
uv = Quaternion.Euler(0, 0, plane.uvAngle) * uv; // Is supposed to rotate the uv but also doesn't do anything
uvs[i] = uv;
}
TextureAxisFromPlane is stolen from QBSP's source:
// Stolen from QBSP
private static readonly Vector3[] QBSP_BASE_AXIS = new Vector3[] {
Vector3.forward, Vector3.right, -Vector3.up, // Floor
-Vector3.forward, Vector3.right, -Vector3.up, // Ceiling
Vector3.forward, Vector3.up, -Vector3.forward, // West Wall
-Vector3.right, Vector3.up, -Vector3.forward, // East Wall
Vector3.up, Vector3.right, -Vector3.forward, // South Wall
-Vector3.up, Vector3.right, -Vector3.forward // North Wall
};
public static Vector3 TextureAxisFromPlane(Vector3 normal, bool isRightAxis)
{
int bestaxis = 0;
float dot, best = 0;
best = 0;
bestaxis = 0;
for (int i = 0; i < 6; i++)
{
dot = Vector3.Dot (normal, QBSP_BASE_AXIS[i*3]);
if (dot > best)
{
best = dot;
bestaxis = i;
}
}
Vector3 final;
if (isRightAxis)
final = QuakeToUnityVectorNoScaling(QBSP_BASE_AXIS[bestaxis*3+1]);
else
final = QuakeToUnityVectorNoScaling(QBSP_BASE_AXIS[bestaxis*3+2]);
return final;
}
It works on most surfaces, but on ones that are parallel with the Y axis are streched like its using a box projection:
Can someone that knows about this stuff more than I do help me? I've been wracking my brain trying to figure this out. Thank you again for your time! :)
help-me-2.jpg
(449.8 kB)
Comment