Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculate texture scale and offset for brushes. #80

Merged
merged 4 commits into from
Jun 4, 2022

Conversation

Nieblist
Copy link

@Nieblist Nieblist commented Apr 23, 2022

  • Map face vertex UVs to VMF UV axes with shift and scale for brushes. Shift and scale are based on texture image size, so use a material with only one image texture to get the right mapping.
  • Add an "Allow Skewed Textures" option in the map export panel to keep non-perpendicular UV axes intact, otherwise it will modify the V axis to make them orthogonal.

@Nieblist
Copy link
Author

Nieblist commented Apr 23, 2022

Hi reviewers. Please note that the Allow Skewed Textures option is not working for all cases right now. It seems to be flipping some textures or otherwise having some issues.

I decided to keep it because it can be useful (I'm using it for my map), but if you prefer I can remove it for now and create another PR in case I find a way to fix it.

@Nieblist Nieblist mentioned this pull request Apr 23, 2022
@Nieblist
Copy link
Author

Nieblist commented May 7, 2022

Hi @bonjorno7, please let me know if there is any reason not to merge this. It has been pretty useful for my map. Do you prefer me to remove the "Allow Skewed Textures" option and keep only orthogonal mappings?

(This is for issue #79)

@bonjorno7
Copy link
Owner

bonjorno7 commented May 7, 2022

Hi @Nieblist sorry for the wait, I've been busy lazy.
I'll post a review in a bit.

Copy link
Owner

@bonjorno7 bonjorno7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you've done an amazing job, and I only have a few small nitpicks and questions.

Comment on lines 58 to 62
settings = Settings(
brush_objects, disp_objects,
geometry_scale, texture_scale, lightmap_scale,
allow_skewed_textures, align_to_grid
)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of a nitpick, but I'd prefer a trailing comma here, so each item gets its own line.

@@ -31,7 +31,7 @@ class SOURCEOPS_MapProps(bpy.types.PropertyGroup):
texture_scale: bpy.props.FloatProperty(
name='Texture Scale',
description='Size of one texel in hammer units',
default=0.5,
default=1.0,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems slightly out of scope, but I'm fine with it.

addon/types/map_export/brush.py Outdated Show resolved Hide resolved
if face_material and face_material.use_nodes:
for mat_node in face_material.node_tree.nodes:
if mat_node.type == 'TEX_IMAGE':
texture_side_length = mat_node.image.size[0]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why the width and not the height, but you don't have to explain if you don't feel like it.

Comment on lines 52 to 54
break

return texture_side_length
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it makes sense to do an early return instead of a break, then return the default value at the bottom; saves you 2 lines of code (44 & 52).

@@ -52,7 +66,7 @@ def calc_uv_axes(settings: typing.Any, bm: bmesh.types.BMesh, face: bmesh.types.
for loop in face.loops[0:3]:
uv = loop[uv_layer].uv
u_vals.append(uv[0])
v_vals.append(uv[1])
v_vals.append(1 - uv[1])
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this have been necessary with my old code too, or is it required because of something in your math?
Just curious; doesn't really matter.

Comment on lines 79 to 126
uv_side_a = mathutils.Vector((u2 - u1, v2 - v1))
uv_side_b = mathutils.Vector((u3 - u1, v3 - v1))
tangent = (p2 - p1) * uv_side_b.y - (p3 - p1) * uv_side_a.y
side_v = (p3 - p1) * uv_side_a.x - (p2 - p1) * uv_side_b.x
determinant = uv_side_a.x * uv_side_b.y - uv_side_b.x * uv_side_a.y

epsilon = 0.0000001

# TODO: Calculate scale and offset
if abs(determinant) > epsilon:
tangent = tangent / determinant
side_v = side_v / determinant

if not settings.allow_skewed_textures:
bitangent = mathutils.Quaternion(face.normal, math.radians(90)) @ tangent
bitangent.normalize()
bitangent = bitangent * side_v.dot(bitangent)
else:
bitangent = side_v

# Scale
texture_side_length = get_texture_size(obj, face)
if texture_side_length > 0:
u_scale = tangent.magnitude / texture_side_length
v_scale = bitangent.magnitude / texture_side_length
else:
u_scale = 1
v_scale = 1

# Offset
tangent_space_transform = mathutils.Matrix((
[tangent.x, bitangent.x, face.normal.x],
[tangent.y, bitangent.y, face.normal.y],
[tangent.z, bitangent.z, face.normal.z]
))
if texture_side_length > 0 and abs(tangent_space_transform.determinant()) > epsilon:
tangent_space_transform.invert()
t1 = tangent_space_transform @ p1
u_offset = (1 - (t1.x - u1) * texture_side_length) % texture_side_length
v_offset = (1 - (t1.y - v1) * texture_side_length) % texture_side_length
else:
u_offset = 0
v_offset = 0

tangent.normalize()
bitangent.normalize()

u_axis = f'[{tangent[0]} {tangent[1]} {tangent[2]} 0] {settings.texture_scale}'
v_axis = f'[{bitangent[0]} {bitangent[1]} {bitangent[2]} 0] {settings.texture_scale}'
u_axis = f'[{tangent[0]} {tangent[1]} {tangent[2]} {u_offset}] {u_scale * settings.texture_scale}'
v_axis = f'[{bitangent[0]} {bitangent[1]} {bitangent[2]} {v_offset}] {v_scale * settings.texture_scale}'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even going to pretend to understand any of this fancy math stuff, but good job!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right yeah this isn't an issue so I'll resolve it.

Comment on lines 11 to 15
def __init__(
self, brush_objects, disp_objects,
geometry_scale, texture_scale, lightmap_scale,
allow_skewed_textures, align_to_grid
):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like a trailing comma here as well.

@bonjorno7
Copy link
Owner

Oh and I'm fine with keeping the skewed textures option, even if it isn't perfect (the rest of the addon isn't either).

@Nieblist
Copy link
Author

Nieblist commented May 10, 2022

Cool! I'll keep it as it is for now then and come back at it if I have time. Please let me know if you find anything else.

@Nieblist
Copy link
Author

Nieblist commented May 23, 2022

Hi @bonjorno7! Sorry to bug you, I'm just pinging you again in case we can merge this :)

@bonjorno7
Copy link
Owner

Oh sorry I forgot, will take a look and maybe merge tomorrow.

@Nieblist
Copy link
Author

Nice, ok!

@bonjorno7
Copy link
Owner

Sorry for being so unavailable, I should be better.
Everything looks good now, and seems to work fine from my testing, so I'll merge.
Thank you for your contribution!

@bonjorno7 bonjorno7 merged commit 1bd507a into bonjorno7:main Jun 4, 2022
bonjorno7 added a commit that referenced this pull request Jun 4, 2022
For adding [brush UV export](#80).
@Nieblist
Copy link
Author

Happy to help, thank you for the plugin!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants