//------------------------------------------------------ // // Public Properties // //------------------------------------------------------ //------------------------------------------------------ // // Public Events // //------------------------------------------------------ //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // NOTE: Geometry3D hit testing takes the rayParams in the outer space of the // Geometry3D. That is, RayHitTest() will apply this geometry's // transform to the ray for the caller. // // This is different than Visual hit testing which does not transform // the hit testing parameters by the Visual's transform. internal void RayHitTest(RayHitTestParameters rayParams, FaceType facesToHit) { Debug.Assert(facesToHit != FaceType.None, "Caller should make sure we're trying to hit something"); Rect3D bounds = Bounds; if (bounds.IsEmpty) { return; } // Point3D origin; Vector3D direction; rayParams.GetLocalLine(out origin, out direction); if (LineUtil.ComputeLineBoxIntersection(ref origin, ref direction, ref bounds, rayParams.IsRay)) { RayHitTestCore(rayParams, facesToHit); } // }
//------------------------------------------------------ // // Public Properties // //------------------------------------------------------ //------------------------------------------------------ // // Public Events // //------------------------------------------------------ //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // NOTE: Geometry3D hit testing takes the rayParams in the outer space of the // Geometry3D. That is, RayHitTest() will apply this geometry's // transform to the ray for the caller. // // This is different than Visual hit testing which does not transform // the hit testing parameters by the Visual's transform. internal void RayHitTest(RayHitTestParameters rayParams, FaceType facesToHit) { Debug.Assert(facesToHit != FaceType.None, "Caller should make sure we're trying to hit something"); Rect3D bounds = Bounds; if (bounds.IsEmpty) { return; } // Geometry3D's do not yet support a Transform property // // Transform3D transform = Transform; // rayParams.PushTransform(transform); Point3D origin; Vector3D direction; rayParams.GetLocalLine(out origin, out direction); if (LineUtil.ComputeLineBoxIntersection(ref origin, ref direction, ref bounds, rayParams.IsRay)) { RayHitTestCore(rayParams, facesToHit); } // Geometry3D's do not yet support a Transform property // // rayParams.PopTransform(transform); }
protected override void FlipAdjacentFacesPosition(Facie facie, FaceType faceType) { if (faceType == FaceType.Up) { if (facie.Position == FaciePositionType.LeftUp) { facie.Position = FaciePositionType.LeftDown; } else if (facie.Position == FaciePositionType.LeftDown) { facie.Position = FaciePositionType.LeftUp; } } else if (faceType == FaceType.Down) { if (facie.Position == FaciePositionType.LeftDown) { facie.Position = FaciePositionType.LeftUp; } else if (facie.Position == FaciePositionType.LeftUp) { facie.Position = FaciePositionType.LeftDown; } } }
public static RelativePosition RelativePositionBetweenFaces(FaceType primary, FaceType secondary) { switch (primary) { case FaceType.Front: switch (secondary) { case FaceType.Front: return RelativePosition.Same; case FaceType.Left: return RelativePosition.Left; case FaceType.Right: return RelativePosition.Right; case FaceType.Back: return RelativePosition.Opposite; } break; case FaceType.Right: switch (secondary) { case FaceType.Front: return RelativePosition.Left; case FaceType.Left: return RelativePosition.Opposite; case FaceType.Right: return RelativePosition.Same; case FaceType.Back: return RelativePosition.Right; } break; case FaceType.Back: switch (secondary) { case FaceType.Front: return RelativePosition.Opposite; case FaceType.Left: return RelativePosition.Right; case FaceType.Right: return RelativePosition.Left; case FaceType.Back: return RelativePosition.Same; } break; case FaceType.Left: switch (secondary) { case FaceType.Front: return RelativePosition.Right; case FaceType.Left: return RelativePosition.Same; case FaceType.Right: return RelativePosition.Opposite; case FaceType.Back: return RelativePosition.Left; } break; } throw new NotImplementedException("The relative position between " + primary + " and " + secondary + " has not been implemented yet"); }
public void UpdateFace() { var horizontal = PlayerInput.Instance.Horizontal.Value; var vertical = PlayerInput.Instance.Vertical.Value; if (!Mathf.Approximately(horizontal, 0)) { if (Mathf.Approximately(horizontal, 1)) { faceType = FaceType.Right; } else { faceType = FaceType.Left; } } if (!Mathf.Approximately(vertical, 0)) { if (Mathf.Approximately(vertical, 1)) { faceType = FaceType.Up; } else { faceType = FaceType.Down; } } m_Animator.SetFloat(m_HashFacePara, (float)faceType); }
public IDictionary <FaciePositionType, string> CreatePositions(FaceType faceType) { switch (faceType) { case FaceType.Front: return(CreateFrontPositions()); case FaceType.Up: return(CreateUpPositions()); case FaceType.Back: return(CreateBackPositions()); case FaceType.Left: return(CreateLeftPositions()); case FaceType.Right: return(CreateRightPositions()); case FaceType.Down: return(CreateDownPositions()); } return(new Dictionary <FaciePositionType, string>()); }
public Face CreateFace(FaceType type) { switch (type) { case FaceType.Front: return(CreateWhiteFace(type)); case FaceType.Up: return(CreateOrangeFace(type)); case FaceType.Down: return(CreateRedFace(type)); case FaceType.Left: return(CreateGreenFace(type)); case FaceType.Right: return(CreateBlueFace(type)); case FaceType.Back: return(CreateYellowFace(type)); } return(null); }
public void ChangeFace(FaceType ft) { faceType = ft; switch (faceType) { case FaceType.defaltFace: currentSprite = defaltFace; break; case FaceType.doFace: currentSprite = doFace; break; case FaceType.eyeOffFace: currentSprite = eyeOffFace; break; case FaceType.hitFace: currentSprite = hitFace; break; case FaceType.mouseFace: currentSprite = mouceFace; break; } if (currentSprite != null) { this.GetComponent <SpriteRenderer>().sprite = currentSprite; currentSprite = this.GetComponent <SpriteRenderer>().sprite; } else { currentSprite = defaltFace; } }
private GeometryModel3D CreateFacie(Facie facie, FaceType type) { var label = new Label { Background = new SolidColorBrush(ColorMapper.Map(facie.Color)), BorderBrush = new SolidColorBrush(Colors.Black), BorderThickness = new Thickness(0.3) }; var positions = positionsFactory.CreatePositions(type); var geometry = new GeometryModel3D { Geometry = new MeshGeometry3D { Positions = CreatePoints(positions, facie.Position), TriangleIndices = new Int32Collection { 2, 1, 3, 2, 0, 1 }, TextureCoordinates = new PointCollection { new Point(-0.5, -0.5), new Point(0.5, -0.5), new Point(-0.5, 0.5), new Point(0.5, 0.5) } }, Material = new DiffuseMaterial(new VisualBrush { Visual = label }), BackMaterial = new DiffuseMaterial(Brushes.Black) }; geometry.SetValue(NameProperty, facie.Key); return(geometry); }
public void UpdateFace(FaceType _type, int _id) { switch (_type) { case FaceType.眼睛: faces[_type].sprite = EyeConfig.Get(_id).GetSprite(); break; case FaceType.嘴巴: faces[_type].sprite = MouthConfig.Get(_id).GetSprite(); break; case FaceType.发型: faces[_type].sprite = HairConfig.Get(_id).GetSprite(); break; case FaceType.耳朵: faces[_type].sprite = EarConfig.Get(_id).GetSprite(); break; case FaceType.发饰: faces[_type].sprite = HairDecorateConfig.Get(_id).GetSprite(); break; default: break; } }
public void SetConfig(FaceType _type, int config_id, UnityAction <FaceUICell> on_click_call_back) { this.on_click_call_back = on_click_call_back; this._type = _type; this.config_id = config_id; switch (_type) { case FaceType.眼睛: cell_image.sprite = EyeConfig.Get(config_id).GetSprite(); break; case FaceType.嘴巴: cell_image.sprite = MouthConfig.Get(config_id).GetSprite(); break; case FaceType.发型: cell_image.sprite = HairConfig.Get(config_id).GetSprite(); break; case FaceType.耳朵: cell_image.sprite = EarConfig.Get(config_id).GetSprite(); break; case FaceType.发饰: cell_image.sprite = HairDecorateConfig.Get(config_id).GetSprite(); break; default: break; } }
private string GetColor(int index, FaceType type) { var face = _cube.GetFace(type); var color = face[index]; switch (color) { case FacePieceType.Red: return("R"); case FacePieceType.Green: return("G"); case FacePieceType.Blue: return("B"); case FacePieceType.White: return("W"); case FacePieceType.Orange: return("O"); case FacePieceType.Yellow: return("Y"); default: return("-"); } }
//-------------------------------------------------------------------------------------------------- StdSelect_TypeOfFace _GetNativeTypeOfFace(FaceType type) { switch (type) { case FaceType.Any: return(StdSelect_TypeOfFace.StdSelect_AnyFace); case FaceType.Plane: return(StdSelect_TypeOfFace.StdSelect_Plane); case FaceType.Cylinder: return(StdSelect_TypeOfFace.StdSelect_Cylinder); case FaceType.Sphere: return(StdSelect_TypeOfFace.StdSelect_Sphere); case FaceType.Torus: return(StdSelect_TypeOfFace.StdSelect_Torus); case FaceType.Revolution: return(StdSelect_TypeOfFace.StdSelect_Revol); case FaceType.Cone: return(StdSelect_TypeOfFace.StdSelect_Cone); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
public void GivenFactory_WhenCreateFace_ThenReturnsExpectedTypeAndColor(FaceType faceType, Color color) { var face = new FaceFactory().CreateFace(faceType); Assert.That(face.Type, Is.EqualTo(faceType)); Assert.IsTrue(face.Facies.All(x => x.Color == color)); }
protected void MoveFromUpToLeft(Cube cube, FaceType faceType, Facie facie) { switch (faceType) { case FaceType.Left: FlipAdjacentFacesPosition(facie, faceType); cube[FaceType.Down].Add(facie); break; case FaceType.Up: FlipAdjacentFacesPosition(facie, faceType); cube[FaceType.Left].Add(facie); break; case FaceType.Right: FlipAdjacentFacesPosition(facie, faceType); cube[FaceType.Up].Add(facie); break; case FaceType.Down: FlipAdjacentFacesPosition(facie, faceType); cube[FaceType.Right].Add(facie); break; } }
public Vector3 GetEffectiveNormal(Halfedge e) { if (e.isBoundary) { return(Vector3.zero); } FaceType faceType = GetFaceType(e.face); switch (faceType) { case FaceType.Smooth: return(normals[e]); case FaceType.Polygonal: case FaceType.Triangular: return(e.face.CalculateNormal()); case FaceType.Directinal1: case FaceType.Directinal2: List <Halfedge> edges = e.face.edges; return(CalculateDirectionalNormal(e, GetFaceType(e.face), edges.IndexOf(e), edges.Count)); default: return(Vector3.zero); } }
public VoxelMeshPart(int faceIndex, FaceType faceType, List2D <FaceType> voxelPlaneFaces, List3D <IVoxel> voxels) { Vertices = new List <Vector3>(); Normals = new List <Vector3>(); Colors = new List <Color>(); UV = new List <Vector2>(); UV2 = new List <Vector2>(); UV3 = new List <Vector2>(); Triangles = new List <int>(); _faceIndex = faceIndex; _faceType = faceType; _voxelPlaneFaces = voxelPlaneFaces; _voxels = voxels; _offset = new Vector3(_voxels.Dimensions.X, _voxels.Dimensions.Y, _voxels.Dimensions.Z) / 2f; if ((faceType & FaceType.XPositive) == FaceType.XPositive || (faceType & FaceType.YPositive) == FaceType.YPositive || (faceType & FaceType.ZPositive) == FaceType.ZPositive) { _normalDirection = 1f; } else { _normalDirection = -1f; } }
private static Facie CreateFacie(FaceType faceType, FaciePositionType positionType, Color color) { return(new Facie(color, positionType) { Key = $"{faceType}{positionType}" }); }
private static Facie CreateCorner(FaceType faceType, FaciePositionType positionType, Color color, Color adjacentColor1, Color adjacentColor2) { return(new Corner(positionType, color, adjacentColor1, adjacentColor2) { Key = $"{faceType}{positionType}" }); }
public static PrimitiveTopology ToPrimitiveTopology(this FaceType faceType) { switch (faceType) { case FaceType.Points: return(PrimitiveTopology.PointList); case FaceType.Lines: return(PrimitiveTopology.LineList); case FaceType.LineStrip: return(PrimitiveTopology.LineStrip); case FaceType.Triangles: return(PrimitiveTopology.TriangleList); case FaceType.TriangleStrip: return(PrimitiveTopology.TriangleStrip); case FaceType.LineLoop: case FaceType.TriangleFan: case FaceType.Quads: case FaceType.QuadStrip: case FaceType.Polygons: throw new NotSupportedException(); default: throw new InvalidEnumArgumentException(nameof(faceType), (int)faceType, typeof(FaceType)); } }
NormColor CalculateFaceColor(Zone owner, Face face, FaceType faceType) { float averageValue = 0; switch (faceType) { case FaceType.Triangular: averageValue += (float)owner.Vertices[face.Vertices[0]].Data[Coding_DatatypeIndex]; averageValue += (float)owner.Vertices[face.Vertices[1]].Data[Coding_DatatypeIndex]; averageValue += (float)owner.Vertices[face.Vertices[2]].Data[Coding_DatatypeIndex]; averageValue /= 3; break; case FaceType.Quadrilateral: averageValue += (float)owner.Vertices[face.Vertices[0]].Data[Coding_DatatypeIndex]; averageValue += (float)owner.Vertices[face.Vertices[1]].Data[Coding_DatatypeIndex]; averageValue += (float)owner.Vertices[face.Vertices[2]].Data[Coding_DatatypeIndex]; averageValue += (float)owner.Vertices[face.Vertices[3]].Data[Coding_DatatypeIndex]; averageValue /= 4; break; } double min = Mesh_Manager.dataTypeRange[Coding_DatatypeIndex].Key, max = Mesh_Manager.dataTypeRange[Coding_DatatypeIndex].Value; Color_Mapper.minValue = (float)min; Color_Mapper.maxValue = (float)max; Color C = Color_Mapper.ValueToColor(averageValue, mappingMode); NormColor color = NormalizeColor(C); return(color); }
/// <summary> /// Initializes a new instance of the <see cref="Face" /> class. /// </summary> /// <param name="geometry">Planar Face3D for the geometry. (required).</param> /// <param name="faceType">faceType (required).</param> /// <param name="boundaryCondition">boundaryCondition (required).</param> /// <param name="properties">Extension properties for particular simulation engines (Radiance, EnergyPlus). (required).</param> /// <param name="apertures">Apertures assigned to this Face. Should be coplanar with this Face and completely within the boundary of the Face to be valid..</param> /// <param name="doors">Doors assigned to this Face. Should be coplanar with this Face and completely within the boundary of the Face to be valid..</param> /// <param name="indoorShades">Shades assigned to the interior side of this object..</param> /// <param name="outdoorShades">Shades assigned to the exterior side of this object (eg. balcony, overhang)..</param> /// <param name="identifier">Text string for a unique object ID. This identifier remains constant as the object is mutated, copied, and serialized to different formats (eg. dict, idf, rad). This identifier is also used to reference the object across a Model. It must be < 100 characters and not contain any spaces or special characters. (required).</param> /// <param name="displayName">Display name of the object with no character restrictions..</param> /// <param name="userData">Optional dictionary of user data associated with the object.All keys and values of this dictionary should be of a standard data type to ensure correct serialization of the object (eg. str, float, int, list)..</param> public Face ( string identifier, Face3D geometry, FaceType faceType, AnyOf <Ground, Outdoors, Adiabatic, Surface> boundaryCondition, FacePropertiesAbridged properties, // Required parameters string displayName = default, Object userData = default, List <Aperture> apertures = default, List <Door> doors = default, List <Shade> indoorShades = default, List <Shade> outdoorShades = default // Optional parameters ) : base(identifier: identifier, displayName: displayName, userData: userData) // BaseClass { // to ensure "geometry" is required (not null) this.Geometry = geometry ?? throw new ArgumentNullException("geometry is a required property for Face and cannot be null"); this.FaceType = faceType; // to ensure "boundaryCondition" is required (not null) this.BoundaryCondition = boundaryCondition ?? throw new ArgumentNullException("boundaryCondition is a required property for Face and cannot be null"); // to ensure "properties" is required (not null) this.Properties = properties ?? throw new ArgumentNullException("properties is a required property for Face and cannot be null"); this.Apertures = apertures; this.Doors = doors; this.IndoorShades = indoorShades; this.OutdoorShades = outdoorShades; // Set non-required readonly properties with defaultValue this.Type = "Face"; // check if object is valid, only check for inherited class if (this.GetType() == typeof(Face)) { this.IsValid(throwException: true); } }
private async Task CheckFace(CubeConfiguration<FaceColour> configuration, FaceType faceToCheck, List<IRotation> solution, bool reverseDirection = false, bool doubleMoves = false) { var checkFace = configuration.Faces[faceToCheck]; var frontFace = configuration.Faces[FaceType.Front]; var isBack = faceToCheck == FaceType.Back; await CheckEdgeOnFace(configuration, solution, checkFace, Edge.Left, !isBack ? Edge.Left : Edge.Right, frontFace, FaceType.Left, reverseDirection, doubleMoves).ConfigureAwait(false); await CheckEdgeOnFace(configuration, solution, checkFace, Edge.Right, isBack ? Edge.Left : Edge.Right, frontFace, FaceType.Right, !reverseDirection, doubleMoves).ConfigureAwait(false); // TODO: THIS CAN BE IMPROVED, INSTEAD MOVE THE FRONT LAYER FIRST, YOU CAN CHOOSE EITHER THE LEFT OR RIGHT DEPENDING ON WHICH HOLDS THE EMPTY COLOUR if (checkFace.GetEdge(m_layer, Edge.Top).Centre() == m_faceColour) { await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceToCheck, RotationDirection.AntiClockwise), solution, configuration).ConfigureAwait(false); await CheckEdgeOnFace(configuration, solution, checkFace, !isBack ? Edge.Left : Edge.Right, Edge.Left, frontFace, !isBack ? FaceType.Left : FaceType.Right, reverseDirection, doubleMoves).ConfigureAwait(false); } if (checkFace.GetEdge(m_layer, Edge.Bottom).Centre() == m_faceColour) { await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceToCheck, RotationDirection.AntiClockwise), solution, configuration).ConfigureAwait(false); await CheckEdgeOnFace(configuration, solution, checkFace, isBack ? Edge.Left : Edge.Right, Edge.Right, frontFace, !isBack ? FaceType.Right : FaceType.Left, reverseDirection, doubleMoves).ConfigureAwait(false); } await CheckEdgeOnFace(configuration, solution, checkFace, Edge.Left, !isBack ? Edge.Left : Edge.Right, frontFace, FaceType.Left, reverseDirection, doubleMoves).ConfigureAwait(false); await CheckEdgeOnFace(configuration, solution, checkFace, Edge.Right, isBack ? Edge.Left : Edge.Right, frontFace, FaceType.Right, !reverseDirection, doubleMoves).ConfigureAwait(false); }
public static Polygon Generate(Vector2 dimensions, int seed, FaceType faceType, int regionCount = 0, float radius = 0) { PointSelector.dimensions = dimensions; PointSelector.seed = seed; PointSelector.regionCount = regionCount; PointSelector.radius = radius; switch (faceType) { case FaceType.Random: return(GenerateRandom()); case FaceType.Square: return(GenerateSquare()); case FaceType.Hexagon: return(GenerateHexagon()); case FaceType.PoisonDisc: return(GeneratePoisonDisc()); default: return(null); } }
private static Facie CreateEdge(FaceType faceType, FaciePositionType positionType, Color color, Color adjacentColor) { return(new Edge(positionType, color, adjacentColor) { Key = $"{faceType}{positionType}" }); }
protected override void FlipAdjacentFacesPosition(Facie facie, FaceType faceType) { if (faceType == FaceType.Front) { if (facie.Position == FaciePositionType.RightUp) { facie.Position = FaciePositionType.RightDown; } else if (facie.Position == FaciePositionType.RightDown) { facie.Position = FaciePositionType.RightUp; } } else if (faceType == FaceType.Back) { if (facie.Position == FaciePositionType.RightDown) { facie.Position = FaciePositionType.RightUp; } else if (facie.Position == FaciePositionType.RightUp) { facie.Position = FaciePositionType.RightDown; } } }
//------------------------------------------------------ // // Public Properties // //------------------------------------------------------ //------------------------------------------------------ // // Public Events // //------------------------------------------------------ //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // NOTE: Geometry3D hit testing takes the rayParams in the outer space of the // Geometry3D. That is, RayHitTest() will apply this geometry's // transform to the ray for the caller. // // This is different than Visual hit testing which does not transform // the hit testing parameters by the Visual's transform. internal void RayHitTest(RayHitTestParameters rayParams, FaceType facesToHit) { Debug.Assert(facesToHit != FaceType.None, "Caller should make sure we're trying to hit something"); Rect3D bounds = Bounds; if (bounds.IsEmpty) { return; } // Point3D origin; Vector3D direction; rayParams.GetLocalLine(out origin, out direction); if (LineUtil.ComputeLineBoxIntersection(ref origin, ref direction, ref bounds, rayParams.IsRay)) { RayHitTestCore(rayParams, facesToHit); } // }
public void GotoFace(FaceType type) { CurrentFace = type; switch (type) { default: case FaceType.Normal: EyeL.localPosition = InitEyeLPos; EyeR.localPosition = InitEyeRPos; EyeL.localRotation = InitEyeRot; EyeR.localRotation = InitEyeRot; EyeL.localScale = InitEyeScl; EyeR.localScale = InitEyeScl; break; case FaceType.Smile: EyeL.localPosition = InitEyeLPos; EyeR.localPosition = InitEyeRPos; EyeL.localRotation = InitEyeRot; EyeR.localRotation = InitEyeRot; EyeL.localScale = InitEyeScl; EyeR.localScale = InitEyeScl; break; case FaceType.Awkward: EyeL.localPosition = InitEyeLPos; EyeR.localPosition = InitEyeRPos; EyeL.localRotation = InitEyeRot; EyeR.localRotation = InitEyeRot; EyeL.localScale = InitEyeScl; EyeR.localScale = InitEyeScl; break; } }
public static Polygon Create(Vector2 values, int seed, FaceType faceType, int territoryCount = 0, float orbit = 0) { //naming the variables in this script PolygonList.values = values; PolygonList.seed = seed; PolygonList.territoryCount = territoryCount; PolygonList.orbit = orbit; switch (faceType) //can switch between face types { case FaceType.Random: return(CreateRandom()); case FaceType.Square: return(CreateSquare()); case FaceType.Hexagon: return(CreateHexagon()); case FaceType.PoisonDisc: return(CreatePoisonDisc()); default: return(null); } }
private async Task CheckEdgeOnFace(CubeConfiguration<FaceColour> configuration, List<IRotation> solution, Face<FaceColour> checkFace, Edge frontEdge, Edge checkEdge, Face<FaceColour> frontFace, FaceType movementFace, bool reverseDirection = false, bool doubleMoves = false) { var numMoves = doubleMoves ? 2 : 1; var center = checkFace.GetEdge(m_layer, checkEdge).Centre(); if (center == m_faceColour) { for (int i = 0; i <= 3; i++) { if (frontFace.GetEdge(m_layer, frontEdge).Centre() == m_faceColour) break; await CommonActions.ApplyAndAddRotation(Rotations.FrontClockwise, solution, configuration).ConfigureAwait(false); } var direction = !reverseDirection ? RotationDirection.Clockwise : RotationDirection.AntiClockwise; var rotation = numMoves == 1 ? Rotations.ByFace(movementFace, direction, m_layer) : Rotations.ByFaceTwice(movementFace, m_layer); await CommonActions.ApplyAndAddRotation(rotation, solution, configuration).ConfigureAwait(false); for (int i = 0; i <= 3; i++) { if (frontFace.GetEdge(m_layer, frontEdge).Centre() != m_faceColour) break; await CommonActions.ApplyAndAddRotation(Rotations.FrontClockwise, solution, configuration).ConfigureAwait(false); } direction = !reverseDirection ? RotationDirection.AntiClockwise : RotationDirection.Clockwise; rotation = numMoves == 1 ? Rotations.ByFace(movementFace, direction, m_layer) : Rotations.ByFaceTwice(movementFace, m_layer); await CommonActions.ApplyAndAddRotation(rotation, solution, configuration).ConfigureAwait(false); } }
public void ChangeFaceTo(FaceType to) { currentFace = to; for(int i = 0; i < faces.Length; i++){ faces[i].enabled = (i == (int)to); } }
/// <summary> /// Single textured voxel /// </summary> /// <param name="textureMapIndex">Main texture map index</param> /// <param name="detailMapIndex">Detail map index</param> /// <param name="alphaLevel">Optional alphaLevel of the voxel</param> /// <param name="facesToRender">Optional faces to render</param> public TextureVoxel(int textureMapIndex, int detailMapIndex, float alphaLevel = 1f, FaceType facesToRender = FaceType.XNegative | FaceType.XPositive | FaceType.YNegative | FaceType.YPositive | FaceType.ZNegative | FaceType.ZPositive) { if (textureMapIndex < 0) { throw new ArgumentException("Cannot create a textured voxel without positive texture map index", nameof(textureMapIndex)); } if (textureMapIndex >= TextureVoxelMap.Count) { throw new ArgumentException("Texture voxel index cannot be greater than number of elements in texture map", nameof(textureMapIndex)); } if (detailMapIndex < 0) { throw new ArgumentException("Cannot create a textured voxel with a non-positive detail map index", nameof(detailMapIndex)); } if (detailMapIndex >= TextureVoxelMap.Count) { throw new ArgumentException("Detail voxel index cannot be greater than number of elements in texture map", nameof(detailMapIndex)); } _hasTexture = true; _textureMapIndex = textureMapIndex; _detailMapIndex = detailMapIndex; _alphaLevel = alphaLevel; _facesToRender = facesToRender; }
internal override void RayHitTestCore(RayHitTestParameters rayParams) { Geometry3D geometry = Geometry; if (geometry != null) { // If our Geometry3D hit test intersects anything we should return "this" Model3D // as the HitTestResult.ModelHit. rayParams.CurrentModel = this; FaceType facesToHit = FaceType.None; if (Material != null) { facesToHit |= FaceType.Front; } if (BackMaterial != null) { facesToHit |= FaceType.Back; } if (facesToHit != FaceType.None) { geometry.RayHitTest(rayParams, facesToHit); } } }
public void GetName_RotationIsOnFace_NameStartsWithCorrectLetter(FaceType face, string firstLetter) { var rotation = new FaceRotation { Face = face }; var name = rotation.GetName(); StringAssert.StartsWith(firstLetter, name); }
/// <summary> /// Copy textured voxel to new instance /// </summary> /// <param name="textureVoxel"></param> /// <param name="facesToRender">Optional faces to render</param> public TextureVoxel(TextureVoxel textureVoxel, FaceType facesToRender = FaceType.XNegative | FaceType.XPositive | FaceType.YNegative | FaceType.YPositive | FaceType.ZNegative | FaceType.ZPositive) { _hasTexture = textureVoxel._hasTexture; _textureMapIndex = textureVoxel._textureMapIndex; _detailMapIndex = textureVoxel._detailMapIndex; _alphaLevel = textureVoxel._alphaLevel; _facesToRender = facesToRender; }
public void ChangeFaceTo(FaceType to) { currentFace = to; for (int i = 0; i < faces.Length; i++) { faces[i].enabled = (i == (int)to); } }
public CardFace(byte[] bytes,FaceType type) { faceBytes = bytes; faceType = type; Stream stream = new MemoryStream(faceBytes); FileReader reader = new FileReader(stream); reader.ReadBytes(4);//skip Tag 'FACE' bgColor = reader.ReadUInt32(); hasLogo = reader.ReadBoolean(); byte[] dataBytes; byte[] readBytes; int len; if (hasLogo) { reader.ReadBytes(16);//skip LogoRect logoDepth = reader.ReadUInt32();//LogoDepth len = (int)(reader.ReadUInt32());//LogoMatrixBytes if (len > 0) { logoMatrix = new Matrix(reader.ReadBytes(24)); } len = (int)(reader.ReadUInt32());//LogoColorTransBytes if (len > 0) { logoColorTrans = new ColorTransform(reader.ReadBytes(32)); } } len = (int)(reader.ReadUInt32());//SymbolBytes if (len > 0) { symbols = new SymbolCollection(reader.ReadBytes(len)); } len = (int)(reader.ReadUInt32());//TextBytes if (len > 0) { texts = new TextCollection(reader.ReadBytes(len)); } len = (int)(reader.ReadUInt32());//ThumbnailBytes if (len > 0) { dataBytes=new byte[len]; readBytes = reader.ReadBytes(len); readBytes.CopyTo(dataBytes,0); thumbnail = new Thumbnail(dataBytes,ThumbnailType.CardThumbnail); } stream.Close(); reader.Close(); }
private static IEnumerable<FaceColour> GetInnerSquareForFace(CubeConfiguration<FaceColour> configuration, FaceType faceType) { var upperEdge = configuration.Faces[faceType].GetEdge(1, Edge.Top).Skip(1).Take(3).ToArray(); var middleEdge = configuration.Faces[faceType].GetEdge(2, Edge.Top).Skip(1).Take(3).ToArray(); var lowerEdge = configuration.Faces[faceType].GetEdge(3, Edge.Top).Skip(1).Take(3).ToArray(); var allItems = upperEdge.Concat(middleEdge).Concat(lowerEdge); return allItems; }
public static void FaceHasCrossOfColour(CubeConfiguration<FaceColour> configuration, FaceType faceType, FaceColour faceColour) { int layer = Math.Max(configuration.Size - 4, 0); var face = configuration.Faces[faceType]; Assert.AreEqual(faceColour, face.Centre); Assert.AreEqual(faceColour, face.GetEdge(layer, Edge.Right).Centre()); Assert.AreEqual(faceColour, face.GetEdge(layer, Edge.Top).Centre()); Assert.AreEqual(faceColour, face.GetEdge(layer, Edge.Bottom).Centre()); Assert.AreEqual(faceColour, face.GetEdge(layer, Edge.Bottom).Centre()); }
private static void AssertCornersAreCorrect(CubeConfiguration<FaceColour> configuration, FaceType faceType) { var colour = configuration.Faces[faceType].Centre; var topEdge = configuration.Faces[faceType].GetEdge(1, Edge.Top); var bottomEdge = configuration.Faces[faceType].GetEdge(1, Edge.Bottom); Assert.AreEqual(colour, topEdge[1]); Assert.AreEqual(colour, topEdge[3]); Assert.AreEqual(colour, bottomEdge[1]); Assert.AreEqual(colour, bottomEdge[3]); }
public static FaceType FaceAtRelativePositionTo(FaceType face, RelativePosition position) { if (position == RelativePosition.Same) return face; switch (face) { case FaceType.Front: switch (position) { case RelativePosition.Right: return FaceType.Right; case RelativePosition.Left: return FaceType.Left; case RelativePosition.Opposite: return FaceType.Back; } break; case FaceType.Right: switch (position) { case RelativePosition.Right: return FaceType.Back; case RelativePosition.Left: return FaceType.Front; case RelativePosition.Opposite: return FaceType.Left; } break; case FaceType.Back: switch (position) { case RelativePosition.Right: return FaceType.Left; case RelativePosition.Left: return FaceType.Right; case RelativePosition.Opposite: return FaceType.Front; } break; case FaceType.Left: switch (position) { case RelativePosition.Right: return FaceType.Front; case RelativePosition.Left: return FaceType.Back; case RelativePosition.Opposite: return FaceType.Right; } break; } throw new Exception("Invalid face type"); }
private async Task CheckMiddleLayersOnFace(CubeConfiguration<FaceColour> configuration, List<IRotation> solution, FaceType face) { var frontFaceColour = configuration.Faces[FaceType.Front].LeftCentre(); var leftFaceColour = configuration.Faces[FaceType.Left].RightCentre(); var rightEdgeOnFace = configuration.Faces[face].GetEdge(Edge.Right); var top = rightEdgeOnFace[configuration.MinInnerLayerIndex()]; var bottom = rightEdgeOnFace[configuration.MaxInnerLayerIndex()]; var joiningFace = FaceRules.FaceAtRelativePositionTo(face, RelativePosition.Right); var leftEdgeOnJoiningFace = configuration.Faces[joiningFace].GetEdge(Edge.Left); var joiningFaceEdgeTop = leftEdgeOnJoiningFace[configuration.MinInnerLayerIndex()]; var joiningFaceEdgeBottom = leftEdgeOnJoiningFace[configuration.MaxInnerLayerIndex()]; if ((top == frontFaceColour && joiningFaceEdgeTop == leftFaceColour) || (bottom == frontFaceColour && joiningFaceEdgeBottom == leftFaceColour) || (top == leftFaceColour && joiningFaceEdgeTop == frontFaceColour) || (bottom == leftFaceColour && joiningFaceEdgeBottom == frontFaceColour)) { var rotationToBringEdgeToFront = GetRotationToPutTredgeOnFront((top == frontFaceColour && joiningFaceEdgeTop == leftFaceColour) || (top == leftFaceColour && joiningFaceEdgeTop == frontFaceColour), face, configuration.MinInnerLayerIndex()); await CommonActions.ApplyAndAddRotation(rotationToBringEdgeToFront, solution, configuration).ConfigureAwait(false); } if ((top == frontFaceColour && joiningFaceEdgeTop == leftFaceColour) || (bottom == frontFaceColour && joiningFaceEdgeBottom == leftFaceColour)) { await PerformFlip(solution, configuration).ConfigureAwait(false); } rightEdgeOnFace = configuration.Faces[face].GetEdge(Edge.Right); top = rightEdgeOnFace[configuration.MinInnerLayerIndex()]; bottom = rightEdgeOnFace[configuration.MaxInnerLayerIndex()]; leftEdgeOnJoiningFace = configuration.Faces[joiningFace].GetEdge(Edge.Left); joiningFaceEdgeTop = leftEdgeOnJoiningFace[configuration.MinInnerLayerIndex()]; joiningFaceEdgeBottom = leftEdgeOnJoiningFace[configuration.MaxInnerLayerIndex()]; if (top == leftFaceColour && joiningFaceEdgeTop == frontFaceColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperClockwise, solution, configuration).ConfigureAwait(false); } if (bottom == leftFaceColour && joiningFaceEdgeBottom == frontFaceColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerDownAntiClockwise, solution, configuration).ConfigureAwait(false); } }
private static async Task SortFace(FaceType face, CubeConfiguration<FaceColour> configuration, List<IRotation> solution) { if (configuration.Faces[face].TopRight() == FaceColour.Yellow) { // Move to Right Face switch (face) { case FaceType.Left: await CommonActions.ApplyAndAddRotation(Rotations.Upper2, solution, configuration).ConfigureAwait(false); break; case FaceType.Front: await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); break; case FaceType.Back: await CommonActions.ApplyAndAddRotation(Rotations.UpperClockwise, solution, configuration).ConfigureAwait(false); break; } await RightFace(solution, configuration).ConfigureAwait(false); } if (configuration.Faces[face].TopLeft() == FaceColour.Yellow) { // Move to Back Face switch (face) { case FaceType.Front: await CommonActions.ApplyAndAddRotation(Rotations.Upper2, solution, configuration).ConfigureAwait(false); break; case FaceType.Right: await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); break; case FaceType.Left: await CommonActions.ApplyAndAddRotation(Rotations.UpperClockwise, solution, configuration).ConfigureAwait(false); break; } await BackFace(solution, configuration).ConfigureAwait(false); } }
public static async Task<CubeRotation> PositionOnBottom(CubeConfiguration<FaceColour> config, FaceType face) { CubeRotation cubeRotation; switch (face) { case FaceType.Down: return null; case FaceType.Upper: cubeRotation = CubeRotations.X2; break; case FaceType.Right: cubeRotation = CubeRotations.ZClockwise; break; case FaceType.Left: cubeRotation = CubeRotations.ZAntiClockwise; break; case FaceType.Front: cubeRotation = CubeRotations.XAntiClockwise; break; case FaceType.Back: cubeRotation = CubeRotations.XClockwise; break; default: throw new Exception("Unknown face"); } await config.RotateCube(cubeRotation).ConfigureAwait(false); return cubeRotation; }
private async Task MoveRowToCorrectFace(FaceType faceToMoveToo, List<IRotation> solution, CubeConfiguration<FaceColour> configuration, bool upper) { // If we get an upper or down face it would imply that we do not have completed rows meaning we have probably skipped steps (some tests do this) if (faceToMoveToo == FaceType.Upper || faceToMoveToo == FaceType.Down) { return; } IRotation rotation = null; var face = upper ? FaceType.Upper : FaceType.Down; RotationDirection direction; var position = FaceRules.RelativePositionBetweenFaces(FaceType.Front, faceToMoveToo); switch (position) { case RelativePosition.Left: direction = upper ? RotationDirection.Clockwise : RotationDirection.AntiClockwise; rotation = Rotations.ByFace(face, direction, configuration.MinInnerLayerIndex()); break; case RelativePosition.Right: direction = !upper ? RotationDirection.Clockwise : RotationDirection.AntiClockwise; rotation = Rotations.ByFace(face, direction, configuration.MinInnerLayerIndex()); break; case RelativePosition.Opposite: rotation = Rotations.ByFaceTwice(face, configuration.MinInnerLayerIndex()); break; } if (rotation != null) { await CommonActions.ApplyAndAddRotation(rotation, solution, configuration).ConfigureAwait(false); } }
public static void FaceIsColour(CubeConfiguration<FaceColour> configuration, FaceType face, FaceColour colour) { Assert.IsTrue(configuration.Faces[face].Items.AsEnumerable().All(c => c == colour)); }
private static async Task CheckTopLayerForWhite(CubeConfiguration<FaceColour> configuration, Face<FaceColour> face, FaceType faceType, ICollection<IRotation> solution) { if (face.GetEdge(Edge.Top).Centre() != FaceColour.White) return; var edge = FaceRules.EdgeJoiningFaceToFace(faceType, FaceType.Upper); var joiningColour = configuration.Faces[FaceType.Upper].GetEdge(edge).Centre(); var faceWithJoiningColour = FaceRules.GetFaceOfColour(joiningColour, configuration); var relativePostion = FaceRules.RelativePositionBetweenFaces(faceWithJoiningColour, faceType); switch (relativePostion) { case RelativePosition.Same: await CommonActions.ApplyAndAddRotation(Rotations.UpperClockwise, solution, configuration).ConfigureAwait(false); await CheckTopLayerForWhite(configuration, configuration.Faces[FaceType.Left], FaceType.Left, solution).ConfigureAwait(false); break; case RelativePosition.Right: await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceType, RotationDirection.AntiClockwise), solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceWithJoiningColour, RotationDirection.Clockwise), solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceType, RotationDirection.Clockwise), solution, configuration).ConfigureAwait(false); break; case RelativePosition.Opposite: await CommonActions.ApplyAndAddRotation(Rotations.UpperClockwise, solution, configuration).ConfigureAwait(false); await CheckTopLayerForWhite(configuration, configuration.Faces[FaceType.Left], FaceType.Left, solution).ConfigureAwait(false); break; case RelativePosition.Left: await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceType, RotationDirection.Clockwise), solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceWithJoiningColour, RotationDirection.AntiClockwise), solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceType, RotationDirection.AntiClockwise), solution, configuration).ConfigureAwait(false); break; } }
private static IRotation GetRotationToPutTredgeOnFront(bool upperLayer, FaceType face, int layer = 0) { if (upperLayer) { switch (face) { case FaceType.Front: return null; case FaceType.Left: return Rotations.ByFace(FaceType.Upper, RotationDirection.AntiClockwise, layer); case FaceType.Right: return Rotations.ByFace(FaceType.Upper, RotationDirection.Clockwise, layer); case FaceType.Back: return Rotations.ByFaceTwice(FaceType.Upper, layer); } } else { switch (face) { case FaceType.Front: return null; case FaceType.Left: return Rotations.ByFace(FaceType.Down, RotationDirection.Clockwise, layer); case FaceType.Right: return Rotations.ByFace(FaceType.Down, RotationDirection.AntiClockwise, layer); case FaceType.Back: return Rotations.ByFaceTwice(FaceType.Down, layer); } } throw new InvalidOperationException("Unhandled tredge combo"); }
public Voxel(ushort _id, string _name, string _desc, bool _visible, bool _trasparent, FaceType _faceType) { id = _id; name = _name; desc = _desc; isVisible = _visible; isTransp = _trasparent; faceType = _faceType; }
private static TredgeMatch MatchColoursOnDownFaceEdge(CubeConfiguration<FaceColour> configuration, FaceColour frontColour, FaceColour leftColour, FaceType face) { var bottomEdge = configuration.Faces[face].GetEdge(Edge.Bottom); var frontBottomLeft = bottomEdge[configuration.MinInnerLayerIndex()]; var frontBottomRight = bottomEdge[configuration.MaxInnerLayerIndex()]; Edge edge; switch (face) { case FaceType.Front: edge = Edge.Top; break; case FaceType.Back: edge = Edge.Bottom; break; case FaceType.Left: edge = Edge.Left; break; case FaceType.Right: edge = Edge.Right; break; default: throw new InvalidOperationException("Cannot get connecting edge as down layer does not connect to " + face); } var downLayerEdge = configuration.Faces[FaceType.Down].GetEdge(edge); if (face == FaceType.Back || face == FaceType.Left) { downLayerEdge = downLayerEdge.Reverse().ToArray(); } var downTopLeft = downLayerEdge[configuration.MinInnerLayerIndex()]; var downTopRight = downLayerEdge[configuration.MaxInnerLayerIndex()]; if (frontBottomLeft == frontColour && downTopLeft == leftColour) { return TredgeMatch.FrontLeftMatchesCenter; } if (frontBottomRight == frontColour && downTopRight == leftColour) { return TredgeMatch.FrontRightMatchesCenter; } if (frontBottomLeft == leftColour && downTopLeft == frontColour) { return TredgeMatch.DownLeftMatchesCenter; } if (frontBottomRight == leftColour && downTopRight == frontColour) { return TredgeMatch.DownRightMatchesCenter; } return TredgeMatch.None; }
private static async Task CheckUpperAndDownEdgesOnFace(CubeConfiguration<FaceColour> configuration, List<IRotation> solution, FaceType faceToCheck) { var frontFaceColour = configuration.Faces[FaceType.Front].LeftCentre(); var leftFaceColour = configuration.Faces[FaceType.Left].RightCentre(); var match = MatchColoursOnUpperFaceEdge(configuration, frontFaceColour, leftFaceColour, faceToCheck); if (match != TredgeMatch.None) { var rotation = GetRotationToPutTredgeOnFront(true, faceToCheck); await CommonActions.ApplyAndAddRotation(rotation, solution, configuration).ConfigureAwait(false); await CheckFrontUpper(configuration, solution, frontFaceColour, leftFaceColour).ConfigureAwait(false); } match = MatchColoursOnDownFaceEdge(configuration, frontFaceColour, leftFaceColour, faceToCheck); if (match != TredgeMatch.None) { var rotation = GetRotationToPutTredgeOnFront(false, faceToCheck); await CommonActions.ApplyAndAddRotation(rotation, solution, configuration).ConfigureAwait(false); await CheckFrontDown(configuration, solution, frontFaceColour, leftFaceColour).ConfigureAwait(false); } }
private static async Task CheckTopLayerForWhite(CubeConfiguration<FaceColour> configuration, ICollection<IRotation> solution, FaceType face, bool leftIsLastInTopEdge = false, bool rightIsLastInTopEdge = false) { // TODO: CUBE ROTATE INSTEAD SO WE ARE ONLY USING RIGHT....? var topEdge = FaceRules.EdgeJoiningFaceToFace(face, FaceType.Upper); var edgeInTopFace = configuration.Faces[FaceType.Upper].GetEdge(topEdge); var rotatingFace = configuration.Faces[face]; if (rotatingFace.TopLeft() == FaceColour.White) { var joiningUpperColour = leftIsLastInTopEdge ? edgeInTopFace.Last() : edgeInTopFace.First(); var joiningUpperFace = FaceRules.GetFaceOfColour(joiningUpperColour, configuration); var relativePositionToUpperJoining = FaceRules.RelativePositionBetweenFaces(face, joiningUpperFace); switch (relativePositionToUpperJoining) { case RelativePosition.Right: await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); break; case RelativePosition.Left: await CommonActions.ApplyAndAddRotation(Rotations.UpperClockwise, solution, configuration).ConfigureAwait(false); break; case RelativePosition.Opposite: await CommonActions.ApplyAndAddRotation(Rotations.Upper2, solution, configuration).ConfigureAwait(false); break; } await CommonActions.ApplyAndAddRotation(Rotations.ByFace(joiningUpperFace, RotationDirection.Clockwise), solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.UpperClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.ByFace(joiningUpperFace, RotationDirection.AntiClockwise), solution, configuration).ConfigureAwait(false); } else if (rotatingFace.TopRight() == FaceColour.White) { var joiningUpperColour = rightIsLastInTopEdge ? edgeInTopFace.Last() : edgeInTopFace.First(); var joiningUpperFace = FaceRules.GetFaceOfColour(joiningUpperColour, configuration); var relativePositionToUpperJoining = FaceRules.RelativePositionBetweenFaces(face, joiningUpperFace); switch (relativePositionToUpperJoining) { case RelativePosition.Same: await CommonActions.ApplyAndAddRotation(Rotations.UpperClockwise, solution, configuration).ConfigureAwait(false); break; case RelativePosition.Left: await CommonActions.ApplyAndAddRotation(Rotations.Upper2, solution, configuration).ConfigureAwait(false); break; case RelativePosition.Opposite: await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); break; } var faceToRotate = FaceRules.FaceAtRelativePositionTo(joiningUpperFace, RelativePosition.Right); await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceToRotate, RotationDirection.Clockwise), solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.ByFace(faceToRotate, RotationDirection.AntiClockwise), solution, configuration).ConfigureAwait(false); } }
internal abstract void RayHitTestCore(RayHitTestParameters rayParams, FaceType hitTestableFaces);
public SphereFace(FaceType newType) { sphereFaceType = newType; }
private static async Task CheckMiddleLayerForWhite(CubeConfiguration<FaceColour> configuration, Face<FaceColour> face, FaceType faceType, ICollection<IRotation> solution) { if (face.GetEdge(Edge.Left).Centre() == FaceColour.White) { await MoveWhiteFromMiddleLayer(configuration, faceType, solution, RelativePosition.Left, Edge.Right, RotationDirection.Clockwise).ConfigureAwait(false); } if (face.GetEdge(Edge.Right).Centre() == FaceColour.White) { await MoveWhiteFromMiddleLayer(configuration, faceType, solution, RelativePosition.Right, Edge.Left, RotationDirection.AntiClockwise).ConfigureAwait(false); } }
private static async Task MoveWhiteFromMiddleLayer(CubeConfiguration<FaceColour> configuration, FaceType faceType, ICollection<IRotation> solution, RelativePosition relativePosition, Edge edge, RotationDirection downDirection) { var joiningFace = FaceRules.FaceAtRelativePositionTo(faceType, relativePosition); var joiningColour = configuration.Faces[joiningFace].GetEdge(edge).Centre(); var faceWithJoiningColour = FaceRules.GetFaceOfColour(joiningColour, configuration); var relativePostion = FaceRules.RelativePositionBetweenFaces(faceWithJoiningColour, joiningFace); switch (relativePostion) { case RelativePosition.Same: await CommonActions.ApplyAndAddRotation(Rotations.ByFace(joiningFace, downDirection), solution, configuration).ConfigureAwait(false); break; case RelativePosition.Left: case RelativePosition.Right: case RelativePosition.Opposite: // TODO: ROTATE SO THAT WE ARE ONLY DOING RIGHT... MOVES await CommonActions.ApplyAndAddRotation(Rotations.ByFace(joiningFace, RotationDirectionEx.Reverse(downDirection)), solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.ByFace(joiningFace, downDirection), solution, configuration).ConfigureAwait(false); await CheckTopFaceForWhite(configuration, joiningFace, solution).ConfigureAwait(false); break; } }
private static async Task CheckTopFaceForWhite(CubeConfiguration<FaceColour> configuration, FaceType faceType, ICollection<IRotation> solution) { var edge = FaceRules.EdgeJoiningFaceToFace(faceType, FaceType.Upper); if (configuration.Faces[FaceType.Upper].GetEdge(edge).Centre() != FaceColour.White) return; var joiningColour = configuration.Faces[faceType].GetEdge(Edge.Top).Centre(); var faceWithJoiningColour = FaceRules.GetFaceOfColour(joiningColour, configuration); var relativePostion = FaceRules.RelativePositionBetweenFaces(faceWithJoiningColour, faceType); IRotation topRotation = null; switch (relativePostion) { case RelativePosition.Same: break; case RelativePosition.Right: topRotation = Rotations.UpperClockwise; break; case RelativePosition.Opposite: topRotation = Rotations.Upper2; break; case RelativePosition.Left: topRotation = Rotations.UpperAntiClockwise; break; } IRotation rotationToBottom = Rotations.ByFaceTwice(faceWithJoiningColour); await CommonActions.ApplyAndAddRotation(topRotation, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(rotationToBottom, solution, configuration).ConfigureAwait(false); }
// // Hits the ray against the mesh // internal override void RayHitTestCore( RayHitTestParameters rayParams, FaceType hitTestableFaces) { Debug.Assert(hitTestableFaces != FaceType.None, "Caller should make sure we're trying to hit something"); Point3DCollection positions = Positions; if (positions == null) { return; } Point3D origin; Vector3D direction; rayParams.GetLocalLine(out origin, out direction); Int32Collection indices = TriangleIndices; // In the line case, we want to hit test all faces because we don't // have a direction. This may differ from what faces we want to // accept. FaceType facesToHit; if (rayParams.IsRay) { facesToHit = hitTestableFaces; } else { facesToHit = FaceType.Front | FaceType.Back; } // // This code duplication is unfortunate but necessary. Breaking it down into methods // further significantly impacts performance. About 5% improvement could be made // by unrolling this code below even more. // // If futher perf investigation is done with this code, be sure to test NGEN assemblies only // as JIT produces different, faster code than NGEN. // if (indices == null || indices.Count == 0) { FrugalStructList<Point3D> ps = positions._collection; int count = ps.Count - (ps.Count % 3); for (int i = count - 1; i >= 2; i -= 3) { int i0 = i - 2; int i1 = i - 1; int i2 = i; Point3D v0 = ps[i0]; Point3D v1 = ps[i1]; Point3D v2 = ps[i2]; double hitTime; Point barycentric; // The line hit test is equivalent to a double sided // triangle hit because it doesn't cull triangles based // on winding if (LineUtil.ComputeLineTriangleIntersection( facesToHit, ref origin, ref direction, ref v0, ref v1, ref v2, out barycentric, out hitTime ) ) { if (rayParams.IsRay) { ValidateRayHit( rayParams, ref origin, ref direction, hitTime, i0, i1, i2, ref barycentric ); } else { ValidateLineHit( rayParams, hitTestableFaces, i0, i1, i2, ref v0, ref v1, ref v2, ref barycentric ); } } } } else // indexed mesh { FrugalStructList<Point3D> ps = positions._collection; FrugalStructList<int> idcs = indices._collection; int count = idcs.Count; int limit = ps.Count; for (int i = 2; i < count; i += 3) { int i0 = idcs[i - 2]; int i1 = idcs[i - 1]; int i2 = idcs[i]; // Quit if we encounter an index out of range. // This is okay because the triangles we ignore are not rendered. // (see: CMilMeshGeometry3DDuce::Realize) if ((0 > i0 || i0 >= limit) || (0 > i1 || i1 >= limit) || (0 > i2 || i2 >= limit)) { break; } Point3D v0 = ps[i0]; Point3D v1 = ps[i1]; Point3D v2 = ps[i2]; double hitTime; Point barycentric; if (LineUtil.ComputeLineTriangleIntersection( facesToHit, ref origin, ref direction, ref v0, ref v1, ref v2, out barycentric, out hitTime ) ) { if (rayParams.IsRay) { ValidateRayHit( rayParams, ref origin, ref direction, hitTime, i0, i1, i2, ref barycentric ); } else { ValidateLineHit( rayParams, hitTestableFaces, i0, i1, i2, ref v0, ref v1, ref v2, ref barycentric ); } } } } }
// // Processes a ray-line intersection to see if it's a valid hit. // // Shares some code with ValidateRayHit // private void ValidateLineHit( RayHitTestParameters rayParams, FaceType facesToHit, int i0, int i1, int i2, ref Point3D v0, ref Point3D v1, ref Point3D v2, ref Point barycentric ) { Matrix3D worldTransformMatrix = rayParams.HasWorldTransformMatrix ? rayParams.WorldTransformMatrix : Matrix3D.Identity; // OK, we have an intersection with the LINE but that could be wrong on three // accounts: // 1. We could have hit the line on the wrong side of the ray's origin. // 2. We may need to cull the intersection if it's beyond the far clipping // plane (only if the hit test originated from a Viewport3DVisual.) // 3. We could have hit a back-facing triangle // We will transform the hit point back into world space to check these // things & compute the correct distance from the origin to the hit point. // Hit point in model space Point3D pointHit = M3DUtil.Interpolate(ref v0, ref v1, ref v2, ref barycentric); Point3D worldPointHit = pointHit; worldTransformMatrix.MultiplyPoint(ref worldPointHit); // Vector from origin to hit point Vector3D hitVector = worldPointHit - rayParams.Origin; Vector3D originalDirection = rayParams.Direction; double rayDistanceUnnormalized = Vector3D.DotProduct(originalDirection, hitVector); if (rayDistanceUnnormalized > 0) { // If we have a HitTestProjectionMatrix than this hit test originated // at a Viewport3DVisual. if (rayParams.HasHitTestProjectionMatrix) { // To test if we are in front of the far clipping plane what we // do conceptually is project our hit point in world space into // homogenous space and verify that it is on the correct side of // the Z=1 plane. // // To save some cycles we only bother computing Z and W of the // projected point and use a simple Z/W > 1 test to see if we // are past the far plane. // // NOTE: HitTestProjectionMatrix is not just the camera matrices. // It has an additional translation to move the ray to the // origin. This extra translation does not effect this test. Matrix3D m = rayParams.HitTestProjectionMatrix; // We directly substitute 1 for p.W below: double pz = worldPointHit.X * m.M13 + worldPointHit.Y * m.M23 + worldPointHit.Z * m.M33 + m.OffsetZ; double pw = worldPointHit.X * m.M14 + worldPointHit.Y * m.M24 + worldPointHit.Z * m.M34 + m.M44; // Early exit if pz/pw > 1. The negated logic is to reject NaNs. if (!(pz / pw <= 1)) { return; } Debug.Assert(!double.IsInfinity(pz / pw) && !double.IsNaN(pz / pw), "Expected near/far tests to cull -Inf/+Inf and NaN."); } Point3D a = v0, b = v1, c = v2; worldTransformMatrix.MultiplyPoint(ref a); worldTransformMatrix.MultiplyPoint(ref b); worldTransformMatrix.MultiplyPoint(ref c); Vector3D normal = Vector3D.CrossProduct(b - a, c - a); double cullSign = -Vector3D.DotProduct(normal, hitVector); double det = worldTransformMatrix.Determinant; bool frontFace = (cullSign > 0) == (det >= 0); if (((facesToHit & FaceType.Front) == FaceType.Front && frontFace) || ((facesToHit & FaceType.Back) == FaceType.Back && !frontFace)) { double dist = hitVector.Length; if (rayParams.HasModelTransformMatrix) { rayParams.ModelTransformMatrix.MultiplyPoint(ref pointHit); } rayParams.ReportResult(this, pointHit, dist, i0, i1, i2, barycentric); } } }
private static async Task CheckBottomFaceForWhite(CubeConfiguration<FaceColour> configuration, FaceType faceType, ICollection<IRotation> solution) { var edge = FaceRules.EdgeJoiningFaceToFace(faceType, FaceType.Down); if (configuration.Faces[FaceType.Down].GetEdge(edge).Centre() != FaceColour.White) return; var joiningFace = configuration.Faces[faceType]; var joiningColour = joiningFace.GetEdge(Edge.Bottom).Centre(); // If the colour does not match, put it on the top face if (joiningColour != joiningFace.Centre) { await CommonActions.ApplyAndAddRotation(Rotations.ByFaceTwice(faceType), solution, configuration).ConfigureAwait(false); } }