コード例 #1
0
ファイル: CubeModel.cs プロジェクト: ARLM-Attic/rubiks-cube
        public bool SelectCubicle(
            Ray ray,
            out Cubicle selectedCubicle,
            out float distance)
        {
            string selectedBasicOp;

            return(_cubeConfiguration.SelectCubicle(ray, out selectedCubicle, out selectedBasicOp, out distance));
        }
コード例 #2
0
        public bool SelectCubicle(
            Ray clickRay,
            out Cubicle selectedCubicle,
            out string basicOp,
            out float closestDistance
            )
        {
            selectedCubicle = null;
            closestDistance = float.MaxValue;
            basicOp         = string.Empty;

            /*
             * Matrix[] transforms = new Matrix[m.Bones.Count];
             * m.CopyAbsoluteBoneTransformsTo(transforms);
             */


            //Transform the ray into the model's local space. This will keep us from having to transform every polygon into world space during the collision testing process. Simply take the inverse of the mesh's world transform and apply it to the ray position and direction. Note that the Direction is transformed using Vector3.TransformNormal. This is to prevent the translation and scaling of the matrix from adjusting the ray direction.

            /*
             * Matrix mat = Matrix.Invert(transform);
             * clickRay.Position = Vector3.Transform(clickRay.Position, mat);
             * clickRay.Direction = Vector3.TransformNormal(clickRay.Direction, mat);
             */


            //for (int i = 0; i < m.Meshes.Count; i++)
            foreach (Cubicle cubicle in _cubeConfiguration.Values)
            {
                float?distance = cubicle.BoundingBox.Intersects(clickRay); // Intersect(cubicle, clickRay);// clickRay.Intersects(box);
                if (distance.HasValue == false)
                {
                    continue;
                }

                if (distance < closestDistance)
                {
                    selectedCubicle = cubicle;
                    closestDistance = (float)distance;
                }
                //Debug.WriteLine(mesh.Name);
            }

            if (selectedCubicle != null)
            {
                string selectName = selectedCubicle.Id;
                if (Cubicle.BasicOpFromSelectedCubicle.ContainsKey(selectName))
                {
                    if (selectName.Length < 3)
                    {
                        basicOp = Cubicle.BasicOpFromSelectedCubicle[selectName];
                    }
                    else
                    {
                        Axis axis = GetClosestAxis(selectedCubicle, clickRay);
                        basicOp = Cubicle.BasicOpFromAxis[axis].First(op => selectName.IndexOf(op) >= 0);
                    }
                }
            }
            return(selectedCubicle != null);
        }
コード例 #3
0
        private Axis GetClosestAxis(Cubicle cubicle, Ray ray)
        {
            //Debug.WriteLine(cubicle.BoundingBox.ToString());
            //UFL-U
            //URF-F
            //UBR-R
            //ULB-B

            Vector3 v1   = Vector3.Zero;
            Vector3 v2   = Vector3.Zero;
            Vector3 v3   = Vector3.Zero;
            Vector3 v4   = Vector3.Zero;
            Vector3 vmin = cubicle.BoundingBox.Min;
            Vector3 vmax = cubicle.BoundingBox.Max;

            switch (cubicle.Id)
            {
            case "UFL":
                v1 = new Vector3(vmin.X, vmin.Y, vmax.Z);
                v2 = new Vector3(vmin.X, vmax.Y, vmin.Z);
                v3 = vmax;
                v4 = new Vector3(vmin.X, vmax.Y, vmax.Z);
                break;

            case "URF":
                v1 = new Vector3(vmax.X, vmin.Y, vmax.Z);
                v2 = new Vector3(vmax.X, vmax.Y, vmin.Z);
                v3 = new Vector3(vmin.X, vmax.Y, vmax.Z);
                v4 = vmax;
                break;

            case "UBR":
                v1 = new Vector3(vmax.X, vmin.Y, vmin.Z);
                v2 = vmax;
                v3 = new Vector3(vmin.X, vmax.Y, vmin.Z);
                v4 = new Vector3(vmax.X, vmax.Y, vmin.Z);
                break;

            case "ULB":
                v1 = vmin;
                v2 = new Vector3(vmin.X, vmax.Y, vmax.Z);
                v3 = new Vector3(vmax.X, vmax.Y, vmin.Z);
                v4 = new Vector3(vmin.X, vmax.Y, vmin.Z);
                break;

            //DLF-D
            //DFR-R
            //DRB-B
            //DBL-L
            case "DLF":
                v1 = vmin;
                v2 = new Vector3(vmin.X, vmax.Y, vmax.Z);
                v3 = new Vector3(vmax.X, vmin.Y, vmax.Z);
                v4 = new Vector3(vmin.X, vmin.Y, vmax.Z);
                break;

            case "DFR":
                v1 = new Vector3(vmax.X, vmin.Y, vmin.Z);
                v2 = vmax;
                v3 = new Vector3(vmin.X, vmin.Y, vmax.Z);
                v4 = new Vector3(vmax.X, vmin.Y, vmax.Z);
                break;

            case "DRB":
                v1 = new Vector3(vmax.X, vmax.Y, vmin.Z);
                v2 = new Vector3(vmax.X, vmin.Y, vmax.Z);
                v3 = vmin;
                v4 = new Vector3(vmax.X, vmin.Y, vmin.Z);
                break;

            case "DBL":
                v1 = new Vector3(vmin.X, vmax.Y, vmin.Z);
                v2 = new Vector3(vmin.X, vmin.Y, vmax.Z);
                v3 = new Vector3(vmax.X, vmin.Y, vmin.Z);
                v4 = vmin;
                break;
            }
            return(GetClosestAxis(v1, v2, v3, v4, ray));
        }