private static void UpdateTimeScale() { var value = 1f; foreach (var kv in timeScaleList) { value *= kv.Value; } Time.timeScale = value; OnScaleChange?.Invoke(value); }
public void ScaleChanged(Vector3 scale) { OnScaleChange?.Invoke(scale); }
public override void Update(Camera cam) { if (!Visible) { return; } var ori = Rotation;// : Quaternion.Identity; Vector3 xdir = Vector3.UnitX; Vector3 ydir = Vector3.UnitY; Vector3 zdir = Vector3.UnitZ; Vector3[] axes = { xdir, ydir, zdir }; Vector3[] sides1 = { ydir, zdir, xdir }; Vector3[] sides2 = { zdir, xdir, ydir }; WidgetAxis[] sideax1 = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X }; WidgetAxis[] sideax2 = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y }; Quaternion iori = Quaternion.Invert(ori); Vector3 camrel = iori.Multiply(Position - cam.Position); Vector3 cdir = Vector3.Normalize(camrel); Ray ray = cam.MouseRay; ray.Position = iori.Multiply(ray.Position); ray.Direction = iori.Multiply(ray.Direction); float dist = camrel.Length(); float size = GetWorldSize(Size, dist, cam); float axhitrad = 0.09f * size; float axhitstart = 0.4f * size; float axhitend = 1.33f * size; float innertri = 0.7f * size; float outertri = 1.0f * size; //test for single and double axes hits BoundingBox bb = new BoundingBox(); float hitd = float.MaxValue; float d; Vector3 hitp; WidgetAxis hitax = WidgetAxis.None; for (int i = 0; i < 3; i++) { WidgetAxis ax = (WidgetAxis)(1 << i); Vector3 s = sides1[i] * axhitrad + sides2[i] * axhitrad; bb.Minimum = camrel - s + axes[i] * axhitstart; bb.Maximum = camrel + s + axes[i] * axhitend; if (ray.Intersects(ref bb, out d)) //single axis { if (d < hitd) { hitd = d; hitax = ax; } } Vector3 s1 = axes[i]; Vector3 s2 = sides1[i]; if (GetAxisRayHit(s1, s2, camrel, ray, out hitp)) { //test if hitp is within the inner triangle - uniform scale //test if hitp is within the outer triangle - 2 axes scale float hitpl = hitp.Length(); if (hitpl > hitd) { continue; } Vector3 hitrel = hitp - camrel; float d1 = Vector3.Dot(hitrel, s1); float d2 = Vector3.Dot(hitrel, s2); if ((d1 > 0) && (d2 > 0)) { if ((d1 < innertri) && (d2 < innertri) && ((d1 + d2) < innertri)) { hitd = hitpl; hitax = WidgetAxis.XYZ; } else if ((d1 < outertri) && (d2 < outertri) && ((d1 + d2) < outertri)) { hitd = hitpl; hitax = ax | sideax1[i]; } } } } if (LockXY) { switch (hitax) { case WidgetAxis.X: case WidgetAxis.Y: hitax = WidgetAxis.XY; break; case WidgetAxis.XZ: case WidgetAxis.YZ: hitax = WidgetAxis.XYZ; break; } } MousedAxis = hitax; if (IsDragging && !WasDragging) { //drag start. mark the start vector and axes DraggedAxis = MousedAxis; DragStartScale = Scale; DraggedAxisDir = axes[0]; DraggedAxisSideDir = axes[1]; switch (DraggedAxis) { case WidgetAxis.XZ: DraggedAxisSideDir = axes[2]; break; case WidgetAxis.YZ: DraggedAxisDir = axes[1]; DraggedAxisSideDir = axes[2]; break; case WidgetAxis.Y: DraggedAxisDir = axes[1]; break; case WidgetAxis.Z: DraggedAxisDir = axes[2]; break; } switch (DraggedAxis) //find the best second axis to use, for single axis motion only. { case WidgetAxis.X: case WidgetAxis.Y: case WidgetAxis.Z: int curax = GetAxisIndex(DraggedAxis); int minax = 0; float mindp = float.MaxValue; for (int i = 0; i < 3; i++) { if (i != curax) { float dp = Math.Abs(Vector3.Dot(cdir, axes[i])); if (dp < mindp) { mindp = dp; minax = i; } } } DraggedAxisSideDir = axes[minax]; break; } if (DraggedAxis == WidgetAxis.XYZ) { //all axes, move in the screen plane float ad1 = Math.Abs(Vector3.Dot(cdir, Vector3.UnitY)); float ad2 = Math.Abs(Vector3.Dot(cdir, Vector3.UnitZ)); DraggedAxisDir = Vector3.Normalize(Vector3.Cross(cdir, (ad1 > ad2) ? Vector3.UnitY : Vector3.UnitZ)); DraggedAxisSideDir = Vector3.Normalize(Vector3.Cross(cdir, DraggedAxisDir)); } bool hit = GetAxisRayHit(DraggedAxisDir, DraggedAxisSideDir, camrel, ray, out DragStartVec); if ((MousedAxis == WidgetAxis.None) || !hit) { IsDragging = false; } } else if (IsDragging) { //continue drag. Vector3 newvec; bool hit = GetAxisRayHit(DraggedAxisDir, DraggedAxisSideDir, camrel, ray, out newvec); if (hit) { Vector3 diff = newvec - DragStartVec; switch (DraggedAxis) { case WidgetAxis.X: diff.Y = 0; diff.Z = 0; break; case WidgetAxis.Y: diff.X = 0; diff.Z = 0; break; case WidgetAxis.Z: diff.X = 0; diff.Y = 0; break; } //diff = ori.Multiply(diff); Vector3 ods = DragStartVec - camrel; // ori.Multiply(DragStartVec); float odl = Math.Max(ods.Length(), 0.0001f); //don't divide by 0 float ndl = Math.Max((ods + diff).Length(), 0.001f); //don't scale to 0 size float dl = ndl / odl; if (diff.Length() < 10000.0f) //limit movement in one go, to avoid crazy values... { Vector3 oldscale = Scale; Vector3 sv = Vector3.One; switch (DraggedAxis) { case WidgetAxis.X: sv = new Vector3(dl, 1, 1); break; case WidgetAxis.Y: sv = new Vector3(1, dl, 1); break; case WidgetAxis.Z: sv = new Vector3(1, 1, dl); break; case WidgetAxis.XY: sv = new Vector3(dl, dl, 1); break; case WidgetAxis.YZ: sv = new Vector3(1, dl, dl); break; case WidgetAxis.XZ: sv = new Vector3(dl, 1, dl); break; case WidgetAxis.XYZ: sv = new Vector3(dl); break; } Scale = DragStartScale * sv; if (Scale != oldscale) { OnScaleChange?.Invoke(Scale, oldscale); } } } } WasDragging = IsDragging; }
private void ScaleWidget_OnScaleChange(Vector3 newscale, Vector3 oldscale) { OnScaleChange?.Invoke(newscale, oldscale); }
private void Start() { positionAttribute.OnChanged += (x) => OnPositionChange?.Invoke(x); rotationAttribute.OnChanged += (x) => OnRotationChange?.Invoke(x); scaleAttribute.OnChanged += (x) => OnScaleChange?.Invoke(x); }
private void ScaleChange(object sender, EventArgs e) { Utils.SaveSetting("PhaseInspector.Scale", scaleBar.Value); OnScaleChange?.Invoke(scaleBar.Value); }