/// <summary> /// Use this for transforming points /// </summary> public bool GetTransformPoint( Vector2 mousePoint, out Vector3 point, ModelPanelViewport panel, Vector3 center, SelectionParams selection) { return(GetTransformPoint(mousePoint, out point, panel, Matrix.TranslationMatrix(center), selection)); }
public unsafe void RenderTranslationControl( Vector3 position, float radius, Matrix rotation, ModelPanelViewport panel, SelectionParams selection) { Matrix m = Matrix.TransformMatrix(new Vector3(radius * 0.25f), new Vector3(), position) * CameraFacingRotationMatrix(panel, position); GL.PushMatrix(); GL.MultMatrix((float *)&m); GL.Color4(selection._hiCirc || selection._snapCirc ? Color.Yellow : Color.Gray); GL.Begin(BeginMode.LineLoop); GL.Vertex2(-0.5f, -0.5f); GL.Vertex2(-0.5f, 0.5f); GL.Vertex2(0.5f, 0.5f); GL.Vertex2(0.5f, -0.5f); GL.Vertex2(-0.5f, -0.5f); GL.End(); GL.PopMatrix(); //Enter local space m = Matrix.TransformMatrix(new Vector3(radius), new Vector3(), position) * rotation; GL.PushMatrix(); GL.MultMatrix((float *)&m); GetTranslationAxes(selection).Call(); GL.PopMatrix(); panel.SettingsScreenText["X"] = panel.Camera.Project(new Vector3(_axisLDist + 0.1f, 0, 0) * m) - new Vector3(8.0f, 8.0f, 0); panel.SettingsScreenText["Y"] = panel.Camera.Project(new Vector3(0, _axisLDist + 0.1f, 0) * m) - new Vector3(8.0f, 8.0f, 0); panel.SettingsScreenText["Z"] = panel.Camera.Project(new Vector3(0, 0, _axisLDist + 0.1f) * m) - new Vector3(8.0f, 8.0f, 0); }
public async Task PlaceShipValidation(string row, string col) { var socketId = Context.ConnectionId; int posX = Int32.Parse(row); int posY = Int32.Parse(col); int battleArenaId = baController.GetBAId(playersController.GetPlayerId(socketId)); SelectionParams param = new SelectionParams(socketId, posX, posY, battleArenaId); //depending on client's selection, executing one of the two commands: place [ armor | ship ] selection List <CommandOutcome> outcomes = armorSelection.IsArmorSelected(socketId) ? placeArmorSelection.Execute(param) : placeShipSelection.Execute(param); foreach (var commandOutcome in outcomes) { switch (commandOutcome.outcome) { case PlacementOutcome.Armor: await Clients.Caller.SendAsync("pingArmorCount", commandOutcome.count); await Clients.Caller.SendAsync("pingShipPlaced", row, col, true); break; case PlacementOutcome.Ship: await Clients.Caller.SendAsync("pingShipPlaced", commandOutcome.posX, commandOutcome.posY, false); break; case PlacementOutcome.LastShip: await Clients.Caller.SendAsync("pingShipPlaced", commandOutcome.posX, commandOutcome.posY, false); await Clients.Caller.SendAsync("pingRemove", commandOutcome.idToRemove); break; case PlacementOutcome.Invalid: await Clients.Caller.SendAsync("invalidSelection", row, col); break; } } }
public unsafe void RenderScaleControl( Vector3 pos, float radius, Matrix rotation, ModelPanelViewport panel, SelectionParams selection) { //Enter local space Matrix m = Matrix.TransformMatrix(new Vector3(radius), new Vector3(), pos) * rotation; GL.PushMatrix(); GL.MultMatrix((float *)&m); GetScaleAxes(selection).Call(); GL.PopMatrix(); panel.ScreenText["X"] = panel.Camera.Project(new Vector3(_axisLDist + 0.1f, 0, 0) * m) - new Vector3(8.0f, 8.0f, 0); panel.ScreenText["Y"] = panel.Camera.Project(new Vector3(0, _axisLDist + 0.1f, 0) * m) - new Vector3(8.0f, 8.0f, 0); panel.ScreenText["Z"] = panel.Camera.Project(new Vector3(0, 0, _axisLDist + 0.1f) * m) - new Vector3(8.0f, 8.0f, 0); }
public void RenderTransformControl( Vector3 pos, Matrix rot, float radius, ModelPanelViewport panel, SelectionParams selection) { switch (ControlType) { case TransformType.Translation: RenderTranslationControl(pos, radius, rot, panel, selection); break; case TransformType.Rotation: RenderRotationControl(pos, radius, rot, panel, selection); break; case TransformType.Scale: RenderScaleControl(pos, radius, rot, panel, selection); break; } }
public GLDisplayList GetScaleAxes(SelectionParams selection) { //Create the axes. GLDisplayList axis = new GLDisplayList(); axis.Begin(); //Disable culling so square bases for the arrows aren't necessary to draw GL.Disable(EnableCap.CullFace); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.Begin(BeginMode.Lines); //X if (selection._snapY && selection._snapZ || selection._hiY && selection._hiZ) { GL.Color4(Color.Yellow); } else { GL.Color4(Color.Red); } GL.Vertex3(0.0f, _scaleHalf1LDist, 0.0f); GL.Vertex3(0.0f, 0.0f, _scaleHalf1LDist); GL.Vertex3(0.0f, _scaleHalf2LDist, 0.0f); GL.Vertex3(0.0f, 0.0f, _scaleHalf2LDist); if (selection._snapX || selection._hiX) { GL.Color4(Color.Yellow); } else { GL.Color4(Color.Red); } GL.Vertex3(0.0f, 0.0f, 0.0f); GL.Vertex3(_dst, 0.0f, 0.0f); GL.End(); GL.Begin(BeginMode.Triangles); GL.Vertex3(_axisLDist, 0.0f, 0.0f); GL.Vertex3(_dst, _apthm, -_apthm); GL.Vertex3(_dst, _apthm, _apthm); GL.Vertex3(_axisLDist, 0.0f, 0.0f); GL.Vertex3(_dst, -_apthm, _apthm); GL.Vertex3(_dst, -_apthm, -_apthm); GL.Vertex3(_axisLDist, 0.0f, 0.0f); GL.Vertex3(_dst, _apthm, _apthm); GL.Vertex3(_dst, -_apthm, _apthm); GL.Vertex3(_axisLDist, 0.0f, 0.0f); GL.Vertex3(_dst, -_apthm, -_apthm); GL.Vertex3(_dst, _apthm, -_apthm); GL.End(); GL.Begin(BeginMode.Lines); //Y if (selection._snapZ && selection._snapX || selection._hiZ && selection._hiX) { GL.Color4(Color.Yellow); } else { GL.Color4(Color.Green); } GL.Vertex3(0.0f, 0.0f, _scaleHalf1LDist); GL.Vertex3(_scaleHalf1LDist, 0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, _scaleHalf2LDist); GL.Vertex3(_scaleHalf2LDist, 0.0f, 0.0f); if (selection._snapY || selection._hiY) { GL.Color4(Color.Yellow); } else { GL.Color4(Color.Green); } GL.Vertex3(0.0f, 0.0f, 0.0f); GL.Vertex3(0.0f, _dst, 0.0f); GL.End(); GL.Begin(BeginMode.Triangles); GL.Vertex3(0.0f, _axisLDist, 0.0f); GL.Vertex3(_apthm, _dst, -_apthm); GL.Vertex3(_apthm, _dst, _apthm); GL.Vertex3(0.0f, _axisLDist, 0.0f); GL.Vertex3(-_apthm, _dst, _apthm); GL.Vertex3(-_apthm, _dst, -_apthm); GL.Vertex3(0.0f, _axisLDist, 0.0f); GL.Vertex3(_apthm, _dst, _apthm); GL.Vertex3(-_apthm, _dst, _apthm); GL.Vertex3(0.0f, _axisLDist, 0.0f); GL.Vertex3(-_apthm, _dst, -_apthm); GL.Vertex3(_apthm, _dst, -_apthm); GL.End(); GL.Begin(BeginMode.Lines); //Z if (selection._snapX && selection._snapY || selection._hiX && selection._hiY) { GL.Color4(Color.Yellow); } else { GL.Color4(Color.Blue); } GL.Vertex3(0.0f, _scaleHalf1LDist, 0.0f); GL.Vertex3(_scaleHalf1LDist, 0.0f, 0.0f); GL.Vertex3(0.0f, _scaleHalf2LDist, 0.0f); GL.Vertex3(_scaleHalf2LDist, 0.0f, 0.0f); if (selection._snapZ || selection._hiZ) { GL.Color4(Color.Yellow); } else { GL.Color4(Color.Blue); } GL.Vertex3(0.0f, 0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, _dst); GL.End(); GL.Begin(BeginMode.Triangles); GL.Vertex3(0.0f, 0.0f, _axisLDist); GL.Vertex3(_apthm, -_apthm, _dst); GL.Vertex3(_apthm, _apthm, _dst); GL.Vertex3(0.0f, 0.0f, _axisLDist); GL.Vertex3(-_apthm, _apthm, _dst); GL.Vertex3(-_apthm, -_apthm, _dst); GL.Vertex3(0.0f, 0.0f, _axisLDist); GL.Vertex3(_apthm, _apthm, _dst); GL.Vertex3(-_apthm, _apthm, _dst); GL.Vertex3(0.0f, 0.0f, _axisLDist); GL.Vertex3(-_apthm, -_apthm, _dst); GL.Vertex3(_apthm, -_apthm, _dst); GL.End(); axis.End(); return(axis); }
public unsafe void RenderRotationControl( Vector3 position, float radius, Matrix rotation, ModelPanelViewport panel, SelectionParams selection) { Matrix m = Matrix.TransformMatrix(new Vector3(radius), new Vector3(), position) * CameraFacingRotationMatrix(panel, position); GL.PushMatrix(); GL.MultMatrix((float *)&m); GLDisplayList sphere = TKContext.GetCircleList(); GLDisplayList circle = TKContext.GetRingList(); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.PushAttrib(AttribMask.DepthBufferBit); GL.Enable(EnableCap.DepthTest); GL.DepthFunc(DepthFunction.Lequal); //Orb GL.Color4(0.7f, 0.7f, 0.7f, 0.15f); sphere.Call(); GL.Disable(EnableCap.DepthTest); //Container GL.Color4(0.4f, 0.4f, 0.4f, 1.0f); circle.Call(); //Circ if (selection._snapCirc || selection._hiCirc) { GL.Color4(Color.Yellow); } else { GL.Color4(1.0f, 0.8f, 0.5f, 1.0f); } GL.Scale(_circOrbScale, _circOrbScale, _circOrbScale); circle.Call(); //Pop GL.PopMatrix(); GL.Enable(EnableCap.DepthTest); //Enter local space m = Matrix.TransformMatrix(new Vector3(radius), new Vector3(), position) * rotation; panel.SettingsScreenText["X"] = panel.Camera.Project(new Vector3(1.1f, 0, 0) * m) - new Vector3(8.0f, 8.0f, 0); panel.SettingsScreenText["Y"] = panel.Camera.Project(new Vector3(0, 1.1f, 0) * m) - new Vector3(8.0f, 8.0f, 0); panel.SettingsScreenText["Z"] = panel.Camera.Project(new Vector3(0, 0, 1.1f) * m) - new Vector3(8.0f, 8.0f, 0); GL.PushMatrix(); GL.MultMatrix((float *)&m); //Z if (selection._snapZ || selection._hiZ) { GL.Color4(Color.Yellow); } else { GL.Color4(0.0f, 0.0f, 1.0f, 1.0f); } circle.Call(); GL.Rotate(90.0f, 0.0f, 1.0f, 0.0f); //X if (selection._snapX || selection._hiX) { GL.Color4(Color.Yellow); } else { GL.Color4(Color.Red); } circle.Call(); GL.Rotate(90.0f, 1.0f, 0.0f, 0.0f); //Y if (selection._snapY || selection._hiY) { GL.Color4(Color.Yellow); } else { GL.Color4(Color.Green); } circle.Call(); //Pop GL.PopMatrix(); GL.PopAttrib(); }
/// <summary> /// Gets world-point of specified mouse point projected onto the selected bone's local space if rotating or in world space if translating or scaling. /// Intersects the projected ray with the appropriate plane using the snap flags. /// </summary> public bool GetTransformPoint( Vector2 mousePoint, out Vector3 point, ModelPanelViewport panel, Matrix localTransform, SelectionParams selection) { Vector3 lineStart = panel.UnProject(mousePoint._x, mousePoint._y, 0.0f); Vector3 lineEnd = panel.UnProject(mousePoint._x, mousePoint._y, 1.0f); Vector3 center = localTransform.GetPoint(); Vector3 camera = panel.Camera.GetPoint(); Vector3 normal = new Vector3(); bool axisSnap = selection._snapX || selection._snapY || selection._snapZ; CoordinateType coord = _coordinateTypes[(int)ControlType]; switch (ControlType) { case TransformType.Rotation: float radius = CamDistance(center, ModelPanel.CurrentViewport); if (axisSnap) { switch (coord) { case CoordinateType.Screen: if (selection._snapX || selection._snapY || selection._snapZ) { normal = camera.Normalize(center); } break; case CoordinateType.Local: normal = (localTransform * new Vector3( selection._snapX ? 1.0f : 0.0f, selection._snapY ? 1.0f : 0.0f, selection._snapZ ? 1.0f : 0.0f)).Normalize(center); break; case CoordinateType.World: normal = new Vector3( selection._snapX ? 1.0f : 0.0f, selection._snapY ? 1.0f : 0.0f, selection._snapZ ? 1.0f : 0.0f); break; } } else if (selection._snapCirc) { radius *= _circOrbScale; normal = camera.Normalize(center); } else if (Maths.LineSphereIntersect(lineStart, lineEnd, center, radius, out point)) { return(true); } else { normal = camera.Normalize(center); } if (Maths.LinePlaneIntersect(lineStart, lineEnd, center, normal, out point)) { point = Maths.PointAtLineDistance(center, point, radius); return(true); } break; case TransformType.Translation: case TransformType.Scale: if (axisSnap) { if (selection._snapX && selection._snapY && selection._snapZ) { normal = Vector3.UnitZ * Matrix.RotationMatrix(panel.Camera._rotation); } else { switch (coord) { case CoordinateType.Screen: normal = Vector3.UnitZ * Matrix.RotationMatrix(panel.Camera._rotation); break; case CoordinateType.Local: case CoordinateType.World: //Remove local rotation if (coord == CoordinateType.World) { localTransform = Matrix.TranslationMatrix(center) * Matrix.ScaleMatrix(localTransform.GetScale()); } if (selection._snapX && selection._snapY) { normal = (localTransform * Vector3.UnitZ).Normalize(center); } else if (selection._snapX && selection._snapZ) { normal = (localTransform * Vector3.UnitY).Normalize(center); } else if (selection._snapY && selection._snapZ) { normal = (localTransform * Vector3.UnitX).Normalize(center); } else //One of the snaps { Vector3 unitSnapAxis = new Vector3( selection._snapX ? 1.0f : 0.0f, selection._snapY ? 1.0f : 0.0f, selection._snapZ ? 1.0f : 0.0f); float camDist = camera.TrueDistance(center); Vector3 camVec = camera.Normalize(center); float ratio = camVec.Dot(unitSnapAxis) / (camVec.TrueDistance() * unitSnapAxis.TrueDistance()); float lineDist = camDist * ratio; Vector3 endPoint = localTransform * (unitSnapAxis * lineDist); normal = camera.Normalize(endPoint); } break; } } } else { normal = Vector3.UnitZ * Matrix.RotationMatrix(panel.Camera._rotation); } break; } return(Maths.LinePlaneIntersect(lineStart, lineEnd, center, normal, out point)); }
private void MouseMoveTarget( ModelPanel panel, MouseEventArgs e, float depth, ModelPanelViewport v, Matrix transformMatrix, Matrix invTransformMatrix, SelectionParams selection) { if (ControlType == TransformType.None) { return; } CoordinateType coord = _coordinateTypes[(int)ControlType]; //Get the location of the bone Vector3 center = transformMatrix.GetPoint(); //Standard radius scaling snippet. This is used for orb scaling depending on camera distance. float radius = CamDistance(center, v); bool snapFound = false; if (ControlType == TransformType.Rotation) { //Get point projected onto our orb. Vector3 point = v.ProjectCameraSphere(new Vector2(e.X, e.Y), center, radius, false); //Get the distance of the mouse point from the bone float distance = point.TrueDistance(center); if (Math.Abs(distance - radius) < (radius * _selectOrbScale)) //Point lies within orb radius { selection._hiSphere = true; //Determine axis snapping Vector3 angles = (invTransformMatrix * point).GetAngles() * Maths._rad2degf; angles._x = (float)Math.Abs(angles._x); angles._y = (float)Math.Abs(angles._y); angles._z = (float)Math.Abs(angles._z); if (Math.Abs(angles._y - 90.0f) <= _axisSnapRange) { selection._hiX = true; } else if (angles._x >= (180.0f - _axisSnapRange) || angles._x <= _axisSnapRange) { selection._hiY = true; } else if (angles._y >= (180.0f - _axisSnapRange) || angles._y <= _axisSnapRange) { selection._hiZ = true; } } else if (Math.Abs(distance - (radius * _circOrbScale)) < (radius * _selectOrbScale)) //Point lies on circ line { selection._hiCirc = true; } if (selection._hiX || selection._hiY || selection._hiZ || selection._hiCirc) { snapFound = true; } } else if (ControlType == TransformType.Translation || ControlType == TransformType.Scale) { //No more need to use depth!!! Just some nice math if (_coordinateTypes[(int)ControlType] == CoordinateType.World) { transformMatrix = Matrix.TranslationMatrix(center) * Matrix.ScaleMatrix(transformMatrix.GetScale()); } Vector3[] planePoints = new Vector3[3]; //xy, yz, xz v.ProjectCameraPlanes(new Vector2(e.X, e.Y), transformMatrix, out planePoints[0], out planePoints[1], out planePoints[2]); List <Vector3> testDiffs = new List <Vector3>(); foreach (Vector3 planePoint in planePoints) { Vector3 d = coord == CoordinateType.World ? (planePoint - center) / radius : coord == CoordinateType.Local ? (invTransformMatrix * planePoint) / radius : (panel.Camera._matrix * planePoint - panel.Camera._matrix * center) / radius; if (d._x > -_axisSelectRange && d._x < (_axisLDist + 0.01f) && d._y > -_axisSelectRange && d._y < (_axisLDist + 0.01f) && d._z > -_axisSelectRange && d._z < (_axisLDist + 0.01f)) { testDiffs.Add(d); } } //Check if point lies on a specific axis foreach (Vector3 diff in testDiffs) { float errorRange = _axisSelectRange; if (diff._x > _axisHalfLDist && Math.Abs(diff._y) < errorRange && Math.Abs(diff._z) < errorRange) { selection._hiX = true; } if (diff._y > _axisHalfLDist && Math.Abs(diff._x) < errorRange && Math.Abs(diff._z) < errorRange) { selection._hiY = true; } if (diff._z > _axisHalfLDist && Math.Abs(diff._x) < errorRange && Math.Abs(diff._y) < errorRange) { selection._hiZ = true; } if (snapFound = selection._hiX || selection._hiY || selection._hiZ) { break; } } if (!snapFound) { foreach (Vector3 diff in testDiffs) { if (ControlType == TransformType.Translation) { if (diff._x < _axisHalfLDist && diff._y < _axisHalfLDist && diff._z < _axisHalfLDist) { //Point lies inside the double drag areas if (diff._x > _axisSelectRange) { selection._hiX = true; } if (diff._y > _axisSelectRange) { selection._hiY = true; } if (diff._z > _axisSelectRange) { selection._hiZ = true; } selection._hiCirc = !selection._hiX && !selection._hiY && !selection._hiZ; snapFound = true; } } else if (ControlType == TransformType.Scale) { //Determine if the point is in the double or triple drag triangles float halfDist = _scaleHalf2LDist; float centerDist = _scaleHalf1LDist; if (diff.IsInTriangle(new Vector3(), new Vector3(halfDist, 0, 0), new Vector3(0, halfDist, 0))) { if (diff.IsInTriangle(new Vector3(), new Vector3(centerDist, 0, 0), new Vector3(0, centerDist, 0))) { selection._hiX = selection._hiY = selection._hiZ = true; } else { selection._hiX = selection._hiY = true; } } else if (diff.IsInTriangle(new Vector3(), new Vector3(halfDist, 0, 0), new Vector3(0, 0, halfDist))) { if (diff.IsInTriangle(new Vector3(), new Vector3(centerDist, 0, 0), new Vector3(0, 0, centerDist))) { selection._hiX = selection._hiY = selection._hiZ = true; } else { selection._hiX = selection._hiZ = true; } } else if (diff.IsInTriangle(new Vector3(), new Vector3(0, halfDist, 0), new Vector3(0, 0, halfDist))) { if (diff.IsInTriangle(new Vector3(), new Vector3(0, centerDist, 0), new Vector3(0, 0, centerDist))) { selection._hiX = selection._hiY = selection._hiZ = true; } else { selection._hiY = selection._hiZ = true; } } snapFound = selection._hiX || selection._hiY || selection._hiZ; } if (snapFound) { break; } } } } if (snapFound) { panel.Cursor = Cursors.Hand; panel.Invalidate(); } }
private Vector3 GetLocalTransform( MouseEventArgs e, ModelPanelViewport viewport, Matrix localTransform, Matrix invLocalTransform, Matrix localParentTransform, SelectionParams selection, out Vector3?worldPoint) { worldPoint = null; Vector3 point; if (GetTransformPoint(new Vector2(e.X, e.Y), out point, viewport, localTransform, selection)) { Vector3 transform = new Vector3(), lPoint; CoordinateType coord = _coordinateTypes[(int)ControlType]; switch (ControlType) { case TransformType.Rotation: lPoint = invLocalTransform * point; if (selection._lastPointLocal == lPoint) { return(new Vector3()); } //Get matrix with new rotation applied Matrix m = localParentTransform * Matrix.AxisAngleMatrix(selection._lastPointLocal, lPoint); //Derive angles from matrices, get difference transform = (m.GetAngles() - localParentTransform.GetAngles()).RemappedToRange(-180.0f, 180.0f); break; case TransformType.Translation: case TransformType.Scale: if (ControlType == TransformType.Scale && selection._snapX && selection._snapY && selection._snapZ) { //Get scale factor //TODO: calculate with distance between screen points instead transform = new Vector3((point / selection._lastPointWorld)._y); break; } lPoint = invLocalTransform * point; if (selection._lastPointLocal == lPoint) { return(new Vector3()); } if (!(ControlType == TransformType.Translation && selection._snapCirc)) { switch (coord) { case CoordinateType.World: //Limit world point with snaps if (!selection._snapX) { point._x = selection._lastPointWorld._x; } if (!selection._snapY) { point._y = selection._lastPointWorld._y; } if (!selection._snapZ) { point._z = selection._lastPointWorld._z; } //Remake local point with edited world point lPoint = invLocalTransform * point; break; case CoordinateType.Local: //Limit local point with snaps if (!selection._snapX) { lPoint._x = selection._lastPointLocal._x; } if (!selection._snapY) { lPoint._y = selection._lastPointLocal._y; } if (!selection._snapZ) { lPoint._z = selection._lastPointLocal._z; } break; case CoordinateType.Screen: break; } } if (ControlType == TransformType.Scale) { transform = ((localParentTransform * lPoint) / (localParentTransform * selection._lastPointLocal)); } else { transform = localParentTransform * lPoint - localParentTransform * selection._lastPointLocal; } break; } worldPoint = point; selection._lastPointWorld = point; return(transform); } return(new Vector3()); }