Pose Library: Update to use the asset shelf (when enabled) #104546

Merged
Julian Eisel merged 33 commits from asset-shelf into main 2023-08-04 15:00:21 +02:00
31 changed files with 73 additions and 213 deletions
Showing only changes of commit 2b6d56d552 - Show all commits

View File

@ -53,7 +53,6 @@ from amaranth.render import (
passepartout, passepartout,
final_resolution, final_resolution,
samples_scene, samples_scene,
render_output_z,
) )
from amaranth.animation import ( from amaranth.animation import (

View File

@ -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)

View File

@ -1078,6 +1078,7 @@ def make_track_chunk(ID, ob, ob_pos, ob_rot, ob_size):
action = ob.animation_data.action action = ob.animation_data.action
if action.fcurves: if action.fcurves:
fcurves = 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] kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points]
nkeys = len(kframes) nkeys = len(kframes)
if not 0 in 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 if ID == POS_TRACK_TAG: # Position
for i, frame in enumerate(kframes): for i, frame in enumerate(kframes):
position = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'location'] pos_track = [fc for fc in fcurves if fc is not None and fc.data_path == 'location']
if not position: pos_x = next((tc.evaluate(frame) for tc in pos_track if tc.array_index == 0), ob_pos.x)
position = ob_pos 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_frame", _3ds_uint(int(frame)))
track_chunk.add_variable("tcb_flags", _3ds_ushort()) 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 elif ID == ROT_TRACK_TAG: # Rotation
for i, frame in enumerate(kframes): for i, frame in enumerate(kframes):
quat = ob_rot rot_track = [fc for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
rotation = [fc.evaluate(frame) 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)
if rotation: rot_y = next((tc.evaluate(frame) for tc in rot_track if tc.array_index == 1), ob_rot.y)
quat = mathutils.Euler(rotation).to_quaternion() rot_z = next((tc.evaluate(frame) for tc in rot_track if tc.array_index == 2), ob_rot.z)
axis_angle = quat.angle, quat.axis[0], quat.axis[1], quat.axis[2] 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_frame", _3ds_uint(int(frame)))
track_chunk.add_variable("tcb_flags", _3ds_ushort()) 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 elif ID == SCL_TRACK_TAG: # Scale
for i, frame in enumerate(kframes): for i, frame in enumerate(kframes):
size = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'scale'] scale_track = [fc for fc in fcurves if fc is not None and fc.data_path == 'scale']
if not size: size_x = next((tc.evaluate(frame) for tc in scale_track if tc.array_index == 0), ob_size[0])
size = ob_size 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_frame", _3ds_uint(int(frame)))
track_chunk.add_variable("tcb_flags", _3ds_ushort()) 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 elif ID == ROLL_TRACK_TAG: # Roll
for i, frame in enumerate(kframes): 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'] roll_track = [fc for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
if not roll: roll = next((tc.evaluate(frame) for tc in roll_track if tc.array_index == 1), ob_rot.y)
roll = ob_rot.to_euler()
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame))) track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
track_chunk.add_variable("tcb_flags", _3ds_ushort()) 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: 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 action = ob.data.animation_data.action
if action.fcurves: if action.fcurves:
fcurves = 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] kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points]
nkeys = len(kframes) nkeys = len(kframes)
if not 0 in 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 elif ID == FOV_TRACK_TAG: # Field of view
for i, frame in enumerate(kframes): for i, frame in enumerate(kframes):
lens = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'lens'] lens = next((fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'lens'), ob.data.lens)
if not lens: fov = 2 * math.atan(ob.data.sensor_width / (2 * lens))
lens.append(ob.data.lens)
fov = 2 * math.atan(ob.data.sensor_width / (2 * lens[0]))
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame))) track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
track_chunk.add_variable("tcb_flags", _3ds_ushort()) track_chunk.add_variable("tcb_flags", _3ds_ushort())
track_chunk.add_variable("fov", _3ds_float(round(math.degrees(fov), 4))) 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 elif ID == HOTSPOT_TRACK_TAG: # Hotspot
beam_angle = math.degrees(ob.data.spot_size) beam_angle = math.degrees(ob.data.spot_size)
for i, frame in enumerate(kframes): 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'] blend = next((fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == 'spot_blend'), ob.data.spot_blend)
if not blend: hot_spot = beam_angle - (blend * math.floor(beam_angle))
blend.append(ob.data.spot_blend)
hot_spot = beam_angle - (blend[0] * math.floor(beam_angle))
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame))) track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
track_chunk.add_variable("tcb_flags", _3ds_ushort()) track_chunk.add_variable("tcb_flags", _3ds_ushort())
track_chunk.add_variable("hotspot", _3ds_float(round(hot_spot, 4))) track_chunk.add_variable("hotspot", _3ds_float(round(hot_spot, 4)))
elif ID == FALLOFF_TRACK_TAG: # Falloff elif ID == FALLOFF_TRACK_TAG: # Falloff
for i, frame in enumerate(kframes): 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'] 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)
if not fall_off:
fall_off.append(ob.data.spot_size)
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame))) track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
track_chunk.add_variable("tcb_flags", _3ds_ushort()) 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: else:
track_chunk.add_variable("track_flags", _3ds_ushort(0x40)) # Based on observation default flag is 0x40 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)) track_chunk.add_variable("position", _3ds_point_3d(ob_pos))
elif ID == ROT_TRACK_TAG: # Rotation (angle first [radians], followed by axis) 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 elif ID == SCL_TRACK_TAG: # Scale vector
track_chunk.add_variable("scale", _3ds_point_3d(ob_size)) track_chunk.add_variable("scale", _3ds_point_3d(ob_size))
elif ID == ROLL_TRACK_TAG: # Roll angle 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 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 elif ID == FOV_TRACK_TAG: # Field of view
track_chunk.add_variable("fov", _3ds_float(round(math.degrees(ob.data.angle), 4))) 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 else: # Calculate child position and rotation of the object center, no scale applied
ob_pos = translation[name] - translation[parent.name] 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) 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)) 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 # Calculate target position
ob_pos = translation[name] ob_pos = translation[name]
ob_rot = rotation[name].to_euler() ob_rot = rotation[name]
ob_size = scale[name] ob_size = scale[name]
diagonal = math.copysign(math.sqrt(pow(ob_pos[0],2) + pow(ob_pos[1],2)), ob_pos[1]) 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 action = ob.animation_data.action
if action.fcurves: if action.fcurves:
fcurves = 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] kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points]
nkeys = len(kframes) nkeys = len(kframes)
if not 0 in 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)) track_chunk.add_variable("nkeys", _3ds_uint(nkeys))
for i, frame in enumerate(kframes): 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'] loc_target = [fc 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'] locate_x = next((tc.evaluate(frame) for tc in loc_target if tc.array_index == 0), ob_pos.x)
if not target_pos: locate_y = next((tc.evaluate(frame) for tc in loc_target if tc.array_index == 1), ob_pos.y)
target_pos.append(ob_pos) locate_z = next((tc.evaluate(frame) for tc in loc_target if tc.array_index == 2), ob_pos.z)
if not target_rot: rot_target = [fc for fc in fcurves if fc is not None and fc.data_path == 'rotation_euler']
target_rot.insert(0, ob_rot.x) rotate_x = next((tc.evaluate(frame) for tc in rot_target if tc.array_index == 0), ob_rot.x)
target_rot.insert(1, ob_rot.y) rotate_z = next((tc.evaluate(frame) for tc in rot_target if tc.array_index == 2), ob_rot.z)
target_rot.insert(2, ob_rot.z) diagonal = math.copysign(math.sqrt(pow(locate_x, 2) + pow(locate_y, 2)), locate_y)
diagonal = math.copysign(math.sqrt(pow(target_pos[0],2) + pow(target_pos[1],2)), target_pos[1]) target_x = locate_x + (locate_y * math.tan(rotate_z))
target_x = target_pos[0] + (target_pos[1] * math.tan(target_rot[2])) target_y = locate_y + (locate_x * math.tan(math.radians(90) - rotate_z))
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) - rotate_x)
target_z = -1 * diagonal * math.tan(math.radians(90) - target_rot[0])
track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame))) track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame)))
track_chunk.add_variable("tcb_flags", _3ds_ushort()) track_chunk.add_variable("tcb_flags", _3ds_ushort())
track_chunk.add_variable("position", _3ds_point_3d((target_x, target_y, target_z))) 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 action = world.animation_data.action
if action.fcurves: if action.fcurves:
fcurves = 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] kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points]
nkeys = len(kframes) nkeys = len(kframes)
if not 0 in 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: for ob, data, matrix in mesh_objects:
translation[ob.name] = ob.location 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 scale[ob.name] = ob.scale
name_id[ob.name] = len(name_id) name_id[ob.name] = len(name_id)
object_id[ob.name] = len(object_id) object_id[ob.name] = len(object_id)
for ob in empty_objects: for ob in empty_objects:
translation[ob.name] = ob.location 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 scale[ob.name] = ob.scale
name_id[ob.name] = len(name_id) name_id[ob.name] = len(name_id)
for ob in light_objects: 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) object_id[ob.name] = len(object_id)
for ob in camera_objects: 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) object_id[ob.name] = len(object_id)
# Create object chunks for all meshes # 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 # Export light and spotlight target node
if write_keyframe: 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_object_node(ob, translation, rotation, scale, name_id))
if ob.data.type == 'SPOT': if ob.data.type == 'SPOT':
kfdata.add_subchunk(make_target_node(ob, translation, rotation, scale, name_id)) 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 # Export camera and target node
if write_keyframe: 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_object_node(ob, translation, rotation, scale, name_id))
kfdata.add_subchunk(make_target_node(ob, translation, rotation, scale, name_id)) kfdata.add_subchunk(make_target_node(ob, translation, rotation, scale, name_id))

View File

@ -584,6 +584,9 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
else: else:
tilt = -1 * (math.copysign(pitch, pos[0])) tilt = -1 * (math.copysign(pitch, pos[0]))
pan = -1 * (math.radians(90) - math.atan(pos[1] / foc)) 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]): 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]) 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]) 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: else:
tilt = -1 * (math.copysign(pitch, pos[1])) tilt = -1 * (math.copysign(pitch, pos[1]))
pan = -1 * (math.radians(90) - math.acos(pos[0] / foc)) 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 direction = tilt, pan
return direction return direction
def read_track_data(temp_chunk): def read_track_data(temp_chunk):
"""Trackflags 0x1, 0x2 and 0x3 are for looping. 0x8, 0x10 and 0x20 """Trackflags 0x1, 0x2 and 0x3 are for looping. 0x8, 0x10 and 0x20
locks the XYZ axes. 0x100, 0x200 and 0x400 unlinks the XYZ axes""" 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) temp_data = file.read(SZ_U_SHORT)
tflags = struct.unpack('<H', temp_data)[0] tflags = struct.unpack('<H', temp_data)[0]
new_chunk.bytes_read += SZ_U_SHORT 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 return keyframe_data
def read_track_angle(temp_chunk): def read_track_angle(temp_chunk):
new_chunk.bytes_read += SZ_U_SHORT * 5
temp_data = file.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) temp_data = file.read(SZ_U_INT)
nkeys = struct.unpack('<I', temp_data)[0] nkeys = struct.unpack('<I', temp_data)[0]
new_chunk.bytes_read += SZ_U_INT 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) path, filename = os.path.split(file.name)
realname, ext = os.path.splitext(filename) realname, ext = os.path.splitext(filename)
world = bpy.data.worlds.new("Ambient: " + realname) world = bpy.data.worlds.new("Ambient: " + realname)
world.light_settings.use_ambient_occlusion = True
context.scene.world = world context.scene.world = world
read_chunk(file, temp_chunk) read_chunk(file, temp_chunk)
if temp_chunk.ID == COLOR_F: 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 elif KEYFRAME and new_chunk.ID == ROT_TRACK_TAG and tracking == 'OBJECT': # Rotation
keyframe_rotation = {} keyframe_rotation = {}
new_chunk.bytes_read += SZ_U_SHORT
temp_data = file.read(SZ_U_SHORT) temp_data = file.read(SZ_U_SHORT)
tflags = struct.unpack('<H', temp_data)[0] tflags = struct.unpack('<H', temp_data)[0]
new_chunk.bytes_read += SZ_U_SHORT new_chunk.bytes_read += SZ_U_SHORT

View File

@ -578,12 +578,9 @@ def fbx_data_light_elements(root, lamp, scene_data):
light_key = scene_data.data_lights[lamp] light_key = scene_data.data_lights[lamp]
do_light = True do_light = True
decay_type = FBX_LIGHT_DECAY_TYPES['CONSTANT']
do_shadow = False do_shadow = False
shadow_color = Vector((0.0, 0.0, 0.0)) shadow_color = Vector((0.0, 0.0, 0.0))
if lamp.type not in {'HEMI'}: 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_light = True
do_shadow = lamp.use_shadow do_shadow = lamp.use_shadow
shadow_color = lamp.shadow_color 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_bool", b"CastLight", do_light)
elem_props_template_set(tmpl, props, "p_color", b"Color", lamp.color) 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_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_enum", b"DecayType", FBX_LIGHT_DECAY_TYPES['INVERSE_SQUARE'])
elem_props_template_set(tmpl, props, "p_double", b"DecayStart", lamp.distance * gscale) 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_bool", b"CastShadows", do_shadow)
elem_props_template_set(tmpl, props, "p_color", b"ShadowColor", shadow_color) elem_props_template_set(tmpl, props, "p_color", b"ShadowColor", shadow_color)
if lamp.type in {'SPOT'}: if lamp.type in {'SPOT'}:
@ -2929,25 +2926,20 @@ def fbx_data_from_scene(scene, depsgraph, settings):
_objs_indices = {} _objs_indices = {}
for ma, (ma_key, ob_objs) in data_materials.items(): for ma, (ma_key, ob_objs) in data_materials.items():
for ob_obj in ob_objs: 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). # 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. # Material indices for mesh faces are determined by their order in 'ma to ob' connections.
# Only materials for meshes currently... # Only materials for meshes currently...
# Note in case of dupliobjects a same me/ma idx will be generated several times... # 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! # 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: 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 continue
_mesh_key, me, _free = data_meshes[ob_obj] _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 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 del _objs_indices
# Textures # Textures

View File

@ -6,5 +6,3 @@ lampdata = bpy.context.object.data
lampdata.color = (1.0, 1.0, 0.9843137264251709) lampdata.color = (1.0, 1.0, 0.9843137264251709)
lampdata.energy = 1.2 #100 000lux lampdata.energy = 1.2 #100 000lux
#lampdata.distance = 0.001
#lampdata.falloff_type = 'INVERSE_SQUARE'

View File

@ -13,4 +13,3 @@ lampdata.pov.shadow_ray_samples_x = 2
#lampdata.pov.shadow_ray_samples_y = 3 #lampdata.pov.shadow_ray_samples_y = 3
lampdata.color = (1.0, 1.0, 1.0) lampdata.color = (1.0, 1.0, 1.0)
lampdata.energy = 1.094316#91193 #lux lampdata.energy = 1.094316#91193 #lux
lampdata.distance =695699968

View File

@ -10,4 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 2
lampdata.pov.shadow_ray_samples_y = 3 lampdata.pov.shadow_ray_samples_y = 3
lampdata.color = (1.0, 1.0, 1.0) lampdata.color = (1.0, 1.0, 1.0)
lampdata.energy = 1.094316#91193 #lux lampdata.energy = 1.094316#91193 #lux
lampdata.distance = 1.0

View File

@ -10,5 +10,3 @@ lampdata.spot_size = 0.872665
lampdata.spot_blend = 0.9 lampdata.spot_blend = 0.9
lampdata.color = (0.99, 0.9882352948188782, 0.998) 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.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'

View File

@ -10,5 +10,3 @@ lampdata.spot_size = 0.6
lampdata.spot_blend = 0.9 lampdata.spot_blend = 0.9
lampdata.color = (0.9490196108818054, 0.9882352948188782, 1.0) 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.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'

View File

@ -12,5 +12,3 @@ lampdata.spot_size = 1.9
lampdata.spot_blend = 0.9 lampdata.spot_blend = 0.9
lampdata.color = (1.0, 0.9450980424880981, 0.8784313797950745) 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.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'

View File

@ -6,5 +6,3 @@ lampdata = bpy.context.object.data
lampdata.color = (1.0, 0.8392156958580017, 0.6666666865348816) 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.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'

View File

@ -6,5 +6,3 @@ lampdata = bpy.context.object.data
lampdata.color = (1.0, 0.8196078431372549, 0.6980392156862745) 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.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'

View File

@ -10,5 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 1
lampdata.pov.shadow_ray_samples_y = 2 lampdata.pov.shadow_ray_samples_y = 2
lampdata.color = (1.0, 0.95686274766922, 0.9490200281143188) 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.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'

View File

@ -10,5 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 1
lampdata.pov.shadow_ray_samples_y = 2 lampdata.pov.shadow_ray_samples_y = 2
lampdata.color = (0.901, 1.0, 0.979) 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.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'

View File

@ -10,4 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 1
lampdata.pov.shadow_ray_samples_y = 2 lampdata.pov.shadow_ray_samples_y = 2
lampdata.color = (0.95686274766922, 1.0, 0.9803921580314636) 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.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/...

View File

@ -11,5 +11,3 @@ lampdata.pov.shadow_ray_samples_x = 1
lampdata.pov.shadow_ray_samples_y = 2 lampdata.pov.shadow_ray_samples_y = 2
lampdata.color = (0.8313725590705872, 0.9215686321258545, 1.0) 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.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'

View File

@ -10,5 +10,3 @@ lampdata.size_y = 0.59
lampdata.pov.shadow_ray_samples_x = 1 lampdata.pov.shadow_ray_samples_x = 1
lampdata.pov.shadow_ray_samples_y = 2 lampdata.pov.shadow_ray_samples_y = 2
lampdata.color = (1.0, 0.95686274766922, 0.8980392217636108) 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/...

View File

@ -10,4 +10,3 @@ lampdata.pov.shadow_ray_samples_x = 1
lampdata.pov.shadow_ray_samples_y = 2 lampdata.pov.shadow_ray_samples_y = 2
lampdata.color = (1.0, 0.83, 0.986274528503418) 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.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/...

View File

@ -10,5 +10,3 @@ lampdata.spot_size = 3.14
lampdata.spot_blend = 0.9 lampdata.spot_blend = 0.9
lampdata.color = (1.0, 0.9450980424880981, 0.8784313797950745) 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.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'

View File

@ -7,7 +7,5 @@ lampdata = bpy.context.object.data
lampdata.show_cone = True lampdata.show_cone = True
lampdata.color = (1.0, 0.772549033164978, 0.5607843399047852) 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.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_size = 1.9
lampdata.spot_blend = 0.9 lampdata.spot_blend = 0.9
lampdata.falloff_type = 'INVERSE_SQUARE'

View File

@ -7,5 +7,3 @@ lampdata = bpy.context.object.data
lampdata.color = (1.0, 0.5764706134796143, 0.16078431904315948) 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.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'

View File

@ -9,5 +9,3 @@ lampdata.spot_size = 1.25
lampdata.spot_blend = 0.9 lampdata.spot_blend = 0.9
lampdata.color = (0.8470588326454163, 0.9686274528503418, 1.0) 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.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'

View File

@ -14,5 +14,3 @@ lampdata.spot_size = 1.5
lampdata.spot_blend = 0.3 lampdata.spot_blend = 0.3
lampdata.color = (1.0, 0.9803921580314636, 0.95686274766922) 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.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'

View File

@ -9,4 +9,3 @@ lampdata.spot_size = 1.39626 #80 degrees in radian
lampdata.spot_blend = 0.5 lampdata.spot_blend = 0.5
lampdata.color = (1.0, 0.9372549057006836, 0.9686274528503418) 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.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/...

View File

@ -11,4 +11,3 @@ lampdata.pov.shadow_ray_samples_x = 2
lampdata.pov.shadow_ray_samples_y = 2 lampdata.pov.shadow_ray_samples_y = 2
lampdata.color = (1.0, 0.8292156958580017, 0.6966666865348816) 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.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/...

View File

@ -8,4 +8,3 @@ lampdata.size = 0.038
lampdata.size_y = 1.2192 lampdata.size_y = 1.2192
lampdata.color = (0.6549019813537598, 0.0, 1.0) 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.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/...

View File

@ -6,5 +6,3 @@ lampdata = bpy.context.object.data
lampdata.color = (0.6549019813537598, 0.0, 1.0) 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.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'

View File

@ -20,5 +20,3 @@ lampdata.color = (1.0, 0.7176470756530762, 0.2980392277240753)
#Family Living Room 50 #Family Living Room 50
#Sunset & Sunrise 400 lux #Sunset & Sunrise 400 lux
lampdata.energy = 2.0 #two times lux value lampdata.energy = 2.0 #two times lux value
lampdata.distance = 0.004
lampdata.falloff_type = 'INVERSE_SQUARE'

View File

@ -294,7 +294,7 @@ def export_lights(lamps, file, scene, global_matrix, tab_write):
tab_write(file, "point_at <0, 0, -1>\n") tab_write(file, "point_at <0, 0, -1>\n")
if lamp.pov.use_halo: if lamp.pov.use_halo:
tab_write(file, "looks_like{\n") 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, "hollow\n")
tab_write(file, "material{\n") tab_write(file, "material{\n")
tab_write(file, "texture{\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' tab_write(file, "point_at <0, 0, -1>\n") # *must* be after 'parallel'
elif lamp.type == "AREA": 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 # Area lights have no falloff type, so always use blenders lamp quad equivalent
# for those? # for those?
tab_write(file, "fade_power %d\n" % 2) 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 # Sun shouldn't be attenuated. Area lights have no falloff attribute so they
# are put to type 2 attenuation a little higher above. # are put to type 2 attenuation a little higher above.
if lamp.type not in {"SUN", "AREA"}: if lamp.type not in {"SUN", "AREA"}:
if lamp.falloff_type == "INVERSE_SQUARE": tab_write(file, "fade_power %d\n" % 2) # Use blenders lamp quad equivalent
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)
write_matrix(file, matrix) write_matrix(file, matrix)

View File

@ -465,28 +465,9 @@ class LIGHT_PT_POV_light(PovLightButtonsPanel, Panel):
sub.prop(light, "energy") sub.prop(light, "energy")
if light.type in {"POINT", "SPOT"}: if light.type in {"POINT", "SPOT"}:
sub.label(text="Falloff:") sub.prop(light, "shadow_soft_size", text="Radius")
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")
if light.type == "AREA": if light.type == "AREA":
col.prop(light, "distance")
col.separator()
col.prop(light, "shape") col.prop(light, "shape")
sub = col.column(align=True) sub = col.column(align=True)
@ -640,22 +621,6 @@ class LIGHT_PT_POV_spot(PovLightButtonsPanel, Panel):
draw = properties_data_light.DATA_PT_spot.draw 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): class OBJECT_PT_POV_rainbow(PovLightButtonsPanel, Panel):
"""Use this class to define buttons from the rainbow panel of """Use this class to define buttons from the rainbow panel of
properties window. inheriting lamp buttons panel class""" properties window. inheriting lamp buttons panel class"""