in layer1/Scene.cpp [4832:5660]
static int SceneDrag(Block * block, int x, int y, int mod, double when)
{
PyMOLGlobals *G = block->m_G;
CScene *I = G->Scene;
float scale, vScale;
float v1[3], v2[3], n1[3], n2[3], r1, r2, cp[3], v3[3];
float dx, dy, dt;
float axis[3], axis2[3], theta, omega;
float old_front, old_back, old_origin;
int mode;
int eff_width;
int moved_flag;
int adjust_flag;
int drag_handled = false;
int virtual_trackball;
CObject *obj;
if(I->PossibleSingleClick) {
double slowest_single_click_drag = 0.15;
if((when - I->LastClickTime) > slowest_single_click_drag) {
I->PossibleSingleClick = 0;
}
}
if(I->LoopFlag) {
return SceneLoopDrag(block, x, y, mod);
}
if(I->ButtonsShown && I->PressMode) {
if(I->ButtonsValid) {
SceneElem *elem = I->SceneVLA;
int i;
drag_handled = true;
I->Over = -1;
for(i = 0; i < I->NScene; i++) {
if(elem->drawn &&
(x >= elem->x1) && (y >= elem->y1) && (x < elem->x2) && (y < elem->y2)) {
I->Over = i;
OrthoDirty(G);
break;
}
elem++;
}
switch (I->PressMode) {
case 2:
if(I->Over >= 0) {
if(I->Pressed != I->Over) {
const char *cur_name = SettingGetGlobal_s(G, cSetting_scene_current_name);
if(cur_name && elem->name && (strcmp(cur_name, elem->name))) {
OrthoLineType buffer;
int animate = -1;
if(mod & cOrthoCTRL)
animate = 0;
sprintf(buffer, "cmd.scene('''%s''',animate=%d)", elem->name, animate);
PParse(G, buffer);
PFlush(G);
PLog(G, buffer, cPLog_pym);
}
I->Pressed = I->Over;
}
} else {
I->Pressed = -1;
}
case 3:
if((I->Over >= 0) && (I->Pressed != I->Over))
I->PressMode = 4; /* activate dragging */
break;
}
if(I->PressMode == 4) { /* dragging */
if((I->Over >= 0) && (I->Pressed != I->Over) && (I->Pressed >= 0)) {
SceneElem *pressed = I->SceneVLA + I->Pressed;
OrthoLineType buffer;
if(I->Over > 0) { /* not over the first scene in list */
SceneElem *first = elem - 1;
SceneElem *second = pressed;
if(first >= pressed) {
first = elem;
second = pressed;
}
sprintf(buffer, "cmd.scene_order('''%s %s''')", first->name, second->name);
} else {
sprintf(buffer, "cmd.scene_order('''%s''',location='top')", pressed->name);
}
PParse(G, buffer);
PFlush(G);
PLog(G, buffer, cPLog_pym);
I->Pressed = I->Over;
I->ButtonsValid = false;
if(SettingGetGlobal_b(G, cSetting_scene_buttons)){
OrthoInvalidateDoDraw(G);
}
}
}
}
}
if(!drag_handled) {
mode = ButModeTranslate(G, I->Button, mod);
y = y - I->margin.bottom;
scale = (float) I->Height;
if(scale > I->Width)
scale = (float) I->Width;
scale = 0.45F * scale;
SceneInvalidateCopy(G, false);
SceneDontCopyNext(G);
switch (mode) {
case cButModePickAtom:
obj = (CObject *) I->LastPicked.context.object;
if(obj)
switch (obj->type) {
case cObjectGadget:
{
ObjectGadget *gad;
gad = (ObjectGadget *) obj;
ObjectGadgetGetVertex(gad, I->LastPicked.src.index, I->LastPicked.src.bond,
v1);
vScale = SceneGetExactScreenVertexScale(G, v1);
if(stereo_via_adjacent_array(I->StereoMode)) {
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
/* transform into model coodinate space */
switch (obj->Context) {
case 1:
{
float divisor;
divisor = (float) I->Width;
if(I->Height < I->Width)
divisor = (float) I->Height;
v2[0] = (x - I->LastX) / divisor;
v2[1] = (y - I->LastY) / divisor;
v2[2] = 0;
}
break;
default:
case 0:
v2[0] = (x - I->LastX) * vScale;
v2[1] = (y - I->LastY) * vScale;
v2[2] = 0;
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v2, v2);
break;
}
add3f(v1, v2, v2);
ObjectGadgetSetVertex(gad, I->LastPicked.src.index, I->LastPicked.src.bond,
v2);
if (I->LastPicked.src.index){ // pick id on gadget is 1 for band (to change values),
// 0 for everything else (to move it around)
SceneChanged(G); // changing values, need to update gadget text
} else {
PyMOL_NeedRedisplay(G->PyMOL); // moving gadget, just re-draw
}
}
break;
}
I->LastX = x;
I->LastY = y;
break;
case cButModeRotDrag:
eff_width = I->Width;
if(stereo_via_adjacent_array(I->StereoMode)) {
eff_width = I->Width / 2;
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
virtual_trackball = SettingGet_i(G, NULL, NULL, cSetting_virtual_trackball);
if (virtual_trackball==2 &&
(!I->prev_no_z_rotation1 || !I->prev_no_z_rotation2)) {
/* when virtual_trackball=2 and twisting, need to set v1,v2 relative to orig */
v2[0] = (float) (eff_width / 2) - I->orig_x_rotation;
v2[1] = (float) (I->Height / 2) - I->orig_y_rotation;
v1[0] = v2[0] - (float) (x - I->LastX);
v1[1] = v2[1] - (float) (y - I->LastY);
} else if(virtual_trackball==1){
v1[0] = (float) (eff_width / 2) - x;
v1[1] = (float) (I->Height / 2) - y;
v2[0] = (float) (eff_width / 2) - I->LastX;
v2[1] = (float) (I->Height / 2) - I->LastY;
} else {
v1[0] = (float) (I->LastX) - x;
v1[1] = (float) (I->LastY) - y;
v2[0] = 0;
v2[1] = 0;
}
r1 = (float) sqrt1f(v1[0] * v1[0] + v1[1] * v1[1]);
r2 = (float) sqrt1f(v2[0] * v2[0] + v2[1] * v2[1]);
{
short r1lt, r2lt;
if(virtual_trackball==2) {
r1lt = I->prev_no_z_rotation1;
r2lt = I->prev_no_z_rotation2;
} else {
r1lt = r1 < scale;
r2lt = r2 < scale;
I->prev_no_z_rotation1 = r1 < scale;
I->prev_no_z_rotation2 = r2 < scale;
I->orig_x_rotation = x;
I->orig_y_rotation = y;
}
if(r1lt) {
v1[2] = (float) sqrt1f(scale * scale - r1 * r1);
} else {
v1[2] = 0.0;
}
if(r2lt) {
v2[2] = (float) sqrt1f(scale * scale - r2 * r2);
} else {
v2[2] = 0.0;
}
}
normalize23f(v1, n1);
normalize23f(v2, n2);
cross_product3f(n1, n2, cp);
theta = (float) (SettingGet_f(G, NULL, NULL, cSetting_mouse_scale) *
2 * 180 *
asin(sqrt1f(cp[0] * cp[0] + cp[1] * cp[1] + cp[2] * cp[2])) / cPI);
dx = (v1[0] - v2[0]);
dy = (v1[1] - v2[1]);
dt =
(float) (SettingGet_f(G, NULL, NULL, cSetting_mouse_limit) *
sqrt1f(dx * dx + dy * dy) / scale);
if(theta > dt)
theta = dt;
normalize23f(cp, axis);
axis[2] = -axis[2];
theta = theta / (1.0F + (float) fabs(axis[2]));
/* transform into model coodinate space */
MatrixInvTransformC44fAs33f3f(I->RotMatrix, axis, v2);
v1[0] = (float) (cPI * theta / 180.0);
EditorDrag(G, NULL, -1, mode,
SettingGetGlobal_i(G, cSetting_state) - 1, v1, v2, v3);
I->LastX = x;
I->LastY = y;
break;
case cButModeMovDrag:
case cButModeMovDragZ:
if(I->Threshold) {
if((abs(x - I->ThresholdX) > I->Threshold) ||
(abs(y - I->ThresholdY) > I->Threshold)) {
I->Threshold = 0;
}
}
if(!I->Threshold) {
copy3f(I->Origin, v1);
vScale = SceneGetExactScreenVertexScale(G, v1);
if(stereo_via_adjacent_array(I->StereoMode)) {
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
if(mode == cButModeMovDragZ) {
v2[0] = 0;
v2[1] = 0;
v2[2] = -(y - I->LastY) * vScale;
} else {
v2[0] = (x - I->LastX) * vScale;
v2[1] = (y - I->LastY) * vScale;
v2[2] = 0;
}
v3[0] = 0.0F;
v3[1] = 0.0F;
v3[2] = 1.0F;
/* transform into model coodinate space */
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v2, v2);
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v3, v3);
EditorDrag(G, NULL, -1, mode,
SettingGetGlobal_i(G, cSetting_state) - 1, v1, v2, v3);
}
I->LastX = x;
I->LastY = y;
break;
case cButModeRotObj:
case cButModeMovObj:
case cButModeMovObjZ:
case cButModeRotView:
case cButModeMovView:
case cButModeMovViewZ:
case cButModeRotFrag:
case cButModeMovFrag:
case cButModeMovFragZ:
case cButModeTorFrag:
case cButModeMoveAtom:
case cButModeMoveAtomZ:
case cButModePkTorBnd:
obj = (CObject *) I->LastPicked.context.object;
if(obj) {
if(I->Threshold) {
if((abs(x - I->ThresholdX) > I->Threshold) ||
(abs(y - I->ThresholdY) > I->Threshold)) {
I->Threshold = 0;
}
}
if(!I->Threshold)
switch (obj->type) {
case cObjectGadget: /* note repeated above */
{
ObjectGadget *gad;
gad = (ObjectGadget *) obj;
ObjectGadgetGetVertex(gad, I->LastPicked.src.index, I->LastPicked.src.bond,
v1);
vScale = SceneGetExactScreenVertexScale(G, v1);
if(stereo_via_adjacent_array(I->StereoMode)) {
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
/* transform into model coodinate space */
switch (obj->Context) {
case 1:
{
float divisor;
divisor = (float) I->Width;
if(I->Height < I->Width)
divisor = (float) I->Height;
v2[0] = (x - I->LastX) / divisor;
v2[1] = (y - I->LastY) / divisor;
v2[2] = 0;
}
break;
default:
case 0:
v2[0] = (x - I->LastX) * vScale;
v2[1] = (y - I->LastY) * vScale;
v2[2] = 0;
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v2, v2);
break;
}
add3f(v1, v2, v2);
ObjectGadgetSetVertex(gad, I->LastPicked.src.index, I->LastPicked.src.bond,
v2);
if (I->LastPicked.src.index){ // pick id on gadget is 1 for band (to change values),
// 0 for everything else (to move it around)
SceneChanged(G); // changing values, need to update gadget text
} else {
PyMOL_NeedRedisplay(G->PyMOL); // moving gadget, just re-draw
}
}
break;
case cObjectMolecule:
if(ObjectMoleculeGetAtomTxfVertex((ObjectMolecule *) obj,
I->LastPicked.context.state,
I->LastPicked.src.index, v1)) {
/* scale properly given the current projection matrix */
vScale = SceneGetExactScreenVertexScale(G, v1);
if(stereo_via_adjacent_array(I->StereoMode)) {
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
switch (mode) {
case cButModeMovFragZ:
case cButModeMovObjZ:
case cButModeMovViewZ:
case cButModeMoveAtomZ:
v2[0] = 0;
v2[1] = 0;
v2[2] = -(y - I->LastY) * vScale;
break;
default:
v2[0] = (x - I->LastX) * vScale;
v2[1] = (y - I->LastY) * vScale;
v2[2] = 0;
break;
}
v3[0] = 0.0F;
v3[1] = 0.0F;
v3[2] = 1.0F;
/* transform into model coodinate space */
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v2, v2);
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v3, v3);
if(I->LastPicked.src.bond >= cPickableAtom) {
if((mode != cButModeMoveAtom) && (mode != cButModeMoveAtomZ)) {
EditorDrag(G, obj, I->LastPicked.src.index, mode,
SettingGetGlobal_i(G, cSetting_state) - 1, v1, v2, v3);
switch(mode) {
case cButModeMovViewZ:
case cButModeRotView:
case cButModeMovView:
if(SettingGetGlobal_i(G,cSetting_movie_auto_store) &&
SettingGetGlobal_i(G,cSetting_movie_auto_interpolate)) {
I->ReinterpolateFlag = true;
I->ReinterpolateObj = obj;
}
break;
}
} else {
int log_trans = SettingGetGlobal_b(G, cSetting_log_conformations);
ObjectMolecule *objOM = (ObjectMolecule *) obj;
ObjectMoleculeMoveAtom(objOM,
I->LastPicked.context.state,
I->LastPicked.src.index, v2, 1, log_trans);
/* -- JV - if this object knows about distances, then move them if necessary */
/* check the dynamic_measures setting and make sure the object has a distance measure, first */
/* obviated by new method
if (SettingGetGlobal_i(G, cSetting_dynamic_measures))
ObjectMoleculeMoveDist( (ObjectMolecule *) obj, SettingGetGlobal_i(G, cSetting_state)-1, I->LastPicked.src.index, v2, 1, log_trans);
*/
SceneInvalidate(G);
}
} else {
int log_trans = SettingGetGlobal_b(G, cSetting_log_conformations);
ObjectMolecule *objOM = (ObjectMolecule *) obj;
float diffInPixels[2];
diffInPixels[0] = (x - I->LastX);
diffInPixels[1] = (y - I->LastY);
ObjectMoleculeMoveAtomLabel(objOM,
I->LastPicked.context.state,
I->LastPicked.src.index, v2, log_trans, diffInPixels);
SceneInvalidate(G);
}
}
break;
case cObjectSlice:
{
ObjectSlice *slice = (ObjectSlice *) obj;
if(I->LastPickVertexFlag) {
copy3f(I->LastPickVertex, v1);
vScale = SceneGetExactScreenVertexScale(G, v1);
if(stereo_via_adjacent_array(I->StereoMode)) {
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
v2[0] = (x - I->LastX) * vScale;
v2[1] = (y - I->LastY) * vScale;
v2[2] = 0;
v3[0] = 0.0F;
v3[1] = 0.0F;
v3[2] = 1.0F;
/* transform into model coodinate space */
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v2, v2);
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v3, v3);
ObjectSliceDrag(slice, SceneGetState(G), mode, v1, v2, v3);
}
}
break;
case cObjectMeasurement:
if(ObjectDistGetLabelTxfVertex((ObjectDist *) obj,
I->LastPicked.context.state,
I->LastPicked.src.index, v1)) {
/* scale properly given the current projection matrix */
vScale = SceneGetExactScreenVertexScale(G, v1);
if(stereo_via_adjacent_array(I->StereoMode)) {
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
switch (mode) {
case cButModeMovFragZ:
case cButModeMovObjZ:
case cButModeMovViewZ:
case cButModeMoveAtomZ:
v2[0] = 0;
v2[1] = 0;
v2[2] = -(y - I->LastY) * vScale;
break;
default:
v2[0] = (x - I->LastX) * vScale;
v2[1] = (y - I->LastY) * vScale;
v2[2] = 0;
break;
}
v3[0] = 0.0F;
v3[1] = 0.0F;
v3[2] = 1.0F;
/* transform into model coodinate space */
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v2, v2);
MatrixInvTransformC44fAs33f3f(I->RotMatrix, v3, v3);
if(I->LastPicked.src.bond == cPickableLabel) {
int log_trans = SettingGetGlobal_b(G, cSetting_log_conformations);
ObjectDistMoveLabel((ObjectDist *) obj,
I->LastPicked.context.state,
I->LastPicked.src.index, v2, 1, log_trans);
SceneInvalidate(G);
}
}
break;
default:
break;
}
}
I->LastX = x;
I->LastY = y;
break;
case cButModeTransXY:
SceneNoteMouseInteraction(G);
vScale = SceneGetExactScreenVertexScale(G, I->Origin);
if(stereo_via_adjacent_array(I->StereoMode)) {
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
v2[0] = (x - I->LastX) * vScale;
v2[1] = (y - I->LastY) * vScale;
v2[2] = 0.0F;
moved_flag = false;
if(I->LastX != x) {
I->Pos[0] += v2[0];
I->LastX = x;
SceneInvalidate(G);
moved_flag = true;
}
if(I->LastY != y) {
I->Pos[1] += v2[1];
I->LastY = y;
SceneInvalidate(G);
moved_flag = true;
}
EditorFavorOrigin(G, NULL);
if(moved_flag && SettingGetGlobal_b(G, cSetting_roving_origin)) {
SceneGetCenter(G, v2); /* gets position of center of screen */
SceneOriginSet(G, v2, true);
}
if(moved_flag && SettingGetGlobal_b(G, cSetting_roving_detail)) {
SceneRovingDirty(G);
}
break;
case cButModeRotXYZ:
case cButModeRotZ:
case cButModeInvRotZ:
case cButModeTransZ:
case cButModeClipNF:
case cButModeClipN:
case cButModeClipF:
case cButModeRotL:
case cButModeMovL:
case cButModeMvzL:
SceneNoteMouseInteraction(G);
virtual_trackball = SettingGet_i(G, NULL, NULL, cSetting_virtual_trackball);
eff_width = I->Width;
if(stereo_via_adjacent_array(I->StereoMode)) {
eff_width = I->Width / 2;
x = get_stereo_x(x, &I->LastX, I->Width, NULL);
}
if (virtual_trackball==2 &&
(!I->prev_no_z_rotation1 || !I->prev_no_z_rotation2)) {
/* when virtual_trackball=2 and twisting, need to set v1,v2 relative to orig */
v2[0] = (float) (eff_width / 2) - I->orig_x_rotation;
v2[1] = (float) (I->Height / 2) - I->orig_y_rotation;
v1[0] = v2[0] - (float) (x - I->LastX);
v1[1] = v2[1] - (float) (y - I->LastY);
} else if(virtual_trackball==1){
v1[0] = (float) (eff_width / 2) - x;
v1[1] = (float) (I->Height / 2) - y;
v2[0] = (float) (eff_width / 2) - I->LastX;
v2[1] = (float) (I->Height / 2) - I->LastY;
} else {
v1[0] = (float) (I->LastX) - x;
v1[1] = (float) (I->LastY) - y;
v2[0] = 0;
v2[1] = 0;
}
r1 = (float) sqrt1f(v1[0] * v1[0] + v1[1] * v1[1]);
r2 = (float) sqrt1f(v2[0] * v2[0] + v2[1] * v2[1]);
{
short r1lt, r2lt;
if(SettingGet_i(G, NULL, NULL, cSetting_virtual_trackball)==2) {
r1lt = I->prev_no_z_rotation1;
r2lt = I->prev_no_z_rotation2;
} else {
r1lt = r1 < scale;
r2lt = r2 < scale;
I->prev_no_z_rotation1 = r1 < scale;
I->prev_no_z_rotation2 = r2 < scale;
I->orig_x_rotation = x;
I->orig_y_rotation = y;
}
if(r1lt) {
float val = scale * scale - r1 * r1;
short isNeg = val < 0.f;
v1[2] = (float) sqrt(fabs(val)) * (isNeg ? -1.f : 1.f);
} else {
v1[2] = 0.0;
}
if(r2lt) {
float val = scale * scale - r2 * r2;
short isNeg = val < 0.f;
v2[2] = (float) sqrt(fabs(val)) * (isNeg ? -1.f : 1.f);
} else {
v2[2] = 0.0;
}
}
normalize23f(v1, n1);
normalize23f(v2, n2);
cross_product3f(n1, n2, cp);
theta = (float) (SettingGet_f(G, NULL, NULL, cSetting_mouse_scale) *
2 * 180 *
asin(sqrt1f(cp[0] * cp[0] + cp[1] * cp[1] + cp[2] * cp[2])) / cPI);
dx = (v1[0] - v2[0]);
dy = (v1[1] - v2[1]);
dt =
(float) (SettingGet_f(G, NULL, NULL, cSetting_mouse_limit) *
sqrt1f(dx * dx + dy * dy) / scale);
if(theta > dt)
theta = dt;
normalize23f(cp, axis);
theta = theta / (1.0F + (float) fabs(axis[2]));
v1[2] = 0.0;
v2[2] = 0.0;
normalize23f(v1, n1);
normalize23f(v2, n2);
cross_product3f(n1, n2, cp);
omega =
(float) (2 * 180 * asin(sqrt1f(cp[0] * cp[0] + cp[1] * cp[1] + cp[2] * cp[2])) /
cPI);
normalize23f(cp, axis2);
old_front = I->Front;
old_back = I->Back;
old_origin = -I->Pos[2];
moved_flag = false;
adjust_flag = false;
switch (mode) {
case cButModeRotXYZ:
if(I->LastX != x) {
SceneRotate(G, theta, axis[0], axis[1], -axis[2]);
I->LastX = x;
adjust_flag = true;
}
if(I->LastY != y) {
SceneRotate(G, theta, axis[0], axis[1], -axis[2]);
I->LastY = y;
adjust_flag = true;
}
break;
case cButModeRotZ:
if(I->LastX != x) {
SceneRotate(G, omega, axis2[0], axis2[1], -axis2[2]);
I->LastX = x;
adjust_flag = true;
}
if(I->LastY != y) {
SceneRotate(G, omega, axis2[0], axis2[1], -axis2[2]);
I->LastY = y;
adjust_flag = true;
}
break;
case cButModeInvRotZ:
if(I->LastX != x) {
SceneRotate(G, (I->LastX - x) / 2.0F, 0.0F, 0.0F, 1.0F);
I->LastX = x;
adjust_flag = true;
}
break;
case cButModeTransZ:
// zoom
if(I->LastY != y) {
{
// the 5.0 min depth below is an empirical value
float factor = SettingGetGlobal_f(G, cSetting_mouse_z_scale) *
(y - I->LastY) / 400.0 * std::max(5.f, -I->Pos[2]);
if(!SettingGetGlobal_b(G, cSetting_legacy_mouse_zoom))
factor = -factor;
I->Pos[2] += factor;
I->Front -= factor;
I->Back -= factor;
UpdateFrontBackSafe(I);
}
I->LastY = y;
SceneInvalidate(G);
adjust_flag = true;
}
break;
case cButModeClipNF:
if(I->LastX != x) {
I->Back -= (((float) x) - I->LastX) / 10;
I->LastX = x;
moved_flag = true;
}
if(I->LastY != y) {
I->Front -= (((float) y) - I->LastY) / 10;
I->LastY = y;
moved_flag = true;
}
if(moved_flag) {
SceneClipSet(G, I->Front, I->Back);
}
break;
case cButModeClipN:
if(I->LastX != x || I->LastY != y) {
I->Front -= (x - I->LastX + y - I->LastY) / 10.f;
I->LastX = x;
I->LastY = y;
SceneClipSet(G, I->Front, I->Back);
moved_flag = true;
}
break;
case cButModeClipF:
if(I->LastX != x || I->LastY != y) {
I->Back -= (x - I->LastX + y - I->LastY) / 10.f;
I->LastX = x;
I->LastY = y;
SceneClipSet(G, I->Front, I->Back);
moved_flag = true;
}
break;
case cButModeRotL:
case cButModeMovL:
{
/* when light_count == 1, there is an ambient light;
* when light_count == 2, there are two lights, the ambient and
* a directional, called "light". When there are three, it's the
* ambient, light and the third is light2, and so on.
*
* Should we use an off-by-one here to make this easier for the
* user to understand? light1 is ambient, light2 is first directional
*
*/
float pos[3];
int which_light;
float ms = 0.01;
which_light = light_setting_indices[glm::clamp(
SettingGetGlobal_i(G, cSetting_edit_light), 1, 9) - 1];
copy3f(SettingGet<const float *>(G, which_light), pos);
pos[0] += (float) dx * ms;
pos[1] += (float) dy * ms;
SettingSet_3fv(G->Setting, which_light, pos);
SettingGenerateSideEffects(G, which_light, NULL, 0, 1);
I->LastX = x;
I->LastY = y;
}
break;
case cButModeMvzL:
{
float pos[3];
int which_light;
float ms = 0.01;
float factor = 0.f;
/* when light_count == 1, there is an ambient light;
* when light_count == 2, there are two lights, the ambient and
* a directional, called "light". When there are three, it's the
* ambient, light and the third is light2, and so on.
*/
which_light = light_setting_indices[glm::clamp(
SettingGetGlobal_i(G, cSetting_edit_light), 1, 9) - 1];
if(I->LastY != y) {
factor = 400 / ((I->FrontSafe + I->BackSafe) / 2);
if(factor >= 0.0F) {
factor = SettingGetGlobal_f(G, cSetting_mouse_z_scale) *
(((float) y) - I->LastY) / factor;
if(!SettingGetGlobal_b(G, cSetting_legacy_mouse_zoom))
factor = -factor;
}
}
copy3f(SettingGet<const float *>(G, which_light), pos);
SettingGenerateSideEffects(G, which_light, NULL, 0, 1);
pos[2] -= factor * ms;
SettingSet_3fv(G->Setting, which_light, pos);
I->LastX = x;
I->LastY = y;
}
break;
}
if(moved_flag)
SceneDoRoving(G, old_front, old_back, old_origin, adjust_flag, false);
}
}
if(I->PossibleSingleClick) {
int max_single_click_drag = 4;
int dx = abs(I->StartX - I->LastX);
int dy = abs(I->StartY - I->LastY);
if((dx > max_single_click_drag) || (dy > max_single_click_drag)) {
I->PossibleSingleClick = false;
}
}
return (1);
}