Skip to content

Commit

Permalink
Merge pull request #88 from monkeyman192/feature/handle_materials
Browse files Browse the repository at this point in the history
Feature/handle materials
  • Loading branch information
monkeyman192 authored Oct 11, 2022
2 parents 3c63b8d + bd07322 commit d7510a2
Show file tree
Hide file tree
Showing 39 changed files with 1,606 additions and 813 deletions.
116 changes: 98 additions & 18 deletions BlenderExtensions/ContextMenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

# stdlib imports
from copy import copy
import math

# Local imports
from ..utils.misc import get_root_node, clone_node
from ..ModelExporter.utils import get_children

# Blender imports
import bmesh
Expand All @@ -13,6 +15,9 @@
from mathutils import Matrix


CONE_ROTATION_MAT = Matrix.Rotation(math.radians(90), 4, 'X')


class AddReferenceNode(Operator):
"""Add a new NMS reference node"""
bl_idname = "nmsdk.add_reference_node"
Expand Down Expand Up @@ -72,7 +77,7 @@ def execute(self, context):
class AddBoxCollisionNode(Operator):
"""Add a new NMS box collision node"""
bl_idname = "nmsdk.add_box_collision_node"
bl_label = "Box Collision node"
bl_label = "Box collision node"

@classmethod
def poll(cls, context):
Expand Down Expand Up @@ -103,6 +108,76 @@ def execute(self, context):
return {'FINISHED'}


class AddSphereCollisionNode(Operator):
"""Add a new NMS sphere collision node"""
bl_idname = "nmsdk.add_sphere_collision_node"
bl_label = "Sphere collision node"

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

def execute(self, context):
selected_objs = getattr(context, "selected_objects", None)
if not selected_objs:
self.report({'ERROR_INVALID_INPUT'},
'Please select an object to add a child node to')
return {'FINISHED'}
# Create a new empty reference node.
for obj in selected_objs:
# Create a new sphere for collisions
mesh = bpy.data.meshes.new('sphere')
bm = bmesh.new()
bmesh.ops.create_icosphere(bm, subdivisions=4, radius=0.5)
bm.to_mesh(mesh)
bm.free()
sphere = bpy.data.objects.new('sphere', mesh)
sphere.NMSNode_props.node_types = 'Collision'
sphere.NMSCollision_props.collision_types = 'Sphere'
sphere.matrix_world = Matrix()
sphere.parent = obj
bpy.context.scene.collection.objects.link(sphere)
sphere.rotation_mode = 'QUATERNION'

return {'FINISHED'}


class AddCylinderCollisionNode(Operator):
"""Add a new NMS cylinder collision node"""
bl_idname = "nmsdk.add_cylinder_collision_node"
bl_label = "Cylinder collision node"

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

def execute(self, context):
selected_objs = getattr(context, "selected_objects", None)
if not selected_objs:
self.report({'ERROR_INVALID_INPUT'},
'Please select an object to add a child node to')
return {'FINISHED'}
# Create a new empty reference node.
for obj in selected_objs:
# Create a new cylinder for collisions
mesh = bpy.data.meshes.new('cylinder')
bm = bmesh.new()
bmesh.ops.create_cone(bm, cap_ends=True, cap_tris=True,
radius1=0.5, radius2=0.5, depth=1.0,
segments=20, matrix=CONE_ROTATION_MAT)
bm.to_mesh(mesh)
bm.free()
cylinder = bpy.data.objects.new('cylinder', mesh)
cylinder.NMSNode_props.node_types = 'Collision'
cylinder.NMSCollision_props.collision_types = 'Cylinder'
cylinder.matrix_world = Matrix()
cylinder.parent = obj
bpy.context.scene.collection.objects.link(cylinder)
cylinder.rotation_mode = 'QUATERNION'

return {'FINISHED'}


class CloneNodes(Operator):
"""Clone the selcted node(s)"""
bl_idname = "nmsdk.clone_nodes"
Expand Down Expand Up @@ -183,21 +258,18 @@ def execute(self, context):
obj.matrix_local = trans
del trans
else:
# 1. copy the world matrix of the object.
trans = copy(obj.matrix_world)
# 2. Set the world matrix of the object to be the Identity
# matrix.
obj.matrix_world = Matrix()
# 3. Change the object to be in the coordinate system of the
# root node. Apply this change the object.
obj.data.transform(root_obj.matrix_world)
obj.matrix_world = Matrix()
# 4. Parent the object to the required object.
obj.parent = parent_obj
# 5. Set the objects transform from before.
obj.matrix_local = trans
bpy.ops.object.parent_set()
obj.matrix_world = trans
del trans

# Go over all the children nodes, and if any don't have data
# then they are empty. We'll set these as Locators.
# Also check the obj itself while we are here...
for child in [obj] + get_children(obj):
if not child.data:
child.NMSNode_props.node_types = 'Locator'

return {'FINISHED'}


Expand All @@ -211,8 +283,13 @@ def draw(self, context):
row.operator('nmsdk.add_reference_node')
row = layout.row()
row.operator('nmsdk.add_locator_node')
layout.separator()
row = layout.row()
row.operator('nmsdk.add_box_collision_node')
row = layout.row()
row.operator('nmsdk.add_sphere_collision_node')
row = layout.row()
row.operator('nmsdk.add_cylinder_collision_node')


class NMSDK_MT_clone_NMS_Scenenodes(Menu):
Expand Down Expand Up @@ -248,16 +325,19 @@ def parent_menu_func(self, context):
def add_obj_menu_func(self, context):
""" Add the sub-menu to the context menu. """
layout = self.layout
layout.separator()
row = layout.row()
row.menu("NMSDK_MT_add_NMS_Scenenodes")
row = layout.row()
row.menu("NMSDK_MT_clone_NMS_Scenenodes")
if get_root_node(context.active_object) is not None:
layout.separator()
row = layout.row()
row.menu("NMSDK_MT_add_NMS_Scenenodes")
row = layout.row()
row.menu("NMSDK_MT_clone_NMS_Scenenodes")


classes = (NMSDK_OT_move_to_parent,
AddReferenceNode,
AddBoxCollisionNode,
AddSphereCollisionNode,
AddCylinderCollisionNode,
AddLocatorNode,
NMSDK_MT_add_NMS_Scenenodes,
NMSDK_MT_clone_NMS_Scenenodes,
Expand Down
8 changes: 4 additions & 4 deletions BlenderExtensions/EntityPanels.py
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,9 @@ def register():

@staticmethod
def unregister():
del bpy.types.Object.EntityStructs
# unregister the panels
for cls in reversed(panel_classes):
unregister_class(cls)

# unregister the property classes
for cls in reversed(classes):
Expand All @@ -1444,6 +1446,4 @@ def unregister():
del bpy.types.Object.NMSEntity_props
del bpy.types.Object.NMSPhysics_props

# unregister the panels
for cls in reversed(panel_classes):
register_class(cls)
unregister_class(EntityItem)
47 changes: 42 additions & 5 deletions BlenderExtensions/NMSObjectsPanels.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ class NMSMaterialProperties(bpy.types.PropertyGroup):


class NMSLightProperties(bpy.types.PropertyGroup):
intensity_value: FloatProperty(name="Intensity",
description="Intensity of the light.")
intensity_value: FloatProperty(
name="Intensity",
description="Intensity of the light.",
default=1000, min=0)
FOV_value: FloatProperty(
name="FOV", description="Field of View of the lightsource.",
default=360, min=0, max=360)
Expand All @@ -78,6 +80,12 @@ class NMSAnimationProperties(bpy.types.PropertyGroup):
("Loop", "Loop", "Animation loops continuously")])


class NMSJointProperties(bpy.types.PropertyGroup):
joint_id: IntProperty(
name="Joint Index",
description="The index of the joint, used for animation purposes.")


class NMSLocatorProperties(bpy.types.PropertyGroup):
has_entity: BoolProperty(
name="Requires Entity",
Expand Down Expand Up @@ -331,6 +339,30 @@ def draw(self, context):
row.prop(obj.NMSLocator_props, "has_entity")


class NMSDK_PT_JointPropertyPanel(bpy.types.Panel):
"""Creates a Panel in the scene context of the properties editor"""
bl_label = "NMS Joint Properties"
bl_idname = "NMSDK_PT_JointPropertyPanel"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"

@classmethod
def poll(cls, context):
if (getParentRefScene(context.object) is not None and
context.object.NMSNode_props.node_types == 'Joint'):
return True
else:
return False

def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.label(text="Joint Index: ")
row.label(text=str(obj.NMSJoint_props.joint_id))


class NMSDK_PT_RotationPropertyPanel(bpy.types.Panel):
"""Creates a Panel in the scene context of the properties editor"""
bl_label = "NMS Rotation Properties"
Expand Down Expand Up @@ -439,6 +471,7 @@ def draw(self, context):
NMSReferenceProperties,
NMSLocatorProperties,
NMSLightProperties,
NMSJointProperties,
NMSRotationProperties,
NMSAnimationProperties,
NMSCollisionProperties,
Expand All @@ -451,6 +484,7 @@ def draw(self, context):
NMSDK_PT_LocatorPropertyPanel,
NMSDK_PT_RotationPropertyPanel,
NMSDK_PT_LightPropertyPanel,
NMSDK_PT_JointPropertyPanel,
NMSDK_PT_AnimationPropertyPanel,
NMSDK_PT_CollisionPropertyPanel,
NMSDK_PT_DescriptorPropertyPanel)
Expand All @@ -473,6 +507,8 @@ def register():
type=NMSReferenceProperties)
bpy.types.Object.NMSLocator_props = bpy.props.PointerProperty(
type=NMSLocatorProperties)
bpy.types.Object.NMSJoint_props = bpy.props.PointerProperty(
type=NMSJointProperties)
bpy.types.Object.NMSRotation_props = bpy.props.PointerProperty(
type=NMSRotationProperties)
bpy.types.Object.NMSLight_props = bpy.props.PointerProperty(
Expand All @@ -489,6 +525,9 @@ def register():

@staticmethod
def unregister():
# unregister the panels
for cls_ in reversed(panel_classes):
unregister_class(cls_)
# unregister the property classes
for cls_ in reversed(classes):
unregister_class(cls_)
Expand All @@ -499,10 +538,8 @@ def unregister():
del bpy.types.Object.NMSReference_props
del bpy.types.Object.NMSRotation_props
del bpy.types.Object.NMSLocator_props
del bpy.types.Object.NMSJoint_props
del bpy.types.Object.NMSLight_props
del bpy.types.Object.NMSAnimation_props
del bpy.types.Object.NMSCollision_props
del bpy.types.Object.NMSDescriptor_props
# unregister the panels
for cls_ in reversed(panel_classes):
unregister_class(cls_)
Loading

0 comments on commit d7510a2

Please sign in to comment.