Beispiel #1
0
        public void Should_SerializeInt4()
        {
            Int4 value = Int4.MaxValue; // range -7 to 7

            Assert.AreEqual(false, value._sign);
            Assert.AreEqual(1, value.GetBit(0));
            Assert.AreEqual(1, value.GetBit(1));
            Assert.AreEqual(1, value.GetBit(2));
            Assert.AreEqual(new Bit[] { 1, 1, 1, 0 }, value.GetBits());

            value = Int4.MinValue;
            Assert.AreEqual(true, value._sign);
            Assert.AreEqual(1, value.GetBit(0));
            Assert.AreEqual(1, value.GetBit(1));
            Assert.AreEqual(1, value.GetBit(2));
            Assert.AreEqual(new Bit[] { 1, 1, 1, 1 }, value.GetBits());

            // test overflow
            value = (Int4)10;
            Assert.AreEqual(2, value);
            Assert.AreEqual(false, value._sign);
            Assert.AreEqual(0, value.GetBit(0));
            Assert.AreEqual(1, value.GetBit(1));
            Assert.AreEqual(0, value.GetBit(2));
            Assert.AreEqual(new Bit[] { 0, 1, 0, 0 }, value.GetBits());
        }
Beispiel #2
0
        /// <summary>
        /// Get an array of four-component vectors that contain integer data.
        /// </summary>
        /// <param name="count">The number of array elements to set. </param>
        /// <returns>Returns an array of four-component vectors that contain integer data. </returns>
        /// <unmanaged>HRESULT ID3D11EffectVectorVariable::GetIntVectorArray([Out, Buffer] int* pData,[None] int Offset,[None] int Count)</unmanaged>
        public SharpDX.Int4[] GetIntVectorArray(int count)
        {
            var temp = new Int4[count];

            GetIntVectorArray(temp, 0, count);
            return(temp);
        }
        public void Indexers_WithInvalidOffsets_ShouldThrow()
        {
            var int4 = new Int4(1, 2, 3, 4);

            Should.Throw <ArgumentOutOfRangeException>(() => int4[-1]);
            Should.Throw <ArgumentOutOfRangeException>(() => int4[4] = 5);
        }
Beispiel #4
0
 public static void Scale(ref Int4 m, int s, out Int4 result)
 {
     result.A = m.A * s;
     result.B = m.B * s;
     result.C = m.C * s;
     result.D = m.D * s;
 }
Beispiel #5
0
        public bool Equals(Int4 p)
        {
            if ((object)p == null)
                return false;

            return (x == p.x) && (y == p.y) && (z == p.z) && (w == p.w);
        }
 /// <summary>
 /// Adds a Int4 instance to a serialization info object
 /// </summary>
 /// <param name="info">Serialization info</param>
 /// <param name="name">Name</param>
 /// <param name="value">Value</param>
 public static void AddInt4(this SerializationInfo info, string name, Int4 value)
 {
     info.AddValue(string.Format("{0}.X", name), value.X);
     info.AddValue(string.Format("{0}.Y", name), value.Y);
     info.AddValue(string.Format("{0}.Z", name), value.Z);
     info.AddValue(string.Format("{0}.W", name), value.W);
 }
Beispiel #7
0
        private void UpdateWindowPosition()
        {
            if (updateRequested || !attached)
            {
                return;
            }

            updateRequested = true;

            Dispatcher.InvokeAsync(() =>
            {
                updateRequested = false;
                Visual root     = null;
                var shouldShow  = true;
                var parent      = (Visual)VisualTreeHelper.GetParent(this);
                while (parent != null)
                {
                    root = parent;

                    var parentElement = parent as FrameworkElement;
                    if (parentElement != null)
                    {
                        if (!parentElement.IsLoaded || !parentElement.IsVisible)
                        {
                            shouldShow = false;
                        }
                    }

                    parent = VisualTreeHelper.GetParent(root) as Visual;
                }

                if (root == null)
                {
                    return;
                }

                // Find proper position for the game
                var positionTransform = TransformToAncestor(root);
                var areaPosition      = positionTransform.Transform(new Point(0, 0));
                var boundingBox       = new Int4((int)(areaPosition.X * dpiScale.DpiScaleX), (int)(areaPosition.Y * dpiScale.DpiScaleY), (int)(ActualWidth * dpiScale.DpiScaleX), (int)(ActualHeight * dpiScale.DpiScaleY));
                if (boundingBox != lastBoundingBox)
                {
                    lastBoundingBox = boundingBox;
                    // Move the window asynchronously, without activating it, without touching the Z order
                    // TODO: do we want SWP_NOCOPYBITS?
                    const int flags = NativeHelper.SWP_ASYNCWINDOWPOS | NativeHelper.SWP_NOACTIVATE | NativeHelper.SWP_NOZORDER;
                    NativeHelper.SetWindowPos(Handle, NativeHelper.HWND_TOP, boundingBox.X, boundingBox.Y, boundingBox.Z, boundingBox.W, flags);

                    var style = NativeHelper.GetWindowLong(Handle, NativeHelper.GWL_STYLE);
                    // Workaround for missing keyboard input see issue #94
                    NativeHelper.SetWindowLong(Handle, NativeHelper.GWL_STYLE, style & ~NativeHelper.WS_CHILD);
                }

                if (attached)
                {
                    NativeHelper.ShowWindow(Handle, shouldShow ? NativeHelper.SW_SHOWNOACTIVATE : NativeHelper.SW_HIDE);
                }
            }, DispatcherPriority.Input); // This code must be dispatched after the DispatcherPriority.Loaded to properly work since it's checking the IsLoaded flag!
        }
Beispiel #8
0
 public void Reset()
 {
     RegistersCollection.Reset();
     registerAddress = 0;
     Int3.Unset();
     Int4.Unset();
     this.Log(LogLevel.Noisy, "Reset registers");
 }
Beispiel #9
0
        private void UpdateWindowPosition()
        {
            if (updateRequested)
            {
                return;
            }

            updateRequested = true;

            Dispatcher.InvokeAsync(() =>
            {
                updateRequested = false;
                Visual root     = null;
                bool shouldShow = true;
                var parent      = (Visual)VisualTreeHelper.GetParent(this);
                while (parent != null)
                {
                    root = parent;

                    parent            = VisualTreeHelper.GetParent(root) as Visual;
                    var parentElement = parent as FrameworkElement;
                    if (parentElement != null && !parentElement.IsLoaded)
                    {
                        shouldShow = false;
                    }

                    if (parent == null)
                    {
                        break;
                    }
                }

                if (root == null)
                {
                    return;
                }

                // Find proper position for the game
                var positionTransform = TransformToAncestor(root);
                var areaPosition      = positionTransform.Transform(new Point(0, 0));
                var boundingBox       = new Int4((int)areaPosition.X, (int)areaPosition.Y, (int)ActualWidth, (int)ActualHeight);
                if (boundingBox == lastBoundingBox)
                {
                    return;
                }

                lastBoundingBox = boundingBox;

                // Move the window asynchronously, without activating it, without touching the Z order
                // TODO: do we want SWP_NOCOPYBITS?
                const int flags = NativeHelper.SWP_ASYNCWINDOWPOS | NativeHelper.SWP_NOACTIVATE | NativeHelper.SWP_NOZORDER;
                NativeHelper.SetWindowPos(Handle, NativeHelper.HWND_TOP, boundingBox.X, boundingBox.Y, boundingBox.Z, boundingBox.W, flags);
                if (shouldShow)
                {
                    NativeHelper.ShowWindow(Handle, NativeHelper.SW_SHOWNOACTIVATE);
                }
            }, DispatcherPriority.Input); // This code must be dispatched after the DispatcherPriority.Loaded to properly work since it's checking the IsLoaded flag!
        }
    private unsafe static void ModifyInt4ByAddressOfRef(ref Int4 value)
    {
        void *pVoid = UnsafeUtility.AddressOf(ref value);

        UnsafeUtility.WriteArrayElement(destination: pVoid, index: 0, value: 4);
        UnsafeUtility.WriteArrayElement(destination: pVoid, index: 1, value: 3);
        UnsafeUtility.WriteArrayElement(destination: pVoid, index: 2, value: 2);
        UnsafeUtility.WriteArrayElement(destination: pVoid, index: 3, value: 1);
    }
Beispiel #11
0
        public static void Test()
        {
            {
                //Nested versus flattened tests
                var s8  = new OuterStruct8();
                var s16 = new OuterStruct16();
                var s   = 0f;
                OuterStruct8.Test(ref s8, s, out var result8);
                OuterStruct16.Test(ref s16, s, out var result16);

                var d = new DummyOuterStruct();
                DummyOuterStruct.Test(ref d, 0f, out var dResult);

                var f = new ScalarFlattenedStruct();
                ScalarFlattenedStruct.Test(ref f, s, out var flattenedResult);
            }

            {
                //Field count tests
                var i4  = new Int4();
                var i5  = new Int5();
                var l4  = new Long4();
                var l5  = new Long5();
                var vf4 = new VectorFloat4();
                var vf5 = new VectorFloat5();
                var s   = new Vector <float>();
                Int4.Test(ref i4, 0, out var i4result);
                Int5.Test(ref i5, 0, out var i5result);
                Long4.Test(ref l4, 0, out var l4result);
                Long5.Test(ref l5, 0, out var l5result);
                VectorFloat4.Test(ref vf4, ref s, out var vf4Result);
                VectorFloat5.Test(ref vf5, ref s, out var vf5Result);
            }

            {
                //Assignment-only tests
                var s16 = new DummyStruct16();
                var s32 = new DummyStruct32();
                var s48 = new DummyStruct48();
                var s64 = new DummyStruct64();
                var s80 = new DummyStruct80();
                DoDummies(ref s16, out var result16);
                DoDummies(ref s32, out var result32);
                DoDummies(ref s48, out var result48);
                DoDummies(ref s64, out var result64);
                DoDummies(ref s80, out var result80);
            }

            {
                TestScalarStruct();
                TestStruct();
                TestStructManuallyInlined();
                TestStructless();
            }
        }
Beispiel #12
0
 /// <summary>
 /// Patch header pointers
 /// </summary>
 /// <param name="header">Header</param>
 public void Patch(MeshHeader header)
 {
     Verts        = new Vector3[header.VertCount];
     Polys        = new Poly[header.PolyCount];
     Links        = new Link[header.MaxLinkCount];
     DetailMeshes = new PolyDetail[header.DetailMeshCount];
     DetailVerts  = new Vector3[header.DetailVertCount];
     DetailTris   = new Int4[header.DetailTriCount];
     BvTree       = new BVNode[header.BvNodeCount];
     OffMeshCons  = new OffMeshConnection[header.OffMeshConCount];
 }
Beispiel #13
0
 public Piece(int grid_x, int grid_y, float x, float y, float r, float rv, Quad quad, Int4 color_prev, Int4 color_next)
 {
     this.grid_x     = grid_x;
     this.grid_y     = grid_y;
     this.x          = x;
     this.y          = y;
     this.r          = r;
     this.rv         = rv;
     this.quad       = quad;
     this.color_prev = color_prev;
     this.color_next = color_next;
 }
Beispiel #14
0
    protected Int4 readInt4()
    {
        Int4 result = new Int4
        {
            x = readInt(),
            y = readInt(),
            z = readInt(),
            w = readInt()
        };

        return(result);
    }
Beispiel #15
0
        /// <summary>
        /// Clears a read-write Texture. This texture must have been created with read-write/unordered access.
        /// </summary>
        /// <param name="texture">The texture.</param>
        /// <param name="value">The value.</param>
        /// <exception cref="System.ArgumentNullException">texture</exception>
        /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;texture</exception>
        public unsafe void ClearReadWrite(Texture texture, Int4 value)
        {
            if (texture == null)
            {
                throw new ArgumentNullException("texture");
            }
            if (texture.NativeUnorderedAccessView == null)
            {
                throw new ArgumentException("Expecting buffer supporting UAV", "texture");
            }

            NativeDeviceContext.ClearUnorderedAccessView(texture.NativeUnorderedAccessView, *(RawInt4 *)&value);
        }
Beispiel #16
0
        private void OnValueChanged()
        {
            if (IsSetBlocked)
            {
                return;
            }

            var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding || WElement.IsSliding;
            var token     = isSliding ? this : null;
            var value     = new Int4(XElement.IntValue.Value, YElement.IntValue.Value, ZElement.IntValue.Value, WElement.IntValue.Value);

            SetValue(value, token);
        }
Beispiel #17
0
        /// <summary>
        /// Clears a read-write Buffer. This buffer must have been created with read-write/unordered access.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <param name="value">The value.</param>
        /// <exception cref="System.ArgumentNullException">buffer</exception>
        /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;buffer</exception>
        public unsafe void ClearReadWrite(Buffer buffer, Int4 value)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (buffer.NativeUnorderedAccessView == null)
            {
                throw new ArgumentException("Expecting buffer supporting UAV", nameof(buffer));
            }

            NativeDeviceContext.ClearUnorderedAccessView(buffer.NativeUnorderedAccessView, *(RawInt4 *)&value);
        }
        /// <summary>
        /// Clears a read-write Texture. This texture must have been created with read-write/unordered access.
        /// </summary>
        /// <param name="texture">The texture.</param>
        /// <param name="value">The value.</param>
        /// <exception cref="System.ArgumentNullException">texture</exception>
        /// <exception cref="System.ArgumentException">Expecting texture supporting UAV;texture</exception>
        public unsafe void ClearReadWrite(Texture texture, Int4 value)
        {
            if (texture is null)
            {
                throw new ArgumentNullException(nameof(texture));
            }
            if (texture.NativeUnorderedAccessView is null)
            {
                throw new ArgumentException("Expecting texture supporting UAV.", nameof(texture));
            }

            NativeDeviceContext.ClearUnorderedAccessView(texture.NativeUnorderedAccessView, *(RawInt4 *)&value);
        }
Beispiel #19
0
        public static Mesh NewMesh(Vertex[] vertices, Mesh.Usage drawMode, Mesh.Usage usage)
        {
            var posArray   = new Float2[vertices.Length];
            var uvArray    = new Float2[vertices.Length];
            var colorArray = new Int4[vertices.Length];

            for (int i = 0; i < vertices.Length; i++)
            {
                posArray[i]   = vertices[i].pos;
                uvArray[i]    = vertices[i].uv;
                colorArray[i] = vertices[i].color;
            }
            return(NewMesh(posArray, uvArray, colorArray, drawMode, usage));
        }
 public unsafe void ClearUnorderedAccessView(
     GpuDescriptorHandle viewGpuHandleInCurrentHeap,
     CpuDescriptorHandle viewCpuHandle,
     ID3D12Resource resource,
     Int4 clearValue,
     params InteropRect[] rectangles)
 {
     if (rectangles.Length == 0)
     {
         ClearUnorderedAccessViewUint(viewGpuHandleInCurrentHeap, viewCpuHandle, resource, clearValue, 0, null);
     }
     else
     {
         ClearUnorderedAccessViewUint(viewGpuHandleInCurrentHeap, viewCpuHandle, resource, clearValue, rectangles.Length, rectangles);
     }
 }
Beispiel #21
0
        private SkinnedModel CreateVirtualModel(SkinnedModel skinnedModel)
        {
            if (!skinnedModel || skinnedModel.Skeleton == null)
            {
                return(null);
            }

            SkinnedModel virtualModel = Content.CreateVirtualAsset <SkinnedModel>();

            virtualModel.Skeleton = skinnedModel.Skeleton;

            virtualModel.SetupMaterialSlots(skinnedModel.MaterialSlotsCount);
            for (int i = 0; i < virtualModel.MaterialSlotsCount; i++)
            {
                virtualModel.MaterialSlots[i].Material    = skinnedModel.MaterialSlots[i].Material;
                virtualModel.MaterialSlots[i].Name        = skinnedModel.MaterialSlots[i].Name;
                virtualModel.MaterialSlots[i].ShadowsMode = skinnedModel.MaterialSlots[i].ShadowsMode;
            }

            virtualModel.SetupMeshes(skinnedModel.MeshesCount);
            for (int i = 0; i < virtualModel.MeshesCount; i++)
            {
                virtualModel.Meshes[i].MaterialSlotIndex = skinnedModel.Meshes[i].MaterialSlotIndex;
                int[] indices = skinnedModel.Meshes[i].DownloadIndexBuffer();

                var       vertices     = skinnedModel.Meshes[i].DownloadVertexBuffer();
                Vector3[] positions    = new Vector3[vertices.Length];
                Int4[]    blendIndices = new Int4[vertices.Length];
                Vector4[] blendWeights = new Vector4[vertices.Length];
                Vector3[] normals      = new Vector3[vertices.Length];
                Vector3[] tangents     = new Vector3[vertices.Length];
                Vector2[] uv           = new Vector2[vertices.Length];

                for (int j = 0; j < vertices.Length; j++)
                {
                    positions[j]    = vertices[j].Position;
                    blendIndices[j] = vertices[j].BlendIndices;
                    blendWeights[j] = vertices[j].BlendWeights;
                    normals[j]      = vertices[j].Normal;
                    tangents[j]     = vertices[j].Tangent;
                    uv[j]           = vertices[j].TexCoord;
                }

                virtualModel.Meshes[i].UpdateMesh(positions, indices, blendIndices, blendWeights, normals, tangents, uv);
            }
            return(virtualModel);
        }
Beispiel #22
0
        private void Detach()
        {
            if (attached)
            {
                // Hide window, clear parent
                NativeHelper.ShowWindow(Handle, NativeHelper.SW_HIDE);
                NativeHelper.SetParent(Handle, IntPtr.Zero);

                // Unregister keyboard sink
                var site = ((IKeyboardInputSink)this).KeyboardInputSite;
                ((IKeyboardInputSink)this).KeyboardInputSite = null;
                site?.Unregister();

                // Make sure we will actually attach next time Attach() is called
                lastBoundingBox = Int4.Zero;
                attached        = false;
            }
        }
Beispiel #23
0
 public void Serialize(ref Int4 value)
 {
     // Write optimized version without using Serialize methods
     if (Mode == SerializerMode.Write)
     {
         Writer.Write(value.X);
         Writer.Write(value.Y);
         Writer.Write(value.Z);
         Writer.Write(value.W);
     }
     else
     {
         value.X = Reader.ReadInt32();
         value.Y = Reader.ReadInt32();
         value.Z = Reader.ReadInt32();
         value.W = Reader.ReadInt32();
     }
 }
Beispiel #24
0
        public override void OnUpdate(float deltaTime, Particle *arrayPtr, int length)
        {
            if (ParticleEngine.NativeEnabled)
            {
                nativeModule_TextureAnimationModule_SetTextureSize(SubmodulePtr, new NativeVector2(Emitter.TextureSize));
                return;
            }

            Particle *tail        = arrayPtr + length;
            int       totalFrames = SheetRows * SheetColumns;
            int       frameSize   = (int)Emitter.TextureSize.X / SheetRows;

            switch (loopMode)
            {
            case LoopMode.Life: {
                for (Particle *particle = arrayPtr; particle < tail; particle++)
                {
                    int frame = (int)Between(0.0f, totalFrames, particle->TimeAlive / particle->InitialLife);
#if NETSTANDARD2_1
                    int frameX = (int)MathF.Floor(frame % SheetRows);
                    int frameY = (int)MathF.Floor(frame / SheetRows);
#else
                    int frameX = (int)Math.Floor((double)frame % SheetRows);
                    int frameY = (int)Math.Floor((double)frame / SheetRows);
#endif
                    particle->SourceRectangle = new Int4(
                        frameX * frameSize,
                        frameY * frameSize,
                        frameSize,
                        frameSize);
                }
            } break;

            case LoopMode.Loop: {
                for (Particle *particle = arrayPtr; particle < tail; particle++)
                {
                    // TODO:
                }
            } break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        public void Indexers_WithValidOffsets_ShouldSetGetIndividualComponents()
        {
            var int4 = new Int4(1, 2, 3, 4);

            int4.X.ShouldBe(1);
            int4.Y.ShouldBe(2);
            int4.Z.ShouldBe(3);
            int4.W.ShouldBe(4);

            int4[0] = -10;
            int4[1] = -20;
            int4[2] = -30;
            int4[3] = -40;

            int4.X.ShouldBe(-10);
            int4.Y.ShouldBe(-20);
            int4.Z.ShouldBe(-30);
            int4.W.ShouldBe(-40);
        }
    private unsafe static void TestUnsafeUtility()
    {
        // Allocate
        void *a = UnsafeUtility.Malloc(
            size: ARRAY_SIZE * UnsafeUtility.SizeOf <int>(),
            alignment: UnsafeUtility.AlignOf <byte>(),
            allocator: Allocator.Temp);
        void *b = UnsafeUtility.Malloc(
            size: ARRAY_SIZE * UnsafeUtility.SizeOf <int>(),
            alignment: UnsafeUtility.AlignOf <byte>(),
            allocator: Allocator.Temp);

        for (int i = 0; i < ARRAY_SIZE; i++)
        {
            ((int *)a)[i] = i;
        }

        Print5IntArray((int *)b);
        UnsafeUtility.MemCpy(destination: b, source: a, size: ARRAY_SIZE * UnsafeUtility.SizeOf <int>());
        Print5IntArray((int *)b);

        for (int i = 0; i < ARRAY_SIZE; i++)
        {
            UnsafeUtility.WriteArrayElement(
                destination: b,
                index: i,
                value: -i);
        }

        Print5IntFromVoidArray(b);

        // Free
        UnsafeUtility.Free(memory: a, allocator: Allocator.Temp);
        UnsafeUtility.Free(memory: b, allocator: Allocator.Temp);

        Debug.Log($"Vowel.I : {UnsafeUtility.EnumToInt(Vowel.I)}");

        Int4 int4 = new Int4();

        Debug.Log(int4);
        ModifyInt4ByAddressOfRef(ref int4);
        Debug.Log(int4);
    }
Beispiel #27
0
        private void UpdateWindowPosition()
        {
            if (updateRequested)
            {
                return;
            }

            updateRequested = true;

            Dispatcher.InvokeAsync(() =>
            {
                updateRequested = false;
                // We do not use Window.GetParent because this method can return a window that is not yet the actual ancestor of this element.
                var parentWindow = this.FindVisualParentOfType <Window>();
                if (parentWindow == null)
                {
                    return;
                }

                // Find proper position for the game
                var positionTransform = TransformToAncestor(parentWindow);
                var areaPosition      = positionTransform.Transform(new Point(0, 0));
                var boundingBox       = new Int4((int)areaPosition.X, (int)areaPosition.Y, (int)ActualWidth, (int)ActualHeight);
                if (boundingBox == lastBoundingBox)
                {
                    return;
                }

                lastBoundingBox = boundingBox;

                // Move the window asynchronously, without activating it, without touching the Z order
                // TODO: do we want SWP_NOCOPYBITS?
                const int flags = NativeHelper.SWP_ASYNCWINDOWPOS | NativeHelper.SWP_NOACTIVATE | NativeHelper.SWP_NOZORDER;
                NativeHelper.SetWindowPos(Handle, NativeHelper.HWND_TOP, boundingBox.X, boundingBox.Y, boundingBox.Z, boundingBox.W, flags);
                NativeHelper.ShowWindow(Handle, NativeHelper.SW_SHOWNOACTIVATE);
            });
        }
Beispiel #28
0
 /// <summary>
 /// Fills structured buffer with given values
 /// </summary>
 /// <param name="buffer"></param>
 /// <param name="values"></param>
 public void Clear(StructuredBuffer buffer, Int4 values)
 {
     lock (deviceContext) {
         deviceContext.ClearUnorderedAccessView(buffer.UAV, SharpDXHelper.Convert(values));
     }
 }
        public unsafe void ClearReadWrite(Texture texture, Int4 value)
        {
#if DEBUG
            GraphicsDevice.EnsureContextActive();
#endif

#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
            Internal.Refactor.ThrowNotImplementedException();
#else
            if (activeTexture != 0)
            {
                activeTexture = 0;
                GL.ActiveTexture(TextureUnit.Texture0);
            }

            GL.BindTexture(texture.TextureTarget, texture.TextureId);

            GL.ClearTexImage(texture.TextureId, 0, texture.TextureFormat, texture.TextureType, ref value);

            GL.BindTexture(texture.TextureTarget, 0);
            boundShaderResourceViews[0] = null;
#endif
        }
        public unsafe void ClearReadWrite(Buffer buffer, Int4 value)
        {
#if DEBUG
            GraphicsDevice.EnsureContextActive();
#endif

#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
            Internal.Refactor.ThrowNotImplementedException();
#else
            if ((buffer.ViewFlags & BufferFlags.UnorderedAccess) != BufferFlags.UnorderedAccess)
                throw new ArgumentException("Buffer does not support unordered access");

            GL.BindBuffer(buffer.BufferTarget, buffer.BufferId);
            GL.ClearBufferData(buffer.BufferTarget, buffer.TextureInternalFormat, buffer.TextureFormat, All.UnsignedInt8888, ref value);
            GL.BindBuffer(buffer.BufferTarget, 0);
#endif
        }
        private void UpdateWindowPosition()
        {
            if (updateRequested)
                return;

            updateRequested = true;

            Dispatcher.InvokeAsync(() =>
            {
                updateRequested = false;
                Visual root = null;
                var shouldShow = true;
                var parent = (Visual)VisualTreeHelper.GetParent(this);
                while (parent != null)
                {
                    root = parent;

                    parent = VisualTreeHelper.GetParent(root) as Visual;
                    var parentElement = parent as FrameworkElement;
                    if (parentElement != null && !parentElement.IsLoaded)
                        shouldShow = false;

                    if (parent == null)
                        break;
                }

                if (root == null)
                    return;

                // Find proper position for the game
                var positionTransform = TransformToAncestor(root);
                var areaPosition = positionTransform.Transform(new Point(0, 0));
                var boundingBox = new Int4((int)(areaPosition.X*dpiScale.DpiScaleX), (int)(areaPosition.Y*dpiScale.DpiScaleY), (int)(ActualWidth*dpiScale.DpiScaleX), (int)(ActualHeight*dpiScale.DpiScaleY));
                if (boundingBox == lastBoundingBox)
                    return;

                lastBoundingBox = boundingBox;

                // Move the window asynchronously, without activating it, without touching the Z order
                // TODO: do we want SWP_NOCOPYBITS?
                const int flags = NativeHelper.SWP_ASYNCWINDOWPOS | NativeHelper.SWP_NOACTIVATE | NativeHelper.SWP_NOZORDER;
                NativeHelper.SetWindowPos(Handle, NativeHelper.HWND_TOP, boundingBox.X, boundingBox.Y, boundingBox.Z, boundingBox.W, flags);
                if (shouldShow)
                {
                    NativeHelper.ShowWindow(Handle, NativeHelper.SW_SHOWNOACTIVATE);
                }
            }, DispatcherPriority.Input); // This code must be dispatched after the DispatcherPriority.Loaded to properly work since it's checking the IsLoaded flag!
        }
        private void Detach()
        {
            if (!attached)
                return;

            // Hide window, clear parent
            NativeHelper.ShowWindow(Handle, NativeHelper.SW_HIDE);
            NativeHelper.SetParent(Handle, IntPtr.Zero);

            // Unregister keyboard sink
            var site = ((IKeyboardInputSink)this).KeyboardInputSite;
            ((IKeyboardInputSink)this).KeyboardInputSite = null;
            site?.Unregister();

            // Make sure we will actually attach next time Attach() is called
            lastBoundingBox = Int4.Zero;
            attached = false;
        }
Beispiel #33
0
 public static RawInt4 Convert( Int4 v )
 {
     return new RawInt4{ X = v.X, Y = v.Y, Z = v.Z, W = v.W };
 }
 public void Serialize(ref Int4 value)
 {
     // Write optimized version without using Serialize methods
     if (Mode == SerializerMode.Write)
     {
         Writer.Write(value.X);
         Writer.Write(value.Y);
         Writer.Write(value.Z);
         Writer.Write(value.W);
     }
     else
     {
         value.X = Reader.ReadInt32();
         value.Y = Reader.ReadInt32();
         value.Z = Reader.ReadInt32();
         value.W = Reader.ReadInt32();
     }
 }
Beispiel #35
0
        private void Update(EvaluationContext context)
        {
            if (_parameterConstBuffer == null)
            {
                Init();
            }

            var  uav1             = BufferUav.GetValue(context);
            var  uav2             = BufferUav2.GetValue(context);
            var  srv1             = BufferSrv.GetValue(context);
            var  srv2             = BufferSrv2.GetValue(context);
            bool spreadOverFrames = SpreadOverFrames.GetValue(context);

            if (uav1 == null || uav2 == null)
            {
                return;
            }

            var resourceManager = ResourceManager.Instance();
            var device          = resourceManager.Device;
            var deviceContext   = device.ImmediateContext;
            var csStage         = deviceContext.ComputeShader;

            var           prevShader      = csStage.Get();
            var           prevConstBuffer = csStage.GetConstantBuffers(0, 1)[0];
            ComputeShader sortShader      = resourceManager.GetComputeShader(_sortShaderId);
            ComputeShader transposeShader = resourceManager.GetComputeShader(_transposeShaderId);

            csStage.Set(sortShader);
            csStage.SetConstantBuffer(0, _parameterConstBuffer);
            csStage.SetUnorderedAccessView(0, uav1);

            int numBufferElements = uav1.Description.Buffer.ElementCount; //;32*1024; //512 * 512 * 2;
            int bitonicBlockSize  = 1024;

            if (spreadOverFrames)
            {
                if (_level <= bitonicBlockSize)
                // for (int level = 2; level <= bitonicBlockSize; level <<= 1)
                {
                    Int4 sortParams = new Int4(_level, _level, bitonicBlockSize, numBufferElements / bitonicBlockSize);
                    resourceManager.SetupConstBuffer(sortParams, ref _parameterConstBuffer);
                    deviceContext.Dispatch(numBufferElements / bitonicBlockSize, 1, 1);
                }
                else
                {
                    int matWidth  = bitonicBlockSize;
                    int matHeight = numBufferElements / bitonicBlockSize;
                    // Then sort the rows and columns for the levels > than the block size
                    // Transpose. Sort the Columns. Transpose. Sort the Rows.
                    // for (int level = (bitonicBlockSize * 2); level <= numBufferElements; level <<= 1)
                    // {
                    csStage.Set(transposeShader);
                    csStage.SetShaderResource(0, null);
                    csStage.SetUnorderedAccessView(0, null);
                    csStage.SetShaderResource(0, srv1);
                    csStage.SetUnorderedAccessView(0, uav2);
                    Int4 param = new Int4(_level / bitonicBlockSize, (_level & ~numBufferElements) / bitonicBlockSize, matWidth, matHeight);
                    resourceManager.SetupConstBuffer(param, ref _parameterConstBuffer);
                    deviceContext.Dispatch(matWidth / 32, matHeight / 32, 1);

                    csStage.Set(sortShader);
                    deviceContext.Dispatch(numBufferElements / bitonicBlockSize, 1, 1);

                    csStage.Set(transposeShader);
                    csStage.SetShaderResource(0, null);
                    csStage.SetUnorderedAccessView(0, null);
                    csStage.SetShaderResource(0, srv2);
                    csStage.SetUnorderedAccessView(0, uav1);
                    param = new Int4(bitonicBlockSize, _level, matHeight, matWidth);
                    resourceManager.SetupConstBuffer(param, ref _parameterConstBuffer);
                    deviceContext.Dispatch(matHeight / 32, matWidth / 32, 1);

                    csStage.Set(sortShader);
                    deviceContext.Dispatch(numBufferElements / bitonicBlockSize, 1, 1);
                }

                _level <<= 1;
                if (_level > numBufferElements)
                {
                    _level = 2;
                }
            }
            else
            {
                // single frame sort
                for (int level = 2; level <= bitonicBlockSize; level <<= 1)
                {
                    Int4 sortParams = new Int4(level, level, bitonicBlockSize, numBufferElements / bitonicBlockSize);
                    resourceManager.SetupConstBuffer(sortParams, ref _parameterConstBuffer);
                    deviceContext.Dispatch(numBufferElements / bitonicBlockSize, 1, 1);
                }

                int matWidth  = bitonicBlockSize;
                int matHeight = numBufferElements / bitonicBlockSize;
                // Then sort the rows and columns for the levels > than the block size
                // Transpose. Sort the Columns. Transpose. Sort the Rows.
                for (int level = (bitonicBlockSize * 2); level <= numBufferElements; level <<= 1)
                {
                    csStage.Set(transposeShader);
                    csStage.SetShaderResource(0, null);
                    csStage.SetUnorderedAccessView(0, null);
                    csStage.SetShaderResource(0, srv1);
                    csStage.SetUnorderedAccessView(0, uav2);
                    Int4 param = new Int4(level / bitonicBlockSize, (level & ~numBufferElements) / bitonicBlockSize, matWidth, matHeight);
                    resourceManager.SetupConstBuffer(param, ref _parameterConstBuffer);
                    deviceContext.Dispatch(matWidth / 32, matHeight / 32, 1);

                    csStage.Set(sortShader);
                    deviceContext.Dispatch(numBufferElements / bitonicBlockSize, 1, 1);

                    csStage.Set(transposeShader);
                    csStage.SetShaderResource(0, null);
                    csStage.SetUnorderedAccessView(0, null);
                    csStage.SetShaderResource(0, srv2);
                    csStage.SetUnorderedAccessView(0, uav1);
                    param = new Int4(bitonicBlockSize, level, matHeight, matWidth);
                    resourceManager.SetupConstBuffer(param, ref _parameterConstBuffer);
                    deviceContext.Dispatch(matHeight / 32, matWidth / 32, 1);

                    csStage.Set(sortShader);
                    deviceContext.Dispatch(numBufferElements / bitonicBlockSize, 1, 1);
                }
            }

            csStage.SetUnorderedAccessView(0, null);
            csStage.SetUnorderedAccessView(1, null);
            csStage.SetShaderResource(0, null);
            csStage.SetShaderResource(1, null);
            csStage.SetConstantBuffer(0, prevConstBuffer);
            csStage.Set(prevShader);
        }
Beispiel #36
0
        /// <summary>
        /// Clears a read-write Texture. This texture must have been created with read-write/unordered access.
        /// </summary>
        /// <param name="texture">The texture.</param>
        /// <param name="value">The value.</param>
        /// <exception cref="System.ArgumentNullException">texture</exception>
        /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;texture</exception>
        public unsafe void ClearReadWrite(Texture texture, Int4 value)
        {
            if (texture == null) throw new ArgumentNullException("texture");
            if (texture.NativeUnorderedAccessView == null) throw new ArgumentException("Expecting buffer supporting UAV", "texture");

            NativeDeviceContext.ClearUnorderedAccessView(texture.NativeUnorderedAccessView, *(RawInt4*)&value);
        }
		/// <summary>
		/// Fills structured buffer with given values
		/// </summary>
		/// <param name="buffer"></param>
		/// <param name="values"></param>
		public void Clear ( StructuredBuffer buffer, Int4 values )
		{
			lock (deviceContext) {
				deviceContext.ClearUnorderedAccessView( buffer.UAV, SharpDXHelper.Convert( values ) );
			}
		}
Beispiel #38
0
        public static unsafe LightProbeRuntimeData GenerateRuntimeData(FastList <LightProbeComponent> lightProbes)
        {
            // TODO: Better check: coplanar, etc... (maybe the check inside BowyerWatsonTetrahedralization might be enough -- tetrahedron won't be in positive order)
            if (lightProbes.Count < 4)
            {
                throw new InvalidOperationException("Can't generate lightprobes if less than 4 of them exists.");
            }

            var lightProbePositions    = new FastList <Vector3>();
            var lightProbeCoefficients = new Color3[lightProbes.Count * LambertHamonicOrder * LambertHamonicOrder];

            fixed(Color3 *destColors = lightProbeCoefficients)
            {
                for (var lightProbeIndex = 0; lightProbeIndex < lightProbes.Count; lightProbeIndex++)
                {
                    var lightProbe = lightProbes[lightProbeIndex];

                    // Copy light position
                    lightProbePositions.Add(lightProbe.Entity.Transform.WorldMatrix.TranslationVector);

                    // Copy coefficients
                    if (lightProbe.Coefficients != null)
                    {
                        var lightProbeCoefStart = lightProbeIndex * LambertHamonicOrder * LambertHamonicOrder;
                        for (var index = 0; index < LambertHamonicOrder * LambertHamonicOrder; index++)
                        {
                            destColors[lightProbeCoefStart + index] = index < lightProbe.Coefficients.Count ? lightProbe.Coefficients[index] : new Color3();
                        }
                    }
                }
            }

            // Generate light probe structure
            var tetra       = new BowyerWatsonTetrahedralization();
            var tetraResult = tetra.Compute(lightProbePositions);

            var matrices     = new Vector4[tetraResult.Tetrahedra.Count * 3];
            var probeIndices = new Int4[tetraResult.Tetrahedra.Count];

            // Prepare data for GPU: matrices and indices
            for (int i = 0; i < tetraResult.Tetrahedra.Count; ++i)
            {
                var tetrahedron       = tetraResult.Tetrahedra[i];
                var tetrahedronMatrix = Matrix.Identity;

                // Compute the tetrahedron matrix
                // https://en.wikipedia.org/wiki/Barycentric_coordinate_system#Barycentric_coordinates_on_tetrahedra
                var vertex3 = tetraResult.Vertices[tetrahedron.Vertices[3]];
                *((Vector3 *)&tetrahedronMatrix.M11) = tetraResult.Vertices[tetrahedron.Vertices[0]] - vertex3;
                *((Vector3 *)&tetrahedronMatrix.M12) = tetraResult.Vertices[tetrahedron.Vertices[1]] - vertex3;
                *((Vector3 *)&tetrahedronMatrix.M13) = tetraResult.Vertices[tetrahedron.Vertices[2]] - vertex3;
                tetrahedronMatrix.Invert(); // TODO: Optimize 3x3 invert

                tetrahedronMatrix.Transpose();

                // Store position of last vertex in last row
                tetrahedronMatrix.M41 = vertex3.X;
                tetrahedronMatrix.M42 = vertex3.Y;
                tetrahedronMatrix.M43 = vertex3.Z;

                matrices[i * 3 + 0] = tetrahedronMatrix.Column1;
                matrices[i * 3 + 1] = tetrahedronMatrix.Column2;
                matrices[i * 3 + 2] = tetrahedronMatrix.Column3;

                probeIndices[i] = *(Int4 *)tetrahedron.Vertices;
            }

            var lightProbesCopy = new object[lightProbes.Count];

            for (int i = 0; i < lightProbes.Count; ++i)
            {
                lightProbesCopy[i] = lightProbes[i];
            }

            var result = new LightProbeRuntimeData
            {
                LightProbes     = lightProbesCopy,
                Vertices        = tetraResult.Vertices,
                UserVertexCount = tetraResult.UserVertexCount,
                Tetrahedra      = tetraResult.Tetrahedra,
                Faces           = tetraResult.Faces,

                Coefficients      = lightProbeCoefficients,
                Matrices          = matrices,
                LightProbeIndices = probeIndices,
            };

            return(result);
        }
Beispiel #39
0
        private ModelData.MeshPart Process(ModelData.Mesh mesh, Assimp.Mesh assimpMesh)
        {
            var meshPart = new ModelData.MeshPart()
                               {
                                   MaterialIndex = assimpMesh.MaterialIndex,
                                   VertexBufferRange = new ModelData.BufferRange() { Slot = mesh.VertexBuffers.Count },
                                   IndexBufferRange = new ModelData.BufferRange() { Slot = mesh.IndexBuffers.Count }
                               };

            var vertexBuffer = new ModelData.VertexBuffer()
            {
                Layout = new List<VertexElement>()
            };
            mesh.VertexBuffers.Add(vertexBuffer);

            var indexBuffer = new ModelData.IndexBuffer();
            mesh.IndexBuffers.Add(indexBuffer);

            var layout = vertexBuffer.Layout;

            int vertexBufferElementSize = 0;

            // Add position
            layout.Add(VertexElement.PositionTransformed(Format.R32G32B32_Float, 0));
            vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector3>();

            // Add normals
            if (assimpMesh.HasNormals)
            {
                layout.Add(VertexElement.Normal(0, Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector3>();
            }

            // Add colors
            if (assimpMesh.VertexColorChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.VertexColorChannelCount; i++)
                {
                    if (assimpMesh.HasVertexColors(i))
                    {
                        layout.Add(VertexElement.Color(localIndex, Format.R32G32B32A32_Float, vertexBufferElementSize));
                        vertexBufferElementSize += Utilities.SizeOf<SharpDX.Color4>();
                        localIndex++;
                    }
                }
            }

            // Add textures
            if (assimpMesh.TextureCoordsChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.TextureCoordsChannelCount; i++)
                {
                    if (assimpMesh.HasTextureCoords(i))
                    {
                        var uvCount = assimpMesh.GetUVComponentCount(i);

                        if (uvCount == 2)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector2>();
                        }
                        else if (uvCount == 3)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32B32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector3>();
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexpected uv count");
                        }

                        localIndex++;
                    }
                }
            }

            // Add tangent / bitangent
            if (assimpMesh.HasTangentBasis)
            {
                layout.Add(VertexElement.Tangent(Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector3>();

                layout.Add(VertexElement.BiTangent(Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector3>();
            }

            // Extract Skinning Indices / Weights
            bool hasWeights = false;
            var skinningCount   = new int[assimpMesh.VertexCount];
            var skinningIndices = new Int4[assimpMesh.VertexCount];
            var skinningWeights = new Vector4[assimpMesh.VertexCount];

            if (assimpMesh.HasBones)
            {
                meshPart.BoneOffsetMatrices = new Matrix[assimpMesh.BoneCount];
                for (int i = 0; i < assimpMesh.Bones.Length; i++)
                {
                    var bone = assimpMesh.Bones[i];
                    meshPart.BoneOffsetMatrices[i] = ConvertMatrix(bone.OffsetMatrix);
                    if (bone.HasVertexWeights)
                    {
                        var boneNode = scene.RootNode.FindNode(bone.Name);
                        var boneIndex = skinnedBones[boneNode];
                        for (int j = 0; j < bone.VertexWeightCount; j++)
                        {
                            var weights = bone.VertexWeights[j];
                            var vertexSkinningCount = skinningCount[weights.VertexID];

                            skinningIndices[weights.VertexID][vertexSkinningCount] = boneIndex;

                            skinningWeights[weights.VertexID][vertexSkinningCount] = weights.Weight;

                            skinningCount[weights.VertexID] = ++vertexSkinningCount;
                        }

                        hasWeights = true;
                    }
                }

                if (hasWeights)
                {
                    layout.Add(VertexElement.BlendIndices(Format.R16G16B16A16_SInt, vertexBufferElementSize));
                    vertexBufferElementSize += Utilities.SizeOf<SharpDX.Int4>();

                    layout.Add(VertexElement.BlendWeights(Format.R32G32B32A32_Float, vertexBufferElementSize));
                    vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector4>();
                }
            }

            // Write all vertices
            meshPart.VertexBufferRange.Count = assimpMesh.VertexCount;
            vertexBuffer.Count = assimpMesh.VertexCount;
            vertexBuffer.Buffer = new byte[vertexBufferElementSize * assimpMesh.VertexCount];

            // Update the MaximumBufferSizeInBytes needed to load this model
            if (vertexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes)
            {
                model.MaximumBufferSizeInBytes = vertexBuffer.Buffer.Length;
            }

            var vertexStream = DataStream.Create(vertexBuffer.Buffer, true, true);
            for (int i = 0; i < assimpMesh.VertexCount; i++)
            {
                var position = assimpMesh.Vertices[i];
                vertexStream.Write(position);

                // Store bounding points for BoundingSphere pre-calculation
                boundingPoints[currentBoundingPointIndex++] = new Vector3(position.X, position.Y, position.Z);

                // Add normals
                if (assimpMesh.HasNormals)
                {
                    vertexStream.Write(assimpMesh.Normals[i]);
                }

                // Add colors
                if (assimpMesh.VertexColorChannelCount > 0)
                {
                    for (int j = 0; j < assimpMesh.VertexColorChannelCount; j++)
                    {
                        if (assimpMesh.HasVertexColors(j))
                        {
                            vertexStream.Write(assimpMesh.GetVertexColors(j)[i]);
                        }
                    }
                }

                // Add textures
                if (assimpMesh.TextureCoordsChannelCount > 0)
                {
                    for (int j = 0; j < assimpMesh.TextureCoordsChannelCount; j++)
                    {
                        if (assimpMesh.HasTextureCoords(j))
                        {
                            var uvCount = assimpMesh.GetUVComponentCount(j);

                            var uv = assimpMesh.GetTextureCoords(j)[i];

                            if (uvCount == 2)
                            {
                                vertexStream.Write(new Vector2(uv.X, uv.Y));
                            }
                            else
                            {
                                vertexStream.Write(uv);
                            }
                        }
                    }
                }

                // Add tangent / bitangent
                if (assimpMesh.HasTangentBasis)
                {
                    vertexStream.Write(assimpMesh.Tangents[i]);
                    vertexStream.Write(assimpMesh.BiTangents[i]);
                }

                // Add Skinning Indices/Weights
                if (assimpMesh.HasBones && hasWeights)
                {
                    vertexStream.Write(skinningIndices[i]);
                    vertexStream.Write(skinningWeights[i]);
                }
            }
            vertexStream.Dispose();

            // Write all indices
            var indices = assimpMesh.GetIntIndices();
            indexBuffer.Count = indices.Length;
            meshPart.IndexBufferRange.Count = indices.Length;
            if (meshPart.VertexBufferRange.Count < 65536)
            {
                // Write only short indices if count is less than the size of a short
                indexBuffer.Buffer = new byte[indices.Length * 2];
                using (var indexStream = DataStream.Create(indexBuffer.Buffer, true, true))
                    foreach (int index in indices) indexStream.Write((ushort)index);
            }
            else
            {
                // Otherwise, use full 32-bit precision to store indices
                indexBuffer.Buffer = new byte[indices.Length * 4];
                using (var indexStream = DataStream.Create(indexBuffer.Buffer, true, true))
                    indexStream.WriteRange(indices);
            }

            // Update the MaximumBufferSizeInBytes needed to load this model
            if (indexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes)
            {
                model.MaximumBufferSizeInBytes = indexBuffer.Buffer.Length;
            }

            return meshPart;
        }
Beispiel #40
0
 public static void Test(ref Int4 m, int s, out Int4 result)
 {
     //no locals initialized
     Scale(ref m, s, out var temp);
     Scale(ref temp, s, out result);
 }
Beispiel #41
0
 /// <summary>
 /// Clears a read-write Buffer. This buffer must have been created with read-write/unordered access.
 /// </summary>
 /// <param name="buffer">The buffer.</param>
 /// <param name="value">The value.</param>
 /// <exception cref="System.ArgumentNullException">buffer</exception>
 /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;buffer</exception>
 public void ClearReadWrite(Buffer buffer, Int4 value)
 {
     throw new NotImplementedException();
 }
Beispiel #42
0
 /// <summary>
 /// Clears a read-write Texture. This texture must have been created with read-write/unordered access.
 /// </summary>
 /// <param name="texture">The texture.</param>
 /// <param name="value">The value.</param>
 /// <exception cref="System.ArgumentNullException">texture</exception>
 /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;texture</exception>
 public void ClearReadWrite(Texture texture, Int4 value)
 {
     throw new NotImplementedException();
 }
Beispiel #43
0
 public static Int4 Clamp(Int4 v, int min, int max)
 {
     return new Int4(Clamp(v.x, min, max), Clamp(v.y, min, max), Clamp(v.z, min, max), Clamp(v.w, min, max));
 }