Skip to content

Commit

Permalink
Merge pull request #5 from NMC-TBone/dev
Browse files Browse the repository at this point in the history
Huge update
  • Loading branch information
NMC-TBone authored Jul 5, 2022
2 parents caa2207 + 0b6930d commit 27f46c9
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 57 deletions.
34 changes: 28 additions & 6 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"author": "T-Bone",
"description": "Additionals For Giants I3D Exporter",
"blender": (3, 0, 0),
"version": (2, 0, 5),
"version": (2, 0, 6),
"location": "View3D > UI > GIANTS I3D Exporter > I3D Exporter Additionals",
"warning": "",
"category": "Game Engine"
Expand Down Expand Up @@ -183,6 +183,9 @@ class I3DEA_PG_List(bpy.types.PropertyGroup):
custom_text_box: bpy.props.BoolProperty(name="Custom name", description="If checked you will be able to add custom name for the track pieces", default=False)
custom_text: bpy.props.StringProperty(name="Custom track name", description="Set custom name", default="trackPiece")
add_empty_int: bpy.props.IntProperty(name="Number of empties add: ", description="Place your number", default=1, min=1, max=5)
piece_distance: bpy.props.FloatProperty(name="Track piece distance: ", description="Add track piece distance", default=0.2, precision=10, min=0.0001)
curve_length_disp: bpy.props.FloatProperty(name="curve_length", default=0.0, precision=10)
track_piece_amount: bpy.props.StringProperty(name="Track pieces possible along curve", description="The amount of track links that will fit along the curve")

UI_meshTools: bpy.props.BoolProperty(name="Mesh-Tools", default=False)
UI_track_tools: bpy.props.BoolProperty(name="UV-Tools", default=False)
Expand Down Expand Up @@ -223,9 +226,9 @@ def draw(self, context):
row.operator("i3dea.remove_doubles", text="Clean Meshes")
row.operator("i3dea.mesh_name", text="Set Mesh Name")
row = box.row()
row.operator("i3dea.curve_length", text="Get Curve Length")

row.operator("i3dea.mirror_orientation", text="Set mirror orientation")
if giants_i3d:
row = box.row()
row.operator("i3dea.ignore", text="Add Suffix _ignore")
# "Track-Tools" Box
box = layout.box()
Expand All @@ -250,7 +253,22 @@ def draw(self, context):
box = col.box()
row = box.row()
row.prop(context.scene.i3dea, "add_empty_int", text="")
row.operator("i3dea.add_empty", text="Add Empty")
row.operator("i3dea.add_empty", text="Add Empty", icon='EMPTY_DATA')
box = col.box()
row = box.row()
row.operator("i3dea.curve_length", text="Get Curve Length", icon='MOD_LENGTH')
row.prop(context.scene.i3dea, "curve_length_disp", text="")
box = col.box()
row = box.row()
row.prop(context.scene.i3dea, "piece_distance", text="")
row.operator("i3dea.calculate_amount", text="Calculate Amount")
row = box.row()
row.prop(context.scene.i3dea, "track_piece_amount", text="")
box = col.box()
row = box.row()
row.operator("i3dea.track_on_curve", text="Add track along curve")
row.operator("i3dea.track_on_curve_delete", text="Delete")
# row.prop(context.scene.i3dea, "curve_length_disp", text="")
# ---------------------------------------------------------------
# "Skeleton-Tools" Box
box = layout.box()
Expand All @@ -261,7 +279,7 @@ def draw(self, context):
if context.scene.i3dea.UI_skeletons:
row = box.row()
row.prop(context.scene.i3dea, "skeletons_dropdown", text="")
row.operator("i3dea.skeletons", text="Create")
row.operator("i3dea.skeletons", text="Create", icon='BONE_DATA')
# ---------------------------------------------------------------
# "Material-Tools" box
box = layout.box()
Expand Down Expand Up @@ -351,10 +369,14 @@ def execute(self, context):
I3DEA_OT_addon_disable_stjerne,
track_tools.I3DEA_OT_make_uvset,
track_tools.I3DEA_OT_add_empty,
track_tools.I3DEA_OT_curve_length,
track_tools.I3DEA_OT_calculate_amount,
track_tools.I3DEA_OT_track_on_curve,
track_tools.I3DEA_OT_track_on_curve_delete,
mesh_tools.I3DEA_OT_remove_doubles,
mesh_tools.I3DEA_OT_mesh_name,
mesh_tools.I3DEA_OT_curve_length,
mesh_tools.I3DEA_OT_ignore,
mesh_tools.I3DEA_OT_mirror_orientation,
skeletons.I3DEA_OT_skeletons,
material_tools.I3DEA_OT_mirror_material,
material_tools.I3DEA_OT_remove_duplicate_material,
Expand Down
126 changes: 104 additions & 22 deletions tools/mesh_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

import bmesh
import bpy
from math import radians
import math

from mathutils import Matrix


class I3DEA_OT_remove_doubles(bpy.types.Operator):
Expand All @@ -32,7 +34,7 @@ class I3DEA_OT_remove_doubles(bpy.types.Operator):
def execute(self, context):
smooth_angle = 180
merge_threshold = .0001
smooth_radians = radians(smooth_angle)
smooth_radians = math.radians(smooth_angle)
sel_obj = bpy.context.selected_objects
act_obj = bpy.context.active_object

Expand Down Expand Up @@ -83,26 +85,6 @@ def execute(self, context):
return {'FINISHED'}


class I3DEA_OT_curve_length(bpy.types.Operator):
bl_idname = "i3dea.curve_length"
bl_label = "Get Curve Length"
bl_description = "Measure length of the selected curve"
bl_options = {'REGISTER', 'UNDO'}

@classmethod
def poll(cls, context):
return context.object is not None

def execute(self, context):
if bpy.context.active_object.type == "CURVE":
curve_length = bpy.context.active_object.data.splines[0].calc_length(resolution=1024)
self.report({'INFO'}, bpy.utils.units.to_string(bpy.context.scene.unit_settings.system, 'LENGTH', curve_length))
else:
self.report({'WARNING'}, "Active object is not a curve")
return {'CANCELLED'}
return {'FINISHED'}


class I3DEA_OT_ignore(bpy.types.Operator):
bl_idname = "i3dea.ignore"
bl_label = "Suffix _ignore"
Expand All @@ -114,3 +96,103 @@ def execute(self, context):
for (i, o) in enumerate(objects):
o.name = "{}_ignore".format(o.name)
return {'FINISHED'}


class I3DEA_OT_mirror_orientation(bpy.types.Operator):
bl_idname = "i3dea.mirror_orientation"
bl_label = "Calculate Amount"
bl_description = "Calculates how many track pieces that fit from given track piece length and curve length"
bl_options = {'REGISTER', 'UNDO'}

def execute(self, context):
types = ['MESH', 'CAMERA', 'EMPTY']

selected_list = [obj for obj in bpy.context.selected_objects if obj.type in types]
camera_list = [mesh for mesh in selected_list if mesh.type == 'CAMERA']
mesh_list = [mesh for mesh in selected_list if mesh.type == 'MESH']
empty_list = [mesh for mesh in selected_list if mesh.type == 'EMPTY']

if len(bpy.context.selected_objects) == 3:
for camera, mirror, target in zip(camera_list, mesh_list, empty_list):

mirror_parent = get_parent(mirror.name)
mirror_axis_target = bpy.ops.object.empty_add(type='ARROWS')
mirror_axis_target = bpy.context.active_object
mirror_axis_target.name = "mirror_axis_target"
target_mirror = bpy.ops.object.empty_add(type='ARROWS')
target_mirror = bpy.context.active_object
target_mirror.name = "target_mirror"

camera_pos = camera.location
mirror_pos = mirror.location
target_pos = target.location

v1 = vector_norm([mirror_pos[0]-camera_pos[0], mirror_pos[1]-camera_pos[1], mirror_pos[2]-camera_pos[2]])
v2 = vector_norm([mirror_pos[0]-target_pos[0], mirror_pos[1]-target_pos[1], mirror_pos[2]-target_pos[2]])

v3 = [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]]

bpy.data.objects[target_mirror.name].location = (mirror_pos[0], mirror_pos[1], mirror_pos[2])
bpy.data.objects[mirror_axis_target.name].location = (mirror_pos[0] - v3[0], mirror_pos[1] - v3[1], mirror_pos[2] - v3[2])

mirror_axis_target.constraints.new('TRACK_TO')
mirror_axis_target.constraints['Track To'].track_axis = 'TRACK_NEGATIVE_Z'
mirror_axis_target.constraints['Track To'].up_axis = 'UP_Y'
mirror_axis_target.constraints['Track To'].target = target_mirror
# mirror_axis_target.rotation_euler = (0, math.radians(-180), 0)
bpy.context.view_layer.objects.active = mirror_axis_target
mirror_axis_target.select_set(True)
bpy.ops.constraint.apply(constraint="Track To", owner='OBJECT')
mirror_axis_target.select_set(False)

matrix_world = mirror.matrix_world.copy()
mirror.parent = mirror_axis_target
mirror.matrix_parent_inverse = Matrix.Identity(4)
mirror.matrix_world = matrix_world
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = mirror
mirror.select_set(True)
bpy.ops.object.transform_apply(location=False, rotation=True, scale=False)
mirror.select_set(False)

if mirror_parent is not None:
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = mirror_parent
mirror_parent.select_set(True)
mirror.select_set(True)
bpy.ops.object.parent_set(type='OBJECT', keep_transform=True)
mirror_parent.select_set(False)
else:
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = mirror
mirror.select_set(True)
bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM')
mirror.select_set(False)

bpy.data.objects.remove(mirror_axis_target)
bpy.data.objects.remove(target_mirror)
#
else:
self.report({'ERROR'}, "You need to select 3 objects (camera, mirror, empty)")
return {'FINISHED'}


def get_parent(node):
parents = bpy.data.objects[node].parent
parent = None
if parents is None:
pass
else:
parent = parents
return parent


def vector_length(v):
return math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])


def vector_norm(v):
length = vector_length(v)
if length == 0:
length = 1
return [v[0]/length, v[1]/length, v[2]/length]
Loading

0 comments on commit 27f46c9

Please sign in to comment.