Pose Library: Update to use the asset shelf (when enabled) #104546
@ -53,7 +53,6 @@ from amaranth.render import (
|
||||
passepartout,
|
||||
final_resolution,
|
||||
samples_scene,
|
||||
render_output_z,
|
||||
)
|
||||
|
||||
from amaranth.animation import (
|
||||
|
@ -1,44 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2019-2023 Blender Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
EXR Render: Warn when Z not connected
|
||||
Display a little warning label when exporting EXR, with Z Buffer enabled, but
|
||||
forgot to plug the Z input in the Compositor.
|
||||
|
||||
Might be a bit too specific, but found it nice to remember to plug the Z input
|
||||
if we explicitly specify for Z Buffers to be saved (because it's disabled by
|
||||
default).
|
||||
|
||||
Find it on the Output panel, Render properties.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
# // FEATURE: Object ID for objects inside DupliGroups
|
||||
# UI: Warning about Z not connected when using EXR
|
||||
def ui_render_output_z(self, context):
|
||||
|
||||
scene = bpy.context.scene
|
||||
image = scene.render.image_settings
|
||||
if scene.render.use_compositing and \
|
||||
image.file_format == 'OPEN_EXR' and \
|
||||
image.use_zbuffer:
|
||||
if scene.node_tree and scene.node_tree.nodes:
|
||||
for no in scene.node_tree.nodes:
|
||||
if no.type == 'COMPOSITE':
|
||||
if not no.inputs['Z'].is_linked:
|
||||
self.layout.label(
|
||||
text="The Z output in node \"%s\" is not connected" %
|
||||
no.name, icon="ERROR")
|
||||
|
||||
# // UI: Warning about Z not connected
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.RENDER_PT_output.append(ui_render_output_z)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.RENDER_PT_output.remove(ui_render_output_z)
|
@ -1078,6 +1078,7 @@ def make_track_chunk(ID, ob, ob_pos, ob_rot, ob_size):
|
||||
action = ob.animation_data.action
|
||||
if action.fcurves:
|
||||
fcurves = action.fcurves
|
||||
fcurves.update()
|
||||
kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points]
|
||||
nkeys = len(kframes)
|
||||
if not 0 in kframes:
|
||||
@ -1091,46 +1092,48 @@ def make_track_chunk(ID, ob, ob_pos, ob_rot, ob_size):
|
||||
|
||||
if ID == POS_TRACK_TAG: # Position
|
||||
for i, frame in enumerate(kframes):
|
||||
position = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'location']
|
||||
if not position:
|
||||
position = ob_pos
|
||||
pos_track = [fc for fc in fcurves if fc is not None and fc.data_path == 'location']
|
||||
pos_x = next((tc.evaluate(frame) for tc in pos_track if tc.array_index == 0), ob_pos.x)
|
||||
pos_y = next((tc.evaluate(frame) for tc in pos_track if tc.array_index == 1), ob_pos.y)
|
||||
pos_z = next((tc.evaluate(frame) for tc in pos_track if tc.array_index == 2), ob_pos.z)
|
||||
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
|
||||
track_chunk.add_variable("tcb_flags", _3ds_ushort())
|
||||
track_chunk.add_variable("position", _3ds_point_3d(position))
|
||||
track_chunk.add_variable("position", _3ds_point_3d((pos_x, pos_y, pos_z)))
|
||||
|
||||
elif ID == ROT_TRACK_TAG: # Rotation
|
||||
for i, frame in enumerate(kframes):
|
||||
quat = ob_rot
|
||||
rotation = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
|
||||
if rotation:
|
||||
quat = mathutils.Euler(rotation).to_quaternion()
|
||||
axis_angle = quat.angle, quat.axis[0], quat.axis[1], quat.axis[2]
|
||||
rot_track = [fc for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
|
||||
rot_x = next((tc.evaluate(frame) for tc in rot_track if tc.array_index == 0), ob_rot.x)
|
||||
rot_y = next((tc.evaluate(frame) for tc in rot_track if tc.array_index == 1), ob_rot.y)
|
||||
rot_z = next((tc.evaluate(frame) for tc in rot_track if tc.array_index == 2), ob_rot.z)
|
||||
quat = mathutils.Euler((rot_x, rot_y, rot_z)).to_quaternion().inverted()
|
||||
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
|
||||
track_chunk.add_variable("tcb_flags", _3ds_ushort())
|
||||
track_chunk.add_variable("rotation", _3ds_point_4d(axis_angle))
|
||||
track_chunk.add_variable("rotation", _3ds_point_4d((quat.angle, quat.axis[0], quat.axis[1], quat.axis[2])))
|
||||
|
||||
elif ID == SCL_TRACK_TAG: # Scale
|
||||
for i, frame in enumerate(kframes):
|
||||
size = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'scale']
|
||||
if not size:
|
||||
size = ob_size
|
||||
scale_track = [fc for fc in fcurves if fc is not None and fc.data_path == 'scale']
|
||||
size_x = next((tc.evaluate(frame) for tc in scale_track if tc.array_index == 0), ob_size[0])
|
||||
size_y = next((tc.evaluate(frame) for tc in scale_track if tc.array_index == 1), ob_size[1])
|
||||
size_z = next((tc.evaluate(frame) for tc in scale_track if tc.array_index == 2), ob_size[2])
|
||||
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
|
||||
track_chunk.add_variable("tcb_flags", _3ds_ushort())
|
||||
track_chunk.add_variable("scale", _3ds_point_3d(size))
|
||||
track_chunk.add_variable("scale", _3ds_point_3d((size_x, size_y, size_z)))
|
||||
|
||||
elif ID == ROLL_TRACK_TAG: # Roll
|
||||
for i, frame in enumerate(kframes):
|
||||
roll = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
|
||||
if not roll:
|
||||
roll = ob_rot.to_euler()
|
||||
roll_track = [fc for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
|
||||
roll = next((tc.evaluate(frame) for tc in roll_track if tc.array_index == 1), ob_rot.y)
|
||||
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
|
||||
track_chunk.add_variable("tcb_flags", _3ds_ushort())
|
||||
track_chunk.add_variable("roll", _3ds_float(round(math.degrees(roll[1]), 4)))
|
||||
track_chunk.add_variable("roll", _3ds_float(round(math.degrees(roll), 4)))
|
||||
|
||||
elif ID in {COL_TRACK_TAG, FOV_TRACK_TAG, HOTSPOT_TRACK_TAG, FALLOFF_TRACK_TAG} and ob.data.animation_data and ob.data.animation_data.action:
|
||||
action = ob.data.animation_data.action
|
||||
if action.fcurves:
|
||||
fcurves = action.fcurves
|
||||
fcurves.update()
|
||||
kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points]
|
||||
nkeys = len(kframes)
|
||||
if not 0 in kframes:
|
||||
@ -1153,10 +1156,8 @@ def make_track_chunk(ID, ob, ob_pos, ob_rot, ob_size):
|
||||
|
||||
elif ID == FOV_TRACK_TAG: # Field of view
|
||||
for i, frame in enumerate(kframes):
|
||||
lens = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'lens']
|
||||
if not lens:
|
||||
lens.append(ob.data.lens)
|
||||
fov = 2 * math.atan(ob.data.sensor_width / (2 * lens[0]))
|
||||
lens = next((fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'lens'), ob.data.lens)
|
||||
fov = 2 * math.atan(ob.data.sensor_width / (2 * lens))
|
||||
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
|
||||
track_chunk.add_variable("tcb_flags", _3ds_ushort())
|
||||
track_chunk.add_variable("fov", _3ds_float(round(math.degrees(fov), 4)))
|
||||
@ -1164,22 +1165,18 @@ def make_track_chunk(ID, ob, ob_pos, ob_rot, ob_size):
|
||||
elif ID == HOTSPOT_TRACK_TAG: # Hotspot
|
||||
beam_angle = math.degrees(ob.data.spot_size)
|
||||
for i, frame in enumerate(kframes):
|
||||
blend = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'spot_blend']
|
||||
if not blend:
|
||||
blend.append(ob.data.spot_blend)
|
||||
hot_spot = beam_angle - (blend[0] * math.floor(beam_angle))
|
||||
blend = next((fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'spot_blend'), ob.data.spot_blend)
|
||||
hot_spot = beam_angle - (blend * math.floor(beam_angle))
|
||||
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
|
||||
track_chunk.add_variable("tcb_flags", _3ds_ushort())
|
||||
track_chunk.add_variable("hotspot", _3ds_float(round(hot_spot, 4)))
|
||||
|
||||
elif ID == FALLOFF_TRACK_TAG: # Falloff
|
||||
for i, frame in enumerate(kframes):
|
||||
fall_off = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'spot_size']
|
||||
if not fall_off:
|
||||
fall_off.append(ob.data.spot_size)
|
||||
fall_off = next((fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'spot_size'), ob.data.spot_size)
|
||||
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
|
||||
track_chunk.add_variable("tcb_flags", _3ds_ushort())
|
||||
track_chunk.add_variable("falloff", _3ds_float(round(math.degrees(fall_off[0]), 4)))
|
||||
track_chunk.add_variable("falloff", _3ds_float(round(math.degrees(fall_off), 4)))
|
||||
|
||||
else:
|
||||
track_chunk.add_variable("track_flags", _3ds_ushort(0x40)) # Based on observation default flag is 0x40
|
||||
@ -1195,16 +1192,17 @@ def make_track_chunk(ID, ob, ob_pos, ob_rot, ob_size):
|
||||
track_chunk.add_variable("position", _3ds_point_3d(ob_pos))
|
||||
|
||||
elif ID == ROT_TRACK_TAG: # Rotation (angle first [radians], followed by axis)
|
||||
track_chunk.add_variable("rotation", _3ds_point_4d((ob_rot.angle, ob_rot.axis[0], ob_rot.axis[1], ob_rot.axis[2])))
|
||||
quat = ob_rot.to_quaternion().inverted()
|
||||
track_chunk.add_variable("rotation", _3ds_point_4d((quat.angle, quat.axis[0], quat.axis[1], quat.axis[2])))
|
||||
|
||||
elif ID == SCL_TRACK_TAG: # Scale vector
|
||||
track_chunk.add_variable("scale", _3ds_point_3d(ob_size))
|
||||
|
||||
elif ID == ROLL_TRACK_TAG: # Roll angle
|
||||
track_chunk.add_variable("roll", _3ds_float(round(math.degrees(ob.rotation_euler[1]), 4)))
|
||||
track_chunk.add_variable("roll", _3ds_float(round(math.degrees(ob_rot.y), 4)))
|
||||
|
||||
elif ID == COL_TRACK_TAG: # Color values
|
||||
track_chunk.add_variable("color", _3ds_float_color(ob.data.color))
|
||||
track_chunk.add_variable("color", _3ds_float_color(ob.data.color[:3]))
|
||||
|
||||
elif ID == FOV_TRACK_TAG: # Field of view
|
||||
track_chunk.add_variable("fov", _3ds_float(round(math.degrees(ob.data.angle), 4)))
|
||||
@ -1311,7 +1309,7 @@ def make_object_node(ob, translation, rotation, scale, name_id):
|
||||
|
||||
else: # Calculate child position and rotation of the object center, no scale applied
|
||||
ob_pos = translation[name] - translation[parent.name]
|
||||
ob_rot = rotation[name].cross(rotation[parent.name].copy().inverted())
|
||||
ob_rot = rotation[name].to_quaternion().cross(rotation[parent.name].to_quaternion().copy().inverted()).to_euler()
|
||||
ob_size = (1.0, 1.0, 1.0)
|
||||
|
||||
obj_node.add_subchunk(make_track_chunk(POS_TRACK_TAG, ob, ob_pos, ob_rot, ob_size))
|
||||
@ -1360,7 +1358,7 @@ def make_target_node(ob, translation, rotation, scale, name_id):
|
||||
|
||||
# Calculate target position
|
||||
ob_pos = translation[name]
|
||||
ob_rot = rotation[name].to_euler()
|
||||
ob_rot = rotation[name]
|
||||
ob_size = scale[name]
|
||||
|
||||
diagonal = math.copysign(math.sqrt(pow(ob_pos[0],2) + pow(ob_pos[1],2)), ob_pos[1])
|
||||
@ -1375,6 +1373,7 @@ def make_target_node(ob, translation, rotation, scale, name_id):
|
||||
action = ob.animation_data.action
|
||||
if action.fcurves:
|
||||
fcurves = action.fcurves
|
||||
fcurves.update()
|
||||
kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points]
|
||||
nkeys = len(kframes)
|
||||
if not 0 in kframes:
|
||||
@ -1387,18 +1386,17 @@ def make_target_node(ob, translation, rotation, scale, name_id):
|
||||
track_chunk.add_variable("nkeys", _3ds_uint(nkeys))
|
||||
|
||||
for i, frame in enumerate(kframes):
|
||||
target_pos = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'location']
|
||||
target_rot = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
|
||||
if not target_pos:
|
||||
target_pos.append(ob_pos)
|
||||
if not target_rot:
|
||||
target_rot.insert(0, ob_rot.x)
|
||||
target_rot.insert(1, ob_rot.y)
|
||||
target_rot.insert(2, ob_rot.z)
|
||||
diagonal = math.copysign(math.sqrt(pow(target_pos[0],2) + pow(target_pos[1],2)), target_pos[1])
|
||||
target_x = target_pos[0] + (target_pos[1] * math.tan(target_rot[2]))
|
||||
target_y = target_pos[1] + (target_pos[0] * math.tan(math.radians(90) - target_rot[2]))
|
||||
target_z = -1 * diagonal * math.tan(math.radians(90) - target_rot[0])
|
||||
loc_target = [fc for fc in fcurves if fc is not None and fc.data_path == 'location']
|
||||
locate_x = next((tc.evaluate(frame) for tc in loc_target if tc.array_index == 0), ob_pos.x)
|
||||
locate_y = next((tc.evaluate(frame) for tc in loc_target if tc.array_index == 1), ob_pos.y)
|
||||
locate_z = next((tc.evaluate(frame) for tc in loc_target if tc.array_index == 2), ob_pos.z)
|
||||
rot_target = [fc for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
|
||||
rotate_x = next((tc.evaluate(frame) for tc in rot_target if tc.array_index == 0), ob_rot.x)
|
||||
rotate_z = next((tc.evaluate(frame) for tc in rot_target if tc.array_index == 2), ob_rot.z)
|
||||
diagonal = math.copysign(math.sqrt(pow(locate_x, 2) + pow(locate_y, 2)), locate_y)
|
||||
target_x = locate_x + (locate_y * math.tan(rotate_z))
|
||||
target_y = locate_y + (locate_x * math.tan(math.radians(90) - rotate_z))
|
||||
target_z = -1 * diagonal * math.tan(math.radians(90) - rotate_x)
|
||||
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
|
||||
track_chunk.add_variable("tcb_flags", _3ds_ushort())
|
||||
track_chunk.add_variable("position", _3ds_point_3d((target_x, target_y, target_z)))
|
||||
@ -1442,6 +1440,7 @@ def make_ambient_node(world):
|
||||
action = world.animation_data.action
|
||||
if action.fcurves:
|
||||
fcurves = action.fcurves
|
||||
fcurves.update()
|
||||
kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points]
|
||||
nkeys = len(kframes)
|
||||
if not 0 in kframes:
|
||||
@ -1616,21 +1615,29 @@ def save(operator, context, filepath="", use_selection=False, use_hierarchy=Fals
|
||||
|
||||
for ob, data, matrix in mesh_objects:
|
||||
translation[ob.name] = ob.location
|
||||
rotation[ob.name] = ob.rotation_euler.to_quaternion().inverted()
|
||||
rotation[ob.name] = ob.rotation_euler
|
||||
scale[ob.name] = ob.scale
|
||||
name_id[ob.name] = len(name_id)
|
||||
object_id[ob.name] = len(object_id)
|
||||
|
||||
for ob in empty_objects:
|
||||
translation[ob.name] = ob.location
|
||||
rotation[ob.name] = ob.rotation_euler.to_quaternion().inverted()
|
||||
rotation[ob.name] = ob.rotation_euler
|
||||
scale[ob.name] = ob.scale
|
||||
name_id[ob.name] = len(name_id)
|
||||
|
||||
for ob in light_objects:
|
||||
translation[ob.name] = ob.location
|
||||
rotation[ob.name] = ob.rotation_euler
|
||||
scale[ob.name] = ob.scale
|
||||
name_id[ob.name] = len(name_id)
|
||||
object_id[ob.name] = len(object_id)
|
||||
|
||||
for ob in camera_objects:
|
||||
translation[ob.name] = ob.location
|
||||
rotation[ob.name] = ob.rotation_euler
|
||||
scale[ob.name] = ob.scale
|
||||
name_id[ob.name] = len(name_id)
|
||||
object_id[ob.name] = len(object_id)
|
||||
|
||||
# Create object chunks for all meshes
|
||||
@ -1729,10 +1736,6 @@ def save(operator, context, filepath="", use_selection=False, use_hierarchy=Fals
|
||||
|
||||
# Export light and spotlight target node
|
||||
if write_keyframe:
|
||||
translation[ob.name] = ob.location
|
||||
rotation[ob.name] = ob.rotation_euler.to_quaternion()
|
||||
scale[ob.name] = ob.scale
|
||||
name_id[ob.name] = len(name_id)
|
||||
kfdata.add_subchunk(make_object_node(ob, translation, rotation, scale, name_id))
|
||||
if ob.data.type == 'SPOT':
|
||||
kfdata.add_subchunk(make_target_node(ob, translation, rotation, scale, name_id))
|
||||
@ -1769,10 +1772,6 @@ def save(operator, context, filepath="", use_selection=False, use_hierarchy=Fals
|
||||
|
||||
# Export camera and target node
|
||||
if write_keyframe:
|
||||
translation[ob.name] = ob.location
|
||||
rotation[ob.name] = ob.rotation_euler.to_quaternion()
|
||||
scale[ob.name] = ob.scale
|
||||
name_id[ob.name] = len(name_id)
|
||||
kfdata.add_subchunk(make_object_node(ob, translation, rotation, scale, name_id))
|
||||
kfdata.add_subchunk(make_target_node(ob, translation, rotation, scale, name_id))
|
||||
|
||||
|
@ -584,6 +584,9 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
else:
|
||||
tilt = -1 * (math.copysign(pitch, pos[0]))
|
||||
pan = -1 * (math.radians(90) - math.atan(pos[1] / foc))
|
||||
if abs(location[1]) < abs(target[1]):
|
||||
tilt = -1 * tilt
|
||||
pan = -1 * pan
|
||||
elif abs(location[1] - target[1]) > abs(location[0] - target[0]):
|
||||
foc = math.copysign(math.sqrt(pow(pos[1],2) + pow(pos[0],2)), pos[1])
|
||||
dia = math.copysign(math.sqrt(pow(foc,2) + pow(target[2],2)), pos[1])
|
||||
@ -594,13 +597,15 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
else:
|
||||
tilt = -1 * (math.copysign(pitch, pos[1]))
|
||||
pan = -1 * (math.radians(90) - math.acos(pos[0] / foc))
|
||||
if abs(location[0]) < abs(target[0]):
|
||||
tilt = -1 * tilt
|
||||
pan = -1 * pan
|
||||
direction = tilt, pan
|
||||
return direction
|
||||
|
||||
def read_track_data(temp_chunk):
|
||||
"""Trackflags 0x1, 0x2 and 0x3 are for looping. 0x8, 0x10 and 0x20
|
||||
locks the XYZ axes. 0x100, 0x200 and 0x400 unlinks the XYZ axes"""
|
||||
new_chunk.bytes_read += SZ_U_SHORT
|
||||
temp_data = file.read(SZ_U_SHORT)
|
||||
tflags = struct.unpack('<H', temp_data)[0]
|
||||
new_chunk.bytes_read += SZ_U_SHORT
|
||||
@ -629,8 +634,8 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
return keyframe_data
|
||||
|
||||
def read_track_angle(temp_chunk):
|
||||
new_chunk.bytes_read += SZ_U_SHORT * 5
|
||||
temp_data = file.read(SZ_U_SHORT * 5)
|
||||
new_chunk.bytes_read += SZ_U_SHORT * 5
|
||||
temp_data = file.read(SZ_U_INT)
|
||||
nkeys = struct.unpack('<I', temp_data)[0]
|
||||
new_chunk.bytes_read += SZ_U_INT
|
||||
@ -673,7 +678,6 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
path, filename = os.path.split(file.name)
|
||||
realname, ext = os.path.splitext(filename)
|
||||
world = bpy.data.worlds.new("Ambient: " + realname)
|
||||
world.light_settings.use_ambient_occlusion = True
|
||||
context.scene.world = world
|
||||
read_chunk(file, temp_chunk)
|
||||
if temp_chunk.ID == COLOR_F:
|
||||
@ -1214,7 +1218,6 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
|
||||
elif KEYFRAME and new_chunk.ID == ROT_TRACK_TAG and tracking == 'OBJECT': # Rotation
|
||||
keyframe_rotation = {}
|
||||
new_chunk.bytes_read += SZ_U_SHORT
|
||||
temp_data = file.read(SZ_U_SHORT)
|
||||
tflags = struct.unpack('<H', temp_data)[0]
|
||||
new_chunk.bytes_read += SZ_U_SHORT
|
||||
|
@ -578,12 +578,9 @@ def fbx_data_light_elements(root, lamp, scene_data):
|
||||
|
||||
light_key = scene_data.data_lights[lamp]
|
||||
do_light = True
|
||||
decay_type = FBX_LIGHT_DECAY_TYPES['CONSTANT']
|
||||
do_shadow = False
|
||||
shadow_color = Vector((0.0, 0.0, 0.0))
|
||||
if lamp.type not in {'HEMI'}:
|
||||
if lamp.type not in {'SUN', 'AREA'}:
|
||||
decay_type = FBX_LIGHT_DECAY_TYPES[lamp.falloff_type]
|
||||
do_light = True
|
||||
do_shadow = lamp.use_shadow
|
||||
shadow_color = lamp.shadow_color
|
||||
@ -600,8 +597,8 @@ def fbx_data_light_elements(root, lamp, scene_data):
|
||||
elem_props_template_set(tmpl, props, "p_bool", b"CastLight", do_light)
|
||||
elem_props_template_set(tmpl, props, "p_color", b"Color", lamp.color)
|
||||
elem_props_template_set(tmpl, props, "p_number", b"Intensity", lamp.energy * 100.0)
|
||||
elem_props_template_set(tmpl, props, "p_enum", b"DecayType", decay_type)
|
||||
elem_props_template_set(tmpl, props, "p_double", b"DecayStart", lamp.distance * gscale)
|
||||
elem_props_template_set(tmpl, props, "p_enum", b"DecayType", FBX_LIGHT_DECAY_TYPES['INVERSE_SQUARE'])
|
||||
elem_props_template_set(tmpl, props, "p_double", b"DecayStart", 25.0 * gscale) # 25 is old Blender default
|
||||
elem_props_template_set(tmpl, props, "p_bool", b"CastShadows", do_shadow)
|
||||
elem_props_template_set(tmpl, props, "p_color", b"ShadowColor", shadow_color)
|
||||
if lamp.type in {'SPOT'}:
|
||||
@ -2929,25 +2926,20 @@ def fbx_data_from_scene(scene, depsgraph, settings):
|
||||
_objs_indices = {}
|
||||
for ma, (ma_key, ob_objs) in data_materials.items():
|
||||
for ob_obj in ob_objs:
|
||||
connections.append((b"OO", get_fbx_uuid_from_key(ma_key), ob_obj.fbx_uuid, None))
|
||||
# Get index of this material for this object (or dupliobject).
|
||||
# Material indices for mesh faces are determined by their order in 'ma to ob' connections.
|
||||
# Only materials for meshes currently...
|
||||
# Note in case of dupliobjects a same me/ma idx will be generated several times...
|
||||
# Should not be an issue in practice, and it's needed in case we export duplis but not the original!
|
||||
if ob_obj.type not in BLENDER_OBJECT_TYPES_MESHLIKE:
|
||||
connections.append((b"OO", get_fbx_uuid_from_key(ma_key), ob_obj.fbx_uuid, None))
|
||||
continue
|
||||
_mesh_key, me, _free = data_meshes[ob_obj]
|
||||
material_indices = mesh_material_indices.setdefault(me, {})
|
||||
if ma in material_indices:
|
||||
# Material has already been found for this mesh.
|
||||
# XXX If a mesh has multiple material slots with the same material, they are combined into one slot.
|
||||
# Even if duplicate materials were exported without combining them into one slot, keeping duplicate
|
||||
# materials separated does not appear to be common behaviour of external software when importing FBX.
|
||||
continue
|
||||
connections.append((b"OO", get_fbx_uuid_from_key(ma_key), ob_obj.fbx_uuid, None))
|
||||
idx = _objs_indices[ob_obj] = _objs_indices.get(ob_obj, -1) + 1
|
||||
material_indices[ma] = idx
|
||||
# XXX If a mesh has multiple material slots with the same material, they are combined into one slot.
|
||||
# Even if duplicate materials were exported without combining them into one slot, keeping duplicate
|
||||
# materials separated does not appear to be common behaviour of external software when importing FBX.
|
||||
mesh_material_indices.setdefault(me, {})[ma] = idx
|
||||
del _objs_indices
|
||||
|
||||
# Textures
|
||||
|
@ -6,5 +6,3 @@ lampdata = bpy.context.object.data
|
||||
|
||||
lampdata.color = (1.0, 1.0, 0.9843137264251709)
|
||||
lampdata.energy = 1.2 #100 000lux
|
||||
#lampdata.distance = 0.001
|
||||
#lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -13,4 +13,3 @@ lampdata.pov.shadow_ray_samples_x = 2
|
||||
#lampdata.pov.shadow_ray_samples_y = 3
|
||||
lampdata.color = (1.0, 1.0, 1.0)
|
||||
lampdata.energy = 1.094316#91193 #lux
|
||||
lampdata.distance =695699968
|
||||
|
@ -10,4 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 2
|
||||
lampdata.pov.shadow_ray_samples_y = 3
|
||||
lampdata.color = (1.0, 1.0, 1.0)
|
||||
lampdata.energy = 1.094316#91193 #lux
|
||||
lampdata.distance = 1.0
|
||||
|
@ -10,5 +10,3 @@ lampdata.spot_size = 0.872665
|
||||
lampdata.spot_blend = 0.9
|
||||
lampdata.color = (0.99, 0.9882352948188782, 0.998)
|
||||
lampdata.energy = 223.81796 #240000lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 0.001
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -10,5 +10,3 @@ lampdata.spot_size = 0.6
|
||||
lampdata.spot_blend = 0.9
|
||||
lampdata.color = (0.9490196108818054, 0.9882352948188782, 1.0)
|
||||
lampdata.energy = 20.98293#9000lm/21.446(=lux)*0.004*6.25(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 0.025
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -12,5 +12,3 @@ lampdata.spot_size = 1.9
|
||||
lampdata.spot_blend = 0.9
|
||||
lampdata.color = (1.0, 0.9450980424880981, 0.8784313797950745)
|
||||
lampdata.energy = 12.43433#5000/21.446 #lumen values/20 or lux when available used as a basis
|
||||
lampdata.distance = 0.015#energy calculated for length 0.075 but width gives better result
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -6,5 +6,3 @@ lampdata = bpy.context.object.data
|
||||
|
||||
lampdata.color = (1.0, 0.8392156958580017, 0.6666666865348816)
|
||||
lampdata.energy = 7.46060#3.7303#1000/21.446/(lampdistance/candledistance) #lumen values/21.446 or lux when available used as a basis
|
||||
lampdata.distance = 0.05
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -6,5 +6,3 @@ lampdata = bpy.context.object.data
|
||||
|
||||
lampdata.color = (1.0, 0.8196078431372549, 0.6980392156862745)
|
||||
lampdata.energy = 2.98424#400/21.446 #lumen values/21.446 or lux when available used as a basis
|
||||
lampdata.distance = 0.05
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -10,5 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 1
|
||||
lampdata.pov.shadow_ray_samples_y = 2
|
||||
lampdata.color = (1.0, 0.95686274766922, 0.9490200281143188)
|
||||
lampdata.energy = 4.45304#4775lm/21.446(=lux)*0.004(distance) *2 for distance is the point of half strength 6200lm?
|
||||
lampdata.distance = 1.0 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
#lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -10,5 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 1
|
||||
lampdata.pov.shadow_ray_samples_y = 2
|
||||
lampdata.color = (0.901, 1.0, 0.979)
|
||||
lampdata.energy = 2.14492#2300lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 1.0 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
#lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -10,4 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 1
|
||||
lampdata.pov.shadow_ray_samples_y = 2
|
||||
lampdata.color = (0.95686274766922, 1.0, 0.9803921580314636)
|
||||
lampdata.energy = 1.25898#1350lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 1.0 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
|
@ -11,5 +11,3 @@ lampdata.pov.shadow_ray_samples_x = 1
|
||||
lampdata.pov.shadow_ray_samples_y = 2
|
||||
lampdata.color = (0.8313725590705872, 0.9215686321258545, 1.0)
|
||||
lampdata.energy = 1.25898#1350lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 1.0 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
#lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -10,5 +10,3 @@ lampdata.size_y = 0.59
|
||||
lampdata.pov.shadow_ray_samples_x = 1
|
||||
lampdata.pov.shadow_ray_samples_y = 2
|
||||
lampdata.color = (1.0, 0.95686274766922, 0.8980392217636108)
|
||||
lampdata.energy = 1.25898#1350lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 1.0 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
|
@ -10,4 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 1
|
||||
lampdata.pov.shadow_ray_samples_y = 2
|
||||
lampdata.color = (1.0, 0.83, 0.986274528503418)
|
||||
lampdata.energy = 4.66287 #0.93257#4.66287#5000lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 0.1 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
|
@ -10,5 +10,3 @@ lampdata.spot_size = 3.14
|
||||
lampdata.spot_blend = 0.9
|
||||
lampdata.color = (1.0, 0.9450980424880981, 0.8784313797950745)
|
||||
lampdata.energy = 2.61121#2800/21.446 #lumen values/20 or lux when available used as a basis
|
||||
lampdata.distance = 0.15#energy calculated for length 0.075 but width gives better result
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -7,7 +7,5 @@ lampdata = bpy.context.object.data
|
||||
lampdata.show_cone = True
|
||||
lampdata.color = (1.0, 0.772549033164978, 0.5607843399047852)
|
||||
lampdata.energy = 4.47636#12000lm/21.446(=lux)*0.004(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 1.0
|
||||
lampdata.spot_size = 1.9
|
||||
lampdata.spot_blend = 0.9
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -7,5 +7,3 @@ lampdata = bpy.context.object.data
|
||||
|
||||
lampdata.color = (1.0, 0.5764706134796143, 0.16078431904315948)
|
||||
lampdata.energy = 8.43048#22600lm/21.446(=lux)*0.004(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 1.0
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -9,5 +9,3 @@ lampdata.spot_size = 1.25
|
||||
lampdata.spot_blend = 0.9
|
||||
lampdata.color = (0.8470588326454163, 0.9686274528503418, 1.0)
|
||||
lampdata.energy = 17.25263#7400lm/21.446(=lux)*0.004*6.25(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 0.025
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -14,5 +14,3 @@ lampdata.spot_size = 1.5
|
||||
lampdata.spot_blend = 0.3
|
||||
lampdata.color = (1.0, 0.9803921580314636, 0.95686274766922)
|
||||
lampdata.energy = 51.29162#55000lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 0.01
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -9,4 +9,3 @@ lampdata.spot_size = 1.39626 #80 degrees in radian
|
||||
lampdata.spot_blend = 0.5
|
||||
lampdata.color = (1.0, 0.9372549057006836, 0.9686274528503418)
|
||||
lampdata.energy = 1.39886#1500lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 1.18 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
|
@ -11,4 +11,3 @@ lampdata.pov.shadow_ray_samples_x = 2
|
||||
lampdata.pov.shadow_ray_samples_y = 2
|
||||
lampdata.color = (1.0, 0.8292156958580017, 0.6966666865348816)
|
||||
lampdata.energy = 0.83932#900lm/21.446(=lux)*0.004*2.5(distance) *2 for distance is the point of half strength
|
||||
lampdata.distance = 1.18 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
|
@ -8,4 +8,3 @@ lampdata.size = 0.038
|
||||
lampdata.size_y = 1.2192
|
||||
lampdata.color = (0.6549019813537598, 0.0, 1.0)
|
||||
lampdata.energy = 1.86515#100/21.446 #lumen values/21.446 or lux when available used as a basis
|
||||
lampdata.distance = 0.4 #dist values multiplied by 10 for area lights for same power as bulb/spot/...
|
||||
|
@ -6,5 +6,3 @@ lampdata = bpy.context.object.data
|
||||
|
||||
lampdata.color = (0.6549019813537598, 0.0, 1.0)
|
||||
lampdata.energy = 1.86515#100/21.446 #lumen values/21.446 or lux when available used as a basis
|
||||
lampdata.distance = 0.01
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -20,5 +20,3 @@ lampdata.color = (1.0, 0.7176470756530762, 0.2980392277240753)
|
||||
#Family Living Room 50
|
||||
#Sunset & Sunrise 400 lux
|
||||
lampdata.energy = 2.0 #two times lux value
|
||||
lampdata.distance = 0.004
|
||||
lampdata.falloff_type = 'INVERSE_SQUARE'
|
||||
|
@ -294,7 +294,7 @@ def export_lights(lamps, file, scene, global_matrix, tab_write):
|
||||
tab_write(file, "point_at <0, 0, -1>\n")
|
||||
if lamp.pov.use_halo:
|
||||
tab_write(file, "looks_like{\n")
|
||||
tab_write(file, "sphere{<0,0,0>,%.6f\n" % lamp.distance)
|
||||
tab_write(file, "sphere{<0,0,0>,%.6f\n" % lamp.shadow_soft_size)
|
||||
tab_write(file, "hollow\n")
|
||||
tab_write(file, "material{\n")
|
||||
tab_write(file, "texture{\n")
|
||||
@ -322,7 +322,6 @@ def export_lights(lamps, file, scene, global_matrix, tab_write):
|
||||
tab_write(file, "point_at <0, 0, -1>\n") # *must* be after 'parallel'
|
||||
|
||||
elif lamp.type == "AREA":
|
||||
tab_write(file, "fade_distance %.6f\n" % (lamp.distance / 2.0))
|
||||
# Area lights have no falloff type, so always use blenders lamp quad equivalent
|
||||
# for those?
|
||||
tab_write(file, "fade_power %d\n" % 2)
|
||||
@ -355,19 +354,7 @@ def export_lights(lamps, file, scene, global_matrix, tab_write):
|
||||
# Sun shouldn't be attenuated. Area lights have no falloff attribute so they
|
||||
# are put to type 2 attenuation a little higher above.
|
||||
if lamp.type not in {"SUN", "AREA"}:
|
||||
if lamp.falloff_type == "INVERSE_SQUARE":
|
||||
tab_write(file, "fade_distance %.6f\n" % (sqrt(lamp.distance / 2.0)))
|
||||
tab_write(file, "fade_power %d\n" % 2) # Use blenders lamp quad equivalent
|
||||
elif lamp.falloff_type == "INVERSE_LINEAR":
|
||||
tab_write(file, "fade_distance %.6f\n" % (lamp.distance / 2.0))
|
||||
tab_write(file, "fade_power %d\n" % 1) # Use blenders lamp linear
|
||||
elif lamp.falloff_type == "CONSTANT":
|
||||
tab_write(file, "fade_distance %.6f\n" % (lamp.distance / 2.0))
|
||||
tab_write(file, "fade_power %d\n" % 3)
|
||||
# Use blenders lamp constant equivalent no attenuation.
|
||||
# Using Custom curve for fade power 3 for now.
|
||||
elif lamp.falloff_type == "CUSTOM_CURVE":
|
||||
tab_write(file, "fade_power %d\n" % 4)
|
||||
tab_write(file, "fade_power %d\n" % 2) # Use blenders lamp quad equivalent
|
||||
|
||||
write_matrix(file, matrix)
|
||||
|
||||
|
@ -465,28 +465,9 @@ class LIGHT_PT_POV_light(PovLightButtonsPanel, Panel):
|
||||
sub.prop(light, "energy")
|
||||
|
||||
if light.type in {"POINT", "SPOT"}:
|
||||
sub.label(text="Falloff:")
|
||||
sub.prop(light, "falloff_type", text="")
|
||||
sub.prop(light, "distance")
|
||||
|
||||
if light.falloff_type == "LINEAR_QUADRATIC_WEIGHTED":
|
||||
col.label(text="Attenuation Factors:")
|
||||
sub = col.column(align=True)
|
||||
sub.prop(light, "linear_attenuation", slider=True, text="Linear")
|
||||
sub.prop(light, "quadratic_attenuation", slider=True, text="Quadratic")
|
||||
|
||||
elif light.falloff_type == "INVERSE_COEFFICIENTS":
|
||||
col.label(text="Inverse Coefficients:")
|
||||
sub = col.column(align=True)
|
||||
sub.prop(light, "constant_coefficient", text="Constant")
|
||||
sub.prop(light, "linear_coefficient", text="Linear")
|
||||
sub.prop(light, "quadratic_coefficient", text="Quadratic")
|
||||
sub.prop(light, "shadow_soft_size", text="Radius")
|
||||
|
||||
if light.type == "AREA":
|
||||
col.prop(light, "distance")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.prop(light, "shape")
|
||||
|
||||
sub = col.column(align=True)
|
||||
@ -640,22 +621,6 @@ class LIGHT_PT_POV_spot(PovLightButtonsPanel, Panel):
|
||||
draw = properties_data_light.DATA_PT_spot.draw
|
||||
|
||||
|
||||
class LIGHT_PT_POV_falloff_curve(PovLightButtonsPanel, Panel):
|
||||
bl_label = properties_data_light.DATA_PT_falloff_curve.bl_label
|
||||
bl_options = properties_data_light.DATA_PT_falloff_curve.bl_options
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
lamp = context.light
|
||||
engine = context.scene.render.engine
|
||||
|
||||
return (
|
||||
lamp and lamp.type in {"POINT", "SPOT"} and lamp.falloff_type == "CUSTOM_CURVE"
|
||||
) and (engine in cls.COMPAT_ENGINES)
|
||||
|
||||
draw = properties_data_light.DATA_PT_falloff_curve.draw
|
||||
|
||||
|
||||
class OBJECT_PT_POV_rainbow(PovLightButtonsPanel, Panel):
|
||||
"""Use this class to define buttons from the rainbow panel of
|
||||
properties window. inheriting lamp buttons panel class"""
|
||||
|
Loading…
Reference in New Issue
Block a user