コード例 #1
0
 public static void WpfColorFromColor4(ref Color4 source, ref WpfMedia.Color target)
 {
     target.A = (byte)EngineMath.Clamp(0f, 255f, source.Alpha * 255f);
     target.R = (byte)EngineMath.Clamp(0f, 255f, source.Alpha * 255f);
     target.G = (byte)EngineMath.Clamp(0f, 255f, source.Alpha * 255f);
     target.B = (byte)EngineMath.Clamp(0f, 255f, source.Alpha * 255f);
 }
コード例 #2
0
        /// <summary>
        /// Builds a geosphere geometry.
        /// </summary>
        public static BuiltVerticesRange BuildGeosphere(this GeometrySurface target, float radius, int countSubdivisions)
        {
            // Implemented with sample code from http://www.d3dcoder.net/d3d11.htm, Source Code Set II

            countSubdivisions = Math.Max(countSubdivisions, 0);
            radius            = Math.Max(Math.Abs(radius), EngineMath.TOLERANCE_FLOAT_POSITIVE); // <-- this one prevents device by zero

            var startVertex   = target.Owner.CountVertices;
            var startTriangle = target.Owner.CountTriangles;

            // Build an icosahedron
            const float X   = 0.525731f;
            const float Z   = 0.850651f;
            var         pos = new[]
            {
                new Vector3(-X, 0f, Z), new Vector3(X, 0f, Z),
                new Vector3(-X, 0f, -Z), new Vector3(X, 0f, -Z),
                new Vector3(0f, Z, X), new Vector3(0f, Z, -X),
                new Vector3(0f, -Z, X), new Vector3(0f, -Z, -X),
                new Vector3(Z, X, 0f), new Vector3(-Z, X, 0f),
                new Vector3(Z, -X, 0f), new Vector3(-Z, -X, 0f)
            };
            var k = new[]
            {
                1, 4, 0, 4, 9, 0, 4, 5, 9, 8, 5, 4, 1, 8, 4,
                1, 10, 8, 10, 3, 8, 8, 3, 5, 3, 2, 5, 3, 7, 2,
                3, 10, 7, 10, 6, 7, 6, 11, 7, 6, 0, 11, 6, 1, 0,
                10, 1, 6, 11, 0, 9, 2, 11, 9, 5, 2, 9, 11, 2, 7
            };

            foreach (var actPosition in pos)
            {
                target.Owner.AddVertex(new VertexBasic(actPosition));
            }
            for (var loop = 0; loop < k.Length; loop += 3)
            {
                target.AddTriangle(k[loop], k[loop + 1], k[loop + 2]);
            }

            // Subdivide it n times
            for (var loop = 0; loop < countSubdivisions; loop++)
            {
                target.Subdivide(startTriangle);
            }

            // Project vertices onto sphere and scale
            var vertexCount = target.Owner.CountVertices;

            for (var actVertexIndex = startVertex; actVertexIndex < vertexCount; actVertexIndex++)
            {
                ref var actVertex = ref target.Owner.GetVertexBasicRef(actVertexIndex);
                actVertex.Normal   = Vector3.Normalize(actVertex.Position);
                actVertex.Position = actVertex.Normal * radius;

                var theta = EngineMath.AngleFromXY(actVertex.Position.X, actVertex.Position.Z);
                var phi   = (float)Math.Acos(actVertex.Position.Y / radius);
                actVertex.TexCoord1 = new Vector2(
                    theta / EngineMath.PI_2,
                    phi / EngineMath.PI);
            }
コード例 #3
0
 public void BitmapComparison_Positive()
 {
     using (var leftBitmap = TestUtilities.LoadBitmapFromResource("BitmapComparison", "FlatShadedObject.png"))
         using (var rightBitmap = TestUtilities.LoadBitmapFromResource("BitmapComparison", "FlatShadedObject.png"))
         {
             Assert.IsTrue(
                 EngineMath.EqualsWithTolerance(BitmapComparison.CalculatePercentageDifference(leftBitmap, rightBitmap), 0f));
         }
 }
コード例 #4
0
 public void BitmapComparison_Negative_BlackWhite()
 {
     using (var leftBitmap = TestUtilities.LoadBitmapFromResource("BitmapComparison", "WhiteScreen.png"))
         using (var rightBitmap = TestUtilities.LoadBitmapFromResource("BitmapComparison", "BlackScreen.png"))
         {
             var comparisonResult = BitmapComparison.CalculatePercentageDifference(leftBitmap, rightBitmap);
             Assert.IsTrue(EngineMath.EqualsWithTolerance(comparisonResult, 1.0f));
         }
 }
コード例 #5
0
    static public Color ParseColor24(string text, int offset)
    {
        int   r = (EngineMath.HexToDecimal(text[offset]) << 4) | EngineMath.HexToDecimal(text[offset + 1]);
        int   g = (EngineMath.HexToDecimal(text[offset + 2]) << 4) | EngineMath.HexToDecimal(text[offset + 3]);
        int   b = (EngineMath.HexToDecimal(text[offset + 4]) << 4) | EngineMath.HexToDecimal(text[offset + 5]);
        float f = 1f / 255f;

        return(new Color(f * r, f * g, f * b));
    }
コード例 #6
0
        public static Color UIColorFromColor4(ref Color4 color)
        {
            var uiColor = new Color
            {
                A = (byte)EngineMath.Clamp(0f, 255f, color.Alpha * 255f),
                R = (byte)EngineMath.Clamp(0f, 255f, color.Red * 255f),
                G = (byte)EngineMath.Clamp(0f, 255f, color.Green * 255f),
                B = (byte)EngineMath.Clamp(0f, 255f, color.Blue * 255f)
            };

            return(uiColor);
        }
コード例 #7
0
        public static void EnsureNormalized(
            this Vector2 vectorValue, string checkedVariableName,
            [CallerMemberName]
            string callerMethod = "")
        {
            if (string.IsNullOrEmpty(callerMethod))
            {
                callerMethod = "Unknown";
            }

            if (!EngineMath.EqualsWithTolerance(vectorValue.Length(), 1f))
            {
                throw new SeeingSharpCheckException(string.Format(
                                                        "Vector {0} within method {1} must be normalized!",
                                                        checkedVariableName, callerMethod, vectorValue));
            }
        }
コード例 #8
0
        public static void EnsureNotEqual(
            this Vector2 vectorValueLeft, Vector2 vectorValueRight, string checkedVariableName, string comparedVariableName,
            [CallerMemberName]
            string callerMethod = "")
        {
            if (string.IsNullOrEmpty(callerMethod))
            {
                callerMethod = "Unknown";
            }

            if (EngineMath.EqualsWithTolerance(vectorValueLeft.X, vectorValueRight.X) &&
                EngineMath.EqualsWithTolerance(vectorValueLeft.Y, vectorValueRight.Y))
            {
                throw new SeeingSharpCheckException(
                          $"Vector {checkedVariableName} within method {callerMethod} with value {vectorValueLeft} musst not be equal with the vector {comparedVariableName}!");
            }
        }
コード例 #9
0
        /// <summary>
        /// Sets current transform settings on this graphics object.
        /// (be careful, the state is changed on device level!)
        /// </summary>
        /// <param name="transformSettings">The settings to be set.</param>
        internal void PushTransformSettings(Graphics2DTransformSettings transformSettings)
        {
            _transformSettings = transformSettings;

            switch (transformSettings.TransformMode)
            {
            // Overtake given scaling matrix
            case Graphics2DTransformMode.Custom:
                this.TransformStack.Push(transformSettings.CustomTransform);
                break;

            // Calculate scaling matrix here
            case Graphics2DTransformMode.AutoScaleToVirtualScreen:
                var virtualWidth  = _transformSettings.VirtualScreenSize.Width;
                var virtualHeight = _transformSettings.VirtualScreenSize.Height;
                if (EngineMath.EqualsWithTolerance(virtualWidth, 0f))
                {
                    virtualWidth = this.ScreenPixelSize.Width;
                }
                if (EngineMath.EqualsWithTolerance(virtualHeight, 0f))
                {
                    virtualHeight = this.ScreenPixelSize.Height;
                }

                var scaleFactorX        = this.ScreenPixelSize.Width / virtualWidth;
                var scaleFactorY        = this.ScreenPixelSize.Height / virtualHeight;
                var combinedScaleFactor = Math.Min(scaleFactorX, scaleFactorY);
                var truePixelWidth      = virtualWidth * combinedScaleFactor;
                var truePixelHeight     = virtualHeight * combinedScaleFactor;

                this.TransformStack.Push();
                this.TransformStack.TransformLocal(
                    Matrix3x2.CreateScale(combinedScaleFactor) *
                    Matrix3x2.CreateTranslation(this.ScreenPixelSize.Width / 2f - truePixelWidth / 2f, this.ScreenPixelSize.Height / 2f - truePixelHeight / 2f));
                break;

            default:
                throw new SeeingSharpGraphicsException($"Unable to handle transform mode {transformSettings.TransformMode}");
            }

            // Apply current transform
            this.ApplyTransformStack();
        }
コード例 #10
0
ファイル: EngineMath.cs プロジェクト: lwx1010/2D_XProject
    /// <summary>
    /// Determine the distance from the mouse position to the screen space rectangle specified by the 4 points.
    /// </summary>

    static public float DistanceToRectangle(Vector2[] screenPoints, Vector2 mousePos)
    {
        bool oddNodes = false;
        int  j        = 4;

        for (int i = 0; i < 5; i++)
        {
            Vector3 v0 = screenPoints[EngineMath.RepeatIndex(i, 4)];
            Vector3 v1 = screenPoints[EngineMath.RepeatIndex(j, 4)];

            if ((v0.y > mousePos.y) != (v1.y > mousePos.y))
            {
                if (mousePos.x < (v1.x - v0.x) * (mousePos.y - v0.y) / (v1.y - v0.y) + v0.x)
                {
                    oddNodes = !oddNodes;
                }
            }
            j = i;
        }

        if (!oddNodes)
        {
            float dist, closestDist = -1f;

            for (int i = 0; i < 4; i++)
            {
                Vector3 v0 = screenPoints[i];
                Vector3 v1 = screenPoints[EngineMath.RepeatIndex(i + 1, 4)];

                dist = DistancePointToLineSegment(mousePos, v0, v1);

                if (dist < closestDist || closestDist < 0f)
                {
                    closestDist = dist;
                }
            }
            return(closestDist);
        }
        else
        {
            return(0f);
        }
    }
コード例 #11
0
        public static void EnsureNotEqual(
            this Vector4 vectorValueLeft, Vector4 vectorValueRight, string checkedVariableName, string comparedVariableName,
            [CallerMemberName]
            string callerMethod = "")
        {
            if (string.IsNullOrEmpty(callerMethod))
            {
                callerMethod = "Unknown";
            }

            if (EngineMath.EqualsWithTolerance(vectorValueLeft.X, vectorValueRight.X) &&
                EngineMath.EqualsWithTolerance(vectorValueLeft.Y, vectorValueRight.Y) &&
                EngineMath.EqualsWithTolerance(vectorValueLeft.Z, vectorValueRight.Z) &&
                EngineMath.EqualsWithTolerance(vectorValueLeft.W, vectorValueRight.W))
            {
                throw new SeeingSharpCheckException(string.Format(
                                                        "Vector {0} within method {1} with value {2} musst not be equal with the vector {3}!",
                                                        checkedVariableName, callerMethod, vectorValueLeft, comparedVariableName));
            }
        }
コード例 #12
0
        public static Modell ReadModell(string path)
        {
            if (!File.Exists(path))
            {
                throw new Exception("File was not exist");
            }
            string[]       lines         = File.ReadAllLines(path);
            List <Vector3> localVertices = new List <Vector3>();
            List <Vector2> uv            = new List <Vector2>();
            List <int>     uvIndex       = new List <int>();
            List <int>     faces         = new List <int>();
            List <Vector3> normal        = new List <Vector3>();
            List <int>     normalIndexes = new List <int>();

            foreach (string line in lines)
            {
                if (line.Length > 0)
                {
                    if (line[0] == 'v' && line[1] != 'n' && line[1] != 't')
                    {
                        int  end      = 0;
                        bool finished = false;
                        foreach (char chr in line)
                        {
                            if (chr == 'v' && !finished)
                            {
                                end++;
                            }
                            else if (chr == ' ' && !finished)
                            {
                                end++;
                            }
                            else
                            {
                                finished = true;
                            }
                        }
                        string[] data = line.Substring(end, line.Length - end).Split(' ');
                        localVertices.Add(new Vector3(float.Parse(data[0].Replace('.', ',')), float.Parse(data[1].Replace('.', ',')), float.Parse(data[2].Replace('.', ','))));
                    }
                    else if (line[0] == 'f')
                    {
                        string[] data = line.Substring(2, line.Length - 2).Split(' ');
                        foreach (string vert in data)
                        {
                            string[] v_index = vert.Split('/');
                            faces.Add(int.Parse(v_index[0]));
                            uvIndex.Add(int.Parse(v_index[1]));
                            normalIndexes.Add(int.Parse(v_index[2]));
                        }
                    }
                    else if (line[0] == 'v' && line[1] == 't')
                    {
                        int  end      = 0;
                        bool finished = false;
                        foreach (char chr in line)
                        {
                            if (chr == 'v' && !finished)
                            {
                                end++;
                            }
                            else if (chr == 't' && !finished)
                            {
                                end++;
                            }
                            else if (chr == ' ' && !finished)
                            {
                                end++;
                            }
                            else
                            {
                                finished = true;
                            }
                        }
                        string[] data = line.Substring(end, line.Length - end).Split(' ');
                        uv.Add(new Vector2(float.Parse(data[0].Replace('.', ',')), float.Parse(data[1].Replace('.', ','))));
                    }
                    else if (line[0] == 'v' && line[1] == 'n')
                    {
                        int  end      = 0;
                        bool finished = false;
                        foreach (char chr in line)
                        {
                            if (chr == 'v' && !finished)
                            {
                                end++;
                            }
                            else if (chr == ' ' && !finished)
                            {
                                end++;
                            }
                            else if (chr == 'n' && !finished)
                            {
                                end++;
                            }
                            else
                            {
                                finished = true;
                            }
                        }
                        string[] data = line.Substring(end, line.Length - end).Split(' ');
                        normal.Add(new Vector3(float.Parse(data[0].Replace('.', ',')), float.Parse(data[1].Replace('.', ',')), float.Parse(data[2].Replace('.', ','))));
                    }
                }
            }
            List <Vector3>   finalVertices = new List <Vector3>();
            List <Vector3>   finalNormals  = new List <Vector3>();
            List <Vector2>   finalUV       = new List <Vector2>();
            List <Texture2D> textures      = new List <Texture2D>();
            List <Color>     colors        = new List <Color>();
            Random           rnd           = new Random();
            Texture2D        texture       = LoadResources.ReadTexture(Directory.GetCurrentDirectory() + @"\Mods\Default\Textures\rock.jpg");

            foreach (int vert_index in faces)
            {
                finalVertices.Add(localVertices[vert_index - 1]);
                textures.Add(texture);
                colors.Add(Color.FromArgb(255, rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255)));
            }

            foreach (int uv_index in uvIndex)
            {
                finalUV.Add(EngineMath.RotateVector(uv[uv_index - 1], 180));
            }

            foreach (int normal_index in normalIndexes)
            {
                finalNormals.Add(normal[normal_index - 1]);
            }
            Modell modell = new Modell()
            {
                vertices = finalVertices.ToArray(), uv = finalUV.ToArray(), normal = finalNormals.ToArray(), location = path
            };

            return(modell);
        }
コード例 #13
0
    static public float ParseAlpha(string text, int index)
    {
        int a = (EngineMath.HexToDecimal(text[index + 1]) << 4) | EngineMath.HexToDecimal(text[index + 2]);

        return(Mathf.Clamp01(a / 255f));
    }
コード例 #14
0
        /// <summary>
        /// Sets the current geometry of this object.
        /// </summary>
        /// <param name="geometry">The new geometry to be set.</param>
        /// <param name="flatteningTolerance">The maximum bounds on the distance between points in the polygonal approximation of the geometry. Smaller values produce more accurate results but cause slower execution.</param>
        /// <param name="extrudeOptions">Additional options for extruding.</param>
        internal void SetGeometry(
            D2D.ID2D1Geometry geometry, float flatteningTolerance,
            ExtrudeGeometryOptions extrudeOptions = ExtrudeGeometryOptions.None)
        {
            // Get triangles out of given geometry
            List <D2D.Triangle[]>?generatedTriangles = null;

            using (var tessellationSink = new ExtruderTessellationSink())
            {
                geometry.Tessellate(flatteningTolerance, tessellationSink);
                generatedTriangles = tessellationSink.Triangles;
            }

            // Ensure that triangle list is created
            if (_generatedTriangles == null)
            {
                _generatedTriangles = new List <D2D.Triangle[]>();
            }

            // Define methods for calculating bounds
            var minX     = float.MaxValue;
            var maxX     = float.MinValue;
            var minY     = float.MaxValue;
            var maxY     = float.MinValue;
            var minPoint = Vector2.Zero;

            void UpdateMinWidthHeight(PointF actCorner)
            {
                if (actCorner.X < minX)
                {
                    minX = actCorner.X;
                }
                if (actCorner.X > maxX)
                {
                    maxX = actCorner.X;
                }
                if (actCorner.Y < minY)
                {
                    minY = actCorner.Y;
                }
                if (actCorner.Y > maxY)
                {
                    maxY = actCorner.Y;
                }
            }

            //  Do some postprocessing
            var triangleCount = 0;
            var bounds        = new SizeF();

            foreach (var actTriangleArray in generatedTriangles)
            {
                foreach (var actTriangle in actTriangleArray)
                {
                    UpdateMinWidthHeight(actTriangle.Point1);
                    UpdateMinWidthHeight(actTriangle.Point2);
                    UpdateMinWidthHeight(actTriangle.Point3);

                    triangleCount++;
                }
            }
            if (triangleCount > 0)
            {
                bounds   = new SizeF(maxX - minX, maxY - minY);
                minPoint = new Vector2(minX, minY);
            }

            // Change with / height of the geometry depending on ExtrudeGeometryOptions
            if (extrudeOptions.HasFlag(ExtrudeGeometryOptions.RescaleToUnitSize))
            {
                var scaleFactorX = !EngineMath.EqualsWithTolerance(bounds.Width, 0f) ? 1f / bounds.Width : 1f;
                var scaleFactorY = !EngineMath.EqualsWithTolerance(bounds.Height, 0f) ? 1f / bounds.Height : 1f;
                if (scaleFactorX < scaleFactorY)
                {
                    scaleFactorY = scaleFactorX;
                }
                else
                {
                    scaleFactorX = scaleFactorY;
                }

                foreach (var actTriangleArray in generatedTriangles)
                {
                    for (var loop = 0; loop < actTriangleArray.Length; loop++)
                    {
                        var actTriangle = actTriangleArray[loop];
                        actTriangle.Point1 = new PointF(actTriangle.Point1.X * scaleFactorX, actTriangle.Point1.Y * scaleFactorY);
                        actTriangle.Point2 = new PointF(actTriangle.Point2.X * scaleFactorX, actTriangle.Point2.Y * scaleFactorY);
                        actTriangle.Point3 = new PointF(actTriangle.Point3.X * scaleFactorX, actTriangle.Point3.Y * scaleFactorY);

                        actTriangleArray[loop] = actTriangle;
                    }
                }
                bounds = new SizeF(
                    bounds.Width * scaleFactorX,
                    bounds.Height * scaleFactorY);
                minPoint = new Vector2(minPoint.X * scaleFactorX, minPoint.Y * scaleFactorY);
            }

            // Change the origin depending on ExtrudeGeometryOptions
            if (extrudeOptions.HasFlag(ExtrudeGeometryOptions.ChangeOriginToCenter))
            {
                var newOrigin = new Vector2(
                    minPoint.X + bounds.Width / 2f,
                    minPoint.Y + bounds.Height / 2f);
                foreach (var actTriangleArray in generatedTriangles)
                {
                    for (var loop = 0; loop < actTriangleArray.Length; loop++)
                    {
                        var actTriangle = actTriangleArray[loop];
                        actTriangle.Point1 = MathConverter.RawFromVector2(MathConverter.Vector2FromRaw(actTriangle.Point1) - newOrigin);
                        actTriangle.Point2 = MathConverter.RawFromVector2(MathConverter.Vector2FromRaw(actTriangle.Point2) - newOrigin);
                        actTriangle.Point3 = MathConverter.RawFromVector2(MathConverter.Vector2FromRaw(actTriangle.Point3) - newOrigin);

                        actTriangleArray[loop] = actTriangle;
                    }
                }
                minPoint = new Vector2(0f, 0f);
            }

            // Apply values
            this.TriangleCount  = triangleCount;
            this.Bounds         = bounds;
            _generatedTriangles = generatedTriangles;
        }
コード例 #15
0
        /// <summary>
        /// Querries all current input states.
        /// </summary>
        public IEnumerable <InputStateBase> GetInputStates()
        {
            // Update connected states first
            for (int loop = 0; loop < m_controllers.Length; loop++)
            {
                bool isConnected = m_controllers[loop].IsConnected;

                if (!isConnected)
                {
                    m_states[loop].NotifyConnected(false);
                    continue;
                }
                m_states[loop].NotifyConnected(true);

                // Query all state structures
                XI.State   xiState   = m_controllers[loop].GetState();
                XI.Gamepad xiGamepad = xiState.Gamepad;

                // Convert float values
                GamepadReportedState repState = new GamepadReportedState()
                {
                    LeftThumbstickX  = EngineMath.Clamp((float)xiGamepad.LeftThumbX / (float)short.MaxValue, -1f, 1f),
                    LeftThumbstickY  = EngineMath.Clamp((float)xiGamepad.LeftThumbY / (float)short.MaxValue, -1f, 1f),
                    LeftTrigger      = EngineMath.Clamp((float)xiGamepad.LeftTrigger / 255f, 0f, 1f),
                    RightThumbstickX = EngineMath.Clamp((float)xiGamepad.RightThumbX / (float)short.MaxValue, -1f, 1f),
                    RightThumbstickY = EngineMath.Clamp((float)xiGamepad.RightThumbY / (float)short.MaxValue, -1f, 1f),
                    RightTrigger     = EngineMath.Clamp((float)xiGamepad.RightTrigger / 255f, 0, 1f)
                };

                // Convert button states
                GamepadButton pressedButtons = GamepadButton.None;
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.A))
                {
                    pressedButtons |= GamepadButton.A;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.B))
                {
                    pressedButtons |= GamepadButton.B;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.Back))
                {
                    pressedButtons |= GamepadButton.View;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.DPadDown))
                {
                    pressedButtons |= GamepadButton.DPadDown;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.DPadLeft))
                {
                    pressedButtons |= GamepadButton.DPadLeft;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.DPadRight))
                {
                    pressedButtons |= GamepadButton.DPadRight;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.DPadUp))
                {
                    pressedButtons |= GamepadButton.DPadUp;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.LeftShoulder))
                {
                    pressedButtons |= GamepadButton.LeftShoulder;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.LeftThumb))
                {
                    pressedButtons |= GamepadButton.LeftThumbstick;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.RightShoulder))
                {
                    pressedButtons |= GamepadButton.RightShoulder;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.RightThumb))
                {
                    pressedButtons |= GamepadButton.RightThumbstick;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.Start))
                {
                    pressedButtons |= GamepadButton.Menu;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.X))
                {
                    pressedButtons |= GamepadButton.X;
                }
                if (xiGamepad.Buttons.HasFlag(XI.GamepadButtonFlags.Y))
                {
                    pressedButtons |= GamepadButton.Y;
                }
                repState.Buttons = pressedButtons;

                // Report controller state to the system
                m_states[loop].NotifyState(repState);
            }

            // Now return all input states
            for (int loop = 0; loop < m_states.Length; loop++)
            {
                yield return(m_states[loop]);
            }
        }
コード例 #16
0
        /// <summary>
        /// Loads a ac file from the given uri
        /// </summary>
        internal static ACFileInfo LoadFile(Stream inStream)
        {
            ACFileInfo?  result = null;
            StreamReader?reader = null;

            try
            {
                reader = new StreamReader(inStream);

                //Check for correct header
                var header = reader.ReadLine();
                if (header == null ||
                    !header.StartsWith("AC3D"))
                {
                    throw new SeeingSharpGraphicsException("Header of AC3D file not found!");
                }

                //Create file information object
                result = new ACFileInfo();

                //Create a loaded objects stack
                var       loadedObjects  = new Stack <ACObjectInfo>();
                var       parentObjects  = new Stack <ACObjectInfo>();
                ACSurface?currentSurface = null;

                //Read the file
                while (!reader.EndOfStream)
                {
                    var actLine = reader.ReadLine() !.Trim();

                    var firstWord  = string.Empty;
                    var spaceIndex = actLine.IndexOf(' ');
                    if (spaceIndex == -1)
                    {
                        firstWord = actLine;
                    }
                    else
                    {
                        firstWord = firstWord = actLine.Substring(0, spaceIndex);
                    }

                    switch (firstWord)
                    {
                    //New Material info
                    case "MATERIAL":
                        var materialInfo = new ACMaterialInfo();
                        {
                            //Get the name of the material
                            var materialData = actLine.Split(' ');

                            if (materialData.Length > 1)
                            {
                                materialInfo.Name = materialData[1].Trim(' ', '"');
                            }

                            //Parse components
                            for (var loop = 0; loop < materialData.Length; loop++)
                            {
                                switch (materialData[loop])
                                {
                                case "rgb":
                                    var diffuseColor = materialInfo.Diffuse;
                                    diffuseColor.Alpha   = 1f;
                                    diffuseColor.Red     = float.Parse(materialData[loop + 1], CultureInfo.InvariantCulture);
                                    diffuseColor.Green   = float.Parse(materialData[loop + 2], CultureInfo.InvariantCulture);
                                    diffuseColor.Blue    = float.Parse(materialData[loop + 3], CultureInfo.InvariantCulture);
                                    materialInfo.Diffuse = diffuseColor;
                                    break;

                                case "amb":
                                    var ambientColor = new Color4();
                                    ambientColor.Red     = float.Parse(materialData[loop + 1], CultureInfo.InvariantCulture);
                                    ambientColor.Green   = float.Parse(materialData[loop + 2], CultureInfo.InvariantCulture);
                                    ambientColor.Blue    = float.Parse(materialData[loop + 3], CultureInfo.InvariantCulture);
                                    materialInfo.Ambient = ambientColor;
                                    break;

                                case "emis":
                                    var emissiveColor = new Color4();
                                    emissiveColor.Red     = float.Parse(materialData[loop + 1], CultureInfo.InvariantCulture);
                                    emissiveColor.Green   = float.Parse(materialData[loop + 2], CultureInfo.InvariantCulture);
                                    emissiveColor.Blue    = float.Parse(materialData[loop + 3], CultureInfo.InvariantCulture);
                                    materialInfo.Emissive = emissiveColor;
                                    break;

                                case "spec":
                                    var specularColor = new Color4();
                                    specularColor.Red     = float.Parse(materialData[loop + 1], CultureInfo.InvariantCulture);
                                    specularColor.Green   = float.Parse(materialData[loop + 2], CultureInfo.InvariantCulture);
                                    specularColor.Blue    = float.Parse(materialData[loop + 3], CultureInfo.InvariantCulture);
                                    materialInfo.Specular = specularColor;
                                    break;

                                case "shi":
                                    materialInfo.Shininess = float.Parse(materialData[loop + 1], CultureInfo.InvariantCulture);
                                    break;

                                case "trans":
                                    diffuseColor         = materialInfo.Diffuse;
                                    diffuseColor.Alpha   = 1f - EngineMath.Clamp(float.Parse(materialData[loop + 1], CultureInfo.InvariantCulture), 0f, 1f);
                                    materialInfo.Diffuse = diffuseColor;
                                    break;
                                }
                            }
                            result.Materials.Add(materialInfo);
                        }
                        break;

                    //New object starts here
                    case "OBJECT":
                    {
                        var newObject = new ACObjectInfo();

                        var lineData = actLine.Split(' ');
                        if (lineData[1] == "poly")
                        {
                            newObject.Type = ACObjectType.Poly;
                        }
                        else if (lineData[1] == "group")
                        {
                            newObject.Type = ACObjectType.Group;
                        }
                        else if (lineData[1] == "world")
                        {
                            newObject.Type = ACObjectType.World;
                        }

                        loadedObjects.Push(newObject);
                    }
                    break;

                    //End of an object, kids following
                    case "kids":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            //Parse kid count
                            var kidCount = 0;
                            var lineData = actLine.Split(' ');

                            if (lineData.Length >= 1)
                            {
                                int.TryParse(lineData[1], out kidCount);
                            }

                            var currentObject = loadedObjects.Peek();

                            if (currentObject != null)
                            {
                                //AddObject object to parent object, if any related
                                var addedToParent = false;

                                if (parentObjects.Count > 0)
                                {
                                    var currentParent = parentObjects.Peek();

                                    if (currentParent.Children.Count < currentParent.KidCount)
                                    {
                                        currentParent.Children.Add(currentObject);
                                        addedToParent = true;
                                    }
                                    else
                                    {
                                        while (parentObjects.Count > 0)
                                        {
                                            parentObjects.Pop();

                                            if (parentObjects.Count == 0)
                                            {
                                                break;
                                            }

                                            currentParent = parentObjects.Peek();

                                            if (currentParent == null)
                                            {
                                                break;
                                            }
                                            if (currentParent.Children.Count < currentParent.KidCount)
                                            {
                                                break;
                                            }
                                        }

                                        if (currentParent != null &&
                                            currentParent.Children.Count < currentParent.KidCount)
                                        {
                                            currentParent.Children.Add(currentObject);
                                            addedToParent = true;
                                        }
                                    }
                                }

                                //Enable this object as parent object
                                currentObject.KidCount = kidCount;

                                if (currentObject.KidCount > 0)
                                {
                                    parentObjects.Push(currentObject);
                                }

                                //AddObject to scene root if this object has no parent
                                loadedObjects.Pop();

                                if (!addedToParent)
                                {
                                    if (loadedObjects.Count == 0)
                                    {
                                        result.Objects.Add(currentObject);
                                    }
                                    else
                                    {
                                        loadedObjects.Peek().Children.Add(currentObject);
                                    }
                                }
                                currentObject = null;
                            }
                        }
                        break;

                    //Current object's name
                    case "name":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            var currentObject = loadedObjects.Peek();
                            if (currentObject != null)
                            {
                                currentObject.Name = actLine.Replace("name ", "").Replace("\"", "");
                            }
                        }
                        break;

                    case "data":
                        break;

                    case "texture":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            var currentObject = loadedObjects.Peek();

                            if (currentObject != null)
                            {
                                var lineData = actLine.Split(' ');
                                currentObject.Texture = lineData[1].Trim('"');
                            }
                        }
                        break;

                    case "texrep":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            var currentObject = loadedObjects.Peek();

                            if (currentObject != null)
                            {
                                var lineData = actLine.Split(' ');

                                var repetition = new Vector2
                                {
                                    X = float.Parse(lineData[1], CultureInfo.InvariantCulture),
                                    Y = float.Parse(lineData[2], CultureInfo.InvariantCulture)
                                };

                                currentObject.TextureRepeat = repetition;
                            }
                        }
                        break;

                    case "texoff":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            var currentObject = loadedObjects.Peek();

                            if (currentObject != null)
                            {
                                var lineData = actLine.Split(' ');

                                var offset = new Vector2
                                {
                                    X = float.Parse(lineData[1], CultureInfo.InvariantCulture),
                                    Y = float.Parse(lineData[2], CultureInfo.InvariantCulture)
                                };

                                currentObject.TextureRepeat = offset;
                            }
                        }
                        break;

                    case "rot":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            var currentObject = loadedObjects.Peek();

                            if (currentObject != null)
                            {
                                var lineData = actLine.Split(' ');

                                var rotation = Matrix4x4.Identity;
                                rotation.M11 = !string.IsNullOrEmpty(lineData[1]) ? float.Parse(lineData[1], CultureInfo.InvariantCulture) : 0f;
                                rotation.M12 = !string.IsNullOrEmpty(lineData[2]) ? float.Parse(lineData[2], CultureInfo.InvariantCulture) : 0f;
                                rotation.M13 = !string.IsNullOrEmpty(lineData[3]) ? float.Parse(lineData[3], CultureInfo.InvariantCulture) : 0f;
                                rotation.M21 = !string.IsNullOrEmpty(lineData[4]) ? float.Parse(lineData[4], CultureInfo.InvariantCulture) : 0f;
                                rotation.M22 = !string.IsNullOrEmpty(lineData[5]) ? float.Parse(lineData[5], CultureInfo.InvariantCulture) : 0f;
                                rotation.M23 = !string.IsNullOrEmpty(lineData[6]) ? float.Parse(lineData[6], CultureInfo.InvariantCulture) : 0f;
                                rotation.M31 = !string.IsNullOrEmpty(lineData[7]) ? float.Parse(lineData[7], CultureInfo.InvariantCulture) : 0f;
                                rotation.M32 = !string.IsNullOrEmpty(lineData[8]) ? float.Parse(lineData[8], CultureInfo.InvariantCulture) : 0f;
                                rotation.M33 = !string.IsNullOrEmpty(lineData[9]) ? float.Parse(lineData[9], CultureInfo.InvariantCulture) : 0f;

                                currentObject.Rotation = rotation;
                            }
                        }
                        break;

                    case "url":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            var currentObject = loadedObjects.Peek();

                            if (currentObject != null)
                            {
                                var lineData = actLine.Split(' ');
                                currentObject.Url = lineData[1].Trim('"');
                            }
                        }
                        break;

                    //Current object's location
                    case "loc":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            var currentObject = loadedObjects.Peek();

                            if (currentObject != null)
                            {
                                var lineData = actLine.Split(' ');

                                var location = new Vector3
                                {
                                    X = float.Parse(lineData[1], CultureInfo.InvariantCulture),
                                    Y = float.Parse(lineData[2], CultureInfo.InvariantCulture),
                                    Z = float.Parse(lineData[3], CultureInfo.InvariantCulture)
                                };

                                currentObject.Translation = location;
                            }
                        }
                        break;

                    case "numvert":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            var currentObject = loadedObjects.Peek();

                            if (currentObject != null)
                            {
                                var lineData         = actLine.Split(' ');
                                var numberOfVertices = int.Parse(lineData[1], CultureInfo.InvariantCulture);

                                for (var loop = 0; loop < numberOfVertices; loop++)
                                {
                                    var actInnerLine   = reader.ReadLine() !.Trim();
                                    var splittedVertex = actInnerLine.Split(' ');

                                    var position = new Vector3
                                    {
                                        X = float.Parse(splittedVertex[0], CultureInfo.InvariantCulture),
                                        Y = float.Parse(splittedVertex[1], CultureInfo.InvariantCulture),
                                        Z = float.Parse(splittedVertex[2], CultureInfo.InvariantCulture)
                                    };

                                    currentObject.Vertices.Add(new ACVertex {
                                        Position = position
                                    });
                                }
                            }
                        }
                        break;

                    //Start of a list of surfaces
                    case "numsurf":
                        break;

                    //New surface starts here
                    case "SURF":
                    {
                        if (currentSurface == null)
                        {
                            currentSurface = new ACSurface();
                        }

                        var lineData = actLine.Split(' ');
                        lineData[1]          = lineData[1].Substring(2);
                        currentSurface.Flags = int.Parse(lineData[1], NumberStyles.HexNumber);
                    }
                    break;

                    //Current surface's material
                    case "mat":
                    {
                        if (currentSurface == null)
                        {
                            currentSurface = new ACSurface();
                        }

                        var lineData = actLine.Split(' ');
                        currentSurface.Material = int.Parse(lineData[1], CultureInfo.InvariantCulture);
                    }
                    break;

                    //Current surface's indices
                    case "refs":
                        if (loadedObjects.Count == 0)
                        {
                            break;
                        }
                        {
                            if (currentSurface == null)
                            {
                                currentSurface = new ACSurface();
                            }

                            var lineData     = actLine.Split(' ');
                            var numberOfRefs = int.Parse(lineData[1], CultureInfo.InvariantCulture);

                            for (var loop = 0; loop < numberOfRefs; loop++)
                            {
                                var actInnerLine = reader.ReadLine() !.Trim();
                                var splittedRef  = actInnerLine.Split(' ');

                                var texCoord        = new Vector2();
                                int vertexReference = ushort.Parse(splittedRef[0], CultureInfo.InvariantCulture);
                                texCoord.X = float.Parse(splittedRef[1], CultureInfo.InvariantCulture);
                                texCoord.Y = float.Parse(splittedRef[2], CultureInfo.InvariantCulture);

                                currentSurface.TextureCoordinates.Add(texCoord);
                                currentSurface.VertexReferences.Add(vertexReference);
                            }

                            var currentObject = loadedObjects.Peek();

                            currentObject?.Surfaces.Add(currentSurface);

                            currentSurface = null;
                        }
                        break;
                    }
                }
            }
            finally
            {
                SeeingSharpUtil.SafeDispose(ref reader);
            }

            return(result);
        }
コード例 #17
0
        /// <summary>
        /// Creates and adds the root for all imported scene objects.
        /// </summary>
        public void FinishLoading(BoundingBox boundingBox)
        {
            this.EnsureNotFinished();

            try
            {
                // Generic checks
                if (this.Objects.Count == 0)
                {
                    throw new SeeingSharpException("No objects imported");
                }
                if (EngineMath.EqualsWithTolerance(boundingBox.Width, 0) ||
                    EngineMath.EqualsWithTolerance(boundingBox.Height, 0) ||
                    EngineMath.EqualsWithTolerance(boundingBox.Depth, 0))
                {
                    throw new SeeingSharpException($"BoundingBox of the loaded model data seems to be empty (Width={boundingBox.Width}, Height={boundingBox.Height}, Depth={boundingBox.Height}");
                }

                // Create root for the imported object graph
                var rootObject = new ScenePivotObject();
                rootObject.TransformationType = SpacialTransformationType.ScalingTranslationEulerAngles;
                rootObject.Name = $"{IMPORT_ROOT_NODE_NAME_PREFIX} {_importId}";

                // Configure base transformation of the root object
                switch (_importOptions.ResourceCoordinateSystem)
                {
                case CoordinateSystem.LeftHanded_UpY:
                    break;

                case CoordinateSystem.LeftHanded_UpZ:
                    rootObject.Scaling       = new Vector3(1f, -1f, 1f);
                    rootObject.RotationEuler = new Vector3(-EngineMath.RAD_90DEG, 0f, 0f);
                    break;

                case CoordinateSystem.RightHanded_UpY:
                    rootObject.Scaling = new Vector3(1f, 1f, -1f);
                    break;

                case CoordinateSystem.RightHanded_UpZ:
                    rootObject.Scaling       = new Vector3(-1f, 1f, -1f);
                    rootObject.RotationEuler = new Vector3(EngineMath.RAD_90DEG, 0f, 0f);
                    break;
                }

                // Configure position and scaling of the root object
                if (_importOptions.FitToCube)
                {
                    var scaleFactor = Math.Min(
                        1f / boundingBox.Width,
                        Math.Min(1f / boundingBox.Height, 1f / boundingBox.Depth));
                    rootObject.Scaling *= scaleFactor;
                    rootObject.Position = new Vector3(
                        (0f - (boundingBox.Minimum.X + (boundingBox.Maximum.X - boundingBox.Minimum.X) / 2f)) *
                        scaleFactor,
                        (0f - (boundingBox.Minimum.Y + (boundingBox.Maximum.Y - boundingBox.Minimum.Y) / 2f)) *
                        scaleFactor,
                        (0f - (boundingBox.Minimum.Z + (boundingBox.Maximum.Z - boundingBox.Minimum.Z) / 2f)) *
                        scaleFactor);
                }

                // Find current root objects and assign them as child to the new root object
                foreach (var actRootObject in this.FindRootObjects())
                {
                    _parentChildRelationships.Add(
                        new ParentChildRelationship(rootObject, actRootObject));
                }

                // AddObject the object finally
                _objects.Add(rootObject);
                this.RootObject  = rootObject;
                this.BoundingBox = boundingBox;

                _isValid = true;
            }
            catch (Exception ex)
            {
                this.FinishLoading(ex);
            }
            finally
            {
                _isFinished = true;
            }
        }
コード例 #18
0
        /// <summary>
        /// Queries for the ObjectId at the given location.
        /// </summary>
        /// <param name="texture">The uploaded texture.</param>
        /// <param name="xPos">The x position where to start.</param>
        /// <param name="yPos">The y position where to start.</param>
        public static unsafe float QueryForObjectId(this MemoryMappedTexture <float> texture, int xPos, int yPos)
        {
            var pixelSize = texture.PixelSize;

            if (xPos < 0)
            {
                throw new ArgumentException("xPos");
            }
            if (xPos >= pixelSize.Width)
            {
                throw new ArgumentException("xPos");
            }
            if (yPos < 0)
            {
                throw new ArgumentException("yPos");
            }
            if (yPos >= pixelSize.Height)
            {
                throw new ArgumentException("yPos");
            }

            // Loop over more pixels to be sure, that we are directly facing one object
            //  => This is needed because of manipulations done by multisampling (=Antialiasing)
            var pointerNative = texture.GetNativePointer();
            var currentX      = xPos;
            var currentY      = yPos;
            var lastObjId     = pointerNative[currentY * pixelSize.Width + currentX];

            for (var loopActQueryStep = 0; loopActQueryStep < s_queryObjectIdSteps.Length; loopActQueryStep++)
            {
                // Calculate current query location
                var currentStep = s_queryObjectIdSteps[loopActQueryStep];
                currentX += currentStep.X;
                currentY += currentStep.Y;

                // Check whether we are still in a valid pixel coordinate
                if (currentX < 0)
                {
                    continue;
                }
                if (currentX >= pixelSize.Width)
                {
                    continue;
                }
                if (currentY < 0)
                {
                    continue;
                }
                if (currentY >= pixelSize.Height)
                {
                    continue;
                }

                // Read current value and compare with last one
                //  (If equal, than at least two pixels are the same => Return this ObjectId)
                var currObjId = pointerNative[currentY * pixelSize.Width + currentX];
                if (EngineMath.EqualsWithTolerance(currObjId, lastObjId))
                {
                    return(currObjId);
                }

                // No match found, continue with next one
                lastObjId = currObjId;
            }

            // No clear match found
            return(0f);
        }