private Quaternion GetRotation(Vector3 axis, ShapeUtils.Direction direction) { return(Quaternion.LookRotation(MainDirection, UpVector) * Quaternion.FromToRotation(axis, ShapeUtils.GetLocalFaceDirection(direction))); }
private void UpdateLayerValues() { Name = _container.LayerNames[_index]; Color = ShapeUtils.ToWpfColor(_container.LayerColors[_index]); IsVisible = _container.IsLayerVisible(_index); }
public static Point3D ComputeMiddlePointPosition(Node rectangleNode, int wireIndex) { return (ComputeMiddlePointPosition(ShapeUtils.ExtractSubShape(rectangleNode, wireIndex, TopAbsShapeEnum.TopAbs_EDGE))); }
/// <summary> /// Finds closest edge to ray, including principal axes of the target object. /// </summary> /// <param name="ray">The ray.</param> /// <param name="triangleEdge">Triangle edge from raycast result.</param> /// <param name="principalEdgeExtension">Extension of principal axes relative to bounding box or object faces.</param> /// <returns>Edge (principal or triangle) closest to the given ray.</returns> private AGXUnity.Edge FindClosestEdgeIncludingTargetPrincipalAxes(Ray ray, AGXUnity.Edge triangleEdge, float principalEdgeExtension = 10.0f) { if (m_collectedData.Target == null) { return(new AGXUnity.Edge()); } var edges = new AGXUnity.Edge[4]; var shape = m_collectedData.Target.GetComponent <Shape>(); var shapeUtils = shape?.GetUtils(); if (shapeUtils != null) { Array.Copy(shapeUtils.GetPrincipalEdgesWorld(principalEdgeExtension), edges, 3); } else { var mesh = shape is AGXUnity.Collide.Mesh ? (shape as AGXUnity.Collide.Mesh).SourceObjects.FirstOrDefault() : m_collectedData.Target.GetComponent <MeshFilter>() != null? m_collectedData.Target.GetComponent <MeshFilter>().sharedMesh: null; var halfExtents = 0.5f * Vector3.one; if (mesh != null) { halfExtents = mesh.bounds.extents; } Array.Copy(ShapeUtils.ExtendAndTransformEdgesToWorld(m_collectedData.Target.transform, new AGXUnity.Edge[] { new AGXUnity.Edge() { Start = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Negative_X), End = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Positive_X), Normal = ShapeUtils.GetLocalFaceDirection(ShapeUtils.Direction.Positive_Y), Type = AGXUnity.Edge.EdgeType.Principal }, new AGXUnity.Edge() { Start = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Negative_Y), End = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Positive_Y), Normal = ShapeUtils.GetLocalFaceDirection(ShapeUtils.Direction.Positive_Z), Type = AGXUnity.Edge.EdgeType.Principal }, new AGXUnity.Edge() { Start = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Negative_Z), End = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Positive_Z), Normal = ShapeUtils.GetLocalFaceDirection(ShapeUtils.Direction.Positive_X), Type = AGXUnity.Edge.EdgeType.Principal } }, principalEdgeExtension), edges, 3); } edges[3] = triangleEdge; return(ShapeUtils.FindClosestEdgeToSegment(ray.origin, ray.GetPoint(5000.0f), edges).Edge); }
public override void OnImportAsset(AssetImportContext ctx) { // We're using a hardcoded window size of 100x100. This way, using a pixels per point value of 100 // results in a sprite of size 1 when the SVG file has a viewbox specified. SVGParser.SceneInfo sceneInfo; using (StreamReader stream = new StreamReader(ctx.assetPath)) { sceneInfo = SVGParser.ImportSVG(stream, 0, 1, 100, 100, PreserveViewport); } if (sceneInfo.Scene == null || sceneInfo.Scene.Root == null) { throw new Exception("Wowzers!"); } float stepDist = StepDistance; float samplingStepDist = SamplingStepDistance; float maxCord = MaxCordDeviationEnabled ? MaxCordDeviation : float.MaxValue; float maxTangent = MaxTangentAngleEnabled ? MaxTangentAngle : Mathf.PI * 0.5f; if (!AdvancedMode) { // Automatically compute sensible tessellation options from the // vector scene's bouding box and target resolution ComputeTessellationOptions(sceneInfo, TargetResolution, ResolutionMultiplier, out stepDist, out maxCord, out maxTangent); } var tessOptions = new ShapeUtils.TessellationOptions(); tessOptions.MaxCordDeviation = maxCord; tessOptions.MaxTanAngleDeviation = maxTangent; tessOptions.SamplingStepSize = 1.0f / (float)samplingStepDist; tessOptions.StepDistance = stepDist; var rect = Rect.zero; if (PreserveViewport) { rect = sceneInfo.SceneViewport; } var geometry = ShapeUtils.TessellateScene(sceneInfo.Scene, tessOptions, sceneInfo.NodeOpacity); string name = System.IO.Path.GetFileNameWithoutExtension(ctx.assetPath); var gameObject = new GameObject("Shape" + name, typeof(MeshFilter), typeof(MeshRenderer)); var mesh = new Mesh(); mesh.name = "Mesh" + name; CalculateSideExtrusion(mesh, geometry); mesh.RecalculateBounds(); mesh.RecalculateNormals(); var mat = new Material(Shader.Find("Standard")); mat.name = "Material" + name; gameObject.GetComponent <MeshFilter>().mesh = mesh; gameObject.GetComponent <MeshRenderer>().material = mat; ctx.AddObjectToAsset("shape", gameObject); ctx.AddObjectToAsset("mesh", mesh); ctx.AddObjectToAsset("material", mat); ctx.SetMainObject(gameObject); }
private static IEnumerable <Point3D> BuildEdgeIntersectionList(List <SolverGeometricObject> solverGeometry) { var geometry = solverGeometry; var intersectionList = new List <Point3D>(); var boxes = new SortedDictionary <int, ShapeBoundBox>(); foreach (var geometricObject in geometry) { if (geometricObject.Parent == null) { continue; } if (geometricObject.Builder.Shape == null) { continue; } var transformedShape = geometricObject.Builder.Shape.Located(new TopLocLocation(geometricObject.Builder.Transformation)); var bndBox = ShapeUtils.ExtractBoundingBox(transformedShape); boxes[geometricObject.Parent.Index] = bndBox; } foreach (var geometricObject in geometry) { if (geometricObject.Edges.Count == 0) { continue; } if (geometricObject.Edges.Count > 20) { continue; } if (geometricObject.Parent == null) { continue; } if (!boxes.ContainsKey(geometricObject.Parent.Index)) { continue; } foreach (var destinationObject in geometry) { if (destinationObject.Parent == null) { continue; } if (destinationObject.Edges.Count == 0) { continue; } if (geometricObject.Edges.Count == 1 || destinationObject.Edges.Count == 1) { continue; } if (destinationObject.Edges.Count > 20) { continue; } if (geometricObject.Parent.Index == destinationObject.Parent.Index) { continue; } if (!boxes.ContainsKey(destinationObject.Parent.Index)) { continue; } var sourceBox = boxes[geometricObject.Parent.Index]; var destBox = boxes[destinationObject.Parent.Index]; if (sourceBox == null || destBox == null) { continue; } if (sourceBox.IsOut(destBox)) { continue; } BuildEdgeIntersections(geometricObject, destinationObject, intersectionList); } } foreach (var geometricObject in geometry) { if (geometricObject.Edges.Count == 0) { continue; } foreach (var destinationObject in geometry) { if (destinationObject.Edges.Count == 0) { continue; } if (destinationObject.Builder.Node.Index <= geometricObject.Builder.Node.Index) { continue; } if (geometricObject.Edges.Count == 1 || destinationObject.Edges.Count == 1) { BuildEdgeIntersections(geometricObject, destinationObject, intersectionList); } } } return(intersectionList); }
/// <summary> /// Called when a user wants to update the canvas background color. /// </summary> /// <param name="color">hex color</param> public async Task UpdateBackgroundColor(string color) { await ShapeUtils.UpdateBackgroundColor(Context, Clients, color); }
/// <summary> /// Called when a user wants to download the canvas as SVG. /// </summary> public async Task GetSVG() { await ShapeUtils.GetSVG(Context, Clients); }
/// <summary> /// Called when a user wants to delete a shape. /// </summary> /// <param name="shapeIDString">Shape id</param> public async Task DeleteShape(string shapeIDString) { await ShapeUtils.DeleteShape(Context, Clients, shapeIDString); }
/// <summary> /// Called when a user wants to update a shape permissions (edition and deletion). /// </summary> /// <param name="shapeIDString">Shape id</param> /// <param name="permission"> /// New permission: should be 2-bit string like '3' -> 0b11. /// First bit allows edition. Second bit allows deletion. /// </param> public async Task UpdateShapePermission(string shapeIDString, string permission) { await ShapeUtils.UpdateShapePermission(Context, Clients, shapeIDString, permission);; }
/// <summary> /// Called when a user wants to update a shape. /// </summary> /// <param name="shapeType">Shape type: </param> /// <param name="updatedShape">JSON shape definition. Should contain ID to retrieve the shape to update.</param> public async Task UpdateShape(string shapeType, string updatedShape) { await ShapeUtils.UpdateShape(Context, Clients, shapeType, updatedShape); }
/// <summary> /// Called when a user wants to add a shape. /// </summary> /// <param name="shapeType">Shape type: </param> /// <param name="newShape">JSON shape definition</param> public async Task AddShape(string shapeType, string newShape) { await ShapeUtils.AddShape(Context, Clients, shapeType, newShape); }
public DrawingShape GetShape(CanvasEventArgs a, TikzStyle style) { if (click == 0) // first click, draw a straight line { if (a.MouseState == MouseState.DOWN) { //FIXME: small bug here, sometimes when a user clicks for the first time long line appears for a split second, noticeable but should not influence performance firstPoint = a.Point; bezier = new BezierSegment() { Point3 = a.Point.GetSystemPoint() }; figure = new PathFigure(); figure.Segments.Add(bezier); path = new ArrowPath(); path.SetStyle(style); path.Margin = ShapeUtils.GetMargin(firstPoint.X, firstPoint.Y); pf = new PathFigure[] { figure }; path.Data = new PathGeometry(pf); current = new DrawingShape( new TikzBezier(path, style), ShapeState.START ); } else if (a.MouseState == MouseState.MOVE) { bezier.Point3 = GetPointWithoutMargin(firstPoint, a.Point); } else { bezier.Point3 = GetPointWithoutMargin(firstPoint, a.Point); click++; } return(current); } else if (click == 1) // second click, select first control point { if (a.MouseState == MouseState.DOWN) { secondPointSelected = true; bezier.Point1 = GetPointWithoutMargin(firstPoint, a.Point); } else if (a.MouseState == MouseState.MOVE) { if (secondPointSelected) { bezier.Point1 = GetPointWithoutMargin(firstPoint, a.Point); } } else { bezier.Point1 = GetPointWithoutMargin(firstPoint, a.Point); click++; } return(current); } else if (click == 2) // third click, select second control point { if (a.MouseState == MouseState.DOWN) { thirdPointSelected = true; bezier.Point2 = GetPointWithoutMargin(firstPoint, a.Point); } else if (a.MouseState == MouseState.MOVE) { if (thirdPointSelected) { bezier.Point2 = GetPointWithoutMargin(firstPoint, a.Point); } } else { bezier.Point2 = GetPointWithoutMargin(firstPoint, a.Point); current.ShapeState = ShapeState.FINISHED; click = 0; secondPointSelected = thirdPointSelected = false; } Canvas.SetLeft(current.TikzShape.Shape, 0); Canvas.SetTop(current.TikzShape.Shape, 0); return(current); } else { throw new Exception("Sth went wrong, bezier line should be drawn in 3 clicks"); } }
public float GetRotationTo(float x, float y) { float r = MathUtils.Atan2(x - X(), y - Y()); return(ShapeUtils.GetAngleDiff(rotation, r)); }
// ReadFromClient: Begin interpreting packets from the specified client, performing actions based on the data received private static async void ReadFromClient(ProtocolModel.ConnectionClient connectionClient) { try { await Task.Run(() => { while (connectionClient.Client.Connected) { if (connectionClient.Client.GetStream().DataAvailable) { // Data Processing string json = DataUtils.ReadJsonFromStream(connectionClient.Client.GetStream(), SizeLimit); var token = json.Split(new[] { PacketSplitter }, StringSplitOptions.RemoveEmptyEntries); foreach (var msgToken in token) { ProtocolModel.Base baseMessage = JsonConvert.DeserializeObject <ProtocolModel.Base>(msgToken); switch (baseMessage.Type) { // RequestJoin: Add Client Data to observable Player Array (Adding the GUID from the connectionClient) then re-broadcast the new playerList case ProtocolModel.MessageType.RequestJoin: { ProtocolModel.Player player = JsonConvert.DeserializeObject <ProtocolModel.Player>(baseMessage.Data.ToString()); player.Id = connectionClient.Id; Players.Add(player); BroadcastPlayers(); RequestSendMessage($"--> {Players.First(i => i.Id == connectionClient.Id).Name} has joined."); break; } // LobbyMessage: Broadcast a General Status Message from the Server case ProtocolModel.MessageType.LobbyMessage: { SendFromServer(json); break; } // RequestStart: Sets appropriate flags for Game Running, and begins auto-populating the game panel case ProtocolModel.MessageType.RequestStart: { // Clear all Player points before starting ClearScores(); GameRunning = true; BeginShapeGen(); RequestSendMessage($"--> Game started by {Players.First(i => i.Id == connectionClient.Id).Name} (Host)"); break; } // RequestGameSettings: Requests a copy of the current public game settings available to all users case ProtocolModel.MessageType.RequestGameSettings: { SendFromServer(JsonConvert.SerializeObject(new ProtocolModel.Base { Type = ProtocolModel.MessageType.RequestGameSettings, Data = new ProtocolModel.GameSetting { GameName = GameName, CurrentPlayers = Players.Count, GameSize = GameSize + 1, GameInProgress = GameRunning, DefaultPointValues = AveragePoints, MaxShapeCount = MaxShapeCount, MaxShapeTicks = MaxShapeTicks, Timer = GameRefreshTime.ToString(), Win = GameWinPoint.ToString(), PanelSize = new Point(GamePanelSizeX, GamePanelSizeY) } })); break; } // RequestSendCoords: Queries the ClickCoords reported in order to check for Shape collission case ProtocolModel.MessageType.RequestSendCoords: { ProtocolModel.ClickCoords point = JsonConvert.DeserializeObject <ProtocolModel.ClickCoords>(baseMessage.Data.ToString()); for (int j = ShapesPanel.Count - 1; j >= 0; j--) { var item = ShapesPanel[j]; if (ShapeUtils.ContainsShape(item.Type, point.Location, item.Location)) { ShapesPanel.Remove(item); Players.First(i => i.Id == connectionClient.Id).Score += item.Value; BroadcastShapes(); BroadcastPlayers(); if (GameRunning) { int modifiedValue = item.Value >= 0 ? item.Value : Math.Abs(item.Value); RequestSendMessage($"--> {Players.First(i => i.Id == connectionClient.Id).Name} has {(item.Value >= 0 ? "gained" : "lost")} {modifiedValue} {(modifiedValue > 1 ? "points" : "point")} from clicking a {item.Color.Name} {Enum.GetName(typeof(ProtocolModel.ShapeType), item.Type)}"); } break; } } break; } } } } Thread.Sleep(25); } }); } finally { // If the task ends unexpectedly or the player disconnects at some point, // display a LEFT_GAME message in chat, and ensure their data is cleaned up // // Normally, this type of stuff would occur immediatly when the manual leave actions occur // That is still highly TODO, so this event only plays whenever the next packet tries to passthrough ProtocolModel.Player player = Players.First(i => i.Id == connectionClient.Id); Players.Remove(player); connectionClient.Client.Close(); BroadcastPlayers(); RequestSendMessage($"--> {player.Name} has left the game."); } }