Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
StjerneIdioten committed Nov 26, 2021
2 parents 5514a9e + a639e0e commit 5c01d0d
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 84 deletions.
4 changes: 2 additions & 2 deletions addon/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion addon/.idea/addon.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions addon/.idea/dictionaries/StjerneIdioten.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions addon/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions addon/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion addon/i3dio/__init__.py
Expand Up @@ -32,7 +32,7 @@
"description": "Exports blender projects into GIANTS I3D format for use in Giants Engine based games such as "
"Farming Simulator",
"version": (0, 0, 0), # Always (0, 0, 0) since versioning is controlled by the CI
"blender": (2, 92, 0),
"blender": (2, 93, 0),
"location": "File > Import-Export",
"warning": "First Unofficial Alpha Version",
"support": "COMMUNITY",
Expand Down
17 changes: 17 additions & 0 deletions addon/i3dio/node_classes/material.py
Expand Up @@ -49,6 +49,7 @@ def _resolve_with_nodes(self):
self._diffuse_from_nodes(main_node)
self._normal_from_nodes(main_node)
self._specular_from_nodes(main_node)
self._emissive_from_nodes(main_node)
else:
self.logger.warning(f"Uses nodes but Principled BSDF node is not found!")

Expand Down Expand Up @@ -110,6 +111,22 @@ def _diffuse_from_nodes(self, node):
# Write the diffuse colors
self._write_diffuse(diffuse)

def _emissive_from_nodes(self, node):
emission_socket = node.inputs['Emission']
if emission_socket.is_linked:
try:
emissive_path = emission_socket.links[0].from_node.image.filepath
except (AttributeError, IndexError, KeyError):
pass
else:
if emissive_path is not None:
self.logger.info("Has Emissivemap")
file_id = self.i3d.add_file_image(emissive_path)
self.xml_elements['Emissive'] = xml_i3d.SubElement(self.element, 'Emissivemap')
self._write_attribute('fileId', file_id, 'Emissive')
return
self.logger.debug("Has no Emissivemap")

def _resolve_without_nodes(self):
material = self.blender_material
self._write_diffuse(material.diffuse_color)
Expand Down
44 changes: 0 additions & 44 deletions addon/i3dio/node_classes/node.py
Expand Up @@ -242,50 +242,6 @@ def _transform_for_conversion(self) -> mathutils.Matrix:

def populate_xml_element(self):
light = self.blender_object.data
# self.logger.info(f"Is a light of type {light.type!r}")
# falloff_type = None
# if light.type == 'POINT':
# light_type = 'point'
# falloff_type = light.falloff_type
# elif light.type == 'SUN':
# light_type = 'directional'
# elif light.type == 'SPOT':
# light_type = 'spot'
# falloff_type = light.falloff_type
# cone_angle = math.degrees(light.spot_size)
# self._write_attribute('coneAngle', cone_angle)
# self.logger.info(f"Has a cone angle of {cone_angle}")
# # Blender spot 0.0 -> 1.0, GE spot 0.0 -> 5.0
# drop_off = 5.0 * light.spot_blend
# self._write_attribute('dropOff', drop_off)
# self.logger.info(f"Has a drop off of {drop_off}")
# elif light.type == 'AREA':
# light_type = 'point'
# self.logger.warning(f"Is an AREA light, which is not supported and defaults to point light")
#
# self._write_attribute('type', light_type)
#
# color = "{0:f} {1:f} {2:f}".format(*light.color)
# self._write_attribute('color', color)
# self.logger.info(f"Has color {color}")
#
# self._write_attribute('range', light.cutoff_distance)
# self.logger.info(f"Has range {light.cutoff_distance}")
#
# self._write_attribute('castShadowMap', light.use_shadow)
# self.logger.info('casts shadows' if light.use_shadow else 'does not cast shadows')
#
# if falloff_type is not None:
# if falloff_type == 'CONSTANT':
# falloff_type = 0
# self.logger.info(f"Has decay rate of type {'CONSTANT'} which is '0' in i3d")
# elif falloff_type == 'INVERSE_LINEAR':
# falloff_type = 1
# self.logger.info(f"Has decay rate of type {'INVERSE_LINEAR'} which is '1' in i3d")
# elif falloff_type == 'INVERSE_SQUARE':
# falloff_type = 2
# self.logger.info(f"has decay rate of type {'INVERSE_SQUARE'} which is '2' in i3d")
# self._write_attribute('decayRate', falloff_type)

super().populate_xml_element()

Expand Down
8 changes: 4 additions & 4 deletions addon/i3dio/ui/helper_functions.py
Expand Up @@ -63,16 +63,16 @@ def i3d_property(layout, attributes, attribute: str, obj):
row.alignment = 'RIGHT'
# Display the name of the property
lab = row.column()
lab.label(text=attributes.__annotations__[attribute][1]['name'])
lab.label(text=attributes.i3d_map[attribute]['name'])
attrib_row = row.row()
if getattr(obj, attributes.i3d_map[attribute]['tracking']['member_path'], False):
if getattr(obj, attributes.i3d_map[attribute]['tracking']['member_path'], None) is not None:
attrib_row.prop(obj, attributes.i3d_map[attribute]['tracking']['member_path'], text='')
mapping = attributes.i3d_map[attribute]['tracking'].get('mapping')
if mapping is not None:
attrib_row.label(text=f"'{mapping[getattr(obj, attributes.i3d_map[attribute]['tracking']['member_path'])]}' "
f"in GE")

attrib_row.label(text=f"Follows '{attributes.__annotations__[attribute+'_tracking'][1]['name']}'")
attrib_row.label(text=f"Follows '{attributes.i3d_map[attribute]['tracking']['member_path']}")
else:
lab.enabled = False

Expand All @@ -82,7 +82,7 @@ def i3d_property(layout, attributes, attribute: str, obj):
# If we are not tracking a blender builtin
else:
row.prop(attributes, attribute) # Just display the i3d attribute then
if getattr(obj, attributes.i3d_map[attribute]['tracking']['member_path'], False):
if getattr(obj, attributes.i3d_map[attribute]['tracking']['member_path'], None) is not None:
icon = 'UNLOCKED' # Show a unlocked icon to indicate this can be locked to a blender builtin
row.prop(attributes, attribute + '_tracking', icon=icon, icon_only=True, emboss=False)

Expand Down
38 changes: 27 additions & 11 deletions addon/i3dio/ui/object.py
Expand Up @@ -13,6 +13,9 @@
CollectionProperty,
)

from .helper_functions import i3d_property
from ..xml_i3d import i3d_max

classes = []


Expand All @@ -24,10 +27,12 @@ def register(cls):
@register
class I3DNodeObjectAttributes(bpy.types.PropertyGroup):
i3d_map = {
'visibility': {'name': 'visibility', 'default': True},
'visibility': {'name': 'visibility', 'default': True, 'tracking': {'member_path': 'hide_render',
'mapping': {True: False,
False: True}}},
'clip_distance': {'name': 'clipDistance', 'default': 1000000.0},
'min_clip_distance': {'name': 'minClipDistance', 'default': 0.0},
'object_mask': {'name': 'objectMask', 'default': 0},
'object_mask': {'name': 'objectMask', 'default': '0', 'type': 'HEX'},
'rigid_body_type': {'default': 'none'},
'collision': {'name': 'collision', 'default': True},
'collision_mask': {'name': 'collisionMask', 'default': 'ff', 'type': 'HEX'},
Expand All @@ -37,30 +42,41 @@ class I3DNodeObjectAttributes(bpy.types.PropertyGroup):

visibility: BoolProperty(
name="Visibility",
description="Visibility flag inside of Giants Engine, decoupled from blender visibility",
description="Visibility",
default=i3d_map['visibility']['default']
)

visibility_tracking: BoolProperty(
name="Render Visibility",
description="Can be found at: Object Properties -> Visibility -> Renders "
"(can also be toggled through outliner)",
default=True
)

clip_distance: FloatProperty(
name="Clip Distance",
description="Anything above this distance to the camera, wont be rendered",
default=i3d_map['clip_distance']['default'],
min=0.0
min=0.0,
max=i3d_max,
soft_min=0,
soft_max=65535.0
)

min_clip_distance: FloatProperty(
name="Min Clip Distance",
description="Anything below this distance to the camera, wont be rendered",
default=i3d_map['min_clip_distance']['default'],
min=0.0
min=0.0,
max=i3d_max,
soft_min=0,
soft_max=65535.0
)

object_mask: IntProperty(
object_mask: StringProperty(
name="Object Mask",
description="Used for determining if the object interacts with certain rendering effects",
default=i3d_map['object_mask']['default'],
min=0,
max=2147483647
)

rigid_body_type: EnumProperty(
Expand Down Expand Up @@ -118,9 +134,9 @@ def draw(self, context):
layout.use_property_decorate = False
obj = bpy.context.active_object

layout.prop(obj.i3d_attributes, 'visibility')
layout.prop(obj.i3d_attributes, 'clip_distance')
layout.prop(obj.i3d_attributes, 'min_clip_distance')
i3d_property(layout, obj.i3d_attributes, 'visibility', obj)
i3d_property(layout, obj.i3d_attributes, 'clip_distance', obj)
i3d_property(layout, obj.i3d_attributes, 'min_clip_distance', obj)


@register
Expand Down
48 changes: 27 additions & 21 deletions addon/i3dio/ui/shader_picker.py
Expand Up @@ -97,36 +97,42 @@ def execute(self, context):


def parameter_element_as_dict(parameter):
parameter_dictionary = {'name': parameter.attrib['name'],
'type': parameter.attrib['type']}
parameter_list = []

if parameter_dictionary['type'] == 'float':
if parameter.attrib['type'] == 'float':
type_length = 1
elif parameter_dictionary['type'] == 'float2':
elif parameter.attrib['type'] == 'float2':
type_length = 2
elif parameter_dictionary['type'] == 'float3':
elif parameter.attrib['type'] == 'float3':
type_length = 3
elif parameter_dictionary['type'] == 'float4':
elif parameter.attrib['type'] == 'float4':
type_length = 4
else:
print(f"Shader Parameter type is unknown!")

default_value = parameter.attrib.get('defaultValue')

if default_value is not None:
default_value = default_value.split()
# For some reason, Giants shaders has to specify their default values in terms of float4... Where the extra
# parts compared with what the actual type length is, aren't in any way relevant.
if len(default_value) > type_length:
default_value = default_value[:type_length-1]
def parse_default(default):
default_parsed = []
if default is not None:
default_parsed = default.split()
# For some reason, Giants shaders has to specify their default values in terms of float4... Where the extra
# parts compared with what the actual type length is, aren't in any way relevant.
if len(default_parsed) > type_length:
default_parsed = default_parsed[:type_length-1]

default_parsed += ['0']*(type_length-len(default_parsed))
return default_parsed

if 'arraySize' in parameter.attrib:
for child in parameter:
parameter_list.append({'name': f"{parameter.attrib['name']}{child.attrib['index']}",
'type': parameter.attrib['type'],
'default_value': parse_default(child.text)})
else:
default_value = []

default_value += ['0']*(type_length-len(default_value))

parameter_dictionary['default_value'] = default_value
parameter_list.append({'name': parameter.attrib['name'],
'type': parameter.attrib['type'],
'default_value': parse_default(parameter.attrib.get('defaultValue'))})

return parameter_dictionary
return parameter_list


def texture_element_as_dict(texture):
Expand Down Expand Up @@ -165,7 +171,7 @@ def execute(self, context):
for parameter in parameters:
group_name = parameter.attrib.get('group', 'mandatory')
group = grouped_parameters.setdefault(group_name, [])
group.append(parameter_element_as_dict(parameter))
group.extend(parameter_element_as_dict(parameter))

textures = root.find('Textures')
grouped_textures = {}
Expand Down
1 change: 1 addition & 0 deletions docs/developers.rst
Expand Up @@ -6,6 +6,7 @@

developers/guidelines/*
developers/toolchain/*
developers/software_structure/*

Code Reference
==============
Expand Down

0 comments on commit 5c01d0d

Please sign in to comment.