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:
Diffstat (limited to 'source/blender/editors/object/object_lamp.c')
-rw-r--r--source/blender/editors/object/object_lamp.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/source/blender/editors/object/object_lamp.c b/source/blender/editors/object/object_lamp.c
new file mode 100644
index 00000000000..f60c8f3044e
--- /dev/null
+++ b/source/blender/editors/object/object_lamp.c
@@ -0,0 +1,235 @@
+/*
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+
+/** \file blender/editors/object/object_lamp.c
+ * \ingroup edobj
+ */
+
+#include "WM_types.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_matrix.h"
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_object.h"
+
+#include "ED_view3d.h"
+#include "ED_screen.h"
+
+#include "WM_types.h"
+#include "WM_api.h"
+
+#include "BIF_glutil.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "UI_interface.h"
+#include "object_intern.h"
+
+#include "RNA_define.h"
+#include "RNA_access.h"
+
+typedef struct LampPositionData {
+ int pos[2];
+ float quat[4];
+ float lvec[3];
+} LampPositionData;
+
+/* Modal Operator init */
+static int lamp_position_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Object *ob = CTX_data_active_object(C);
+ LampPositionData *data;
+ data = op->customdata = MEM_mallocN(sizeof (LampPositionData), "lamp_position_data");
+
+ copy_v2_v2_int(data->pos, event->mval);
+
+ mat4_to_quat(data->quat, ob->obmat);
+ copy_v3_v3(data->lvec, ob->obmat[2]);
+ negate_v3(data->lvec);
+ normalize_v3(data->lvec);
+
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Repeat operator */
+static int lamp_position_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+
+ LampPositionData *data = op->customdata;
+
+ switch (event->type) {
+ case MOUSEMOVE:
+ {
+ Object *ob = CTX_data_active_object(C);
+ Lamp *la = ob->data;
+ Scene *scene = CTX_data_scene(C);
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ float world_pos[3];
+ int flag = v3d->flag2;
+
+ v3d->flag2 |= V3D_RENDER_OVERRIDE;
+
+ view3d_operator_needs_opengl(C);
+ if (ED_view3d_autodist(scene, ar, v3d, event->mval, world_pos, true, NULL)) {
+ float axis[3];
+
+ /* restore the floag here */
+ v3d->flag2 = flag;
+
+ sub_v3_v3(world_pos, ob->obmat[3]);
+ la->dist = normalize_v3(world_pos);
+
+ cross_v3_v3v3(axis, data->lvec, world_pos);
+ if (normalize_v3(axis) > 0.0001) {
+ float mat[4][4];
+ float quat[4], qfinal[4];
+ float angle = saacos(dot_v3v3(world_pos, data->lvec));
+
+ /* transform the initial rotation quaternion to the new position and set the matrix to the lamp */
+ axis_angle_to_quat(quat, axis, angle);
+ mul_qt_qtqt(qfinal, quat, data->quat);
+ quat_to_mat4(mat, qfinal);
+ copy_v3_v3(mat[3], ob->obmat[3]);
+
+ BKE_object_apply_mat4(ob, mat, true, false);
+ }
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+
+ ED_region_tag_redraw(ar);
+ }
+
+ v3d->flag2 = flag;
+
+ break;
+ }
+
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ MEM_freeN(op->customdata);
+ return OPERATOR_FINISHED;
+ }
+
+ case EVT_WIDGET_UPDATE:
+ {
+ ARegion *ar = CTX_wm_region(C);
+ Object *ob = CTX_data_active_object(C);
+ Lamp *la = ob->data;
+ float value[3], len;
+
+ RNA_float_get_array(op->ptr, "value", value);
+
+ sub_v3_v3(value, ob->obmat[3]);
+
+ len = len_v3(value);
+
+ la->spotsize = len * 0.1f;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+
+ ED_region_tag_redraw(ar);
+ break;
+ }
+
+ case EVT_WIDGET_RELEASED:
+ {
+ MEM_freeN(op->customdata);
+ return OPERATOR_FINISHED;
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int lamp_position_poll(bContext *C)
+{
+ return CTX_wm_region_view3d(C) != NULL;
+}
+
+
+void LAMP_OT_lamp_position(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Lamp Position";
+ ot->idname = "UI_OT_lamp_position";
+ ot->description = "Sample a color from the Blender Window to store in a property";
+
+ /* api callbacks */
+ ot->invoke = lamp_position_invoke;
+ ot->modal = lamp_position_modal;
+ ot->poll = lamp_position_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
+}
+
+int WIDGETGROUP_lamp_poll(const struct bContext *C, struct wmWidgetGroupType *UNUSED(wgrouptype))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ if (ob && ob->type == OB_LAMP) {
+ Lamp *la = ob->data;
+ return (la->type == LA_SPOT);
+ }
+ return false;
+}
+
+void WIDGETGROUP_lamp_draw(const struct bContext *C, struct wmWidgetGroup *wgroup)
+{
+ float color_lamp[4] = {0.5f, 0.5f, 1.0f, 1.0f};
+ Object *ob = CTX_data_active_object(C);
+ Lamp *la = ob->data;
+ wmWidget *widget;
+ PointerRNA ptr;
+ float dir[3];
+
+ widget = WIDGET_arrow_new(wgroup, WIDGET_ARROW_STYLE_INVERTED);
+
+ WIDGET_arrow_set_color(widget, color_lamp);
+
+ RNA_pointer_create(&la->id, &RNA_Lamp, la, &ptr);
+ WM_widget_set_origin(widget, ob->obmat[3]);
+ WM_widget_property(widget, ARROW_SLOT_OFFSET_WORLD_SPACE, &ptr, "spot_size");
+ negate_v3_v3(dir, ob->obmat[2]);
+ WIDGET_arrow_set_direction(widget, dir);
+}