Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stokes <kupomail@gmail.com>2013-12-18 02:42:47 +0400
committerkupoman <kupomail@gmail.com>2013-12-18 05:03:27 +0400
commite9e08a1d12594eab0e341049fc252ff8578e9333 (patch)
treeac7c15959b03398babb68058f3824c2a4dbff5b7 /source/blender
parent173f7a3d30db8cba95656bf03dc842b9300c2436 (diff)
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
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_object.h8
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/object.c154
-rw-r--r--source/blender/blenloader/intern/readfile.c19
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/editors/object/CMakeLists.txt1
-rw-r--r--source/blender/editors/object/object_intern.h4
-rw-r--r--source/blender/editors/object/object_lod.c102
-rw-r--r--source/blender/editors/object/object_ops.c3
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c25
-rw-r--r--source/blender/gpu/intern/gpu_draw.c2
-rw-r--r--source/blender/makesdna/DNA_object_types.h16
-rw-r--r--source/blender/makesrna/intern/rna_object.c49
-rw-r--r--source/blender/windowmanager/WM_types.h1
16 files changed, 388 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 434175624b7..e6e6d621ef3 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -87,6 +87,14 @@ struct Object *BKE_object_add_only_object(struct Main *bmain, int type, const ch
struct Object *BKE_object_add(struct Main *bmain, struct Scene *scene, int type);
void *BKE_object_obdata_add_from_type(struct Main *bmain, int type);
+void BKE_object_lod_add(struct Object *ob);
+void BKE_object_lod_sort(struct Object *ob);
+bool BKE_object_lod_remove(struct Object *ob, int level);
+bool BKE_object_lod_update(struct Object *ob, float camera_position[3]);
+bool BKE_object_lod_is_usable(struct Object *ob, struct Scene *scene);
+struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct Scene *scene);
+struct Object *BKE_object_lod_matob_get(struct Object *ob, struct Scene *scene);
+
struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, int copy_caches);
struct Object *BKE_object_copy(struct Object *ob);
void BKE_object_make_local(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index cf9b838a7c2..9df523a5bfe 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -675,7 +675,7 @@ Material *give_current_material(Object *ob, short act)
{
Material ***matarar, *ma;
short *totcolp;
-
+
if (ob == NULL) return NULL;
/* if object cannot have material, (totcolp == NULL) */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 0694bde7b91..70b5fb9d420 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -388,6 +388,8 @@ void BKE_object_free(Object *ob)
if (ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
+ BLI_freelistN(&ob->lodlevels);
+
/* Free runtime curves data. */
if (ob->curve_cache) {
BLI_freelistN(&ob->curve_cache->bev);
@@ -427,6 +429,7 @@ void BKE_object_unlink(Object *ob)
ModifierData *md;
ARegion *ar;
RegionView3D *rv3d;
+ LodLevel *lod;
int a, found;
unlink_controllers(&ob->controllers);
@@ -608,6 +611,12 @@ void BKE_object_unlink(Object *ob)
DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
+ /* levels of detail */
+ for (lod = obt->lodlevels.first; lod; lod = lod->next) {
+ if (lod->source == ob)
+ lod->source = NULL;
+ }
+
obt = obt->id.next;
}
@@ -1015,6 +1024,138 @@ Object *BKE_object_add(Main *bmain, Scene *scene, int type)
return ob;
}
+void BKE_object_lod_add(Object *ob)
+{
+ LodLevel *lod = MEM_callocN(sizeof(LodLevel), "LoD Level");
+ LodLevel *last = ob->lodlevels.last;
+
+ /* If the lod list is empty, initialize it with the base lod level */
+ if (!last) {
+ LodLevel *base = MEM_callocN(sizeof(LodLevel), "Base LoD Level");
+ BLI_addtail(&ob->lodlevels, base);
+ base->flags = OB_LOD_USE_MESH | OB_LOD_USE_MAT;
+ base->source = ob;
+ last = ob->currentlod = base;
+ }
+
+ lod->distance = last->distance + 25.0f;
+ lod->flags = OB_LOD_USE_MESH | OB_LOD_USE_MAT;
+
+ BLI_addtail(&ob->lodlevels, lod);
+}
+
+static int lod_cmp(void *a, void *b)
+{
+ LodLevel *loda = (LodLevel*)a;
+ LodLevel *lodb = (LodLevel*)b;
+
+ if (loda->distance < lodb->distance) return -1;
+ return loda->distance > lodb->distance;
+}
+
+void BKE_object_lod_sort(Object *ob)
+{
+ BLI_sortlist(&ob->lodlevels, lod_cmp);
+}
+
+bool BKE_object_lod_remove(Object *ob, int level)
+{
+ LodLevel *rem;
+
+ if (level < 1 || level > BLI_countlist(&ob->lodlevels) - 1)
+ return false;
+
+ rem = BLI_findlink(&ob->lodlevels, level);
+
+ if (rem == ob->currentlod) {
+ ob->currentlod = rem->prev;
+ }
+
+ BLI_remlink(&ob->lodlevels, rem);
+ MEM_freeN(rem);
+
+ /* If there are no user defined lods, remove the base lod as well */
+ if (BLI_countlist(&ob->lodlevels) == 1) {
+ LodLevel *base = ob->lodlevels.first;
+ BLI_remlink(&ob->lodlevels, base);
+ MEM_freeN(base);
+ ob->currentlod = NULL;
+ }
+
+ return true;
+}
+
+static LodLevel* lod_level_select(Object *ob, float cam_loc[3])
+{
+ LodLevel *current = ob->currentlod;
+ float ob_loc[3], delta[3];
+ float distance2;
+
+ if (!current) return NULL;
+
+ copy_v3_v3(ob_loc, ob->obmat[3]);
+ sub_v3_v3v3(delta, ob_loc, cam_loc);
+ distance2 = len_squared_v3(delta);
+
+ /* check for higher LoD */
+ if (distance2 < current->distance*current->distance) {
+ while (current->prev && distance2 < current->distance*current->distance) {
+ current = current->prev;
+ }
+ }
+ /* check for lower LoD */
+ else {
+ while (current->next && distance2 > current->next->distance*current->next->distance) {
+ current = current->next;
+ }
+ }
+
+ return current;
+}
+
+bool BKE_object_lod_is_usable(Object *ob, Scene *scene)
+{
+ bool active = (scene) ? ob == OBACT : 0;
+ return (ob->mode == OB_MODE_OBJECT || !active);
+}
+
+bool BKE_object_lod_update(Object *ob, float camera_position[3])
+{
+ LodLevel* cur_level = ob->currentlod;
+ LodLevel* new_level = lod_level_select(ob, camera_position);
+
+ if (new_level != cur_level) {
+ ob->currentlod = new_level;
+ return true;
+ }
+
+ return false;
+}
+
+static Object *lod_ob_get(Object *ob, Scene *scene, int flag)
+{
+ LodLevel *current = ob->currentlod;
+
+ if (!current || !BKE_object_lod_is_usable(ob, scene))
+ return ob;
+
+ while( current->prev && (!(current->flags & flag) || !current->source || current->source->type != OB_MESH)) {
+ current = current->prev;
+ }
+
+ return current->source;
+}
+
+struct Object *BKE_object_lod_meshob_get(Object *ob, Scene *scene)
+{
+ return lod_ob_get(ob, scene, OB_LOD_USE_MESH);
+}
+
+struct Object *BKE_object_lod_matob_get(Object *ob, Scene *scene)
+{
+ return lod_ob_get(ob, scene, OB_LOD_USE_MAT);
+}
+
SoftBody *copy_softbody(SoftBody *sb, int copy_caches)
{
SoftBody *sbn;
@@ -1226,6 +1367,16 @@ static void copy_object_pose(Object *obn, Object *ob)
}
}
+static void copy_object_lod(Object *obn, Object *ob)
+{
+ BLI_duplicatelist(&obn->lodlevels, &ob->lodlevels);
+
+ if (obn->lodlevels.first)
+ ((LodLevel*)obn->lodlevels.first)->source = obn;
+
+ obn->currentlod = (LodLevel*) obn->lodlevels.first;
+}
+
bool BKE_object_pose_context_check(Object *ob)
{
if ((ob) &&
@@ -1346,6 +1497,9 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches)
obn->mpath = NULL;
+ copy_object_lod(obn, ob);
+
+
/* Copy runtime surve data. */
obn->curve_cache = NULL;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index ac34f81907a..f3244a63a8b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4492,6 +4492,16 @@ static void lib_link_object(FileData *fd, Main *main)
ob->rigidbody_constraint->ob1 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob1);
ob->rigidbody_constraint->ob2 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob2);
}
+
+ {
+ LodLevel *level;
+ for (level = ob->lodlevels.first; level; level = level->next) {
+ level->source = newlibadr(fd, ob->id.lib, level->source);
+
+ if (!level->source && level == ob->lodlevels.first)
+ level->source = ob;
+ }
+ }
}
}
@@ -5026,6 +5036,9 @@ static void direct_link_object(FileData *fd, Object *ob)
if (ob->sculpt) {
ob->sculpt = MEM_callocN(sizeof(SculptSession), "reload sculpt session");
}
+
+ link_list(fd, &ob->lodlevels);
+ ob->currentlod = ob->lodlevels.first;
}
/* ************ READ SCENE ***************** */
@@ -8396,6 +8409,12 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
expand_doit(fd, mainvar, ob->rigidbody_constraint->ob2);
}
+ if (ob->currentlod) {
+ LodLevel *level;
+ for (level = ob->lodlevels.first; level; level = level->next) {
+ expand_doit(fd, mainvar, level->source);
+ }
+ }
}
static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index be81f355e26..fd8c711fb1a 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1537,6 +1537,8 @@ static void write_objects(WriteData *wd, ListBase *idbase)
write_particlesystems(wd, &ob->particlesystem);
write_modifiers(wd, &ob->modifiers);
+
+ writelist(wd, DATA, "LodLevel", &ob->lodlevels);
}
ob= ob->id.next;
}
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index 143a33c3fdd..ecc967d5662 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
object_group.c
object_hook.c
object_lattice.c
+ object_lod.c
object_modifier.c
object_ops.c
object_relations.c
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 536f3f05ab2..8b0ddbbeb9b 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -255,5 +255,9 @@ void OBJECT_OT_group_remove(struct wmOperatorType *ot);
/* object_bake.c */
void OBJECT_OT_bake_image(wmOperatorType *ot);
+/* object_lod.c */
+void OBJECT_OT_lod_add(struct wmOperatorType *ot);
+void OBJECT_OT_lod_remove(struct wmOperatorType *ot);
+
#endif /* __OBJECT_INTERN_H__ */
diff --git a/source/blender/editors/object/object_lod.c b/source/blender/editors/object/object_lod.c
new file mode 100644
index 00000000000..952451ee21d
--- /dev/null
+++ b/source/blender/editors/object/object_lod.c
@@ -0,0 +1,102 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/object_lod.c
+ * \ingroup edobj
+ */
+
+
+#include "DNA_object_types.h"
+
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+
+#include "ED_screen.h"
+#include "ED_object.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "object_intern.h"
+
+static int object_lod_add_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+ BKE_object_lod_add(ob);
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_lod_add(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Add Level of Detail";
+ ot->description = "Add a level of detail to this object";
+ ot->idname = "OBJECT_OT_lod_add";
+
+ /* api callbacks */
+ ot->exec = object_lod_add_exec;
+ ot->poll = ED_operator_objectmode;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int object_lod_remove_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+ int index = RNA_int_get(op->ptr, "index");
+ if(!BKE_object_lod_remove(ob, index))
+ return OPERATOR_CANCELLED;
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_LOD, CTX_wm_view3d(C));
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_lod_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Level of Detail";
+ ot->description = "Remove a level of detail from this object";
+ ot->idname = "OBJECT_OT_lod_remove";
+
+ /* api callbacks */
+ ot->exec = object_lod_remove_exec;
+ ot->poll = ED_operator_objectmode;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_int(ot->srna, "index", 1, 1, INT_MAX, "Index", "", 1, INT_MAX);
+} \ No newline at end of file
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index efebbe8ddd7..a06a6d9781f 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -243,6 +243,9 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_bake_image);
WM_operatortype_append(OBJECT_OT_drop_named_material);
WM_operatortype_append(OBJECT_OT_laplaciandeform_bind);
+
+ WM_operatortype_append(OBJECT_OT_lod_add);
+ WM_operatortype_append(OBJECT_OT_lod_remove);
}
void ED_operatormacros_object(void)
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 225c58207e7..1e48be2ffab 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -3359,7 +3359,7 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
- Object *ob = base->object;
+ Object *ob = BKE_object_lod_meshob_get(base->object, scene);
Mesh *me = ob->data;
Material *ma = give_current_material(ob, 1);
const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 03b89972e55..9125d439432 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -809,6 +809,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
case ND_CONSTRAINT:
case ND_KEYS:
case ND_PARTICLE:
+ case ND_LOD:
ED_region_tag_redraw(ar);
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 9dd6ab8f841..701fb26a562 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1956,6 +1956,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
{
RegionView3D *rv3d = ar->regiondata;
ListBase *lb;
+ LodLevel *savedlod;
DupliObject *dob_prev = NULL, *dob, *dob_next = NULL;
Base tbase = {NULL};
BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
@@ -1976,6 +1977,13 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
for (; dob; dob_prev = dob, dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) {
tbase.object = dob->ob;
+ /* Make sure lod is updated from dupli's position */
+
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+ savedlod = dob->ob->currentlod;
+ BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
+
+
/* extra service: draw the duplicator in drawtype of parent, minimum taken
* to allow e.g. boundbox box objects in groups for LOD */
dt = tbase.object->dt;
@@ -2051,13 +2059,13 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
glLoadMatrixf(rv3d->viewmat);
}
else {
- copy_m4_m4(dob->ob->obmat, dob->mat);
draw_object(scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
}
tbase.object->dt = dt;
tbase.object->dtx = dtx;
tbase.object->transflag = transflag;
+ tbase.object->currentlod = savedlod;
}
/* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */
@@ -3183,6 +3191,18 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
}
}
+static void update_lods(Scene *scene, float camera_pos[3])
+{
+ Scene *sce_iter;
+ Base *base;
+ Object *ob;
+
+ for (SETLOOPER(scene, sce_iter, base)) {
+ ob = base->object;
+ BKE_object_lod_update(ob, camera_pos);
+ }
+}
+
/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */
static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit)
{
@@ -3205,6 +3225,9 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
/* setup view matrices */
view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
+ /* Make sure LoDs are up to date */
+ update_lods(scene, rv3d->viewinv[3]);
+
/* clear the background */
view3d_main_area_clear(scene, v3d, ar);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index ee59cf418bf..1f0e20a9210 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -1392,6 +1392,8 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
int gamma = BKE_scene_check_color_management_enabled(scene);
int new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
int use_matcap = (v3d->flag2 & V3D_SHOW_SOLID_MATCAP); /* assumes v3d->defmaterial->preview is set */
+
+ ob = BKE_object_lod_matob_get(ob, scene);
/* initialize state */
memset(&GMS, 0, sizeof(GMS));
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 9d07e046096..bff3ef75a5a 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -105,6 +105,13 @@ enum {
BOUNDBOX_DIRTY = (1 << 1),
};
+typedef struct LodLevel {
+ struct LodLevel *next, *prev;
+ struct Object *source;
+ int flags;
+ float distance;
+} LodLevel;
+
typedef struct Object {
ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
@@ -279,6 +286,9 @@ typedef struct Object {
float ima_ofs[2]; /* offset for image empties */
+ ListBase lodlevels; /* contains data for levels of detail */
+ LodLevel *currentlod;
+
/* Runtime valuated curve-specific data, not stored in the file */
struct CurveCache *curve_cache;
} Object;
@@ -470,6 +480,12 @@ enum {
OB_BOUND_CAPSULE = 7,
};
+/* lod flags */
+enum {
+ OB_LOD_USE_MESH = 1 << 0,
+ OB_LOD_USE_MAT = 1 << 1,
+};
+
/* **************** BASE ********************* */
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 9c1d0c4cc2b..40bea3a6051 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -40,6 +40,7 @@
#include "DNA_meta_types.h"
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
#include "BKE_paint.h"
#include "BKE_editmesh.h"
@@ -1471,6 +1472,11 @@ int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr)
return (ss && ss->bm);
}
+static void rna_Object_lod_distance_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ Object *ob = (Object *)ptr->id.data;
+ BKE_object_lod_sort(ob);
+}
#else
static void rna_def_vertex_group(BlenderRNA *brna)
@@ -2030,6 +2036,41 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
}
+static void rna_def_object_lodlevel(BlenderRNA* brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "LodLevel", NULL);
+ RNA_def_struct_sdna(srna, "LodLevel");
+
+ prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
+ RNA_def_property_float_sdna(prop, NULL, "distance");
+ RNA_def_property_range(prop, 0.0, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Distance", "Distance to begin using this level of detail");
+ RNA_def_property_update(prop, NC_OBJECT|ND_LOD, "rna_Object_lod_distance_update");
+
+ prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "source");
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Object", "Object to use for this level of detail");
+ RNA_def_property_update(prop, NC_OBJECT|ND_LOD, NULL);
+
+ prop = RNA_def_property(srna, "use_mesh", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", OB_LOD_USE_MESH);
+ RNA_def_property_ui_text(prop, "Use Mesh", "Use the mesh from this object at this level of detail");
+ RNA_def_property_ui_icon(prop, ICON_MESH_DATA, 0);
+ RNA_def_property_update(prop, NC_OBJECT|ND_LOD, NULL);
+
+ prop = RNA_def_property(srna, "use_material", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", OB_LOD_USE_MAT);
+ RNA_def_property_ui_text(prop, "Use Material", "Use the material from this object at this level of detail");
+ RNA_def_property_ui_icon(prop, ICON_MATERIAL, 0);
+ RNA_def_property_update(prop, NC_OBJECT|ND_LOD, NULL);
+}
+
+
static void rna_def_object(BlenderRNA *brna)
{
StructRNA *srna;
@@ -2690,6 +2731,13 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Dynamic Topology Sculpting", NULL);
+ /* Levels of Detail */
+ prop = RNA_def_property(srna, "lod_levels", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "lodlevels", NULL);
+ RNA_def_property_struct_type(prop, "LodLevel");
+ RNA_def_property_ui_text(prop, "Level of Detail Levels", "A collection of detail levels to automatically switch between");
+ RNA_def_property_update(prop, NC_OBJECT|ND_LOD, NULL);
+
RNA_api_object(srna);
}
@@ -2800,6 +2848,7 @@ void RNA_def_object(BlenderRNA *brna)
rna_def_material_slot(brna);
rna_def_dupli_object(brna);
RNA_define_animate_sdna(true);
+ rna_def_object_lodlevel(brna);
}
#endif
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index dabb90b2ba0..83c17170f9e 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -297,6 +297,7 @@ typedef struct wmNotifier {
#define ND_PARTICLE (27<<16)
#define ND_POINTCACHE (28<<16)
#define ND_PARENT (29<<16)
+#define ND_LOD (30<<16)
/* NC_MATERIAL Material */
#define ND_SHADING (30<<16)