Game Engine: Level of detail support and tools
Levels of detail can be added and modified in the object panel. The object panel also contains new tools for generating levels of detail, setting up levels of detail based on object names (useful for importing), and clearing an object's level of detail settings. This is meant as a game engine feature, though the level of details settings can be previewed in the viewport. Reviewed By: moguri, nexyon, brecht Differential Revision: http://developer.blender.org/D109
This commit is contained in:
@@ -775,3 +775,154 @@ class DupliOffsetFromCursor(Operator):
|
||||
ob.users_group[group].dupli_offset = scene.cursor_location
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class LodByName(Operator):
|
||||
"""Add levels of detail to this object based on object names"""
|
||||
bl_idname = "object.lod_by_name"
|
||||
bl_label = "Setup Levels of Detail By Name"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.active_object is not None)
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
ob = context.active_object
|
||||
|
||||
prefix = ""
|
||||
suffix = ""
|
||||
name = ""
|
||||
if ob.name.lower().startswith("lod0"):
|
||||
prefix = ob.name[:4]
|
||||
name = ob.name[4:]
|
||||
elif ob.name.lower().endswith("lod0"):
|
||||
name = ob.name[:-4]
|
||||
suffix = ob.name[-4:]
|
||||
else:
|
||||
return {'CANCELLED'}
|
||||
|
||||
level = 0
|
||||
while True:
|
||||
level += 1
|
||||
|
||||
if prefix:
|
||||
prefix = prefix[:3] + str(level)
|
||||
if suffix:
|
||||
suffix = suffix[:3] + str(level)
|
||||
|
||||
lod = None
|
||||
try:
|
||||
lod = bpy.data.objects[prefix + name + suffix]
|
||||
except KeyError:
|
||||
break
|
||||
|
||||
try:
|
||||
ob.lod_levels[level]
|
||||
except IndexError:
|
||||
bpy.ops.object.lod_add()
|
||||
|
||||
ob.lod_levels[level].object = lod
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class LodClearAll(Operator):
|
||||
"""Remove all levels of detail from this object"""
|
||||
bl_idname = "object.lod_clear_all"
|
||||
bl_label = "Clear All Levels of Detail"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.active_object is not None)
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
ob = context.active_object
|
||||
|
||||
if ob.lod_levels:
|
||||
while 'CANCELLED' not in bpy.ops.object.lod_remove():
|
||||
pass
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class LodGenerate(Operator):
|
||||
"""Generates levels of detail using the decimate modifier"""
|
||||
bl_idname = "object.lod_generate"
|
||||
bl_label = "Generate Levels of Detail"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
count = bpy.props.IntProperty(name="Count", default=3)
|
||||
target = bpy.props.FloatProperty(name="Target Size", default=0.1,
|
||||
min=0.0, max=1.0)
|
||||
package = bpy.props.BoolProperty(name="Package into Group", default=False)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.active_object is not None)
|
||||
|
||||
def execute(self, context):
|
||||
scene = bpy.context.scene
|
||||
ob = scene.objects.active
|
||||
|
||||
lod_name = ob.name
|
||||
lod_suffix = "lod"
|
||||
lod_prefix = ""
|
||||
if lod_name.lower().endswith("lod0"):
|
||||
lod_suffix = lod_name[-3:-1]
|
||||
lod_name = lod_name[:-3]
|
||||
elif lod_name.lower().startswith("lod0"):
|
||||
lod_suffix = ""
|
||||
lod_prefix = lod_name[:3]
|
||||
lod_name = lod_name[4:]
|
||||
|
||||
group_name = lod_name.strip(' ._')
|
||||
if self.package:
|
||||
try:
|
||||
bpy.ops.object.group_link(group=group_name)
|
||||
except TypeError:
|
||||
bpy.ops.group.create(name=group_name)
|
||||
|
||||
step = (1.0 - self.target) / (self.count - 1)
|
||||
for i in range(1, self.count):
|
||||
scene.objects.active = ob
|
||||
bpy.ops.object.duplicate()
|
||||
lod = bpy.context.selected_objects[0]
|
||||
|
||||
scene.objects.active = ob
|
||||
bpy.ops.object.lod_add()
|
||||
scene.objects.active = lod
|
||||
|
||||
if lod_prefix:
|
||||
lod.name = lod_prefix + str(i) + lod_name
|
||||
else:
|
||||
lod.name = lod_name + lod_suffix + str(i)
|
||||
|
||||
lod.location.y = ob.location.y + 3.0 * i
|
||||
|
||||
if i == 1:
|
||||
modifier = lod.modifiers.new("lod_decimate", "DECIMATE")
|
||||
else:
|
||||
modifier = lod.modifiers[-1]
|
||||
|
||||
modifier.ratio = 1.0 - step*(i)
|
||||
|
||||
ob.lod_levels[i].object = lod
|
||||
|
||||
if self.package:
|
||||
bpy.ops.object.group_link(group=group_name)
|
||||
lod.parent = ob
|
||||
|
||||
if self.package:
|
||||
for level in ob.lod_levels[1:]:
|
||||
level.object.hide = level.object.hide_render = True
|
||||
|
||||
lod.select = False
|
||||
ob.select = True
|
||||
scene.objects.active = ob
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
Reference in New Issue
Block a user